Merge "Merge android14-tests-dev" into main
diff --git a/Android.bp b/Android.bp
index d668c2b..2b0c301 100644
--- a/Android.bp
+++ b/Android.bp
@@ -65,6 +65,7 @@
":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
":perfetto_protos_perfetto_trace_android_zero_gen",
":perfetto_protos_perfetto_trace_chrome_zero_gen",
+ ":perfetto_protos_perfetto_trace_etw_zero_gen",
":perfetto_protos_perfetto_trace_filesystem_zero_gen",
":perfetto_protos_perfetto_trace_ftrace_zero_gen",
":perfetto_protos_perfetto_trace_gpu_zero_gen",
@@ -151,6 +152,7 @@
"perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
"perfetto_protos_perfetto_trace_android_zero_gen_headers",
"perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_etw_zero_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
"perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
"perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
@@ -331,6 +333,7 @@
":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
":perfetto_protos_perfetto_trace_android_zero_gen",
":perfetto_protos_perfetto_trace_chrome_zero_gen",
+ ":perfetto_protos_perfetto_trace_etw_zero_gen",
":perfetto_protos_perfetto_trace_filesystem_zero_gen",
":perfetto_protos_perfetto_trace_ftrace_zero_gen",
":perfetto_protos_perfetto_trace_gpu_zero_gen",
@@ -426,6 +429,7 @@
"perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
"perfetto_protos_perfetto_trace_android_zero_gen_headers",
"perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_etw_zero_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
"perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
"perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
@@ -534,6 +538,7 @@
":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
":perfetto_protos_perfetto_trace_android_zero_gen",
":perfetto_protos_perfetto_trace_chrome_zero_gen",
+ ":perfetto_protos_perfetto_trace_etw_zero_gen",
":perfetto_protos_perfetto_trace_filesystem_zero_gen",
":perfetto_protos_perfetto_trace_ftrace_zero_gen",
":perfetto_protos_perfetto_trace_gpu_zero_gen",
@@ -639,6 +644,7 @@
"perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
"perfetto_protos_perfetto_trace_android_zero_gen_headers",
"perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_etw_zero_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
"perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
"perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
@@ -776,6 +782,7 @@
":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
":perfetto_protos_perfetto_trace_android_zero_gen",
":perfetto_protos_perfetto_trace_chrome_zero_gen",
+ ":perfetto_protos_perfetto_trace_etw_zero_gen",
":perfetto_protos_perfetto_trace_filesystem_zero_gen",
":perfetto_protos_perfetto_trace_ftrace_zero_gen",
":perfetto_protos_perfetto_trace_gpu_zero_gen",
@@ -860,6 +867,7 @@
"perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
"perfetto_protos_perfetto_trace_android_zero_gen_headers",
"perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_etw_zero_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
"perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
"perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
@@ -945,6 +953,7 @@
":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
":perfetto_protos_perfetto_trace_android_zero_gen",
":perfetto_protos_perfetto_trace_chrome_zero_gen",
+ ":perfetto_protos_perfetto_trace_etw_zero_gen",
":perfetto_protos_perfetto_trace_filesystem_zero_gen",
":perfetto_protos_perfetto_trace_ftrace_zero_gen",
":perfetto_protos_perfetto_trace_gpu_zero_gen",
@@ -1032,6 +1041,7 @@
"perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
"perfetto_protos_perfetto_trace_android_zero_gen_headers",
"perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_etw_zero_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
"perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
"perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
@@ -1084,6 +1094,7 @@
"perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
"perfetto_protos_perfetto_trace_android_zero_gen_headers",
"perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_etw_zero_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
"perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
"perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
@@ -1166,6 +1177,7 @@
":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
":perfetto_protos_perfetto_trace_android_zero_gen",
":perfetto_protos_perfetto_trace_chrome_zero_gen",
+ ":perfetto_protos_perfetto_trace_etw_zero_gen",
":perfetto_protos_perfetto_trace_filesystem_zero_gen",
":perfetto_protos_perfetto_trace_ftrace_zero_gen",
":perfetto_protos_perfetto_trace_gpu_zero_gen",
@@ -1243,6 +1255,7 @@
"perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
"perfetto_protos_perfetto_trace_android_zero_gen_headers",
"perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_etw_zero_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
"perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
"perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
@@ -1334,6 +1347,8 @@
":perfetto_protos_perfetto_trace_android_zero_gen",
":perfetto_protos_perfetto_trace_chrome_cpp_gen",
":perfetto_protos_perfetto_trace_chrome_zero_gen",
+ ":perfetto_protos_perfetto_trace_etw_cpp_gen",
+ ":perfetto_protos_perfetto_trace_etw_zero_gen",
":perfetto_protos_perfetto_trace_filesystem_cpp_gen",
":perfetto_protos_perfetto_trace_filesystem_zero_gen",
":perfetto_protos_perfetto_trace_ftrace_cpp_gen",
@@ -1464,6 +1479,8 @@
"perfetto_protos_perfetto_trace_android_zero_gen_headers",
"perfetto_protos_perfetto_trace_chrome_cpp_gen_headers",
"perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_etw_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_etw_zero_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_cpp_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
"perfetto_protos_perfetto_trace_ftrace_cpp_gen_headers",
@@ -1533,6 +1550,8 @@
"perfetto_protos_perfetto_trace_android_zero_gen_headers",
"perfetto_protos_perfetto_trace_chrome_cpp_gen_headers",
"perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_etw_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_etw_zero_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_cpp_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
"perfetto_protos_perfetto_trace_ftrace_cpp_gen_headers",
@@ -1626,6 +1645,8 @@
":perfetto_protos_perfetto_trace_android_zero_gen",
":perfetto_protos_perfetto_trace_chrome_cpp_gen",
":perfetto_protos_perfetto_trace_chrome_zero_gen",
+ ":perfetto_protos_perfetto_trace_etw_cpp_gen",
+ ":perfetto_protos_perfetto_trace_etw_zero_gen",
":perfetto_protos_perfetto_trace_filesystem_cpp_gen",
":perfetto_protos_perfetto_trace_filesystem_zero_gen",
":perfetto_protos_perfetto_trace_ftrace_cpp_gen",
@@ -1742,6 +1763,8 @@
"perfetto_protos_perfetto_trace_android_zero_gen_headers",
"perfetto_protos_perfetto_trace_chrome_cpp_gen_headers",
"perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_etw_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_etw_zero_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_cpp_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
"perfetto_protos_perfetto_trace_ftrace_cpp_gen_headers",
@@ -1811,6 +1834,8 @@
"perfetto_protos_perfetto_trace_android_zero_gen_headers",
"perfetto_protos_perfetto_trace_chrome_cpp_gen_headers",
"perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_etw_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_etw_zero_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_cpp_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
"perfetto_protos_perfetto_trace_ftrace_cpp_gen_headers",
@@ -2138,6 +2163,9 @@
":perfetto_protos_perfetto_trace_chrome_cpp_gen",
":perfetto_protos_perfetto_trace_chrome_lite_gen",
":perfetto_protos_perfetto_trace_chrome_zero_gen",
+ ":perfetto_protos_perfetto_trace_etw_cpp_gen",
+ ":perfetto_protos_perfetto_trace_etw_lite_gen",
+ ":perfetto_protos_perfetto_trace_etw_zero_gen",
":perfetto_protos_perfetto_trace_filesystem_cpp_gen",
":perfetto_protos_perfetto_trace_filesystem_lite_gen",
":perfetto_protos_perfetto_trace_filesystem_zero_gen",
@@ -2312,6 +2340,8 @@
":perfetto_src_traced_probes_statsd_client_statsd_client",
":perfetto_src_traced_probes_sys_stats_sys_stats",
":perfetto_src_traced_probes_system_info_system_info",
+ ":perfetto_src_traced_relay_integrationtests",
+ ":perfetto_src_traced_relay_lib",
":perfetto_src_tracing_client_api_without_backends",
":perfetto_src_tracing_common",
":perfetto_src_tracing_core_core",
@@ -2406,6 +2436,9 @@
"perfetto_protos_perfetto_trace_chrome_cpp_gen_headers",
"perfetto_protos_perfetto_trace_chrome_lite_gen_headers",
"perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_etw_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_etw_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_etw_zero_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_cpp_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_lite_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
@@ -2489,16 +2522,26 @@
}
// GN: //protos/perfetto/bigtrace:lite
-genrule {
- name: "perfetto_protos_perfetto_bigtrace_lite_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_bigtrace_lite",
srcs: [
"protos/perfetto/bigtrace/orchestrator.proto",
"protos/perfetto/bigtrace/worker.proto",
],
+}
+
+// GN: //protos/perfetto/bigtrace:lite
+genrule {
+ name: "perfetto_protos_perfetto_bigtrace_lite_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_bigtrace_lite",
+ ":perfetto_protos_perfetto_common_lite",
+ ":perfetto_protos_perfetto_trace_processor_lite",
+ ],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_bigtrace_lite)",
out: [
"external/perfetto/protos/perfetto/bigtrace/orchestrator.pb.cc",
"external/perfetto/protos/perfetto/bigtrace/worker.pb.cc",
@@ -2509,13 +2552,14 @@
genrule {
name: "perfetto_protos_perfetto_bigtrace_lite_gen_headers",
srcs: [
- "protos/perfetto/bigtrace/orchestrator.proto",
- "protos/perfetto/bigtrace/worker.proto",
+ ":perfetto_protos_perfetto_bigtrace_lite",
+ ":perfetto_protos_perfetto_common_lite",
+ ":perfetto_protos_perfetto_trace_processor_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_bigtrace_lite)",
out: [
"external/perfetto/protos/perfetto/bigtrace/orchestrator.pb.h",
"external/perfetto/protos/perfetto/bigtrace/worker.pb.h",
@@ -2527,8 +2571,8 @@
}
// GN: //protos/perfetto/common:cpp
-genrule {
- name: "perfetto_protos_perfetto_common_cpp_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_common_cpp",
srcs: [
"protos/perfetto/common/android_energy_consumer_descriptor.proto",
"protos/perfetto/common/android_log_constants.proto",
@@ -2547,11 +2591,19 @@
"protos/perfetto/common/tracing_service_state.proto",
"protos/perfetto/common/track_event_descriptor.proto",
],
+}
+
+// GN: //protos/perfetto/common:cpp
+genrule {
+ name: "perfetto_protos_perfetto_common_cpp_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_common_cpp",
+ ],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_common_cpp)",
out: [
"external/perfetto/protos/perfetto/common/android_energy_consumer_descriptor.gen.cc",
"external/perfetto/protos/perfetto/common/android_log_constants.gen.cc",
@@ -2576,28 +2628,13 @@
genrule {
name: "perfetto_protos_perfetto_common_cpp_gen_headers",
srcs: [
- "protos/perfetto/common/android_energy_consumer_descriptor.proto",
- "protos/perfetto/common/android_log_constants.proto",
- "protos/perfetto/common/builtin_clock.proto",
- "protos/perfetto/common/commit_data_request.proto",
- "protos/perfetto/common/data_source_descriptor.proto",
- "protos/perfetto/common/descriptor.proto",
- "protos/perfetto/common/ftrace_descriptor.proto",
- "protos/perfetto/common/gpu_counter_descriptor.proto",
- "protos/perfetto/common/interceptor_descriptor.proto",
- "protos/perfetto/common/observable_events.proto",
- "protos/perfetto/common/perf_events.proto",
- "protos/perfetto/common/sys_stats_counters.proto",
- "protos/perfetto/common/trace_stats.proto",
- "protos/perfetto/common/tracing_service_capabilities.proto",
- "protos/perfetto/common/tracing_service_state.proto",
- "protos/perfetto/common/track_event_descriptor.proto",
+ ":perfetto_protos_perfetto_common_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_common_cpp)",
out: [
"external/perfetto/protos/perfetto/common/android_energy_consumer_descriptor.gen.h",
"external/perfetto/protos/perfetto/common/android_log_constants.gen.h",
@@ -2623,8 +2660,8 @@
}
// GN: //protos/perfetto/common:lite
-genrule {
- name: "perfetto_protos_perfetto_common_lite_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_common_lite",
srcs: [
"protos/perfetto/common/android_energy_consumer_descriptor.proto",
"protos/perfetto/common/android_log_constants.proto",
@@ -2643,10 +2680,18 @@
"protos/perfetto/common/tracing_service_state.proto",
"protos/perfetto/common/track_event_descriptor.proto",
],
+}
+
+// GN: //protos/perfetto/common:lite
+genrule {
+ name: "perfetto_protos_perfetto_common_lite_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_common_lite",
+ ],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_common_lite)",
out: [
"external/perfetto/protos/perfetto/common/android_energy_consumer_descriptor.pb.cc",
"external/perfetto/protos/perfetto/common/android_log_constants.pb.cc",
@@ -2671,27 +2716,12 @@
genrule {
name: "perfetto_protos_perfetto_common_lite_gen_headers",
srcs: [
- "protos/perfetto/common/android_energy_consumer_descriptor.proto",
- "protos/perfetto/common/android_log_constants.proto",
- "protos/perfetto/common/builtin_clock.proto",
- "protos/perfetto/common/commit_data_request.proto",
- "protos/perfetto/common/data_source_descriptor.proto",
- "protos/perfetto/common/descriptor.proto",
- "protos/perfetto/common/ftrace_descriptor.proto",
- "protos/perfetto/common/gpu_counter_descriptor.proto",
- "protos/perfetto/common/interceptor_descriptor.proto",
- "protos/perfetto/common/observable_events.proto",
- "protos/perfetto/common/perf_events.proto",
- "protos/perfetto/common/sys_stats_counters.proto",
- "protos/perfetto/common/trace_stats.proto",
- "protos/perfetto/common/tracing_service_capabilities.proto",
- "protos/perfetto/common/tracing_service_state.proto",
- "protos/perfetto/common/track_event_descriptor.proto",
+ ":perfetto_protos_perfetto_common_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_common_lite)",
out: [
"external/perfetto/protos/perfetto/common/android_energy_consumer_descriptor.pb.h",
"external/perfetto/protos/perfetto/common/android_log_constants.pb.h",
@@ -2717,8 +2747,8 @@
}
// GN: //protos/perfetto/common:zero
-genrule {
- name: "perfetto_protos_perfetto_common_zero_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_common_zero",
srcs: [
"protos/perfetto/common/android_energy_consumer_descriptor.proto",
"protos/perfetto/common/android_log_constants.proto",
@@ -2737,11 +2767,19 @@
"protos/perfetto/common/tracing_service_state.proto",
"protos/perfetto/common/track_event_descriptor.proto",
],
+}
+
+// GN: //protos/perfetto/common:zero
+genrule {
+ name: "perfetto_protos_perfetto_common_zero_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_common_zero",
+ ],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_common_zero)",
out: [
"external/perfetto/protos/perfetto/common/android_energy_consumer_descriptor.pbzero.cc",
"external/perfetto/protos/perfetto/common/android_log_constants.pbzero.cc",
@@ -2766,28 +2804,13 @@
genrule {
name: "perfetto_protos_perfetto_common_zero_gen_headers",
srcs: [
- "protos/perfetto/common/android_energy_consumer_descriptor.proto",
- "protos/perfetto/common/android_log_constants.proto",
- "protos/perfetto/common/builtin_clock.proto",
- "protos/perfetto/common/commit_data_request.proto",
- "protos/perfetto/common/data_source_descriptor.proto",
- "protos/perfetto/common/descriptor.proto",
- "protos/perfetto/common/ftrace_descriptor.proto",
- "protos/perfetto/common/gpu_counter_descriptor.proto",
- "protos/perfetto/common/interceptor_descriptor.proto",
- "protos/perfetto/common/observable_events.proto",
- "protos/perfetto/common/perf_events.proto",
- "protos/perfetto/common/sys_stats_counters.proto",
- "protos/perfetto/common/trace_stats.proto",
- "protos/perfetto/common/tracing_service_capabilities.proto",
- "protos/perfetto/common/tracing_service_state.proto",
- "protos/perfetto/common/track_event_descriptor.proto",
+ ":perfetto_protos_perfetto_common_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_common_zero)",
out: [
"external/perfetto/protos/perfetto/common/android_energy_consumer_descriptor.pbzero.h",
"external/perfetto/protos/perfetto/common/android_log_constants.pbzero.h",
@@ -2813,8 +2836,8 @@
}
// GN: //protos/perfetto/config/android:cpp
-genrule {
- name: "perfetto_protos_perfetto_config_android_cpp_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_config_android_cpp",
srcs: [
"protos/perfetto/config/android/android_game_intervention_list_config.proto",
"protos/perfetto/config/android/android_log_config.proto",
@@ -2826,11 +2849,20 @@
"protos/perfetto/config/android/surfaceflinger_layers_config.proto",
"protos/perfetto/config/android/surfaceflinger_transactions_config.proto",
],
+}
+
+// GN: //protos/perfetto/config/android:cpp
+genrule {
+ name: "perfetto_protos_perfetto_config_android_cpp_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_common_cpp",
+ ":perfetto_protos_perfetto_config_android_cpp",
+ ],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_android_cpp)",
out: [
"external/perfetto/protos/perfetto/config/android/android_game_intervention_list_config.gen.cc",
"external/perfetto/protos/perfetto/config/android/android_log_config.gen.cc",
@@ -2848,21 +2880,14 @@
genrule {
name: "perfetto_protos_perfetto_config_android_cpp_gen_headers",
srcs: [
- "protos/perfetto/config/android/android_game_intervention_list_config.proto",
- "protos/perfetto/config/android/android_log_config.proto",
- "protos/perfetto/config/android/android_polled_state_config.proto",
- "protos/perfetto/config/android/android_sdk_sysprop_guard_config.proto",
- "protos/perfetto/config/android/android_system_property_config.proto",
- "protos/perfetto/config/android/network_trace_config.proto",
- "protos/perfetto/config/android/packages_list_config.proto",
- "protos/perfetto/config/android/surfaceflinger_layers_config.proto",
- "protos/perfetto/config/android/surfaceflinger_transactions_config.proto",
+ ":perfetto_protos_perfetto_common_cpp",
+ ":perfetto_protos_perfetto_config_android_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_android_cpp)",
out: [
"external/perfetto/protos/perfetto/config/android/android_game_intervention_list_config.gen.h",
"external/perfetto/protos/perfetto/config/android/android_log_config.gen.h",
@@ -2881,8 +2906,8 @@
}
// GN: //protos/perfetto/config/android:lite
-genrule {
- name: "perfetto_protos_perfetto_config_android_lite_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_config_android_lite",
srcs: [
"protos/perfetto/config/android/android_game_intervention_list_config.proto",
"protos/perfetto/config/android/android_log_config.proto",
@@ -2894,10 +2919,19 @@
"protos/perfetto/config/android/surfaceflinger_layers_config.proto",
"protos/perfetto/config/android/surfaceflinger_transactions_config.proto",
],
+}
+
+// GN: //protos/perfetto/config/android:lite
+genrule {
+ name: "perfetto_protos_perfetto_config_android_lite_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_common_lite",
+ ":perfetto_protos_perfetto_config_android_lite",
+ ],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_android_lite)",
out: [
"external/perfetto/protos/perfetto/config/android/android_game_intervention_list_config.pb.cc",
"external/perfetto/protos/perfetto/config/android/android_log_config.pb.cc",
@@ -2915,20 +2949,13 @@
genrule {
name: "perfetto_protos_perfetto_config_android_lite_gen_headers",
srcs: [
- "protos/perfetto/config/android/android_game_intervention_list_config.proto",
- "protos/perfetto/config/android/android_log_config.proto",
- "protos/perfetto/config/android/android_polled_state_config.proto",
- "protos/perfetto/config/android/android_sdk_sysprop_guard_config.proto",
- "protos/perfetto/config/android/android_system_property_config.proto",
- "protos/perfetto/config/android/network_trace_config.proto",
- "protos/perfetto/config/android/packages_list_config.proto",
- "protos/perfetto/config/android/surfaceflinger_layers_config.proto",
- "protos/perfetto/config/android/surfaceflinger_transactions_config.proto",
+ ":perfetto_protos_perfetto_common_lite",
+ ":perfetto_protos_perfetto_config_android_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_android_lite)",
out: [
"external/perfetto/protos/perfetto/config/android/android_game_intervention_list_config.pb.h",
"external/perfetto/protos/perfetto/config/android/android_log_config.pb.h",
@@ -2947,8 +2974,8 @@
}
// GN: //protos/perfetto/config/android:zero
-genrule {
- name: "perfetto_protos_perfetto_config_android_zero_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_config_android_zero",
srcs: [
"protos/perfetto/config/android/android_game_intervention_list_config.proto",
"protos/perfetto/config/android/android_log_config.proto",
@@ -2960,11 +2987,20 @@
"protos/perfetto/config/android/surfaceflinger_layers_config.proto",
"protos/perfetto/config/android/surfaceflinger_transactions_config.proto",
],
+}
+
+// GN: //protos/perfetto/config/android:zero
+genrule {
+ name: "perfetto_protos_perfetto_config_android_zero_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_common_zero",
+ ":perfetto_protos_perfetto_config_android_zero",
+ ],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_android_zero)",
out: [
"external/perfetto/protos/perfetto/config/android/android_game_intervention_list_config.pbzero.cc",
"external/perfetto/protos/perfetto/config/android/android_log_config.pbzero.cc",
@@ -2982,21 +3018,14 @@
genrule {
name: "perfetto_protos_perfetto_config_android_zero_gen_headers",
srcs: [
- "protos/perfetto/config/android/android_game_intervention_list_config.proto",
- "protos/perfetto/config/android/android_log_config.proto",
- "protos/perfetto/config/android/android_polled_state_config.proto",
- "protos/perfetto/config/android/android_sdk_sysprop_guard_config.proto",
- "protos/perfetto/config/android/android_system_property_config.proto",
- "protos/perfetto/config/android/network_trace_config.proto",
- "protos/perfetto/config/android/packages_list_config.proto",
- "protos/perfetto/config/android/surfaceflinger_layers_config.proto",
- "protos/perfetto/config/android/surfaceflinger_transactions_config.proto",
+ ":perfetto_protos_perfetto_common_zero",
+ ":perfetto_protos_perfetto_config_android_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_android_zero)",
out: [
"external/perfetto/protos/perfetto/config/android/android_game_intervention_list_config.pbzero.h",
"external/perfetto/protos/perfetto/config/android/android_log_config.pbzero.h",
@@ -3015,8 +3044,8 @@
}
// GN: //protos/perfetto/config:cpp
-genrule {
- name: "perfetto_protos_perfetto_config_cpp_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_config_cpp",
srcs: [
"protos/perfetto/config/chrome/chrome_config.proto",
"protos/perfetto/config/chrome/scenario_config.proto",
@@ -3026,11 +3055,32 @@
"protos/perfetto/config/test_config.proto",
"protos/perfetto/config/trace_config.proto",
],
+}
+
+// GN: //protos/perfetto/config:cpp
+genrule {
+ name: "perfetto_protos_perfetto_config_cpp_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_common_cpp",
+ ":perfetto_protos_perfetto_config_android_cpp",
+ ":perfetto_protos_perfetto_config_cpp",
+ ":perfetto_protos_perfetto_config_ftrace_cpp",
+ ":perfetto_protos_perfetto_config_gpu_cpp",
+ ":perfetto_protos_perfetto_config_inode_file_cpp",
+ ":perfetto_protos_perfetto_config_interceptors_cpp",
+ ":perfetto_protos_perfetto_config_power_cpp",
+ ":perfetto_protos_perfetto_config_process_stats_cpp",
+ ":perfetto_protos_perfetto_config_profiling_cpp",
+ ":perfetto_protos_perfetto_config_statsd_cpp",
+ ":perfetto_protos_perfetto_config_sys_stats_cpp",
+ ":perfetto_protos_perfetto_config_system_info_cpp",
+ ":perfetto_protos_perfetto_config_track_event_cpp",
+ ],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_cpp)",
out: [
"external/perfetto/protos/perfetto/config/chrome/chrome_config.gen.cc",
"external/perfetto/protos/perfetto/config/chrome/scenario_config.gen.cc",
@@ -3046,19 +3096,26 @@
genrule {
name: "perfetto_protos_perfetto_config_cpp_gen_headers",
srcs: [
- "protos/perfetto/config/chrome/chrome_config.proto",
- "protos/perfetto/config/chrome/scenario_config.proto",
- "protos/perfetto/config/data_source_config.proto",
- "protos/perfetto/config/interceptor_config.proto",
- "protos/perfetto/config/stress_test_config.proto",
- "protos/perfetto/config/test_config.proto",
- "protos/perfetto/config/trace_config.proto",
+ ":perfetto_protos_perfetto_common_cpp",
+ ":perfetto_protos_perfetto_config_android_cpp",
+ ":perfetto_protos_perfetto_config_cpp",
+ ":perfetto_protos_perfetto_config_ftrace_cpp",
+ ":perfetto_protos_perfetto_config_gpu_cpp",
+ ":perfetto_protos_perfetto_config_inode_file_cpp",
+ ":perfetto_protos_perfetto_config_interceptors_cpp",
+ ":perfetto_protos_perfetto_config_power_cpp",
+ ":perfetto_protos_perfetto_config_process_stats_cpp",
+ ":perfetto_protos_perfetto_config_profiling_cpp",
+ ":perfetto_protos_perfetto_config_statsd_cpp",
+ ":perfetto_protos_perfetto_config_sys_stats_cpp",
+ ":perfetto_protos_perfetto_config_system_info_cpp",
+ ":perfetto_protos_perfetto_config_track_event_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_cpp)",
out: [
"external/perfetto/protos/perfetto/config/chrome/chrome_config.gen.h",
"external/perfetto/protos/perfetto/config/chrome/scenario_config.gen.h",
@@ -3136,16 +3193,24 @@
}
// GN: //protos/perfetto/config/ftrace:cpp
+filegroup {
+ name: "perfetto_protos_perfetto_config_ftrace_cpp",
+ srcs: [
+ "protos/perfetto/config/ftrace/ftrace_config.proto",
+ ],
+}
+
+// GN: //protos/perfetto/config/ftrace:cpp
genrule {
name: "perfetto_protos_perfetto_config_ftrace_cpp_gen",
srcs: [
- "protos/perfetto/config/ftrace/ftrace_config.proto",
+ ":perfetto_protos_perfetto_config_ftrace_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_ftrace_cpp)",
out: [
"external/perfetto/protos/perfetto/config/ftrace/ftrace_config.gen.cc",
],
@@ -3155,13 +3220,13 @@
genrule {
name: "perfetto_protos_perfetto_config_ftrace_cpp_gen_headers",
srcs: [
- "protos/perfetto/config/ftrace/ftrace_config.proto",
+ ":perfetto_protos_perfetto_config_ftrace_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_ftrace_cpp)",
out: [
"external/perfetto/protos/perfetto/config/ftrace/ftrace_config.gen.h",
],
@@ -3172,15 +3237,23 @@
}
// GN: //protos/perfetto/config/ftrace:lite
+filegroup {
+ name: "perfetto_protos_perfetto_config_ftrace_lite",
+ srcs: [
+ "protos/perfetto/config/ftrace/ftrace_config.proto",
+ ],
+}
+
+// GN: //protos/perfetto/config/ftrace:lite
genrule {
name: "perfetto_protos_perfetto_config_ftrace_lite_gen",
srcs: [
- "protos/perfetto/config/ftrace/ftrace_config.proto",
+ ":perfetto_protos_perfetto_config_ftrace_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_ftrace_lite)",
out: [
"external/perfetto/protos/perfetto/config/ftrace/ftrace_config.pb.cc",
],
@@ -3190,12 +3263,12 @@
genrule {
name: "perfetto_protos_perfetto_config_ftrace_lite_gen_headers",
srcs: [
- "protos/perfetto/config/ftrace/ftrace_config.proto",
+ ":perfetto_protos_perfetto_config_ftrace_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_ftrace_lite)",
out: [
"external/perfetto/protos/perfetto/config/ftrace/ftrace_config.pb.h",
],
@@ -3206,16 +3279,24 @@
}
// GN: //protos/perfetto/config/ftrace:zero
+filegroup {
+ name: "perfetto_protos_perfetto_config_ftrace_zero",
+ srcs: [
+ "protos/perfetto/config/ftrace/ftrace_config.proto",
+ ],
+}
+
+// GN: //protos/perfetto/config/ftrace:zero
genrule {
name: "perfetto_protos_perfetto_config_ftrace_zero_gen",
srcs: [
- "protos/perfetto/config/ftrace/ftrace_config.proto",
+ ":perfetto_protos_perfetto_config_ftrace_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_ftrace_zero)",
out: [
"external/perfetto/protos/perfetto/config/ftrace/ftrace_config.pbzero.cc",
],
@@ -3225,13 +3306,13 @@
genrule {
name: "perfetto_protos_perfetto_config_ftrace_zero_gen_headers",
srcs: [
- "protos/perfetto/config/ftrace/ftrace_config.proto",
+ ":perfetto_protos_perfetto_config_ftrace_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_ftrace_zero)",
out: [
"external/perfetto/protos/perfetto/config/ftrace/ftrace_config.pbzero.h",
],
@@ -3242,17 +3323,25 @@
}
// GN: //protos/perfetto/config/gpu:cpp
-genrule {
- name: "perfetto_protos_perfetto_config_gpu_cpp_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_config_gpu_cpp",
srcs: [
"protos/perfetto/config/gpu/gpu_counter_config.proto",
"protos/perfetto/config/gpu/vulkan_memory_config.proto",
],
+}
+
+// GN: //protos/perfetto/config/gpu:cpp
+genrule {
+ name: "perfetto_protos_perfetto_config_gpu_cpp_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_config_gpu_cpp",
+ ],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_gpu_cpp)",
out: [
"external/perfetto/protos/perfetto/config/gpu/gpu_counter_config.gen.cc",
"external/perfetto/protos/perfetto/config/gpu/vulkan_memory_config.gen.cc",
@@ -3263,14 +3352,13 @@
genrule {
name: "perfetto_protos_perfetto_config_gpu_cpp_gen_headers",
srcs: [
- "protos/perfetto/config/gpu/gpu_counter_config.proto",
- "protos/perfetto/config/gpu/vulkan_memory_config.proto",
+ ":perfetto_protos_perfetto_config_gpu_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_gpu_cpp)",
out: [
"external/perfetto/protos/perfetto/config/gpu/gpu_counter_config.gen.h",
"external/perfetto/protos/perfetto/config/gpu/vulkan_memory_config.gen.h",
@@ -3282,16 +3370,24 @@
}
// GN: //protos/perfetto/config/gpu:lite
-genrule {
- name: "perfetto_protos_perfetto_config_gpu_lite_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_config_gpu_lite",
srcs: [
"protos/perfetto/config/gpu/gpu_counter_config.proto",
"protos/perfetto/config/gpu/vulkan_memory_config.proto",
],
+}
+
+// GN: //protos/perfetto/config/gpu:lite
+genrule {
+ name: "perfetto_protos_perfetto_config_gpu_lite_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_config_gpu_lite",
+ ],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_gpu_lite)",
out: [
"external/perfetto/protos/perfetto/config/gpu/gpu_counter_config.pb.cc",
"external/perfetto/protos/perfetto/config/gpu/vulkan_memory_config.pb.cc",
@@ -3302,13 +3398,12 @@
genrule {
name: "perfetto_protos_perfetto_config_gpu_lite_gen_headers",
srcs: [
- "protos/perfetto/config/gpu/gpu_counter_config.proto",
- "protos/perfetto/config/gpu/vulkan_memory_config.proto",
+ ":perfetto_protos_perfetto_config_gpu_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_gpu_lite)",
out: [
"external/perfetto/protos/perfetto/config/gpu/gpu_counter_config.pb.h",
"external/perfetto/protos/perfetto/config/gpu/vulkan_memory_config.pb.h",
@@ -3320,17 +3415,25 @@
}
// GN: //protos/perfetto/config/gpu:zero
-genrule {
- name: "perfetto_protos_perfetto_config_gpu_zero_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_config_gpu_zero",
srcs: [
"protos/perfetto/config/gpu/gpu_counter_config.proto",
"protos/perfetto/config/gpu/vulkan_memory_config.proto",
],
+}
+
+// GN: //protos/perfetto/config/gpu:zero
+genrule {
+ name: "perfetto_protos_perfetto_config_gpu_zero_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_config_gpu_zero",
+ ],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_gpu_zero)",
out: [
"external/perfetto/protos/perfetto/config/gpu/gpu_counter_config.pbzero.cc",
"external/perfetto/protos/perfetto/config/gpu/vulkan_memory_config.pbzero.cc",
@@ -3341,14 +3444,13 @@
genrule {
name: "perfetto_protos_perfetto_config_gpu_zero_gen_headers",
srcs: [
- "protos/perfetto/config/gpu/gpu_counter_config.proto",
- "protos/perfetto/config/gpu/vulkan_memory_config.proto",
+ ":perfetto_protos_perfetto_config_gpu_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_gpu_zero)",
out: [
"external/perfetto/protos/perfetto/config/gpu/gpu_counter_config.pbzero.h",
"external/perfetto/protos/perfetto/config/gpu/vulkan_memory_config.pbzero.h",
@@ -3360,16 +3462,24 @@
}
// GN: //protos/perfetto/config/inode_file:cpp
+filegroup {
+ name: "perfetto_protos_perfetto_config_inode_file_cpp",
+ srcs: [
+ "protos/perfetto/config/inode_file/inode_file_config.proto",
+ ],
+}
+
+// GN: //protos/perfetto/config/inode_file:cpp
genrule {
name: "perfetto_protos_perfetto_config_inode_file_cpp_gen",
srcs: [
- "protos/perfetto/config/inode_file/inode_file_config.proto",
+ ":perfetto_protos_perfetto_config_inode_file_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_inode_file_cpp)",
out: [
"external/perfetto/protos/perfetto/config/inode_file/inode_file_config.gen.cc",
],
@@ -3379,13 +3489,13 @@
genrule {
name: "perfetto_protos_perfetto_config_inode_file_cpp_gen_headers",
srcs: [
- "protos/perfetto/config/inode_file/inode_file_config.proto",
+ ":perfetto_protos_perfetto_config_inode_file_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_inode_file_cpp)",
out: [
"external/perfetto/protos/perfetto/config/inode_file/inode_file_config.gen.h",
],
@@ -3396,15 +3506,23 @@
}
// GN: //protos/perfetto/config/inode_file:lite
+filegroup {
+ name: "perfetto_protos_perfetto_config_inode_file_lite",
+ srcs: [
+ "protos/perfetto/config/inode_file/inode_file_config.proto",
+ ],
+}
+
+// GN: //protos/perfetto/config/inode_file:lite
genrule {
name: "perfetto_protos_perfetto_config_inode_file_lite_gen",
srcs: [
- "protos/perfetto/config/inode_file/inode_file_config.proto",
+ ":perfetto_protos_perfetto_config_inode_file_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_inode_file_lite)",
out: [
"external/perfetto/protos/perfetto/config/inode_file/inode_file_config.pb.cc",
],
@@ -3414,12 +3532,12 @@
genrule {
name: "perfetto_protos_perfetto_config_inode_file_lite_gen_headers",
srcs: [
- "protos/perfetto/config/inode_file/inode_file_config.proto",
+ ":perfetto_protos_perfetto_config_inode_file_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_inode_file_lite)",
out: [
"external/perfetto/protos/perfetto/config/inode_file/inode_file_config.pb.h",
],
@@ -3430,16 +3548,24 @@
}
// GN: //protos/perfetto/config/inode_file:zero
+filegroup {
+ name: "perfetto_protos_perfetto_config_inode_file_zero",
+ srcs: [
+ "protos/perfetto/config/inode_file/inode_file_config.proto",
+ ],
+}
+
+// GN: //protos/perfetto/config/inode_file:zero
genrule {
name: "perfetto_protos_perfetto_config_inode_file_zero_gen",
srcs: [
- "protos/perfetto/config/inode_file/inode_file_config.proto",
+ ":perfetto_protos_perfetto_config_inode_file_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_inode_file_zero)",
out: [
"external/perfetto/protos/perfetto/config/inode_file/inode_file_config.pbzero.cc",
],
@@ -3449,13 +3575,13 @@
genrule {
name: "perfetto_protos_perfetto_config_inode_file_zero_gen_headers",
srcs: [
- "protos/perfetto/config/inode_file/inode_file_config.proto",
+ ":perfetto_protos_perfetto_config_inode_file_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_inode_file_zero)",
out: [
"external/perfetto/protos/perfetto/config/inode_file/inode_file_config.pbzero.h",
],
@@ -3466,16 +3592,25 @@
}
// GN: //protos/perfetto/config/interceptors:cpp
+filegroup {
+ name: "perfetto_protos_perfetto_config_interceptors_cpp",
+ srcs: [
+ "protos/perfetto/config/interceptors/console_config.proto",
+ ],
+}
+
+// GN: //protos/perfetto/config/interceptors:cpp
genrule {
name: "perfetto_protos_perfetto_config_interceptors_cpp_gen",
srcs: [
- "protos/perfetto/config/interceptors/console_config.proto",
+ ":perfetto_protos_perfetto_common_cpp",
+ ":perfetto_protos_perfetto_config_interceptors_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_interceptors_cpp)",
out: [
"external/perfetto/protos/perfetto/config/interceptors/console_config.gen.cc",
],
@@ -3485,13 +3620,14 @@
genrule {
name: "perfetto_protos_perfetto_config_interceptors_cpp_gen_headers",
srcs: [
- "protos/perfetto/config/interceptors/console_config.proto",
+ ":perfetto_protos_perfetto_common_cpp",
+ ":perfetto_protos_perfetto_config_interceptors_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_interceptors_cpp)",
out: [
"external/perfetto/protos/perfetto/config/interceptors/console_config.gen.h",
],
@@ -3502,15 +3638,24 @@
}
// GN: //protos/perfetto/config/interceptors:lite
+filegroup {
+ name: "perfetto_protos_perfetto_config_interceptors_lite",
+ srcs: [
+ "protos/perfetto/config/interceptors/console_config.proto",
+ ],
+}
+
+// GN: //protos/perfetto/config/interceptors:lite
genrule {
name: "perfetto_protos_perfetto_config_interceptors_lite_gen",
srcs: [
- "protos/perfetto/config/interceptors/console_config.proto",
+ ":perfetto_protos_perfetto_common_lite",
+ ":perfetto_protos_perfetto_config_interceptors_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_interceptors_lite)",
out: [
"external/perfetto/protos/perfetto/config/interceptors/console_config.pb.cc",
],
@@ -3520,12 +3665,13 @@
genrule {
name: "perfetto_protos_perfetto_config_interceptors_lite_gen_headers",
srcs: [
- "protos/perfetto/config/interceptors/console_config.proto",
+ ":perfetto_protos_perfetto_common_lite",
+ ":perfetto_protos_perfetto_config_interceptors_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_interceptors_lite)",
out: [
"external/perfetto/protos/perfetto/config/interceptors/console_config.pb.h",
],
@@ -3536,16 +3682,25 @@
}
// GN: //protos/perfetto/config/interceptors:zero
+filegroup {
+ name: "perfetto_protos_perfetto_config_interceptors_zero",
+ srcs: [
+ "protos/perfetto/config/interceptors/console_config.proto",
+ ],
+}
+
+// GN: //protos/perfetto/config/interceptors:zero
genrule {
name: "perfetto_protos_perfetto_config_interceptors_zero_gen",
srcs: [
- "protos/perfetto/config/interceptors/console_config.proto",
+ ":perfetto_protos_perfetto_common_zero",
+ ":perfetto_protos_perfetto_config_interceptors_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_interceptors_zero)",
out: [
"external/perfetto/protos/perfetto/config/interceptors/console_config.pbzero.cc",
],
@@ -3555,13 +3710,14 @@
genrule {
name: "perfetto_protos_perfetto_config_interceptors_zero_gen_headers",
srcs: [
- "protos/perfetto/config/interceptors/console_config.proto",
+ ":perfetto_protos_perfetto_common_zero",
+ ":perfetto_protos_perfetto_config_interceptors_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_interceptors_zero)",
out: [
"external/perfetto/protos/perfetto/config/interceptors/console_config.pbzero.h",
],
@@ -3572,8 +3728,8 @@
}
// GN: //protos/perfetto/config:lite
-genrule {
- name: "perfetto_protos_perfetto_config_lite_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_config_lite",
srcs: [
"protos/perfetto/config/chrome/chrome_config.proto",
"protos/perfetto/config/chrome/scenario_config.proto",
@@ -3583,10 +3739,31 @@
"protos/perfetto/config/test_config.proto",
"protos/perfetto/config/trace_config.proto",
],
+}
+
+// GN: //protos/perfetto/config:lite
+genrule {
+ name: "perfetto_protos_perfetto_config_lite_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_common_lite",
+ ":perfetto_protos_perfetto_config_android_lite",
+ ":perfetto_protos_perfetto_config_ftrace_lite",
+ ":perfetto_protos_perfetto_config_gpu_lite",
+ ":perfetto_protos_perfetto_config_inode_file_lite",
+ ":perfetto_protos_perfetto_config_interceptors_lite",
+ ":perfetto_protos_perfetto_config_lite",
+ ":perfetto_protos_perfetto_config_power_lite",
+ ":perfetto_protos_perfetto_config_process_stats_lite",
+ ":perfetto_protos_perfetto_config_profiling_lite",
+ ":perfetto_protos_perfetto_config_statsd_lite",
+ ":perfetto_protos_perfetto_config_sys_stats_lite",
+ ":perfetto_protos_perfetto_config_system_info_lite",
+ ":perfetto_protos_perfetto_config_track_event_lite",
+ ],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_lite)",
out: [
"external/perfetto/protos/perfetto/config/chrome/chrome_config.pb.cc",
"external/perfetto/protos/perfetto/config/chrome/scenario_config.pb.cc",
@@ -3602,18 +3779,25 @@
genrule {
name: "perfetto_protos_perfetto_config_lite_gen_headers",
srcs: [
- "protos/perfetto/config/chrome/chrome_config.proto",
- "protos/perfetto/config/chrome/scenario_config.proto",
- "protos/perfetto/config/data_source_config.proto",
- "protos/perfetto/config/interceptor_config.proto",
- "protos/perfetto/config/stress_test_config.proto",
- "protos/perfetto/config/test_config.proto",
- "protos/perfetto/config/trace_config.proto",
+ ":perfetto_protos_perfetto_common_lite",
+ ":perfetto_protos_perfetto_config_android_lite",
+ ":perfetto_protos_perfetto_config_ftrace_lite",
+ ":perfetto_protos_perfetto_config_gpu_lite",
+ ":perfetto_protos_perfetto_config_inode_file_lite",
+ ":perfetto_protos_perfetto_config_interceptors_lite",
+ ":perfetto_protos_perfetto_config_lite",
+ ":perfetto_protos_perfetto_config_power_lite",
+ ":perfetto_protos_perfetto_config_process_stats_lite",
+ ":perfetto_protos_perfetto_config_profiling_lite",
+ ":perfetto_protos_perfetto_config_statsd_lite",
+ ":perfetto_protos_perfetto_config_sys_stats_lite",
+ ":perfetto_protos_perfetto_config_system_info_lite",
+ ":perfetto_protos_perfetto_config_track_event_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_lite)",
out: [
"external/perfetto/protos/perfetto/config/chrome/chrome_config.pb.h",
"external/perfetto/protos/perfetto/config/chrome/scenario_config.pb.h",
@@ -3630,16 +3814,24 @@
}
// GN: //protos/perfetto/config/power:cpp
+filegroup {
+ name: "perfetto_protos_perfetto_config_power_cpp",
+ srcs: [
+ "protos/perfetto/config/power/android_power_config.proto",
+ ],
+}
+
+// GN: //protos/perfetto/config/power:cpp
genrule {
name: "perfetto_protos_perfetto_config_power_cpp_gen",
srcs: [
- "protos/perfetto/config/power/android_power_config.proto",
+ ":perfetto_protos_perfetto_config_power_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_power_cpp)",
out: [
"external/perfetto/protos/perfetto/config/power/android_power_config.gen.cc",
],
@@ -3649,13 +3841,13 @@
genrule {
name: "perfetto_protos_perfetto_config_power_cpp_gen_headers",
srcs: [
- "protos/perfetto/config/power/android_power_config.proto",
+ ":perfetto_protos_perfetto_config_power_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_power_cpp)",
out: [
"external/perfetto/protos/perfetto/config/power/android_power_config.gen.h",
],
@@ -3666,15 +3858,23 @@
}
// GN: //protos/perfetto/config/power:lite
+filegroup {
+ name: "perfetto_protos_perfetto_config_power_lite",
+ srcs: [
+ "protos/perfetto/config/power/android_power_config.proto",
+ ],
+}
+
+// GN: //protos/perfetto/config/power:lite
genrule {
name: "perfetto_protos_perfetto_config_power_lite_gen",
srcs: [
- "protos/perfetto/config/power/android_power_config.proto",
+ ":perfetto_protos_perfetto_config_power_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_power_lite)",
out: [
"external/perfetto/protos/perfetto/config/power/android_power_config.pb.cc",
],
@@ -3684,12 +3884,12 @@
genrule {
name: "perfetto_protos_perfetto_config_power_lite_gen_headers",
srcs: [
- "protos/perfetto/config/power/android_power_config.proto",
+ ":perfetto_protos_perfetto_config_power_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_power_lite)",
out: [
"external/perfetto/protos/perfetto/config/power/android_power_config.pb.h",
],
@@ -3700,16 +3900,24 @@
}
// GN: //protos/perfetto/config/power:zero
+filegroup {
+ name: "perfetto_protos_perfetto_config_power_zero",
+ srcs: [
+ "protos/perfetto/config/power/android_power_config.proto",
+ ],
+}
+
+// GN: //protos/perfetto/config/power:zero
genrule {
name: "perfetto_protos_perfetto_config_power_zero_gen",
srcs: [
- "protos/perfetto/config/power/android_power_config.proto",
+ ":perfetto_protos_perfetto_config_power_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_power_zero)",
out: [
"external/perfetto/protos/perfetto/config/power/android_power_config.pbzero.cc",
],
@@ -3719,13 +3927,13 @@
genrule {
name: "perfetto_protos_perfetto_config_power_zero_gen_headers",
srcs: [
- "protos/perfetto/config/power/android_power_config.proto",
+ ":perfetto_protos_perfetto_config_power_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_power_zero)",
out: [
"external/perfetto/protos/perfetto/config/power/android_power_config.pbzero.h",
],
@@ -3736,16 +3944,24 @@
}
// GN: //protos/perfetto/config/process_stats:cpp
+filegroup {
+ name: "perfetto_protos_perfetto_config_process_stats_cpp",
+ srcs: [
+ "protos/perfetto/config/process_stats/process_stats_config.proto",
+ ],
+}
+
+// GN: //protos/perfetto/config/process_stats:cpp
genrule {
name: "perfetto_protos_perfetto_config_process_stats_cpp_gen",
srcs: [
- "protos/perfetto/config/process_stats/process_stats_config.proto",
+ ":perfetto_protos_perfetto_config_process_stats_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_process_stats_cpp)",
out: [
"external/perfetto/protos/perfetto/config/process_stats/process_stats_config.gen.cc",
],
@@ -3755,13 +3971,13 @@
genrule {
name: "perfetto_protos_perfetto_config_process_stats_cpp_gen_headers",
srcs: [
- "protos/perfetto/config/process_stats/process_stats_config.proto",
+ ":perfetto_protos_perfetto_config_process_stats_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_process_stats_cpp)",
out: [
"external/perfetto/protos/perfetto/config/process_stats/process_stats_config.gen.h",
],
@@ -3772,15 +3988,23 @@
}
// GN: //protos/perfetto/config/process_stats:lite
+filegroup {
+ name: "perfetto_protos_perfetto_config_process_stats_lite",
+ srcs: [
+ "protos/perfetto/config/process_stats/process_stats_config.proto",
+ ],
+}
+
+// GN: //protos/perfetto/config/process_stats:lite
genrule {
name: "perfetto_protos_perfetto_config_process_stats_lite_gen",
srcs: [
- "protos/perfetto/config/process_stats/process_stats_config.proto",
+ ":perfetto_protos_perfetto_config_process_stats_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_process_stats_lite)",
out: [
"external/perfetto/protos/perfetto/config/process_stats/process_stats_config.pb.cc",
],
@@ -3790,12 +4014,12 @@
genrule {
name: "perfetto_protos_perfetto_config_process_stats_lite_gen_headers",
srcs: [
- "protos/perfetto/config/process_stats/process_stats_config.proto",
+ ":perfetto_protos_perfetto_config_process_stats_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_process_stats_lite)",
out: [
"external/perfetto/protos/perfetto/config/process_stats/process_stats_config.pb.h",
],
@@ -3806,16 +4030,24 @@
}
// GN: //protos/perfetto/config/process_stats:zero
+filegroup {
+ name: "perfetto_protos_perfetto_config_process_stats_zero",
+ srcs: [
+ "protos/perfetto/config/process_stats/process_stats_config.proto",
+ ],
+}
+
+// GN: //protos/perfetto/config/process_stats:zero
genrule {
name: "perfetto_protos_perfetto_config_process_stats_zero_gen",
srcs: [
- "protos/perfetto/config/process_stats/process_stats_config.proto",
+ ":perfetto_protos_perfetto_config_process_stats_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_process_stats_zero)",
out: [
"external/perfetto/protos/perfetto/config/process_stats/process_stats_config.pbzero.cc",
],
@@ -3825,13 +4057,13 @@
genrule {
name: "perfetto_protos_perfetto_config_process_stats_zero_gen_headers",
srcs: [
- "protos/perfetto/config/process_stats/process_stats_config.proto",
+ ":perfetto_protos_perfetto_config_process_stats_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_process_stats_zero)",
out: [
"external/perfetto/protos/perfetto/config/process_stats/process_stats_config.pbzero.h",
],
@@ -3842,18 +4074,27 @@
}
// GN: //protos/perfetto/config/profiling:cpp
-genrule {
- name: "perfetto_protos_perfetto_config_profiling_cpp_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_config_profiling_cpp",
srcs: [
"protos/perfetto/config/profiling/heapprofd_config.proto",
"protos/perfetto/config/profiling/java_hprof_config.proto",
"protos/perfetto/config/profiling/perf_event_config.proto",
],
+}
+
+// GN: //protos/perfetto/config/profiling:cpp
+genrule {
+ name: "perfetto_protos_perfetto_config_profiling_cpp_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_common_cpp",
+ ":perfetto_protos_perfetto_config_profiling_cpp",
+ ],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_profiling_cpp)",
out: [
"external/perfetto/protos/perfetto/config/profiling/heapprofd_config.gen.cc",
"external/perfetto/protos/perfetto/config/profiling/java_hprof_config.gen.cc",
@@ -3865,15 +4106,14 @@
genrule {
name: "perfetto_protos_perfetto_config_profiling_cpp_gen_headers",
srcs: [
- "protos/perfetto/config/profiling/heapprofd_config.proto",
- "protos/perfetto/config/profiling/java_hprof_config.proto",
- "protos/perfetto/config/profiling/perf_event_config.proto",
+ ":perfetto_protos_perfetto_common_cpp",
+ ":perfetto_protos_perfetto_config_profiling_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_profiling_cpp)",
out: [
"external/perfetto/protos/perfetto/config/profiling/heapprofd_config.gen.h",
"external/perfetto/protos/perfetto/config/profiling/java_hprof_config.gen.h",
@@ -3886,17 +4126,26 @@
}
// GN: //protos/perfetto/config/profiling:lite
-genrule {
- name: "perfetto_protos_perfetto_config_profiling_lite_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_config_profiling_lite",
srcs: [
"protos/perfetto/config/profiling/heapprofd_config.proto",
"protos/perfetto/config/profiling/java_hprof_config.proto",
"protos/perfetto/config/profiling/perf_event_config.proto",
],
+}
+
+// GN: //protos/perfetto/config/profiling:lite
+genrule {
+ name: "perfetto_protos_perfetto_config_profiling_lite_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_common_lite",
+ ":perfetto_protos_perfetto_config_profiling_lite",
+ ],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_profiling_lite)",
out: [
"external/perfetto/protos/perfetto/config/profiling/heapprofd_config.pb.cc",
"external/perfetto/protos/perfetto/config/profiling/java_hprof_config.pb.cc",
@@ -3908,14 +4157,13 @@
genrule {
name: "perfetto_protos_perfetto_config_profiling_lite_gen_headers",
srcs: [
- "protos/perfetto/config/profiling/heapprofd_config.proto",
- "protos/perfetto/config/profiling/java_hprof_config.proto",
- "protos/perfetto/config/profiling/perf_event_config.proto",
+ ":perfetto_protos_perfetto_common_lite",
+ ":perfetto_protos_perfetto_config_profiling_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_profiling_lite)",
out: [
"external/perfetto/protos/perfetto/config/profiling/heapprofd_config.pb.h",
"external/perfetto/protos/perfetto/config/profiling/java_hprof_config.pb.h",
@@ -3928,18 +4176,27 @@
}
// GN: //protos/perfetto/config/profiling:zero
-genrule {
- name: "perfetto_protos_perfetto_config_profiling_zero_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_config_profiling_zero",
srcs: [
"protos/perfetto/config/profiling/heapprofd_config.proto",
"protos/perfetto/config/profiling/java_hprof_config.proto",
"protos/perfetto/config/profiling/perf_event_config.proto",
],
+}
+
+// GN: //protos/perfetto/config/profiling:zero
+genrule {
+ name: "perfetto_protos_perfetto_config_profiling_zero_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_common_zero",
+ ":perfetto_protos_perfetto_config_profiling_zero",
+ ],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_profiling_zero)",
out: [
"external/perfetto/protos/perfetto/config/profiling/heapprofd_config.pbzero.cc",
"external/perfetto/protos/perfetto/config/profiling/java_hprof_config.pbzero.cc",
@@ -3951,15 +4208,14 @@
genrule {
name: "perfetto_protos_perfetto_config_profiling_zero_gen_headers",
srcs: [
- "protos/perfetto/config/profiling/heapprofd_config.proto",
- "protos/perfetto/config/profiling/java_hprof_config.proto",
- "protos/perfetto/config/profiling/perf_event_config.proto",
+ ":perfetto_protos_perfetto_common_zero",
+ ":perfetto_protos_perfetto_config_profiling_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_profiling_zero)",
out: [
"external/perfetto/protos/perfetto/config/profiling/heapprofd_config.pbzero.h",
"external/perfetto/protos/perfetto/config/profiling/java_hprof_config.pbzero.h",
@@ -3972,17 +4228,25 @@
}
// GN: //protos/perfetto/config/statsd:cpp
-genrule {
- name: "perfetto_protos_perfetto_config_statsd_cpp_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_config_statsd_cpp",
srcs: [
"protos/perfetto/config/statsd/atom_ids.proto",
"protos/perfetto/config/statsd/statsd_tracing_config.proto",
],
+}
+
+// GN: //protos/perfetto/config/statsd:cpp
+genrule {
+ name: "perfetto_protos_perfetto_config_statsd_cpp_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_config_statsd_cpp",
+ ],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_statsd_cpp)",
out: [
"external/perfetto/protos/perfetto/config/statsd/atom_ids.gen.cc",
"external/perfetto/protos/perfetto/config/statsd/statsd_tracing_config.gen.cc",
@@ -3993,14 +4257,13 @@
genrule {
name: "perfetto_protos_perfetto_config_statsd_cpp_gen_headers",
srcs: [
- "protos/perfetto/config/statsd/atom_ids.proto",
- "protos/perfetto/config/statsd/statsd_tracing_config.proto",
+ ":perfetto_protos_perfetto_config_statsd_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_statsd_cpp)",
out: [
"external/perfetto/protos/perfetto/config/statsd/atom_ids.gen.h",
"external/perfetto/protos/perfetto/config/statsd/statsd_tracing_config.gen.h",
@@ -4012,16 +4275,24 @@
}
// GN: //protos/perfetto/config/statsd:lite
-genrule {
- name: "perfetto_protos_perfetto_config_statsd_lite_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_config_statsd_lite",
srcs: [
"protos/perfetto/config/statsd/atom_ids.proto",
"protos/perfetto/config/statsd/statsd_tracing_config.proto",
],
+}
+
+// GN: //protos/perfetto/config/statsd:lite
+genrule {
+ name: "perfetto_protos_perfetto_config_statsd_lite_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_config_statsd_lite",
+ ],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_statsd_lite)",
out: [
"external/perfetto/protos/perfetto/config/statsd/atom_ids.pb.cc",
"external/perfetto/protos/perfetto/config/statsd/statsd_tracing_config.pb.cc",
@@ -4032,13 +4303,12 @@
genrule {
name: "perfetto_protos_perfetto_config_statsd_lite_gen_headers",
srcs: [
- "protos/perfetto/config/statsd/atom_ids.proto",
- "protos/perfetto/config/statsd/statsd_tracing_config.proto",
+ ":perfetto_protos_perfetto_config_statsd_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_statsd_lite)",
out: [
"external/perfetto/protos/perfetto/config/statsd/atom_ids.pb.h",
"external/perfetto/protos/perfetto/config/statsd/statsd_tracing_config.pb.h",
@@ -4050,17 +4320,25 @@
}
// GN: //protos/perfetto/config/statsd:zero
-genrule {
- name: "perfetto_protos_perfetto_config_statsd_zero_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_config_statsd_zero",
srcs: [
"protos/perfetto/config/statsd/atom_ids.proto",
"protos/perfetto/config/statsd/statsd_tracing_config.proto",
],
+}
+
+// GN: //protos/perfetto/config/statsd:zero
+genrule {
+ name: "perfetto_protos_perfetto_config_statsd_zero_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_config_statsd_zero",
+ ],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_statsd_zero)",
out: [
"external/perfetto/protos/perfetto/config/statsd/atom_ids.pbzero.cc",
"external/perfetto/protos/perfetto/config/statsd/statsd_tracing_config.pbzero.cc",
@@ -4071,14 +4349,13 @@
genrule {
name: "perfetto_protos_perfetto_config_statsd_zero_gen_headers",
srcs: [
- "protos/perfetto/config/statsd/atom_ids.proto",
- "protos/perfetto/config/statsd/statsd_tracing_config.proto",
+ ":perfetto_protos_perfetto_config_statsd_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_statsd_zero)",
out: [
"external/perfetto/protos/perfetto/config/statsd/atom_ids.pbzero.h",
"external/perfetto/protos/perfetto/config/statsd/statsd_tracing_config.pbzero.h",
@@ -4090,16 +4367,25 @@
}
// GN: //protos/perfetto/config/sys_stats:cpp
+filegroup {
+ name: "perfetto_protos_perfetto_config_sys_stats_cpp",
+ srcs: [
+ "protos/perfetto/config/sys_stats/sys_stats_config.proto",
+ ],
+}
+
+// GN: //protos/perfetto/config/sys_stats:cpp
genrule {
name: "perfetto_protos_perfetto_config_sys_stats_cpp_gen",
srcs: [
- "protos/perfetto/config/sys_stats/sys_stats_config.proto",
+ ":perfetto_protos_perfetto_common_cpp",
+ ":perfetto_protos_perfetto_config_sys_stats_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_sys_stats_cpp)",
out: [
"external/perfetto/protos/perfetto/config/sys_stats/sys_stats_config.gen.cc",
],
@@ -4109,13 +4395,14 @@
genrule {
name: "perfetto_protos_perfetto_config_sys_stats_cpp_gen_headers",
srcs: [
- "protos/perfetto/config/sys_stats/sys_stats_config.proto",
+ ":perfetto_protos_perfetto_common_cpp",
+ ":perfetto_protos_perfetto_config_sys_stats_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_sys_stats_cpp)",
out: [
"external/perfetto/protos/perfetto/config/sys_stats/sys_stats_config.gen.h",
],
@@ -4126,15 +4413,24 @@
}
// GN: //protos/perfetto/config/sys_stats:lite
+filegroup {
+ name: "perfetto_protos_perfetto_config_sys_stats_lite",
+ srcs: [
+ "protos/perfetto/config/sys_stats/sys_stats_config.proto",
+ ],
+}
+
+// GN: //protos/perfetto/config/sys_stats:lite
genrule {
name: "perfetto_protos_perfetto_config_sys_stats_lite_gen",
srcs: [
- "protos/perfetto/config/sys_stats/sys_stats_config.proto",
+ ":perfetto_protos_perfetto_common_lite",
+ ":perfetto_protos_perfetto_config_sys_stats_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_sys_stats_lite)",
out: [
"external/perfetto/protos/perfetto/config/sys_stats/sys_stats_config.pb.cc",
],
@@ -4144,12 +4440,13 @@
genrule {
name: "perfetto_protos_perfetto_config_sys_stats_lite_gen_headers",
srcs: [
- "protos/perfetto/config/sys_stats/sys_stats_config.proto",
+ ":perfetto_protos_perfetto_common_lite",
+ ":perfetto_protos_perfetto_config_sys_stats_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_sys_stats_lite)",
out: [
"external/perfetto/protos/perfetto/config/sys_stats/sys_stats_config.pb.h",
],
@@ -4160,16 +4457,25 @@
}
// GN: //protos/perfetto/config/sys_stats:zero
+filegroup {
+ name: "perfetto_protos_perfetto_config_sys_stats_zero",
+ srcs: [
+ "protos/perfetto/config/sys_stats/sys_stats_config.proto",
+ ],
+}
+
+// GN: //protos/perfetto/config/sys_stats:zero
genrule {
name: "perfetto_protos_perfetto_config_sys_stats_zero_gen",
srcs: [
- "protos/perfetto/config/sys_stats/sys_stats_config.proto",
+ ":perfetto_protos_perfetto_common_zero",
+ ":perfetto_protos_perfetto_config_sys_stats_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_sys_stats_zero)",
out: [
"external/perfetto/protos/perfetto/config/sys_stats/sys_stats_config.pbzero.cc",
],
@@ -4179,13 +4485,14 @@
genrule {
name: "perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
srcs: [
- "protos/perfetto/config/sys_stats/sys_stats_config.proto",
+ ":perfetto_protos_perfetto_common_zero",
+ ":perfetto_protos_perfetto_config_sys_stats_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_sys_stats_zero)",
out: [
"external/perfetto/protos/perfetto/config/sys_stats/sys_stats_config.pbzero.h",
],
@@ -4196,16 +4503,25 @@
}
// GN: //protos/perfetto/config/system_info:cpp
+filegroup {
+ name: "perfetto_protos_perfetto_config_system_info_cpp",
+ srcs: [
+ "protos/perfetto/config/system_info/system_info.proto",
+ ],
+}
+
+// GN: //protos/perfetto/config/system_info:cpp
genrule {
name: "perfetto_protos_perfetto_config_system_info_cpp_gen",
srcs: [
- "protos/perfetto/config/system_info/system_info.proto",
+ ":perfetto_protos_perfetto_common_cpp",
+ ":perfetto_protos_perfetto_config_system_info_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_system_info_cpp)",
out: [
"external/perfetto/protos/perfetto/config/system_info/system_info.gen.cc",
],
@@ -4215,13 +4531,14 @@
genrule {
name: "perfetto_protos_perfetto_config_system_info_cpp_gen_headers",
srcs: [
- "protos/perfetto/config/system_info/system_info.proto",
+ ":perfetto_protos_perfetto_common_cpp",
+ ":perfetto_protos_perfetto_config_system_info_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_system_info_cpp)",
out: [
"external/perfetto/protos/perfetto/config/system_info/system_info.gen.h",
],
@@ -4232,15 +4549,24 @@
}
// GN: //protos/perfetto/config/system_info:lite
+filegroup {
+ name: "perfetto_protos_perfetto_config_system_info_lite",
+ srcs: [
+ "protos/perfetto/config/system_info/system_info.proto",
+ ],
+}
+
+// GN: //protos/perfetto/config/system_info:lite
genrule {
name: "perfetto_protos_perfetto_config_system_info_lite_gen",
srcs: [
- "protos/perfetto/config/system_info/system_info.proto",
+ ":perfetto_protos_perfetto_common_lite",
+ ":perfetto_protos_perfetto_config_system_info_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_system_info_lite)",
out: [
"external/perfetto/protos/perfetto/config/system_info/system_info.pb.cc",
],
@@ -4250,12 +4576,13 @@
genrule {
name: "perfetto_protos_perfetto_config_system_info_lite_gen_headers",
srcs: [
- "protos/perfetto/config/system_info/system_info.proto",
+ ":perfetto_protos_perfetto_common_lite",
+ ":perfetto_protos_perfetto_config_system_info_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_system_info_lite)",
out: [
"external/perfetto/protos/perfetto/config/system_info/system_info.pb.h",
],
@@ -4266,16 +4593,25 @@
}
// GN: //protos/perfetto/config/system_info:zero
+filegroup {
+ name: "perfetto_protos_perfetto_config_system_info_zero",
+ srcs: [
+ "protos/perfetto/config/system_info/system_info.proto",
+ ],
+}
+
+// GN: //protos/perfetto/config/system_info:zero
genrule {
name: "perfetto_protos_perfetto_config_system_info_zero_gen",
srcs: [
- "protos/perfetto/config/system_info/system_info.proto",
+ ":perfetto_protos_perfetto_common_zero",
+ ":perfetto_protos_perfetto_config_system_info_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_system_info_zero)",
out: [
"external/perfetto/protos/perfetto/config/system_info/system_info.pbzero.cc",
],
@@ -4285,13 +4621,14 @@
genrule {
name: "perfetto_protos_perfetto_config_system_info_zero_gen_headers",
srcs: [
- "protos/perfetto/config/system_info/system_info.proto",
+ ":perfetto_protos_perfetto_common_zero",
+ ":perfetto_protos_perfetto_config_system_info_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_system_info_zero)",
out: [
"external/perfetto/protos/perfetto/config/system_info/system_info.pbzero.h",
],
@@ -4302,16 +4639,24 @@
}
// GN: //protos/perfetto/config/track_event:cpp
+filegroup {
+ name: "perfetto_protos_perfetto_config_track_event_cpp",
+ srcs: [
+ "protos/perfetto/config/track_event/track_event_config.proto",
+ ],
+}
+
+// GN: //protos/perfetto/config/track_event:cpp
genrule {
name: "perfetto_protos_perfetto_config_track_event_cpp_gen",
srcs: [
- "protos/perfetto/config/track_event/track_event_config.proto",
+ ":perfetto_protos_perfetto_config_track_event_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_track_event_cpp)",
out: [
"external/perfetto/protos/perfetto/config/track_event/track_event_config.gen.cc",
],
@@ -4321,13 +4666,13 @@
genrule {
name: "perfetto_protos_perfetto_config_track_event_cpp_gen_headers",
srcs: [
- "protos/perfetto/config/track_event/track_event_config.proto",
+ ":perfetto_protos_perfetto_config_track_event_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_track_event_cpp)",
out: [
"external/perfetto/protos/perfetto/config/track_event/track_event_config.gen.h",
],
@@ -4338,15 +4683,23 @@
}
// GN: //protos/perfetto/config/track_event:lite
+filegroup {
+ name: "perfetto_protos_perfetto_config_track_event_lite",
+ srcs: [
+ "protos/perfetto/config/track_event/track_event_config.proto",
+ ],
+}
+
+// GN: //protos/perfetto/config/track_event:lite
genrule {
name: "perfetto_protos_perfetto_config_track_event_lite_gen",
srcs: [
- "protos/perfetto/config/track_event/track_event_config.proto",
+ ":perfetto_protos_perfetto_config_track_event_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_track_event_lite)",
out: [
"external/perfetto/protos/perfetto/config/track_event/track_event_config.pb.cc",
],
@@ -4356,12 +4709,12 @@
genrule {
name: "perfetto_protos_perfetto_config_track_event_lite_gen_headers",
srcs: [
- "protos/perfetto/config/track_event/track_event_config.proto",
+ ":perfetto_protos_perfetto_config_track_event_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_track_event_lite)",
out: [
"external/perfetto/protos/perfetto/config/track_event/track_event_config.pb.h",
],
@@ -4372,16 +4725,24 @@
}
// GN: //protos/perfetto/config/track_event:zero
+filegroup {
+ name: "perfetto_protos_perfetto_config_track_event_zero",
+ srcs: [
+ "protos/perfetto/config/track_event/track_event_config.proto",
+ ],
+}
+
+// GN: //protos/perfetto/config/track_event:zero
genrule {
name: "perfetto_protos_perfetto_config_track_event_zero_gen",
srcs: [
- "protos/perfetto/config/track_event/track_event_config.proto",
+ ":perfetto_protos_perfetto_config_track_event_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_track_event_zero)",
out: [
"external/perfetto/protos/perfetto/config/track_event/track_event_config.pbzero.cc",
],
@@ -4391,13 +4752,13 @@
genrule {
name: "perfetto_protos_perfetto_config_track_event_zero_gen_headers",
srcs: [
- "protos/perfetto/config/track_event/track_event_config.proto",
+ ":perfetto_protos_perfetto_config_track_event_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_track_event_zero)",
out: [
"external/perfetto/protos/perfetto/config/track_event/track_event_config.pbzero.h",
],
@@ -4408,8 +4769,8 @@
}
// GN: //protos/perfetto/config:zero
-genrule {
- name: "perfetto_protos_perfetto_config_zero_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_config_zero",
srcs: [
"protos/perfetto/config/chrome/chrome_config.proto",
"protos/perfetto/config/chrome/scenario_config.proto",
@@ -4419,11 +4780,32 @@
"protos/perfetto/config/test_config.proto",
"protos/perfetto/config/trace_config.proto",
],
+}
+
+// GN: //protos/perfetto/config:zero
+genrule {
+ name: "perfetto_protos_perfetto_config_zero_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_common_zero",
+ ":perfetto_protos_perfetto_config_android_zero",
+ ":perfetto_protos_perfetto_config_ftrace_zero",
+ ":perfetto_protos_perfetto_config_gpu_zero",
+ ":perfetto_protos_perfetto_config_inode_file_zero",
+ ":perfetto_protos_perfetto_config_interceptors_zero",
+ ":perfetto_protos_perfetto_config_power_zero",
+ ":perfetto_protos_perfetto_config_process_stats_zero",
+ ":perfetto_protos_perfetto_config_profiling_zero",
+ ":perfetto_protos_perfetto_config_statsd_zero",
+ ":perfetto_protos_perfetto_config_sys_stats_zero",
+ ":perfetto_protos_perfetto_config_system_info_zero",
+ ":perfetto_protos_perfetto_config_track_event_zero",
+ ":perfetto_protos_perfetto_config_zero",
+ ],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_zero)",
out: [
"external/perfetto/protos/perfetto/config/chrome/chrome_config.pbzero.cc",
"external/perfetto/protos/perfetto/config/chrome/scenario_config.pbzero.cc",
@@ -4439,19 +4821,26 @@
genrule {
name: "perfetto_protos_perfetto_config_zero_gen_headers",
srcs: [
- "protos/perfetto/config/chrome/chrome_config.proto",
- "protos/perfetto/config/chrome/scenario_config.proto",
- "protos/perfetto/config/data_source_config.proto",
- "protos/perfetto/config/interceptor_config.proto",
- "protos/perfetto/config/stress_test_config.proto",
- "protos/perfetto/config/test_config.proto",
- "protos/perfetto/config/trace_config.proto",
+ ":perfetto_protos_perfetto_common_zero",
+ ":perfetto_protos_perfetto_config_android_zero",
+ ":perfetto_protos_perfetto_config_ftrace_zero",
+ ":perfetto_protos_perfetto_config_gpu_zero",
+ ":perfetto_protos_perfetto_config_inode_file_zero",
+ ":perfetto_protos_perfetto_config_interceptors_zero",
+ ":perfetto_protos_perfetto_config_power_zero",
+ ":perfetto_protos_perfetto_config_process_stats_zero",
+ ":perfetto_protos_perfetto_config_profiling_zero",
+ ":perfetto_protos_perfetto_config_statsd_zero",
+ ":perfetto_protos_perfetto_config_sys_stats_zero",
+ ":perfetto_protos_perfetto_config_system_info_zero",
+ ":perfetto_protos_perfetto_config_track_event_zero",
+ ":perfetto_protos_perfetto_config_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_config_zero)",
out: [
"external/perfetto/protos/perfetto/config/chrome/chrome_config.pbzero.h",
"external/perfetto/protos/perfetto/config/chrome/scenario_config.pbzero.h",
@@ -4468,17 +4857,39 @@
}
// GN: //protos/perfetto/ipc:cpp
-genrule {
- name: "perfetto_protos_perfetto_ipc_cpp_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_ipc_cpp",
srcs: [
"protos/perfetto/ipc/consumer_port.proto",
"protos/perfetto/ipc/producer_port.proto",
],
+}
+
+// GN: //protos/perfetto/ipc:cpp
+genrule {
+ name: "perfetto_protos_perfetto_ipc_cpp_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_common_cpp",
+ ":perfetto_protos_perfetto_config_android_cpp",
+ ":perfetto_protos_perfetto_config_cpp",
+ ":perfetto_protos_perfetto_config_ftrace_cpp",
+ ":perfetto_protos_perfetto_config_gpu_cpp",
+ ":perfetto_protos_perfetto_config_inode_file_cpp",
+ ":perfetto_protos_perfetto_config_interceptors_cpp",
+ ":perfetto_protos_perfetto_config_power_cpp",
+ ":perfetto_protos_perfetto_config_process_stats_cpp",
+ ":perfetto_protos_perfetto_config_profiling_cpp",
+ ":perfetto_protos_perfetto_config_statsd_cpp",
+ ":perfetto_protos_perfetto_config_sys_stats_cpp",
+ ":perfetto_protos_perfetto_config_system_info_cpp",
+ ":perfetto_protos_perfetto_config_track_event_cpp",
+ ":perfetto_protos_perfetto_ipc_cpp",
+ ],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_ipc_cpp)",
out: [
"external/perfetto/protos/perfetto/ipc/consumer_port.gen.cc",
"external/perfetto/protos/perfetto/ipc/producer_port.gen.cc",
@@ -4489,14 +4900,27 @@
genrule {
name: "perfetto_protos_perfetto_ipc_cpp_gen_headers",
srcs: [
- "protos/perfetto/ipc/consumer_port.proto",
- "protos/perfetto/ipc/producer_port.proto",
+ ":perfetto_protos_perfetto_common_cpp",
+ ":perfetto_protos_perfetto_config_android_cpp",
+ ":perfetto_protos_perfetto_config_cpp",
+ ":perfetto_protos_perfetto_config_ftrace_cpp",
+ ":perfetto_protos_perfetto_config_gpu_cpp",
+ ":perfetto_protos_perfetto_config_inode_file_cpp",
+ ":perfetto_protos_perfetto_config_interceptors_cpp",
+ ":perfetto_protos_perfetto_config_power_cpp",
+ ":perfetto_protos_perfetto_config_process_stats_cpp",
+ ":perfetto_protos_perfetto_config_profiling_cpp",
+ ":perfetto_protos_perfetto_config_statsd_cpp",
+ ":perfetto_protos_perfetto_config_sys_stats_cpp",
+ ":perfetto_protos_perfetto_config_system_info_cpp",
+ ":perfetto_protos_perfetto_config_track_event_cpp",
+ ":perfetto_protos_perfetto_ipc_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_ipc_cpp)",
out: [
"external/perfetto/protos/perfetto/ipc/consumer_port.gen.h",
"external/perfetto/protos/perfetto/ipc/producer_port.gen.h",
@@ -4508,17 +4932,41 @@
}
// GN: //protos/perfetto/ipc:ipc
-genrule {
- name: "perfetto_protos_perfetto_ipc_ipc_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_ipc_ipc",
srcs: [
"protos/perfetto/ipc/consumer_port.proto",
"protos/perfetto/ipc/producer_port.proto",
],
+}
+
+// GN: //protos/perfetto/ipc:ipc
+genrule {
+ name: "perfetto_protos_perfetto_ipc_ipc_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_common_cpp",
+ ":perfetto_protos_perfetto_config_android_cpp",
+ ":perfetto_protos_perfetto_config_cpp",
+ ":perfetto_protos_perfetto_config_ftrace_cpp",
+ ":perfetto_protos_perfetto_config_gpu_cpp",
+ ":perfetto_protos_perfetto_config_inode_file_cpp",
+ ":perfetto_protos_perfetto_config_interceptors_cpp",
+ ":perfetto_protos_perfetto_config_power_cpp",
+ ":perfetto_protos_perfetto_config_process_stats_cpp",
+ ":perfetto_protos_perfetto_config_profiling_cpp",
+ ":perfetto_protos_perfetto_config_statsd_cpp",
+ ":perfetto_protos_perfetto_config_sys_stats_cpp",
+ ":perfetto_protos_perfetto_config_system_info_cpp",
+ ":perfetto_protos_perfetto_config_track_event_cpp",
+ ":perfetto_protos_perfetto_ipc_cpp",
+ ":perfetto_protos_perfetto_ipc_ipc",
+ ":perfetto_protos_perfetto_ipc_wire_protocol_cpp",
+ ],
tools: [
"aprotoc",
"ipc_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location ipc_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location ipc_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_ipc_ipc)",
out: [
"external/perfetto/protos/perfetto/ipc/consumer_port.ipc.cc",
"external/perfetto/protos/perfetto/ipc/producer_port.ipc.cc",
@@ -4529,14 +4977,29 @@
genrule {
name: "perfetto_protos_perfetto_ipc_ipc_gen_headers",
srcs: [
- "protos/perfetto/ipc/consumer_port.proto",
- "protos/perfetto/ipc/producer_port.proto",
+ ":perfetto_protos_perfetto_common_cpp",
+ ":perfetto_protos_perfetto_config_android_cpp",
+ ":perfetto_protos_perfetto_config_cpp",
+ ":perfetto_protos_perfetto_config_ftrace_cpp",
+ ":perfetto_protos_perfetto_config_gpu_cpp",
+ ":perfetto_protos_perfetto_config_inode_file_cpp",
+ ":perfetto_protos_perfetto_config_interceptors_cpp",
+ ":perfetto_protos_perfetto_config_power_cpp",
+ ":perfetto_protos_perfetto_config_process_stats_cpp",
+ ":perfetto_protos_perfetto_config_profiling_cpp",
+ ":perfetto_protos_perfetto_config_statsd_cpp",
+ ":perfetto_protos_perfetto_config_sys_stats_cpp",
+ ":perfetto_protos_perfetto_config_system_info_cpp",
+ ":perfetto_protos_perfetto_config_track_event_cpp",
+ ":perfetto_protos_perfetto_ipc_cpp",
+ ":perfetto_protos_perfetto_ipc_ipc",
+ ":perfetto_protos_perfetto_ipc_wire_protocol_cpp",
],
tools: [
"aprotoc",
"ipc_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location ipc_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location ipc_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_ipc_ipc)",
out: [
"external/perfetto/protos/perfetto/ipc/consumer_port.ipc.h",
"external/perfetto/protos/perfetto/ipc/producer_port.ipc.h",
@@ -4548,16 +5011,24 @@
}
// GN: //protos/perfetto/ipc:wire_protocol_cpp
+filegroup {
+ name: "perfetto_protos_perfetto_ipc_wire_protocol_cpp",
+ srcs: [
+ "protos/perfetto/ipc/wire_protocol.proto",
+ ],
+}
+
+// GN: //protos/perfetto/ipc:wire_protocol_cpp
genrule {
name: "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
srcs: [
- "protos/perfetto/ipc/wire_protocol.proto",
+ ":perfetto_protos_perfetto_ipc_wire_protocol_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_ipc_wire_protocol_cpp)",
out: [
"external/perfetto/protos/perfetto/ipc/wire_protocol.gen.cc",
],
@@ -4567,13 +5038,13 @@
genrule {
name: "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
srcs: [
- "protos/perfetto/ipc/wire_protocol.proto",
+ ":perfetto_protos_perfetto_ipc_wire_protocol_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_ipc_wire_protocol_cpp)",
out: [
"external/perfetto/protos/perfetto/ipc/wire_protocol.gen.h",
],
@@ -4587,6 +5058,8 @@
genrule {
name: "perfetto_protos_perfetto_metrics_chrome_descriptor",
srcs: [
+ ":libprotobuf-internal-descriptor-proto",
+ "protos/perfetto/metrics/android/ad_services_metric.proto",
"protos/perfetto/metrics/android/android_blocking_call.proto",
"protos/perfetto/metrics/android/android_blocking_calls_cuj_metric.proto",
"protos/perfetto/metrics/android/android_boot.proto",
@@ -4668,6 +5141,7 @@
genrule {
name: "perfetto_protos_perfetto_metrics_descriptor",
srcs: [
+ "protos/perfetto/metrics/android/ad_services_metric.proto",
"protos/perfetto/metrics/android/android_blocking_call.proto",
"protos/perfetto/metrics/android/android_blocking_calls_cuj_metric.proto",
"protos/perfetto/metrics/android/android_boot.proto",
@@ -4732,6 +5206,7 @@
genrule {
name: "perfetto_protos_perfetto_metrics_webview_descriptor",
srcs: [
+ "protos/perfetto/metrics/android/ad_services_metric.proto",
"protos/perfetto/metrics/android/android_blocking_call.proto",
"protos/perfetto/metrics/android/android_blocking_calls_cuj_metric.proto",
"protos/perfetto/metrics/android/android_boot.proto",
@@ -4795,8 +5270,8 @@
}
// GN: //protos/perfetto/trace/android:cpp
-genrule {
- name: "perfetto_protos_perfetto_trace_android_cpp_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_trace_android_cpp",
srcs: [
"protos/perfetto/trace/android/android_game_intervention_list.proto",
"protos/perfetto/trace/android/android_log.proto",
@@ -4812,11 +5287,20 @@
"protos/perfetto/trace/android/surfaceflinger_layers.proto",
"protos/perfetto/trace/android/surfaceflinger_transactions.proto",
],
+}
+
+// GN: //protos/perfetto/trace/android:cpp
+genrule {
+ name: "perfetto_protos_perfetto_trace_android_cpp_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_common_cpp",
+ ":perfetto_protos_perfetto_trace_android_cpp",
+ ],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_android_cpp)",
out: [
"external/perfetto/protos/perfetto/trace/android/android_game_intervention_list.gen.cc",
"external/perfetto/protos/perfetto/trace/android/android_log.gen.cc",
@@ -4838,25 +5322,14 @@
genrule {
name: "perfetto_protos_perfetto_trace_android_cpp_gen_headers",
srcs: [
- "protos/perfetto/trace/android/android_game_intervention_list.proto",
- "protos/perfetto/trace/android/android_log.proto",
- "protos/perfetto/trace/android/android_system_property.proto",
- "protos/perfetto/trace/android/camera_event.proto",
- "protos/perfetto/trace/android/frame_timeline_event.proto",
- "protos/perfetto/trace/android/gpu_mem_event.proto",
- "protos/perfetto/trace/android/graphics_frame_event.proto",
- "protos/perfetto/trace/android/initial_display_state.proto",
- "protos/perfetto/trace/android/network_trace.proto",
- "protos/perfetto/trace/android/packages_list.proto",
- "protos/perfetto/trace/android/surfaceflinger_common.proto",
- "protos/perfetto/trace/android/surfaceflinger_layers.proto",
- "protos/perfetto/trace/android/surfaceflinger_transactions.proto",
+ ":perfetto_protos_perfetto_common_cpp",
+ ":perfetto_protos_perfetto_trace_android_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_android_cpp)",
out: [
"external/perfetto/protos/perfetto/trace/android/android_game_intervention_list.gen.h",
"external/perfetto/protos/perfetto/trace/android/android_log.gen.h",
@@ -4879,8 +5352,8 @@
}
// GN: //protos/perfetto/trace/android:lite
-genrule {
- name: "perfetto_protos_perfetto_trace_android_lite_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_trace_android_lite",
srcs: [
"protos/perfetto/trace/android/android_game_intervention_list.proto",
"protos/perfetto/trace/android/android_log.proto",
@@ -4896,10 +5369,19 @@
"protos/perfetto/trace/android/surfaceflinger_layers.proto",
"protos/perfetto/trace/android/surfaceflinger_transactions.proto",
],
+}
+
+// GN: //protos/perfetto/trace/android:lite
+genrule {
+ name: "perfetto_protos_perfetto_trace_android_lite_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_common_lite",
+ ":perfetto_protos_perfetto_trace_android_lite",
+ ],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_android_lite)",
out: [
"external/perfetto/protos/perfetto/trace/android/android_game_intervention_list.pb.cc",
"external/perfetto/protos/perfetto/trace/android/android_log.pb.cc",
@@ -4921,24 +5403,13 @@
genrule {
name: "perfetto_protos_perfetto_trace_android_lite_gen_headers",
srcs: [
- "protos/perfetto/trace/android/android_game_intervention_list.proto",
- "protos/perfetto/trace/android/android_log.proto",
- "protos/perfetto/trace/android/android_system_property.proto",
- "protos/perfetto/trace/android/camera_event.proto",
- "protos/perfetto/trace/android/frame_timeline_event.proto",
- "protos/perfetto/trace/android/gpu_mem_event.proto",
- "protos/perfetto/trace/android/graphics_frame_event.proto",
- "protos/perfetto/trace/android/initial_display_state.proto",
- "protos/perfetto/trace/android/network_trace.proto",
- "protos/perfetto/trace/android/packages_list.proto",
- "protos/perfetto/trace/android/surfaceflinger_common.proto",
- "protos/perfetto/trace/android/surfaceflinger_layers.proto",
- "protos/perfetto/trace/android/surfaceflinger_transactions.proto",
+ ":perfetto_protos_perfetto_common_lite",
+ ":perfetto_protos_perfetto_trace_android_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_android_lite)",
out: [
"external/perfetto/protos/perfetto/trace/android/android_game_intervention_list.pb.h",
"external/perfetto/protos/perfetto/trace/android/android_log.pb.h",
@@ -4979,8 +5450,8 @@
}
// GN: //protos/perfetto/trace/android:zero
-genrule {
- name: "perfetto_protos_perfetto_trace_android_zero_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_trace_android_zero",
srcs: [
"protos/perfetto/trace/android/android_game_intervention_list.proto",
"protos/perfetto/trace/android/android_log.proto",
@@ -4996,11 +5467,20 @@
"protos/perfetto/trace/android/surfaceflinger_layers.proto",
"protos/perfetto/trace/android/surfaceflinger_transactions.proto",
],
+}
+
+// GN: //protos/perfetto/trace/android:zero
+genrule {
+ name: "perfetto_protos_perfetto_trace_android_zero_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_common_zero",
+ ":perfetto_protos_perfetto_trace_android_zero",
+ ],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_android_zero)",
out: [
"external/perfetto/protos/perfetto/trace/android/android_game_intervention_list.pbzero.cc",
"external/perfetto/protos/perfetto/trace/android/android_log.pbzero.cc",
@@ -5022,25 +5502,14 @@
genrule {
name: "perfetto_protos_perfetto_trace_android_zero_gen_headers",
srcs: [
- "protos/perfetto/trace/android/android_game_intervention_list.proto",
- "protos/perfetto/trace/android/android_log.proto",
- "protos/perfetto/trace/android/android_system_property.proto",
- "protos/perfetto/trace/android/camera_event.proto",
- "protos/perfetto/trace/android/frame_timeline_event.proto",
- "protos/perfetto/trace/android/gpu_mem_event.proto",
- "protos/perfetto/trace/android/graphics_frame_event.proto",
- "protos/perfetto/trace/android/initial_display_state.proto",
- "protos/perfetto/trace/android/network_trace.proto",
- "protos/perfetto/trace/android/packages_list.proto",
- "protos/perfetto/trace/android/surfaceflinger_common.proto",
- "protos/perfetto/trace/android/surfaceflinger_layers.proto",
- "protos/perfetto/trace/android/surfaceflinger_transactions.proto",
+ ":perfetto_protos_perfetto_common_zero",
+ ":perfetto_protos_perfetto_trace_android_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_android_zero)",
out: [
"external/perfetto/protos/perfetto/trace/android/android_game_intervention_list.pbzero.h",
"external/perfetto/protos/perfetto/trace/android/android_log.pbzero.h",
@@ -5063,18 +5532,26 @@
}
// GN: //protos/perfetto/trace/chrome:cpp
-genrule {
- name: "perfetto_protos_perfetto_trace_chrome_cpp_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_trace_chrome_cpp",
srcs: [
"protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto",
"protos/perfetto/trace/chrome/chrome_metadata.proto",
"protos/perfetto/trace/chrome/chrome_trace_event.proto",
],
+}
+
+// GN: //protos/perfetto/trace/chrome:cpp
+genrule {
+ name: "perfetto_protos_perfetto_trace_chrome_cpp_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_trace_chrome_cpp",
+ ],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_chrome_cpp)",
out: [
"external/perfetto/protos/perfetto/trace/chrome/chrome_benchmark_metadata.gen.cc",
"external/perfetto/protos/perfetto/trace/chrome/chrome_metadata.gen.cc",
@@ -5086,15 +5563,13 @@
genrule {
name: "perfetto_protos_perfetto_trace_chrome_cpp_gen_headers",
srcs: [
- "protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto",
- "protos/perfetto/trace/chrome/chrome_metadata.proto",
- "protos/perfetto/trace/chrome/chrome_trace_event.proto",
+ ":perfetto_protos_perfetto_trace_chrome_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_chrome_cpp)",
out: [
"external/perfetto/protos/perfetto/trace/chrome/chrome_benchmark_metadata.gen.h",
"external/perfetto/protos/perfetto/trace/chrome/chrome_metadata.gen.h",
@@ -5107,17 +5582,25 @@
}
// GN: //protos/perfetto/trace/chrome:lite
-genrule {
- name: "perfetto_protos_perfetto_trace_chrome_lite_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_trace_chrome_lite",
srcs: [
"protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto",
"protos/perfetto/trace/chrome/chrome_metadata.proto",
"protos/perfetto/trace/chrome/chrome_trace_event.proto",
],
+}
+
+// GN: //protos/perfetto/trace/chrome:lite
+genrule {
+ name: "perfetto_protos_perfetto_trace_chrome_lite_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_trace_chrome_lite",
+ ],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_chrome_lite)",
out: [
"external/perfetto/protos/perfetto/trace/chrome/chrome_benchmark_metadata.pb.cc",
"external/perfetto/protos/perfetto/trace/chrome/chrome_metadata.pb.cc",
@@ -5129,14 +5612,12 @@
genrule {
name: "perfetto_protos_perfetto_trace_chrome_lite_gen_headers",
srcs: [
- "protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto",
- "protos/perfetto/trace/chrome/chrome_metadata.proto",
- "protos/perfetto/trace/chrome/chrome_trace_event.proto",
+ ":perfetto_protos_perfetto_trace_chrome_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_chrome_lite)",
out: [
"external/perfetto/protos/perfetto/trace/chrome/chrome_benchmark_metadata.pb.h",
"external/perfetto/protos/perfetto/trace/chrome/chrome_metadata.pb.h",
@@ -5149,18 +5630,26 @@
}
// GN: //protos/perfetto/trace/chrome:zero
-genrule {
- name: "perfetto_protos_perfetto_trace_chrome_zero_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_trace_chrome_zero",
srcs: [
"protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto",
"protos/perfetto/trace/chrome/chrome_metadata.proto",
"protos/perfetto/trace/chrome/chrome_trace_event.proto",
],
+}
+
+// GN: //protos/perfetto/trace/chrome:zero
+genrule {
+ name: "perfetto_protos_perfetto_trace_chrome_zero_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_trace_chrome_zero",
+ ],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_chrome_zero)",
out: [
"external/perfetto/protos/perfetto/trace/chrome/chrome_benchmark_metadata.pbzero.cc",
"external/perfetto/protos/perfetto/trace/chrome/chrome_metadata.pbzero.cc",
@@ -5172,15 +5661,13 @@
genrule {
name: "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
srcs: [
- "protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto",
- "protos/perfetto/trace/chrome/chrome_metadata.proto",
- "protos/perfetto/trace/chrome/chrome_trace_event.proto",
+ ":perfetto_protos_perfetto_trace_chrome_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_chrome_zero)",
out: [
"external/perfetto/protos/perfetto/trace/chrome/chrome_benchmark_metadata.pbzero.h",
"external/perfetto/protos/perfetto/trace/chrome/chrome_metadata.pbzero.h",
@@ -5260,6 +5747,9 @@
"protos/perfetto/trace/chrome/chrome_metadata.proto",
"protos/perfetto/trace/chrome/chrome_trace_event.proto",
"protos/perfetto/trace/clock_snapshot.proto",
+ "protos/perfetto/trace/etw/etw.proto",
+ "protos/perfetto/trace/etw/etw_event.proto",
+ "protos/perfetto/trace/etw/etw_event_bundle.proto",
"protos/perfetto/trace/extension_descriptor.proto",
"protos/perfetto/trace/filesystem/inode_file_map.proto",
"protos/perfetto/trace/ftrace/android_fs.proto",
@@ -5398,17 +5888,173 @@
],
}
-// GN: //protos/perfetto/trace/filesystem:cpp
-genrule {
- name: "perfetto_protos_perfetto_trace_filesystem_cpp_gen",
+// GN: //protos/perfetto/trace/etw:cpp
+filegroup {
+ name: "perfetto_protos_perfetto_trace_etw_cpp",
srcs: [
- "protos/perfetto/trace/filesystem/inode_file_map.proto",
+ "protos/perfetto/trace/etw/etw.proto",
+ "protos/perfetto/trace/etw/etw_event.proto",
+ "protos/perfetto/trace/etw/etw_event_bundle.proto",
+ ],
+}
+
+// GN: //protos/perfetto/trace/etw:cpp
+genrule {
+ name: "perfetto_protos_perfetto_trace_etw_cpp_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_trace_etw_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_etw_cpp)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/etw/etw.gen.cc",
+ "external/perfetto/protos/perfetto/trace/etw/etw_event.gen.cc",
+ "external/perfetto/protos/perfetto/trace/etw/etw_event_bundle.gen.cc",
+ ],
+}
+
+// GN: //protos/perfetto/trace/etw:cpp
+genrule {
+ name: "perfetto_protos_perfetto_trace_etw_cpp_gen_headers",
+ srcs: [
+ ":perfetto_protos_perfetto_trace_etw_cpp",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_etw_cpp)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/etw/etw.gen.h",
+ "external/perfetto/protos/perfetto/trace/etw/etw_event.gen.h",
+ "external/perfetto/protos/perfetto/trace/etw/etw_event_bundle.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
+}
+
+// GN: //protos/perfetto/trace/etw:lite
+filegroup {
+ name: "perfetto_protos_perfetto_trace_etw_lite",
+ srcs: [
+ "protos/perfetto/trace/etw/etw.proto",
+ "protos/perfetto/trace/etw/etw_event.proto",
+ "protos/perfetto/trace/etw/etw_event_bundle.proto",
+ ],
+}
+
+// GN: //protos/perfetto/trace/etw:lite
+genrule {
+ name: "perfetto_protos_perfetto_trace_etw_lite_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_trace_etw_lite",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_etw_lite)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/etw/etw.pb.cc",
+ "external/perfetto/protos/perfetto/trace/etw/etw_event.pb.cc",
+ "external/perfetto/protos/perfetto/trace/etw/etw_event_bundle.pb.cc",
+ ],
+}
+
+// GN: //protos/perfetto/trace/etw:lite
+genrule {
+ name: "perfetto_protos_perfetto_trace_etw_lite_gen_headers",
+ srcs: [
+ ":perfetto_protos_perfetto_trace_etw_lite",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_etw_lite)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/etw/etw.pb.h",
+ "external/perfetto/protos/perfetto/trace/etw/etw_event.pb.h",
+ "external/perfetto/protos/perfetto/trace/etw/etw_event_bundle.pb.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
+}
+
+// GN: //protos/perfetto/trace/etw:zero
+filegroup {
+ name: "perfetto_protos_perfetto_trace_etw_zero",
+ srcs: [
+ "protos/perfetto/trace/etw/etw.proto",
+ "protos/perfetto/trace/etw/etw_event.proto",
+ "protos/perfetto/trace/etw/etw_event_bundle.proto",
+ ],
+}
+
+// GN: //protos/perfetto/trace/etw:zero
+genrule {
+ name: "perfetto_protos_perfetto_trace_etw_zero_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_trace_etw_zero",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_etw_zero)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/etw/etw.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/etw/etw_event.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/etw/etw_event_bundle.pbzero.cc",
+ ],
+}
+
+// GN: //protos/perfetto/trace/etw:zero
+genrule {
+ name: "perfetto_protos_perfetto_trace_etw_zero_gen_headers",
+ srcs: [
+ ":perfetto_protos_perfetto_trace_etw_zero",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_etw_zero)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/etw/etw.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/etw/etw_event.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/etw/etw_event_bundle.pbzero.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
+}
+
+// GN: //protos/perfetto/trace/filesystem:cpp
+filegroup {
+ name: "perfetto_protos_perfetto_trace_filesystem_cpp",
+ srcs: [
+ "protos/perfetto/trace/filesystem/inode_file_map.proto",
+ ],
+}
+
+// GN: //protos/perfetto/trace/filesystem:cpp
+genrule {
+ name: "perfetto_protos_perfetto_trace_filesystem_cpp_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_trace_filesystem_cpp",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_filesystem_cpp)",
out: [
"external/perfetto/protos/perfetto/trace/filesystem/inode_file_map.gen.cc",
],
@@ -5418,13 +6064,13 @@
genrule {
name: "perfetto_protos_perfetto_trace_filesystem_cpp_gen_headers",
srcs: [
- "protos/perfetto/trace/filesystem/inode_file_map.proto",
+ ":perfetto_protos_perfetto_trace_filesystem_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_filesystem_cpp)",
out: [
"external/perfetto/protos/perfetto/trace/filesystem/inode_file_map.gen.h",
],
@@ -5435,15 +6081,23 @@
}
// GN: //protos/perfetto/trace/filesystem:lite
+filegroup {
+ name: "perfetto_protos_perfetto_trace_filesystem_lite",
+ srcs: [
+ "protos/perfetto/trace/filesystem/inode_file_map.proto",
+ ],
+}
+
+// GN: //protos/perfetto/trace/filesystem:lite
genrule {
name: "perfetto_protos_perfetto_trace_filesystem_lite_gen",
srcs: [
- "protos/perfetto/trace/filesystem/inode_file_map.proto",
+ ":perfetto_protos_perfetto_trace_filesystem_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_filesystem_lite)",
out: [
"external/perfetto/protos/perfetto/trace/filesystem/inode_file_map.pb.cc",
],
@@ -5453,12 +6107,12 @@
genrule {
name: "perfetto_protos_perfetto_trace_filesystem_lite_gen_headers",
srcs: [
- "protos/perfetto/trace/filesystem/inode_file_map.proto",
+ ":perfetto_protos_perfetto_trace_filesystem_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_filesystem_lite)",
out: [
"external/perfetto/protos/perfetto/trace/filesystem/inode_file_map.pb.h",
],
@@ -5469,16 +6123,24 @@
}
// GN: //protos/perfetto/trace/filesystem:zero
+filegroup {
+ name: "perfetto_protos_perfetto_trace_filesystem_zero",
+ srcs: [
+ "protos/perfetto/trace/filesystem/inode_file_map.proto",
+ ],
+}
+
+// GN: //protos/perfetto/trace/filesystem:zero
genrule {
name: "perfetto_protos_perfetto_trace_filesystem_zero_gen",
srcs: [
- "protos/perfetto/trace/filesystem/inode_file_map.proto",
+ ":perfetto_protos_perfetto_trace_filesystem_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_filesystem_zero)",
out: [
"external/perfetto/protos/perfetto/trace/filesystem/inode_file_map.pbzero.cc",
],
@@ -5488,13 +6150,13 @@
genrule {
name: "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
srcs: [
- "protos/perfetto/trace/filesystem/inode_file_map.proto",
+ ":perfetto_protos_perfetto_trace_filesystem_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_filesystem_zero)",
out: [
"external/perfetto/protos/perfetto/trace/filesystem/inode_file_map.pbzero.h",
],
@@ -5505,8 +6167,8 @@
}
// GN: //protos/perfetto/trace/ftrace:cpp
-genrule {
- name: "perfetto_protos_perfetto_trace_ftrace_cpp_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_trace_ftrace_cpp",
srcs: [
"protos/perfetto/trace/ftrace/android_fs.proto",
"protos/perfetto/trace/ftrace/binder.proto",
@@ -5575,11 +6237,19 @@
"protos/perfetto/trace/ftrace/vmscan.proto",
"protos/perfetto/trace/ftrace/workqueue.proto",
],
+}
+
+// GN: //protos/perfetto/trace/ftrace:cpp
+genrule {
+ name: "perfetto_protos_perfetto_trace_ftrace_cpp_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_trace_ftrace_cpp",
+ ],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_ftrace_cpp)",
out: [
"external/perfetto/protos/perfetto/trace/ftrace/android_fs.gen.cc",
"external/perfetto/protos/perfetto/trace/ftrace/binder.gen.cc",
@@ -5654,78 +6324,13 @@
genrule {
name: "perfetto_protos_perfetto_trace_ftrace_cpp_gen_headers",
srcs: [
- "protos/perfetto/trace/ftrace/android_fs.proto",
- "protos/perfetto/trace/ftrace/binder.proto",
- "protos/perfetto/trace/ftrace/block.proto",
- "protos/perfetto/trace/ftrace/cgroup.proto",
- "protos/perfetto/trace/ftrace/clk.proto",
- "protos/perfetto/trace/ftrace/cma.proto",
- "protos/perfetto/trace/ftrace/compaction.proto",
- "protos/perfetto/trace/ftrace/cpuhp.proto",
- "protos/perfetto/trace/ftrace/cros_ec.proto",
- "protos/perfetto/trace/ftrace/dma_fence.proto",
- "protos/perfetto/trace/ftrace/dmabuf_heap.proto",
- "protos/perfetto/trace/ftrace/dpu.proto",
- "protos/perfetto/trace/ftrace/drm.proto",
- "protos/perfetto/trace/ftrace/ext4.proto",
- "protos/perfetto/trace/ftrace/f2fs.proto",
- "protos/perfetto/trace/ftrace/fastrpc.proto",
- "protos/perfetto/trace/ftrace/fence.proto",
- "protos/perfetto/trace/ftrace/filemap.proto",
- "protos/perfetto/trace/ftrace/ftrace.proto",
- "protos/perfetto/trace/ftrace/ftrace_event.proto",
- "protos/perfetto/trace/ftrace/ftrace_event_bundle.proto",
- "protos/perfetto/trace/ftrace/ftrace_stats.proto",
- "protos/perfetto/trace/ftrace/g2d.proto",
- "protos/perfetto/trace/ftrace/generic.proto",
- "protos/perfetto/trace/ftrace/gpu_mem.proto",
- "protos/perfetto/trace/ftrace/gpu_scheduler.proto",
- "protos/perfetto/trace/ftrace/hyp.proto",
- "protos/perfetto/trace/ftrace/i2c.proto",
- "protos/perfetto/trace/ftrace/ion.proto",
- "protos/perfetto/trace/ftrace/ipi.proto",
- "protos/perfetto/trace/ftrace/irq.proto",
- "protos/perfetto/trace/ftrace/kmem.proto",
- "protos/perfetto/trace/ftrace/kvm.proto",
- "protos/perfetto/trace/ftrace/lowmemorykiller.proto",
- "protos/perfetto/trace/ftrace/lwis.proto",
- "protos/perfetto/trace/ftrace/mali.proto",
- "protos/perfetto/trace/ftrace/mdss.proto",
- "protos/perfetto/trace/ftrace/mm_event.proto",
- "protos/perfetto/trace/ftrace/net.proto",
- "protos/perfetto/trace/ftrace/oom.proto",
- "protos/perfetto/trace/ftrace/panel.proto",
- "protos/perfetto/trace/ftrace/power.proto",
- "protos/perfetto/trace/ftrace/printk.proto",
- "protos/perfetto/trace/ftrace/raw_syscalls.proto",
- "protos/perfetto/trace/ftrace/regulator.proto",
- "protos/perfetto/trace/ftrace/samsung.proto",
- "protos/perfetto/trace/ftrace/sched.proto",
- "protos/perfetto/trace/ftrace/scm.proto",
- "protos/perfetto/trace/ftrace/sde.proto",
- "protos/perfetto/trace/ftrace/signal.proto",
- "protos/perfetto/trace/ftrace/skb.proto",
- "protos/perfetto/trace/ftrace/sock.proto",
- "protos/perfetto/trace/ftrace/sync.proto",
- "protos/perfetto/trace/ftrace/synthetic.proto",
- "protos/perfetto/trace/ftrace/systrace.proto",
- "protos/perfetto/trace/ftrace/task.proto",
- "protos/perfetto/trace/ftrace/tcp.proto",
- "protos/perfetto/trace/ftrace/test_bundle_wrapper.proto",
- "protos/perfetto/trace/ftrace/thermal.proto",
- "protos/perfetto/trace/ftrace/trusty.proto",
- "protos/perfetto/trace/ftrace/ufs.proto",
- "protos/perfetto/trace/ftrace/v4l2.proto",
- "protos/perfetto/trace/ftrace/virtio_gpu.proto",
- "protos/perfetto/trace/ftrace/virtio_video.proto",
- "protos/perfetto/trace/ftrace/vmscan.proto",
- "protos/perfetto/trace/ftrace/workqueue.proto",
+ ":perfetto_protos_perfetto_trace_ftrace_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_ftrace_cpp)",
out: [
"external/perfetto/protos/perfetto/trace/ftrace/android_fs.gen.h",
"external/perfetto/protos/perfetto/trace/ftrace/binder.gen.h",
@@ -5801,8 +6406,8 @@
}
// GN: //protos/perfetto/trace/ftrace:lite
-genrule {
- name: "perfetto_protos_perfetto_trace_ftrace_lite_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_trace_ftrace_lite",
srcs: [
"protos/perfetto/trace/ftrace/android_fs.proto",
"protos/perfetto/trace/ftrace/binder.proto",
@@ -5871,10 +6476,18 @@
"protos/perfetto/trace/ftrace/vmscan.proto",
"protos/perfetto/trace/ftrace/workqueue.proto",
],
+}
+
+// GN: //protos/perfetto/trace/ftrace:lite
+genrule {
+ name: "perfetto_protos_perfetto_trace_ftrace_lite_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_trace_ftrace_lite",
+ ],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_ftrace_lite)",
out: [
"external/perfetto/protos/perfetto/trace/ftrace/android_fs.pb.cc",
"external/perfetto/protos/perfetto/trace/ftrace/binder.pb.cc",
@@ -5949,77 +6562,12 @@
genrule {
name: "perfetto_protos_perfetto_trace_ftrace_lite_gen_headers",
srcs: [
- "protos/perfetto/trace/ftrace/android_fs.proto",
- "protos/perfetto/trace/ftrace/binder.proto",
- "protos/perfetto/trace/ftrace/block.proto",
- "protos/perfetto/trace/ftrace/cgroup.proto",
- "protos/perfetto/trace/ftrace/clk.proto",
- "protos/perfetto/trace/ftrace/cma.proto",
- "protos/perfetto/trace/ftrace/compaction.proto",
- "protos/perfetto/trace/ftrace/cpuhp.proto",
- "protos/perfetto/trace/ftrace/cros_ec.proto",
- "protos/perfetto/trace/ftrace/dma_fence.proto",
- "protos/perfetto/trace/ftrace/dmabuf_heap.proto",
- "protos/perfetto/trace/ftrace/dpu.proto",
- "protos/perfetto/trace/ftrace/drm.proto",
- "protos/perfetto/trace/ftrace/ext4.proto",
- "protos/perfetto/trace/ftrace/f2fs.proto",
- "protos/perfetto/trace/ftrace/fastrpc.proto",
- "protos/perfetto/trace/ftrace/fence.proto",
- "protos/perfetto/trace/ftrace/filemap.proto",
- "protos/perfetto/trace/ftrace/ftrace.proto",
- "protos/perfetto/trace/ftrace/ftrace_event.proto",
- "protos/perfetto/trace/ftrace/ftrace_event_bundle.proto",
- "protos/perfetto/trace/ftrace/ftrace_stats.proto",
- "protos/perfetto/trace/ftrace/g2d.proto",
- "protos/perfetto/trace/ftrace/generic.proto",
- "protos/perfetto/trace/ftrace/gpu_mem.proto",
- "protos/perfetto/trace/ftrace/gpu_scheduler.proto",
- "protos/perfetto/trace/ftrace/hyp.proto",
- "protos/perfetto/trace/ftrace/i2c.proto",
- "protos/perfetto/trace/ftrace/ion.proto",
- "protos/perfetto/trace/ftrace/ipi.proto",
- "protos/perfetto/trace/ftrace/irq.proto",
- "protos/perfetto/trace/ftrace/kmem.proto",
- "protos/perfetto/trace/ftrace/kvm.proto",
- "protos/perfetto/trace/ftrace/lowmemorykiller.proto",
- "protos/perfetto/trace/ftrace/lwis.proto",
- "protos/perfetto/trace/ftrace/mali.proto",
- "protos/perfetto/trace/ftrace/mdss.proto",
- "protos/perfetto/trace/ftrace/mm_event.proto",
- "protos/perfetto/trace/ftrace/net.proto",
- "protos/perfetto/trace/ftrace/oom.proto",
- "protos/perfetto/trace/ftrace/panel.proto",
- "protos/perfetto/trace/ftrace/power.proto",
- "protos/perfetto/trace/ftrace/printk.proto",
- "protos/perfetto/trace/ftrace/raw_syscalls.proto",
- "protos/perfetto/trace/ftrace/regulator.proto",
- "protos/perfetto/trace/ftrace/samsung.proto",
- "protos/perfetto/trace/ftrace/sched.proto",
- "protos/perfetto/trace/ftrace/scm.proto",
- "protos/perfetto/trace/ftrace/sde.proto",
- "protos/perfetto/trace/ftrace/signal.proto",
- "protos/perfetto/trace/ftrace/skb.proto",
- "protos/perfetto/trace/ftrace/sock.proto",
- "protos/perfetto/trace/ftrace/sync.proto",
- "protos/perfetto/trace/ftrace/synthetic.proto",
- "protos/perfetto/trace/ftrace/systrace.proto",
- "protos/perfetto/trace/ftrace/task.proto",
- "protos/perfetto/trace/ftrace/tcp.proto",
- "protos/perfetto/trace/ftrace/test_bundle_wrapper.proto",
- "protos/perfetto/trace/ftrace/thermal.proto",
- "protos/perfetto/trace/ftrace/trusty.proto",
- "protos/perfetto/trace/ftrace/ufs.proto",
- "protos/perfetto/trace/ftrace/v4l2.proto",
- "protos/perfetto/trace/ftrace/virtio_gpu.proto",
- "protos/perfetto/trace/ftrace/virtio_video.proto",
- "protos/perfetto/trace/ftrace/vmscan.proto",
- "protos/perfetto/trace/ftrace/workqueue.proto",
+ ":perfetto_protos_perfetto_trace_ftrace_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_ftrace_lite)",
out: [
"external/perfetto/protos/perfetto/trace/ftrace/android_fs.pb.h",
"external/perfetto/protos/perfetto/trace/ftrace/binder.pb.h",
@@ -6095,8 +6643,8 @@
}
// GN: //protos/perfetto/trace/ftrace:zero
-genrule {
- name: "perfetto_protos_perfetto_trace_ftrace_zero_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_trace_ftrace_zero",
srcs: [
"protos/perfetto/trace/ftrace/android_fs.proto",
"protos/perfetto/trace/ftrace/binder.proto",
@@ -6165,11 +6713,19 @@
"protos/perfetto/trace/ftrace/vmscan.proto",
"protos/perfetto/trace/ftrace/workqueue.proto",
],
+}
+
+// GN: //protos/perfetto/trace/ftrace:zero
+genrule {
+ name: "perfetto_protos_perfetto_trace_ftrace_zero_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_trace_ftrace_zero",
+ ],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_ftrace_zero)",
out: [
"external/perfetto/protos/perfetto/trace/ftrace/android_fs.pbzero.cc",
"external/perfetto/protos/perfetto/trace/ftrace/binder.pbzero.cc",
@@ -6244,78 +6800,13 @@
genrule {
name: "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
srcs: [
- "protos/perfetto/trace/ftrace/android_fs.proto",
- "protos/perfetto/trace/ftrace/binder.proto",
- "protos/perfetto/trace/ftrace/block.proto",
- "protos/perfetto/trace/ftrace/cgroup.proto",
- "protos/perfetto/trace/ftrace/clk.proto",
- "protos/perfetto/trace/ftrace/cma.proto",
- "protos/perfetto/trace/ftrace/compaction.proto",
- "protos/perfetto/trace/ftrace/cpuhp.proto",
- "protos/perfetto/trace/ftrace/cros_ec.proto",
- "protos/perfetto/trace/ftrace/dma_fence.proto",
- "protos/perfetto/trace/ftrace/dmabuf_heap.proto",
- "protos/perfetto/trace/ftrace/dpu.proto",
- "protos/perfetto/trace/ftrace/drm.proto",
- "protos/perfetto/trace/ftrace/ext4.proto",
- "protos/perfetto/trace/ftrace/f2fs.proto",
- "protos/perfetto/trace/ftrace/fastrpc.proto",
- "protos/perfetto/trace/ftrace/fence.proto",
- "protos/perfetto/trace/ftrace/filemap.proto",
- "protos/perfetto/trace/ftrace/ftrace.proto",
- "protos/perfetto/trace/ftrace/ftrace_event.proto",
- "protos/perfetto/trace/ftrace/ftrace_event_bundle.proto",
- "protos/perfetto/trace/ftrace/ftrace_stats.proto",
- "protos/perfetto/trace/ftrace/g2d.proto",
- "protos/perfetto/trace/ftrace/generic.proto",
- "protos/perfetto/trace/ftrace/gpu_mem.proto",
- "protos/perfetto/trace/ftrace/gpu_scheduler.proto",
- "protos/perfetto/trace/ftrace/hyp.proto",
- "protos/perfetto/trace/ftrace/i2c.proto",
- "protos/perfetto/trace/ftrace/ion.proto",
- "protos/perfetto/trace/ftrace/ipi.proto",
- "protos/perfetto/trace/ftrace/irq.proto",
- "protos/perfetto/trace/ftrace/kmem.proto",
- "protos/perfetto/trace/ftrace/kvm.proto",
- "protos/perfetto/trace/ftrace/lowmemorykiller.proto",
- "protos/perfetto/trace/ftrace/lwis.proto",
- "protos/perfetto/trace/ftrace/mali.proto",
- "protos/perfetto/trace/ftrace/mdss.proto",
- "protos/perfetto/trace/ftrace/mm_event.proto",
- "protos/perfetto/trace/ftrace/net.proto",
- "protos/perfetto/trace/ftrace/oom.proto",
- "protos/perfetto/trace/ftrace/panel.proto",
- "protos/perfetto/trace/ftrace/power.proto",
- "protos/perfetto/trace/ftrace/printk.proto",
- "protos/perfetto/trace/ftrace/raw_syscalls.proto",
- "protos/perfetto/trace/ftrace/regulator.proto",
- "protos/perfetto/trace/ftrace/samsung.proto",
- "protos/perfetto/trace/ftrace/sched.proto",
- "protos/perfetto/trace/ftrace/scm.proto",
- "protos/perfetto/trace/ftrace/sde.proto",
- "protos/perfetto/trace/ftrace/signal.proto",
- "protos/perfetto/trace/ftrace/skb.proto",
- "protos/perfetto/trace/ftrace/sock.proto",
- "protos/perfetto/trace/ftrace/sync.proto",
- "protos/perfetto/trace/ftrace/synthetic.proto",
- "protos/perfetto/trace/ftrace/systrace.proto",
- "protos/perfetto/trace/ftrace/task.proto",
- "protos/perfetto/trace/ftrace/tcp.proto",
- "protos/perfetto/trace/ftrace/test_bundle_wrapper.proto",
- "protos/perfetto/trace/ftrace/thermal.proto",
- "protos/perfetto/trace/ftrace/trusty.proto",
- "protos/perfetto/trace/ftrace/ufs.proto",
- "protos/perfetto/trace/ftrace/v4l2.proto",
- "protos/perfetto/trace/ftrace/virtio_gpu.proto",
- "protos/perfetto/trace/ftrace/virtio_video.proto",
- "protos/perfetto/trace/ftrace/vmscan.proto",
- "protos/perfetto/trace/ftrace/workqueue.proto",
+ ":perfetto_protos_perfetto_trace_ftrace_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_ftrace_zero)",
out: [
"external/perfetto/protos/perfetto/trace/ftrace/android_fs.pbzero.h",
"external/perfetto/protos/perfetto/trace/ftrace/binder.pbzero.h",
@@ -6391,8 +6882,8 @@
}
// GN: //protos/perfetto/trace/gpu:cpp
-genrule {
- name: "perfetto_protos_perfetto_trace_gpu_cpp_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_trace_gpu_cpp",
srcs: [
"protos/perfetto/trace/gpu/gpu_counter_event.proto",
"protos/perfetto/trace/gpu/gpu_log.proto",
@@ -6400,11 +6891,20 @@
"protos/perfetto/trace/gpu/vulkan_api_event.proto",
"protos/perfetto/trace/gpu/vulkan_memory_event.proto",
],
+}
+
+// GN: //protos/perfetto/trace/gpu:cpp
+genrule {
+ name: "perfetto_protos_perfetto_trace_gpu_cpp_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_common_cpp",
+ ":perfetto_protos_perfetto_trace_gpu_cpp",
+ ],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_gpu_cpp)",
out: [
"external/perfetto/protos/perfetto/trace/gpu/gpu_counter_event.gen.cc",
"external/perfetto/protos/perfetto/trace/gpu/gpu_log.gen.cc",
@@ -6418,17 +6918,14 @@
genrule {
name: "perfetto_protos_perfetto_trace_gpu_cpp_gen_headers",
srcs: [
- "protos/perfetto/trace/gpu/gpu_counter_event.proto",
- "protos/perfetto/trace/gpu/gpu_log.proto",
- "protos/perfetto/trace/gpu/gpu_render_stage_event.proto",
- "protos/perfetto/trace/gpu/vulkan_api_event.proto",
- "protos/perfetto/trace/gpu/vulkan_memory_event.proto",
+ ":perfetto_protos_perfetto_common_cpp",
+ ":perfetto_protos_perfetto_trace_gpu_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_gpu_cpp)",
out: [
"external/perfetto/protos/perfetto/trace/gpu/gpu_counter_event.gen.h",
"external/perfetto/protos/perfetto/trace/gpu/gpu_log.gen.h",
@@ -6443,8 +6940,8 @@
}
// GN: //protos/perfetto/trace/gpu:lite
-genrule {
- name: "perfetto_protos_perfetto_trace_gpu_lite_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_trace_gpu_lite",
srcs: [
"protos/perfetto/trace/gpu/gpu_counter_event.proto",
"protos/perfetto/trace/gpu/gpu_log.proto",
@@ -6452,10 +6949,19 @@
"protos/perfetto/trace/gpu/vulkan_api_event.proto",
"protos/perfetto/trace/gpu/vulkan_memory_event.proto",
],
+}
+
+// GN: //protos/perfetto/trace/gpu:lite
+genrule {
+ name: "perfetto_protos_perfetto_trace_gpu_lite_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_common_lite",
+ ":perfetto_protos_perfetto_trace_gpu_lite",
+ ],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_gpu_lite)",
out: [
"external/perfetto/protos/perfetto/trace/gpu/gpu_counter_event.pb.cc",
"external/perfetto/protos/perfetto/trace/gpu/gpu_log.pb.cc",
@@ -6469,16 +6975,13 @@
genrule {
name: "perfetto_protos_perfetto_trace_gpu_lite_gen_headers",
srcs: [
- "protos/perfetto/trace/gpu/gpu_counter_event.proto",
- "protos/perfetto/trace/gpu/gpu_log.proto",
- "protos/perfetto/trace/gpu/gpu_render_stage_event.proto",
- "protos/perfetto/trace/gpu/vulkan_api_event.proto",
- "protos/perfetto/trace/gpu/vulkan_memory_event.proto",
+ ":perfetto_protos_perfetto_common_lite",
+ ":perfetto_protos_perfetto_trace_gpu_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_gpu_lite)",
out: [
"external/perfetto/protos/perfetto/trace/gpu/gpu_counter_event.pb.h",
"external/perfetto/protos/perfetto/trace/gpu/gpu_log.pb.h",
@@ -6493,8 +6996,8 @@
}
// GN: //protos/perfetto/trace/gpu:zero
-genrule {
- name: "perfetto_protos_perfetto_trace_gpu_zero_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_trace_gpu_zero",
srcs: [
"protos/perfetto/trace/gpu/gpu_counter_event.proto",
"protos/perfetto/trace/gpu/gpu_log.proto",
@@ -6502,11 +7005,20 @@
"protos/perfetto/trace/gpu/vulkan_api_event.proto",
"protos/perfetto/trace/gpu/vulkan_memory_event.proto",
],
+}
+
+// GN: //protos/perfetto/trace/gpu:zero
+genrule {
+ name: "perfetto_protos_perfetto_trace_gpu_zero_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_common_zero",
+ ":perfetto_protos_perfetto_trace_gpu_zero",
+ ],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_gpu_zero)",
out: [
"external/perfetto/protos/perfetto/trace/gpu/gpu_counter_event.pbzero.cc",
"external/perfetto/protos/perfetto/trace/gpu/gpu_log.pbzero.cc",
@@ -6520,17 +7032,14 @@
genrule {
name: "perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
srcs: [
- "protos/perfetto/trace/gpu/gpu_counter_event.proto",
- "protos/perfetto/trace/gpu/gpu_log.proto",
- "protos/perfetto/trace/gpu/gpu_render_stage_event.proto",
- "protos/perfetto/trace/gpu/vulkan_api_event.proto",
- "protos/perfetto/trace/gpu/vulkan_memory_event.proto",
+ ":perfetto_protos_perfetto_common_zero",
+ ":perfetto_protos_perfetto_trace_gpu_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_gpu_zero)",
out: [
"external/perfetto/protos/perfetto/trace/gpu/gpu_counter_event.pbzero.h",
"external/perfetto/protos/perfetto/trace/gpu/gpu_log.pbzero.h",
@@ -6545,16 +7054,29 @@
}
// GN: //protos/perfetto/trace/interned_data:cpp
+filegroup {
+ name: "perfetto_protos_perfetto_trace_interned_data_cpp",
+ srcs: [
+ "protos/perfetto/trace/interned_data/interned_data.proto",
+ ],
+}
+
+// GN: //protos/perfetto/trace/interned_data:cpp
genrule {
name: "perfetto_protos_perfetto_trace_interned_data_cpp_gen",
srcs: [
- "protos/perfetto/trace/interned_data/interned_data.proto",
+ ":perfetto_protos_perfetto_common_cpp",
+ ":perfetto_protos_perfetto_trace_android_cpp",
+ ":perfetto_protos_perfetto_trace_gpu_cpp",
+ ":perfetto_protos_perfetto_trace_interned_data_cpp",
+ ":perfetto_protos_perfetto_trace_profiling_cpp",
+ ":perfetto_protos_perfetto_trace_track_event_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_interned_data_cpp)",
out: [
"external/perfetto/protos/perfetto/trace/interned_data/interned_data.gen.cc",
],
@@ -6564,13 +7086,18 @@
genrule {
name: "perfetto_protos_perfetto_trace_interned_data_cpp_gen_headers",
srcs: [
- "protos/perfetto/trace/interned_data/interned_data.proto",
+ ":perfetto_protos_perfetto_common_cpp",
+ ":perfetto_protos_perfetto_trace_android_cpp",
+ ":perfetto_protos_perfetto_trace_gpu_cpp",
+ ":perfetto_protos_perfetto_trace_interned_data_cpp",
+ ":perfetto_protos_perfetto_trace_profiling_cpp",
+ ":perfetto_protos_perfetto_trace_track_event_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_interned_data_cpp)",
out: [
"external/perfetto/protos/perfetto/trace/interned_data/interned_data.gen.h",
],
@@ -6581,15 +7108,28 @@
}
// GN: //protos/perfetto/trace/interned_data:lite
+filegroup {
+ name: "perfetto_protos_perfetto_trace_interned_data_lite",
+ srcs: [
+ "protos/perfetto/trace/interned_data/interned_data.proto",
+ ],
+}
+
+// GN: //protos/perfetto/trace/interned_data:lite
genrule {
name: "perfetto_protos_perfetto_trace_interned_data_lite_gen",
srcs: [
- "protos/perfetto/trace/interned_data/interned_data.proto",
+ ":perfetto_protos_perfetto_common_lite",
+ ":perfetto_protos_perfetto_trace_android_lite",
+ ":perfetto_protos_perfetto_trace_gpu_lite",
+ ":perfetto_protos_perfetto_trace_interned_data_lite",
+ ":perfetto_protos_perfetto_trace_profiling_lite",
+ ":perfetto_protos_perfetto_trace_track_event_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_interned_data_lite)",
out: [
"external/perfetto/protos/perfetto/trace/interned_data/interned_data.pb.cc",
],
@@ -6599,12 +7139,17 @@
genrule {
name: "perfetto_protos_perfetto_trace_interned_data_lite_gen_headers",
srcs: [
- "protos/perfetto/trace/interned_data/interned_data.proto",
+ ":perfetto_protos_perfetto_common_lite",
+ ":perfetto_protos_perfetto_trace_android_lite",
+ ":perfetto_protos_perfetto_trace_gpu_lite",
+ ":perfetto_protos_perfetto_trace_interned_data_lite",
+ ":perfetto_protos_perfetto_trace_profiling_lite",
+ ":perfetto_protos_perfetto_trace_track_event_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_interned_data_lite)",
out: [
"external/perfetto/protos/perfetto/trace/interned_data/interned_data.pb.h",
],
@@ -6615,16 +7160,29 @@
}
// GN: //protos/perfetto/trace/interned_data:zero
+filegroup {
+ name: "perfetto_protos_perfetto_trace_interned_data_zero",
+ srcs: [
+ "protos/perfetto/trace/interned_data/interned_data.proto",
+ ],
+}
+
+// GN: //protos/perfetto/trace/interned_data:zero
genrule {
name: "perfetto_protos_perfetto_trace_interned_data_zero_gen",
srcs: [
- "protos/perfetto/trace/interned_data/interned_data.proto",
+ ":perfetto_protos_perfetto_common_zero",
+ ":perfetto_protos_perfetto_trace_android_zero",
+ ":perfetto_protos_perfetto_trace_gpu_zero",
+ ":perfetto_protos_perfetto_trace_interned_data_zero",
+ ":perfetto_protos_perfetto_trace_profiling_zero",
+ ":perfetto_protos_perfetto_trace_track_event_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_interned_data_zero)",
out: [
"external/perfetto/protos/perfetto/trace/interned_data/interned_data.pbzero.cc",
],
@@ -6634,13 +7192,18 @@
genrule {
name: "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
srcs: [
- "protos/perfetto/trace/interned_data/interned_data.proto",
+ ":perfetto_protos_perfetto_common_zero",
+ ":perfetto_protos_perfetto_trace_android_zero",
+ ":perfetto_protos_perfetto_trace_gpu_zero",
+ ":perfetto_protos_perfetto_trace_interned_data_zero",
+ ":perfetto_protos_perfetto_trace_profiling_zero",
+ ":perfetto_protos_perfetto_trace_track_event_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_interned_data_zero)",
out: [
"external/perfetto/protos/perfetto/trace/interned_data/interned_data.pbzero.h",
],
@@ -6651,19 +7214,41 @@
}
// GN: //protos/perfetto/trace:minimal_cpp
-genrule {
- name: "perfetto_protos_perfetto_trace_minimal_cpp_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_trace_minimal_cpp",
srcs: [
"protos/perfetto/trace/clock_snapshot.proto",
"protos/perfetto/trace/system_info.proto",
"protos/perfetto/trace/trace_uuid.proto",
"protos/perfetto/trace/trigger.proto",
],
+}
+
+// GN: //protos/perfetto/trace:minimal_cpp
+genrule {
+ name: "perfetto_protos_perfetto_trace_minimal_cpp_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_common_cpp",
+ ":perfetto_protos_perfetto_config_android_cpp",
+ ":perfetto_protos_perfetto_config_cpp",
+ ":perfetto_protos_perfetto_config_ftrace_cpp",
+ ":perfetto_protos_perfetto_config_gpu_cpp",
+ ":perfetto_protos_perfetto_config_inode_file_cpp",
+ ":perfetto_protos_perfetto_config_interceptors_cpp",
+ ":perfetto_protos_perfetto_config_power_cpp",
+ ":perfetto_protos_perfetto_config_process_stats_cpp",
+ ":perfetto_protos_perfetto_config_profiling_cpp",
+ ":perfetto_protos_perfetto_config_statsd_cpp",
+ ":perfetto_protos_perfetto_config_sys_stats_cpp",
+ ":perfetto_protos_perfetto_config_system_info_cpp",
+ ":perfetto_protos_perfetto_config_track_event_cpp",
+ ":perfetto_protos_perfetto_trace_minimal_cpp",
+ ],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_minimal_cpp)",
out: [
"external/perfetto/protos/perfetto/trace/clock_snapshot.gen.cc",
"external/perfetto/protos/perfetto/trace/system_info.gen.cc",
@@ -6676,16 +7261,27 @@
genrule {
name: "perfetto_protos_perfetto_trace_minimal_cpp_gen_headers",
srcs: [
- "protos/perfetto/trace/clock_snapshot.proto",
- "protos/perfetto/trace/system_info.proto",
- "protos/perfetto/trace/trace_uuid.proto",
- "protos/perfetto/trace/trigger.proto",
+ ":perfetto_protos_perfetto_common_cpp",
+ ":perfetto_protos_perfetto_config_android_cpp",
+ ":perfetto_protos_perfetto_config_cpp",
+ ":perfetto_protos_perfetto_config_ftrace_cpp",
+ ":perfetto_protos_perfetto_config_gpu_cpp",
+ ":perfetto_protos_perfetto_config_inode_file_cpp",
+ ":perfetto_protos_perfetto_config_interceptors_cpp",
+ ":perfetto_protos_perfetto_config_power_cpp",
+ ":perfetto_protos_perfetto_config_process_stats_cpp",
+ ":perfetto_protos_perfetto_config_profiling_cpp",
+ ":perfetto_protos_perfetto_config_statsd_cpp",
+ ":perfetto_protos_perfetto_config_sys_stats_cpp",
+ ":perfetto_protos_perfetto_config_system_info_cpp",
+ ":perfetto_protos_perfetto_config_track_event_cpp",
+ ":perfetto_protos_perfetto_trace_minimal_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_minimal_cpp)",
out: [
"external/perfetto/protos/perfetto/trace/clock_snapshot.gen.h",
"external/perfetto/protos/perfetto/trace/system_info.gen.h",
@@ -6699,18 +7295,40 @@
}
// GN: //protos/perfetto/trace:minimal_lite
-genrule {
- name: "perfetto_protos_perfetto_trace_minimal_lite_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_trace_minimal_lite",
srcs: [
"protos/perfetto/trace/clock_snapshot.proto",
"protos/perfetto/trace/system_info.proto",
"protos/perfetto/trace/trace_uuid.proto",
"protos/perfetto/trace/trigger.proto",
],
+}
+
+// GN: //protos/perfetto/trace:minimal_lite
+genrule {
+ name: "perfetto_protos_perfetto_trace_minimal_lite_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_common_lite",
+ ":perfetto_protos_perfetto_config_android_lite",
+ ":perfetto_protos_perfetto_config_ftrace_lite",
+ ":perfetto_protos_perfetto_config_gpu_lite",
+ ":perfetto_protos_perfetto_config_inode_file_lite",
+ ":perfetto_protos_perfetto_config_interceptors_lite",
+ ":perfetto_protos_perfetto_config_lite",
+ ":perfetto_protos_perfetto_config_power_lite",
+ ":perfetto_protos_perfetto_config_process_stats_lite",
+ ":perfetto_protos_perfetto_config_profiling_lite",
+ ":perfetto_protos_perfetto_config_statsd_lite",
+ ":perfetto_protos_perfetto_config_sys_stats_lite",
+ ":perfetto_protos_perfetto_config_system_info_lite",
+ ":perfetto_protos_perfetto_config_track_event_lite",
+ ":perfetto_protos_perfetto_trace_minimal_lite",
+ ],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_minimal_lite)",
out: [
"external/perfetto/protos/perfetto/trace/clock_snapshot.pb.cc",
"external/perfetto/protos/perfetto/trace/system_info.pb.cc",
@@ -6723,15 +7341,26 @@
genrule {
name: "perfetto_protos_perfetto_trace_minimal_lite_gen_headers",
srcs: [
- "protos/perfetto/trace/clock_snapshot.proto",
- "protos/perfetto/trace/system_info.proto",
- "protos/perfetto/trace/trace_uuid.proto",
- "protos/perfetto/trace/trigger.proto",
+ ":perfetto_protos_perfetto_common_lite",
+ ":perfetto_protos_perfetto_config_android_lite",
+ ":perfetto_protos_perfetto_config_ftrace_lite",
+ ":perfetto_protos_perfetto_config_gpu_lite",
+ ":perfetto_protos_perfetto_config_inode_file_lite",
+ ":perfetto_protos_perfetto_config_interceptors_lite",
+ ":perfetto_protos_perfetto_config_lite",
+ ":perfetto_protos_perfetto_config_power_lite",
+ ":perfetto_protos_perfetto_config_process_stats_lite",
+ ":perfetto_protos_perfetto_config_profiling_lite",
+ ":perfetto_protos_perfetto_config_statsd_lite",
+ ":perfetto_protos_perfetto_config_sys_stats_lite",
+ ":perfetto_protos_perfetto_config_system_info_lite",
+ ":perfetto_protos_perfetto_config_track_event_lite",
+ ":perfetto_protos_perfetto_trace_minimal_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_minimal_lite)",
out: [
"external/perfetto/protos/perfetto/trace/clock_snapshot.pb.h",
"external/perfetto/protos/perfetto/trace/system_info.pb.h",
@@ -6745,19 +7374,41 @@
}
// GN: //protos/perfetto/trace:minimal_zero
-genrule {
- name: "perfetto_protos_perfetto_trace_minimal_zero_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_trace_minimal_zero",
srcs: [
"protos/perfetto/trace/clock_snapshot.proto",
"protos/perfetto/trace/system_info.proto",
"protos/perfetto/trace/trace_uuid.proto",
"protos/perfetto/trace/trigger.proto",
],
+}
+
+// GN: //protos/perfetto/trace:minimal_zero
+genrule {
+ name: "perfetto_protos_perfetto_trace_minimal_zero_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_common_zero",
+ ":perfetto_protos_perfetto_config_android_zero",
+ ":perfetto_protos_perfetto_config_ftrace_zero",
+ ":perfetto_protos_perfetto_config_gpu_zero",
+ ":perfetto_protos_perfetto_config_inode_file_zero",
+ ":perfetto_protos_perfetto_config_interceptors_zero",
+ ":perfetto_protos_perfetto_config_power_zero",
+ ":perfetto_protos_perfetto_config_process_stats_zero",
+ ":perfetto_protos_perfetto_config_profiling_zero",
+ ":perfetto_protos_perfetto_config_statsd_zero",
+ ":perfetto_protos_perfetto_config_sys_stats_zero",
+ ":perfetto_protos_perfetto_config_system_info_zero",
+ ":perfetto_protos_perfetto_config_track_event_zero",
+ ":perfetto_protos_perfetto_config_zero",
+ ":perfetto_protos_perfetto_trace_minimal_zero",
+ ],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_minimal_zero)",
out: [
"external/perfetto/protos/perfetto/trace/clock_snapshot.pbzero.cc",
"external/perfetto/protos/perfetto/trace/system_info.pbzero.cc",
@@ -6770,16 +7421,27 @@
genrule {
name: "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
srcs: [
- "protos/perfetto/trace/clock_snapshot.proto",
- "protos/perfetto/trace/system_info.proto",
- "protos/perfetto/trace/trace_uuid.proto",
- "protos/perfetto/trace/trigger.proto",
+ ":perfetto_protos_perfetto_common_zero",
+ ":perfetto_protos_perfetto_config_android_zero",
+ ":perfetto_protos_perfetto_config_ftrace_zero",
+ ":perfetto_protos_perfetto_config_gpu_zero",
+ ":perfetto_protos_perfetto_config_inode_file_zero",
+ ":perfetto_protos_perfetto_config_interceptors_zero",
+ ":perfetto_protos_perfetto_config_power_zero",
+ ":perfetto_protos_perfetto_config_process_stats_zero",
+ ":perfetto_protos_perfetto_config_profiling_zero",
+ ":perfetto_protos_perfetto_config_statsd_zero",
+ ":perfetto_protos_perfetto_config_sys_stats_zero",
+ ":perfetto_protos_perfetto_config_system_info_zero",
+ ":perfetto_protos_perfetto_config_track_event_zero",
+ ":perfetto_protos_perfetto_config_zero",
+ ":perfetto_protos_perfetto_trace_minimal_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_minimal_zero)",
out: [
"external/perfetto/protos/perfetto/trace/clock_snapshot.pbzero.h",
"external/perfetto/protos/perfetto/trace/system_info.pbzero.h",
@@ -6793,8 +7455,8 @@
}
// GN: //protos/perfetto/trace:non_minimal_cpp
-genrule {
- name: "perfetto_protos_perfetto_trace_non_minimal_cpp_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_trace_non_minimal_cpp",
srcs: [
"protos/perfetto/trace/extension_descriptor.proto",
"protos/perfetto/trace/memory_graph.proto",
@@ -6805,11 +7467,50 @@
"protos/perfetto/trace/trace_packet_defaults.proto",
"protos/perfetto/trace/ui_state.proto",
],
+}
+
+// GN: //protos/perfetto/trace:non_minimal_cpp
+genrule {
+ name: "perfetto_protos_perfetto_trace_non_minimal_cpp_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_common_cpp",
+ ":perfetto_protos_perfetto_config_android_cpp",
+ ":perfetto_protos_perfetto_config_cpp",
+ ":perfetto_protos_perfetto_config_ftrace_cpp",
+ ":perfetto_protos_perfetto_config_gpu_cpp",
+ ":perfetto_protos_perfetto_config_inode_file_cpp",
+ ":perfetto_protos_perfetto_config_interceptors_cpp",
+ ":perfetto_protos_perfetto_config_power_cpp",
+ ":perfetto_protos_perfetto_config_process_stats_cpp",
+ ":perfetto_protos_perfetto_config_profiling_cpp",
+ ":perfetto_protos_perfetto_config_statsd_cpp",
+ ":perfetto_protos_perfetto_config_sys_stats_cpp",
+ ":perfetto_protos_perfetto_config_system_info_cpp",
+ ":perfetto_protos_perfetto_config_track_event_cpp",
+ ":perfetto_protos_perfetto_trace_android_cpp",
+ ":perfetto_protos_perfetto_trace_chrome_cpp",
+ ":perfetto_protos_perfetto_trace_etw_cpp",
+ ":perfetto_protos_perfetto_trace_filesystem_cpp",
+ ":perfetto_protos_perfetto_trace_ftrace_cpp",
+ ":perfetto_protos_perfetto_trace_gpu_cpp",
+ ":perfetto_protos_perfetto_trace_interned_data_cpp",
+ ":perfetto_protos_perfetto_trace_minimal_cpp",
+ ":perfetto_protos_perfetto_trace_non_minimal_cpp",
+ ":perfetto_protos_perfetto_trace_perfetto_cpp",
+ ":perfetto_protos_perfetto_trace_power_cpp",
+ ":perfetto_protos_perfetto_trace_profiling_cpp",
+ ":perfetto_protos_perfetto_trace_ps_cpp",
+ ":perfetto_protos_perfetto_trace_statsd_cpp",
+ ":perfetto_protos_perfetto_trace_sys_stats_cpp",
+ ":perfetto_protos_perfetto_trace_system_info_cpp",
+ ":perfetto_protos_perfetto_trace_track_event_cpp",
+ ":perfetto_protos_perfetto_trace_translation_cpp",
+ ],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_non_minimal_cpp)",
out: [
"external/perfetto/protos/perfetto/trace/extension_descriptor.gen.cc",
"external/perfetto/protos/perfetto/trace/memory_graph.gen.cc",
@@ -6826,20 +7527,44 @@
genrule {
name: "perfetto_protos_perfetto_trace_non_minimal_cpp_gen_headers",
srcs: [
- "protos/perfetto/trace/extension_descriptor.proto",
- "protos/perfetto/trace/memory_graph.proto",
- "protos/perfetto/trace/test_event.proto",
- "protos/perfetto/trace/test_extensions.proto",
- "protos/perfetto/trace/trace.proto",
- "protos/perfetto/trace/trace_packet.proto",
- "protos/perfetto/trace/trace_packet_defaults.proto",
- "protos/perfetto/trace/ui_state.proto",
+ ":perfetto_protos_perfetto_common_cpp",
+ ":perfetto_protos_perfetto_config_android_cpp",
+ ":perfetto_protos_perfetto_config_cpp",
+ ":perfetto_protos_perfetto_config_ftrace_cpp",
+ ":perfetto_protos_perfetto_config_gpu_cpp",
+ ":perfetto_protos_perfetto_config_inode_file_cpp",
+ ":perfetto_protos_perfetto_config_interceptors_cpp",
+ ":perfetto_protos_perfetto_config_power_cpp",
+ ":perfetto_protos_perfetto_config_process_stats_cpp",
+ ":perfetto_protos_perfetto_config_profiling_cpp",
+ ":perfetto_protos_perfetto_config_statsd_cpp",
+ ":perfetto_protos_perfetto_config_sys_stats_cpp",
+ ":perfetto_protos_perfetto_config_system_info_cpp",
+ ":perfetto_protos_perfetto_config_track_event_cpp",
+ ":perfetto_protos_perfetto_trace_android_cpp",
+ ":perfetto_protos_perfetto_trace_chrome_cpp",
+ ":perfetto_protos_perfetto_trace_etw_cpp",
+ ":perfetto_protos_perfetto_trace_filesystem_cpp",
+ ":perfetto_protos_perfetto_trace_ftrace_cpp",
+ ":perfetto_protos_perfetto_trace_gpu_cpp",
+ ":perfetto_protos_perfetto_trace_interned_data_cpp",
+ ":perfetto_protos_perfetto_trace_minimal_cpp",
+ ":perfetto_protos_perfetto_trace_non_minimal_cpp",
+ ":perfetto_protos_perfetto_trace_perfetto_cpp",
+ ":perfetto_protos_perfetto_trace_power_cpp",
+ ":perfetto_protos_perfetto_trace_profiling_cpp",
+ ":perfetto_protos_perfetto_trace_ps_cpp",
+ ":perfetto_protos_perfetto_trace_statsd_cpp",
+ ":perfetto_protos_perfetto_trace_sys_stats_cpp",
+ ":perfetto_protos_perfetto_trace_system_info_cpp",
+ ":perfetto_protos_perfetto_trace_track_event_cpp",
+ ":perfetto_protos_perfetto_trace_translation_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_non_minimal_cpp)",
out: [
"external/perfetto/protos/perfetto/trace/extension_descriptor.gen.h",
"external/perfetto/protos/perfetto/trace/memory_graph.gen.h",
@@ -6857,8 +7582,8 @@
}
// GN: //protos/perfetto/trace:non_minimal_lite
-genrule {
- name: "perfetto_protos_perfetto_trace_non_minimal_lite_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_trace_non_minimal_lite",
srcs: [
"protos/perfetto/trace/extension_descriptor.proto",
"protos/perfetto/trace/memory_graph.proto",
@@ -6869,10 +7594,49 @@
"protos/perfetto/trace/trace_packet_defaults.proto",
"protos/perfetto/trace/ui_state.proto",
],
+}
+
+// GN: //protos/perfetto/trace:non_minimal_lite
+genrule {
+ name: "perfetto_protos_perfetto_trace_non_minimal_lite_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_common_lite",
+ ":perfetto_protos_perfetto_config_android_lite",
+ ":perfetto_protos_perfetto_config_ftrace_lite",
+ ":perfetto_protos_perfetto_config_gpu_lite",
+ ":perfetto_protos_perfetto_config_inode_file_lite",
+ ":perfetto_protos_perfetto_config_interceptors_lite",
+ ":perfetto_protos_perfetto_config_lite",
+ ":perfetto_protos_perfetto_config_power_lite",
+ ":perfetto_protos_perfetto_config_process_stats_lite",
+ ":perfetto_protos_perfetto_config_profiling_lite",
+ ":perfetto_protos_perfetto_config_statsd_lite",
+ ":perfetto_protos_perfetto_config_sys_stats_lite",
+ ":perfetto_protos_perfetto_config_system_info_lite",
+ ":perfetto_protos_perfetto_config_track_event_lite",
+ ":perfetto_protos_perfetto_trace_android_lite",
+ ":perfetto_protos_perfetto_trace_chrome_lite",
+ ":perfetto_protos_perfetto_trace_etw_lite",
+ ":perfetto_protos_perfetto_trace_filesystem_lite",
+ ":perfetto_protos_perfetto_trace_ftrace_lite",
+ ":perfetto_protos_perfetto_trace_gpu_lite",
+ ":perfetto_protos_perfetto_trace_interned_data_lite",
+ ":perfetto_protos_perfetto_trace_minimal_lite",
+ ":perfetto_protos_perfetto_trace_non_minimal_lite",
+ ":perfetto_protos_perfetto_trace_perfetto_lite",
+ ":perfetto_protos_perfetto_trace_power_lite",
+ ":perfetto_protos_perfetto_trace_profiling_lite",
+ ":perfetto_protos_perfetto_trace_ps_lite",
+ ":perfetto_protos_perfetto_trace_statsd_lite",
+ ":perfetto_protos_perfetto_trace_sys_stats_lite",
+ ":perfetto_protos_perfetto_trace_system_info_lite",
+ ":perfetto_protos_perfetto_trace_track_event_lite",
+ ":perfetto_protos_perfetto_trace_translation_lite",
+ ],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_non_minimal_lite)",
out: [
"external/perfetto/protos/perfetto/trace/extension_descriptor.pb.cc",
"external/perfetto/protos/perfetto/trace/memory_graph.pb.cc",
@@ -6889,19 +7653,43 @@
genrule {
name: "perfetto_protos_perfetto_trace_non_minimal_lite_gen_headers",
srcs: [
- "protos/perfetto/trace/extension_descriptor.proto",
- "protos/perfetto/trace/memory_graph.proto",
- "protos/perfetto/trace/test_event.proto",
- "protos/perfetto/trace/test_extensions.proto",
- "protos/perfetto/trace/trace.proto",
- "protos/perfetto/trace/trace_packet.proto",
- "protos/perfetto/trace/trace_packet_defaults.proto",
- "protos/perfetto/trace/ui_state.proto",
+ ":perfetto_protos_perfetto_common_lite",
+ ":perfetto_protos_perfetto_config_android_lite",
+ ":perfetto_protos_perfetto_config_ftrace_lite",
+ ":perfetto_protos_perfetto_config_gpu_lite",
+ ":perfetto_protos_perfetto_config_inode_file_lite",
+ ":perfetto_protos_perfetto_config_interceptors_lite",
+ ":perfetto_protos_perfetto_config_lite",
+ ":perfetto_protos_perfetto_config_power_lite",
+ ":perfetto_protos_perfetto_config_process_stats_lite",
+ ":perfetto_protos_perfetto_config_profiling_lite",
+ ":perfetto_protos_perfetto_config_statsd_lite",
+ ":perfetto_protos_perfetto_config_sys_stats_lite",
+ ":perfetto_protos_perfetto_config_system_info_lite",
+ ":perfetto_protos_perfetto_config_track_event_lite",
+ ":perfetto_protos_perfetto_trace_android_lite",
+ ":perfetto_protos_perfetto_trace_chrome_lite",
+ ":perfetto_protos_perfetto_trace_etw_lite",
+ ":perfetto_protos_perfetto_trace_filesystem_lite",
+ ":perfetto_protos_perfetto_trace_ftrace_lite",
+ ":perfetto_protos_perfetto_trace_gpu_lite",
+ ":perfetto_protos_perfetto_trace_interned_data_lite",
+ ":perfetto_protos_perfetto_trace_minimal_lite",
+ ":perfetto_protos_perfetto_trace_non_minimal_lite",
+ ":perfetto_protos_perfetto_trace_perfetto_lite",
+ ":perfetto_protos_perfetto_trace_power_lite",
+ ":perfetto_protos_perfetto_trace_profiling_lite",
+ ":perfetto_protos_perfetto_trace_ps_lite",
+ ":perfetto_protos_perfetto_trace_statsd_lite",
+ ":perfetto_protos_perfetto_trace_sys_stats_lite",
+ ":perfetto_protos_perfetto_trace_system_info_lite",
+ ":perfetto_protos_perfetto_trace_track_event_lite",
+ ":perfetto_protos_perfetto_trace_translation_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_non_minimal_lite)",
out: [
"external/perfetto/protos/perfetto/trace/extension_descriptor.pb.h",
"external/perfetto/protos/perfetto/trace/memory_graph.pb.h",
@@ -6919,8 +7707,8 @@
}
// GN: //protos/perfetto/trace:non_minimal_zero
-genrule {
- name: "perfetto_protos_perfetto_trace_non_minimal_zero_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_trace_non_minimal_zero",
srcs: [
"protos/perfetto/trace/extension_descriptor.proto",
"protos/perfetto/trace/memory_graph.proto",
@@ -6931,11 +7719,50 @@
"protos/perfetto/trace/trace_packet_defaults.proto",
"protos/perfetto/trace/ui_state.proto",
],
+}
+
+// GN: //protos/perfetto/trace:non_minimal_zero
+genrule {
+ name: "perfetto_protos_perfetto_trace_non_minimal_zero_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_common_zero",
+ ":perfetto_protos_perfetto_config_android_zero",
+ ":perfetto_protos_perfetto_config_ftrace_zero",
+ ":perfetto_protos_perfetto_config_gpu_zero",
+ ":perfetto_protos_perfetto_config_inode_file_zero",
+ ":perfetto_protos_perfetto_config_interceptors_zero",
+ ":perfetto_protos_perfetto_config_power_zero",
+ ":perfetto_protos_perfetto_config_process_stats_zero",
+ ":perfetto_protos_perfetto_config_profiling_zero",
+ ":perfetto_protos_perfetto_config_statsd_zero",
+ ":perfetto_protos_perfetto_config_sys_stats_zero",
+ ":perfetto_protos_perfetto_config_system_info_zero",
+ ":perfetto_protos_perfetto_config_track_event_zero",
+ ":perfetto_protos_perfetto_config_zero",
+ ":perfetto_protos_perfetto_trace_android_zero",
+ ":perfetto_protos_perfetto_trace_chrome_zero",
+ ":perfetto_protos_perfetto_trace_etw_zero",
+ ":perfetto_protos_perfetto_trace_filesystem_zero",
+ ":perfetto_protos_perfetto_trace_ftrace_zero",
+ ":perfetto_protos_perfetto_trace_gpu_zero",
+ ":perfetto_protos_perfetto_trace_interned_data_zero",
+ ":perfetto_protos_perfetto_trace_minimal_zero",
+ ":perfetto_protos_perfetto_trace_non_minimal_zero",
+ ":perfetto_protos_perfetto_trace_perfetto_zero",
+ ":perfetto_protos_perfetto_trace_power_zero",
+ ":perfetto_protos_perfetto_trace_profiling_zero",
+ ":perfetto_protos_perfetto_trace_ps_zero",
+ ":perfetto_protos_perfetto_trace_statsd_zero",
+ ":perfetto_protos_perfetto_trace_sys_stats_zero",
+ ":perfetto_protos_perfetto_trace_system_info_zero",
+ ":perfetto_protos_perfetto_trace_track_event_zero",
+ ":perfetto_protos_perfetto_trace_translation_zero",
+ ],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_non_minimal_zero)",
out: [
"external/perfetto/protos/perfetto/trace/extension_descriptor.pbzero.cc",
"external/perfetto/protos/perfetto/trace/memory_graph.pbzero.cc",
@@ -6952,20 +7779,44 @@
genrule {
name: "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
srcs: [
- "protos/perfetto/trace/extension_descriptor.proto",
- "protos/perfetto/trace/memory_graph.proto",
- "protos/perfetto/trace/test_event.proto",
- "protos/perfetto/trace/test_extensions.proto",
- "protos/perfetto/trace/trace.proto",
- "protos/perfetto/trace/trace_packet.proto",
- "protos/perfetto/trace/trace_packet_defaults.proto",
- "protos/perfetto/trace/ui_state.proto",
+ ":perfetto_protos_perfetto_common_zero",
+ ":perfetto_protos_perfetto_config_android_zero",
+ ":perfetto_protos_perfetto_config_ftrace_zero",
+ ":perfetto_protos_perfetto_config_gpu_zero",
+ ":perfetto_protos_perfetto_config_inode_file_zero",
+ ":perfetto_protos_perfetto_config_interceptors_zero",
+ ":perfetto_protos_perfetto_config_power_zero",
+ ":perfetto_protos_perfetto_config_process_stats_zero",
+ ":perfetto_protos_perfetto_config_profiling_zero",
+ ":perfetto_protos_perfetto_config_statsd_zero",
+ ":perfetto_protos_perfetto_config_sys_stats_zero",
+ ":perfetto_protos_perfetto_config_system_info_zero",
+ ":perfetto_protos_perfetto_config_track_event_zero",
+ ":perfetto_protos_perfetto_config_zero",
+ ":perfetto_protos_perfetto_trace_android_zero",
+ ":perfetto_protos_perfetto_trace_chrome_zero",
+ ":perfetto_protos_perfetto_trace_etw_zero",
+ ":perfetto_protos_perfetto_trace_filesystem_zero",
+ ":perfetto_protos_perfetto_trace_ftrace_zero",
+ ":perfetto_protos_perfetto_trace_gpu_zero",
+ ":perfetto_protos_perfetto_trace_interned_data_zero",
+ ":perfetto_protos_perfetto_trace_minimal_zero",
+ ":perfetto_protos_perfetto_trace_non_minimal_zero",
+ ":perfetto_protos_perfetto_trace_perfetto_zero",
+ ":perfetto_protos_perfetto_trace_power_zero",
+ ":perfetto_protos_perfetto_trace_profiling_zero",
+ ":perfetto_protos_perfetto_trace_ps_zero",
+ ":perfetto_protos_perfetto_trace_statsd_zero",
+ ":perfetto_protos_perfetto_trace_sys_stats_zero",
+ ":perfetto_protos_perfetto_trace_system_info_zero",
+ ":perfetto_protos_perfetto_trace_track_event_zero",
+ ":perfetto_protos_perfetto_trace_translation_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_non_minimal_zero)",
out: [
"external/perfetto/protos/perfetto/trace/extension_descriptor.pbzero.h",
"external/perfetto/protos/perfetto/trace/memory_graph.pbzero.h",
@@ -6983,17 +7834,25 @@
}
// GN: //protos/perfetto/trace/perfetto:cpp
-genrule {
- name: "perfetto_protos_perfetto_trace_perfetto_cpp_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_trace_perfetto_cpp",
srcs: [
"protos/perfetto/trace/perfetto/perfetto_metatrace.proto",
"protos/perfetto/trace/perfetto/tracing_service_event.proto",
],
+}
+
+// GN: //protos/perfetto/trace/perfetto:cpp
+genrule {
+ name: "perfetto_protos_perfetto_trace_perfetto_cpp_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_trace_perfetto_cpp",
+ ],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_perfetto_cpp)",
out: [
"external/perfetto/protos/perfetto/trace/perfetto/perfetto_metatrace.gen.cc",
"external/perfetto/protos/perfetto/trace/perfetto/tracing_service_event.gen.cc",
@@ -7004,14 +7863,13 @@
genrule {
name: "perfetto_protos_perfetto_trace_perfetto_cpp_gen_headers",
srcs: [
- "protos/perfetto/trace/perfetto/perfetto_metatrace.proto",
- "protos/perfetto/trace/perfetto/tracing_service_event.proto",
+ ":perfetto_protos_perfetto_trace_perfetto_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_perfetto_cpp)",
out: [
"external/perfetto/protos/perfetto/trace/perfetto/perfetto_metatrace.gen.h",
"external/perfetto/protos/perfetto/trace/perfetto/tracing_service_event.gen.h",
@@ -7023,16 +7881,24 @@
}
// GN: //protos/perfetto/trace/perfetto:lite
-genrule {
- name: "perfetto_protos_perfetto_trace_perfetto_lite_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_trace_perfetto_lite",
srcs: [
"protos/perfetto/trace/perfetto/perfetto_metatrace.proto",
"protos/perfetto/trace/perfetto/tracing_service_event.proto",
],
+}
+
+// GN: //protos/perfetto/trace/perfetto:lite
+genrule {
+ name: "perfetto_protos_perfetto_trace_perfetto_lite_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_trace_perfetto_lite",
+ ],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_perfetto_lite)",
out: [
"external/perfetto/protos/perfetto/trace/perfetto/perfetto_metatrace.pb.cc",
"external/perfetto/protos/perfetto/trace/perfetto/tracing_service_event.pb.cc",
@@ -7043,13 +7909,12 @@
genrule {
name: "perfetto_protos_perfetto_trace_perfetto_lite_gen_headers",
srcs: [
- "protos/perfetto/trace/perfetto/perfetto_metatrace.proto",
- "protos/perfetto/trace/perfetto/tracing_service_event.proto",
+ ":perfetto_protos_perfetto_trace_perfetto_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_perfetto_lite)",
out: [
"external/perfetto/protos/perfetto/trace/perfetto/perfetto_metatrace.pb.h",
"external/perfetto/protos/perfetto/trace/perfetto/tracing_service_event.pb.h",
@@ -7061,17 +7926,25 @@
}
// GN: //protos/perfetto/trace/perfetto:zero
-genrule {
- name: "perfetto_protos_perfetto_trace_perfetto_zero_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_trace_perfetto_zero",
srcs: [
"protos/perfetto/trace/perfetto/perfetto_metatrace.proto",
"protos/perfetto/trace/perfetto/tracing_service_event.proto",
],
+}
+
+// GN: //protos/perfetto/trace/perfetto:zero
+genrule {
+ name: "perfetto_protos_perfetto_trace_perfetto_zero_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_trace_perfetto_zero",
+ ],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_perfetto_zero)",
out: [
"external/perfetto/protos/perfetto/trace/perfetto/perfetto_metatrace.pbzero.cc",
"external/perfetto/protos/perfetto/trace/perfetto/tracing_service_event.pbzero.cc",
@@ -7082,14 +7955,13 @@
genrule {
name: "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
srcs: [
- "protos/perfetto/trace/perfetto/perfetto_metatrace.proto",
- "protos/perfetto/trace/perfetto/tracing_service_event.proto",
+ ":perfetto_protos_perfetto_trace_perfetto_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_perfetto_zero)",
out: [
"external/perfetto/protos/perfetto/trace/perfetto/perfetto_metatrace.pbzero.h",
"external/perfetto/protos/perfetto/trace/perfetto/tracing_service_event.pbzero.h",
@@ -7101,19 +7973,28 @@
}
// GN: //protos/perfetto/trace/power:cpp
-genrule {
- name: "perfetto_protos_perfetto_trace_power_cpp_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_trace_power_cpp",
srcs: [
"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",
"protos/perfetto/trace/power/power_rails.proto",
],
+}
+
+// GN: //protos/perfetto/trace/power:cpp
+genrule {
+ name: "perfetto_protos_perfetto_trace_power_cpp_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_common_cpp",
+ ":perfetto_protos_perfetto_trace_power_cpp",
+ ],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_power_cpp)",
out: [
"external/perfetto/protos/perfetto/trace/power/android_energy_estimation_breakdown.gen.cc",
"external/perfetto/protos/perfetto/trace/power/android_entity_state_residency.gen.cc",
@@ -7126,16 +8007,14 @@
genrule {
name: "perfetto_protos_perfetto_trace_power_cpp_gen_headers",
srcs: [
- "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",
- "protos/perfetto/trace/power/power_rails.proto",
+ ":perfetto_protos_perfetto_common_cpp",
+ ":perfetto_protos_perfetto_trace_power_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_power_cpp)",
out: [
"external/perfetto/protos/perfetto/trace/power/android_energy_estimation_breakdown.gen.h",
"external/perfetto/protos/perfetto/trace/power/android_entity_state_residency.gen.h",
@@ -7149,18 +8028,27 @@
}
// GN: //protos/perfetto/trace/power:lite
-genrule {
- name: "perfetto_protos_perfetto_trace_power_lite_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_trace_power_lite",
srcs: [
"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",
"protos/perfetto/trace/power/power_rails.proto",
],
+}
+
+// GN: //protos/perfetto/trace/power:lite
+genrule {
+ name: "perfetto_protos_perfetto_trace_power_lite_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_common_lite",
+ ":perfetto_protos_perfetto_trace_power_lite",
+ ],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_power_lite)",
out: [
"external/perfetto/protos/perfetto/trace/power/android_energy_estimation_breakdown.pb.cc",
"external/perfetto/protos/perfetto/trace/power/android_entity_state_residency.pb.cc",
@@ -7173,15 +8061,13 @@
genrule {
name: "perfetto_protos_perfetto_trace_power_lite_gen_headers",
srcs: [
- "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",
- "protos/perfetto/trace/power/power_rails.proto",
+ ":perfetto_protos_perfetto_common_lite",
+ ":perfetto_protos_perfetto_trace_power_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_power_lite)",
out: [
"external/perfetto/protos/perfetto/trace/power/android_energy_estimation_breakdown.pb.h",
"external/perfetto/protos/perfetto/trace/power/android_entity_state_residency.pb.h",
@@ -7195,19 +8081,28 @@
}
// GN: //protos/perfetto/trace/power:zero
-genrule {
- name: "perfetto_protos_perfetto_trace_power_zero_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_trace_power_zero",
srcs: [
"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",
"protos/perfetto/trace/power/power_rails.proto",
],
+}
+
+// GN: //protos/perfetto/trace/power:zero
+genrule {
+ name: "perfetto_protos_perfetto_trace_power_zero_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_common_zero",
+ ":perfetto_protos_perfetto_trace_power_zero",
+ ],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_power_zero)",
out: [
"external/perfetto/protos/perfetto/trace/power/android_energy_estimation_breakdown.pbzero.cc",
"external/perfetto/protos/perfetto/trace/power/android_entity_state_residency.pbzero.cc",
@@ -7220,16 +8115,14 @@
genrule {
name: "perfetto_protos_perfetto_trace_power_zero_gen_headers",
srcs: [
- "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",
- "protos/perfetto/trace/power/power_rails.proto",
+ ":perfetto_protos_perfetto_common_zero",
+ ":perfetto_protos_perfetto_trace_power_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_power_zero)",
out: [
"external/perfetto/protos/perfetto/trace/power/android_energy_estimation_breakdown.pbzero.h",
"external/perfetto/protos/perfetto/trace/power/android_entity_state_residency.pbzero.h",
@@ -7243,17 +8136,26 @@
}
// GN: //protos/perfetto/trace_processor:lite
-genrule {
- name: "perfetto_protos_perfetto_trace_processor_lite_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_trace_processor_lite",
srcs: [
"protos/perfetto/trace_processor/metatrace_categories.proto",
"protos/perfetto/trace_processor/stack.proto",
"protos/perfetto/trace_processor/trace_processor.proto",
],
+}
+
+// GN: //protos/perfetto/trace_processor:lite
+genrule {
+ name: "perfetto_protos_perfetto_trace_processor_lite_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_common_lite",
+ ":perfetto_protos_perfetto_trace_processor_lite",
+ ],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_processor_lite)",
out: [
"external/perfetto/protos/perfetto/trace_processor/metatrace_categories.pb.cc",
"external/perfetto/protos/perfetto/trace_processor/stack.pb.cc",
@@ -7265,14 +8167,13 @@
genrule {
name: "perfetto_protos_perfetto_trace_processor_lite_gen_headers",
srcs: [
- "protos/perfetto/trace_processor/metatrace_categories.proto",
- "protos/perfetto/trace_processor/stack.proto",
- "protos/perfetto/trace_processor/trace_processor.proto",
+ ":perfetto_protos_perfetto_common_lite",
+ ":perfetto_protos_perfetto_trace_processor_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_processor_lite)",
out: [
"external/perfetto/protos/perfetto/trace_processor/metatrace_categories.pb.h",
"external/perfetto/protos/perfetto/trace_processor/stack.pb.h",
@@ -7285,16 +8186,24 @@
}
// GN: //protos/perfetto/trace_processor:metrics_impl_zero
+filegroup {
+ name: "perfetto_protos_perfetto_trace_processor_metrics_impl_zero",
+ srcs: [
+ "protos/perfetto/trace_processor/metrics_impl.proto",
+ ],
+}
+
+// GN: //protos/perfetto/trace_processor:metrics_impl_zero
genrule {
name: "perfetto_protos_perfetto_trace_processor_metrics_impl_zero_gen",
srcs: [
- "protos/perfetto/trace_processor/metrics_impl.proto",
+ ":perfetto_protos_perfetto_trace_processor_metrics_impl_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_processor_metrics_impl_zero)",
out: [
"external/perfetto/protos/perfetto/trace_processor/metrics_impl.pbzero.cc",
],
@@ -7304,13 +8213,13 @@
genrule {
name: "perfetto_protos_perfetto_trace_processor_metrics_impl_zero_gen_headers",
srcs: [
- "protos/perfetto/trace_processor/metrics_impl.proto",
+ ":perfetto_protos_perfetto_trace_processor_metrics_impl_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_processor_metrics_impl_zero)",
out: [
"external/perfetto/protos/perfetto/trace_processor/metrics_impl.pbzero.h",
],
@@ -7321,18 +8230,27 @@
}
// GN: //protos/perfetto/trace_processor:zero
-genrule {
- name: "perfetto_protos_perfetto_trace_processor_zero_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_trace_processor_zero",
srcs: [
"protos/perfetto/trace_processor/metatrace_categories.proto",
"protos/perfetto/trace_processor/stack.proto",
"protos/perfetto/trace_processor/trace_processor.proto",
],
+}
+
+// GN: //protos/perfetto/trace_processor:zero
+genrule {
+ name: "perfetto_protos_perfetto_trace_processor_zero_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_common_zero",
+ ":perfetto_protos_perfetto_trace_processor_zero",
+ ],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_processor_zero)",
out: [
"external/perfetto/protos/perfetto/trace_processor/metatrace_categories.pbzero.cc",
"external/perfetto/protos/perfetto/trace_processor/stack.pbzero.cc",
@@ -7344,15 +8262,14 @@
genrule {
name: "perfetto_protos_perfetto_trace_processor_zero_gen_headers",
srcs: [
- "protos/perfetto/trace_processor/metatrace_categories.proto",
- "protos/perfetto/trace_processor/stack.proto",
- "protos/perfetto/trace_processor/trace_processor.proto",
+ ":perfetto_protos_perfetto_common_zero",
+ ":perfetto_protos_perfetto_trace_processor_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_processor_zero)",
out: [
"external/perfetto/protos/perfetto/trace_processor/metatrace_categories.pbzero.h",
"external/perfetto/protos/perfetto/trace_processor/stack.pbzero.h",
@@ -7365,8 +8282,8 @@
}
// GN: //protos/perfetto/trace/profiling:cpp
-genrule {
- name: "perfetto_protos_perfetto_trace_profiling_cpp_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_trace_profiling_cpp",
srcs: [
"protos/perfetto/trace/profiling/deobfuscation.proto",
"protos/perfetto/trace/profiling/heap_graph.proto",
@@ -7374,11 +8291,20 @@
"protos/perfetto/trace/profiling/profile_packet.proto",
"protos/perfetto/trace/profiling/smaps.proto",
],
+}
+
+// GN: //protos/perfetto/trace/profiling:cpp
+genrule {
+ name: "perfetto_protos_perfetto_trace_profiling_cpp_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_common_cpp",
+ ":perfetto_protos_perfetto_trace_profiling_cpp",
+ ],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_profiling_cpp)",
out: [
"external/perfetto/protos/perfetto/trace/profiling/deobfuscation.gen.cc",
"external/perfetto/protos/perfetto/trace/profiling/heap_graph.gen.cc",
@@ -7392,17 +8318,14 @@
genrule {
name: "perfetto_protos_perfetto_trace_profiling_cpp_gen_headers",
srcs: [
- "protos/perfetto/trace/profiling/deobfuscation.proto",
- "protos/perfetto/trace/profiling/heap_graph.proto",
- "protos/perfetto/trace/profiling/profile_common.proto",
- "protos/perfetto/trace/profiling/profile_packet.proto",
- "protos/perfetto/trace/profiling/smaps.proto",
+ ":perfetto_protos_perfetto_common_cpp",
+ ":perfetto_protos_perfetto_trace_profiling_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_profiling_cpp)",
out: [
"external/perfetto/protos/perfetto/trace/profiling/deobfuscation.gen.h",
"external/perfetto/protos/perfetto/trace/profiling/heap_graph.gen.h",
@@ -7417,8 +8340,8 @@
}
// GN: //protos/perfetto/trace/profiling:lite
-genrule {
- name: "perfetto_protos_perfetto_trace_profiling_lite_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_trace_profiling_lite",
srcs: [
"protos/perfetto/trace/profiling/deobfuscation.proto",
"protos/perfetto/trace/profiling/heap_graph.proto",
@@ -7426,10 +8349,19 @@
"protos/perfetto/trace/profiling/profile_packet.proto",
"protos/perfetto/trace/profiling/smaps.proto",
],
+}
+
+// GN: //protos/perfetto/trace/profiling:lite
+genrule {
+ name: "perfetto_protos_perfetto_trace_profiling_lite_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_common_lite",
+ ":perfetto_protos_perfetto_trace_profiling_lite",
+ ],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_profiling_lite)",
out: [
"external/perfetto/protos/perfetto/trace/profiling/deobfuscation.pb.cc",
"external/perfetto/protos/perfetto/trace/profiling/heap_graph.pb.cc",
@@ -7443,16 +8375,13 @@
genrule {
name: "perfetto_protos_perfetto_trace_profiling_lite_gen_headers",
srcs: [
- "protos/perfetto/trace/profiling/deobfuscation.proto",
- "protos/perfetto/trace/profiling/heap_graph.proto",
- "protos/perfetto/trace/profiling/profile_common.proto",
- "protos/perfetto/trace/profiling/profile_packet.proto",
- "protos/perfetto/trace/profiling/smaps.proto",
+ ":perfetto_protos_perfetto_common_lite",
+ ":perfetto_protos_perfetto_trace_profiling_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_profiling_lite)",
out: [
"external/perfetto/protos/perfetto/trace/profiling/deobfuscation.pb.h",
"external/perfetto/protos/perfetto/trace/profiling/heap_graph.pb.h",
@@ -7467,8 +8396,8 @@
}
// GN: //protos/perfetto/trace/profiling:zero
-genrule {
- name: "perfetto_protos_perfetto_trace_profiling_zero_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_trace_profiling_zero",
srcs: [
"protos/perfetto/trace/profiling/deobfuscation.proto",
"protos/perfetto/trace/profiling/heap_graph.proto",
@@ -7476,11 +8405,20 @@
"protos/perfetto/trace/profiling/profile_packet.proto",
"protos/perfetto/trace/profiling/smaps.proto",
],
+}
+
+// GN: //protos/perfetto/trace/profiling:zero
+genrule {
+ name: "perfetto_protos_perfetto_trace_profiling_zero_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_common_zero",
+ ":perfetto_protos_perfetto_trace_profiling_zero",
+ ],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_profiling_zero)",
out: [
"external/perfetto/protos/perfetto/trace/profiling/deobfuscation.pbzero.cc",
"external/perfetto/protos/perfetto/trace/profiling/heap_graph.pbzero.cc",
@@ -7494,17 +8432,14 @@
genrule {
name: "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
srcs: [
- "protos/perfetto/trace/profiling/deobfuscation.proto",
- "protos/perfetto/trace/profiling/heap_graph.proto",
- "protos/perfetto/trace/profiling/profile_common.proto",
- "protos/perfetto/trace/profiling/profile_packet.proto",
- "protos/perfetto/trace/profiling/smaps.proto",
+ ":perfetto_protos_perfetto_common_zero",
+ ":perfetto_protos_perfetto_trace_profiling_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_profiling_zero)",
out: [
"external/perfetto/protos/perfetto/trace/profiling/deobfuscation.pbzero.h",
"external/perfetto/protos/perfetto/trace/profiling/heap_graph.pbzero.h",
@@ -7519,17 +8454,25 @@
}
// GN: //protos/perfetto/trace/ps:cpp
-genrule {
- name: "perfetto_protos_perfetto_trace_ps_cpp_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_trace_ps_cpp",
srcs: [
"protos/perfetto/trace/ps/process_stats.proto",
"protos/perfetto/trace/ps/process_tree.proto",
],
+}
+
+// GN: //protos/perfetto/trace/ps:cpp
+genrule {
+ name: "perfetto_protos_perfetto_trace_ps_cpp_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_trace_ps_cpp",
+ ],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_ps_cpp)",
out: [
"external/perfetto/protos/perfetto/trace/ps/process_stats.gen.cc",
"external/perfetto/protos/perfetto/trace/ps/process_tree.gen.cc",
@@ -7540,14 +8483,13 @@
genrule {
name: "perfetto_protos_perfetto_trace_ps_cpp_gen_headers",
srcs: [
- "protos/perfetto/trace/ps/process_stats.proto",
- "protos/perfetto/trace/ps/process_tree.proto",
+ ":perfetto_protos_perfetto_trace_ps_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_ps_cpp)",
out: [
"external/perfetto/protos/perfetto/trace/ps/process_stats.gen.h",
"external/perfetto/protos/perfetto/trace/ps/process_tree.gen.h",
@@ -7559,16 +8501,24 @@
}
// GN: //protos/perfetto/trace/ps:lite
-genrule {
- name: "perfetto_protos_perfetto_trace_ps_lite_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_trace_ps_lite",
srcs: [
"protos/perfetto/trace/ps/process_stats.proto",
"protos/perfetto/trace/ps/process_tree.proto",
],
+}
+
+// GN: //protos/perfetto/trace/ps:lite
+genrule {
+ name: "perfetto_protos_perfetto_trace_ps_lite_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_trace_ps_lite",
+ ],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_ps_lite)",
out: [
"external/perfetto/protos/perfetto/trace/ps/process_stats.pb.cc",
"external/perfetto/protos/perfetto/trace/ps/process_tree.pb.cc",
@@ -7579,13 +8529,12 @@
genrule {
name: "perfetto_protos_perfetto_trace_ps_lite_gen_headers",
srcs: [
- "protos/perfetto/trace/ps/process_stats.proto",
- "protos/perfetto/trace/ps/process_tree.proto",
+ ":perfetto_protos_perfetto_trace_ps_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_ps_lite)",
out: [
"external/perfetto/protos/perfetto/trace/ps/process_stats.pb.h",
"external/perfetto/protos/perfetto/trace/ps/process_tree.pb.h",
@@ -7597,17 +8546,25 @@
}
// GN: //protos/perfetto/trace/ps:zero
-genrule {
- name: "perfetto_protos_perfetto_trace_ps_zero_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_trace_ps_zero",
srcs: [
"protos/perfetto/trace/ps/process_stats.proto",
"protos/perfetto/trace/ps/process_tree.proto",
],
+}
+
+// GN: //protos/perfetto/trace/ps:zero
+genrule {
+ name: "perfetto_protos_perfetto_trace_ps_zero_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_trace_ps_zero",
+ ],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_ps_zero)",
out: [
"external/perfetto/protos/perfetto/trace/ps/process_stats.pbzero.cc",
"external/perfetto/protos/perfetto/trace/ps/process_tree.pbzero.cc",
@@ -7618,14 +8575,13 @@
genrule {
name: "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
srcs: [
- "protos/perfetto/trace/ps/process_stats.proto",
- "protos/perfetto/trace/ps/process_tree.proto",
+ ":perfetto_protos_perfetto_trace_ps_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_ps_zero)",
out: [
"external/perfetto/protos/perfetto/trace/ps/process_stats.pbzero.h",
"external/perfetto/protos/perfetto/trace/ps/process_tree.pbzero.h",
@@ -7637,16 +8593,25 @@
}
// GN: //protos/perfetto/trace/statsd:cpp
+filegroup {
+ name: "perfetto_protos_perfetto_trace_statsd_cpp",
+ srcs: [
+ "protos/perfetto/trace/statsd/statsd_atom.proto",
+ ],
+}
+
+// GN: //protos/perfetto/trace/statsd:cpp
genrule {
name: "perfetto_protos_perfetto_trace_statsd_cpp_gen",
srcs: [
- "protos/perfetto/trace/statsd/statsd_atom.proto",
+ ":perfetto_protos_perfetto_common_cpp",
+ ":perfetto_protos_perfetto_trace_statsd_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_statsd_cpp)",
out: [
"external/perfetto/protos/perfetto/trace/statsd/statsd_atom.gen.cc",
],
@@ -7656,13 +8621,14 @@
genrule {
name: "perfetto_protos_perfetto_trace_statsd_cpp_gen_headers",
srcs: [
- "protos/perfetto/trace/statsd/statsd_atom.proto",
+ ":perfetto_protos_perfetto_common_cpp",
+ ":perfetto_protos_perfetto_trace_statsd_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_statsd_cpp)",
out: [
"external/perfetto/protos/perfetto/trace/statsd/statsd_atom.gen.h",
],
@@ -7673,15 +8639,24 @@
}
// GN: //protos/perfetto/trace/statsd:lite
+filegroup {
+ name: "perfetto_protos_perfetto_trace_statsd_lite",
+ srcs: [
+ "protos/perfetto/trace/statsd/statsd_atom.proto",
+ ],
+}
+
+// GN: //protos/perfetto/trace/statsd:lite
genrule {
name: "perfetto_protos_perfetto_trace_statsd_lite_gen",
srcs: [
- "protos/perfetto/trace/statsd/statsd_atom.proto",
+ ":perfetto_protos_perfetto_common_lite",
+ ":perfetto_protos_perfetto_trace_statsd_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_statsd_lite)",
out: [
"external/perfetto/protos/perfetto/trace/statsd/statsd_atom.pb.cc",
],
@@ -7691,12 +8666,13 @@
genrule {
name: "perfetto_protos_perfetto_trace_statsd_lite_gen_headers",
srcs: [
- "protos/perfetto/trace/statsd/statsd_atom.proto",
+ ":perfetto_protos_perfetto_common_lite",
+ ":perfetto_protos_perfetto_trace_statsd_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_statsd_lite)",
out: [
"external/perfetto/protos/perfetto/trace/statsd/statsd_atom.pb.h",
],
@@ -7707,16 +8683,25 @@
}
// GN: //protos/perfetto/trace/statsd:zero
+filegroup {
+ name: "perfetto_protos_perfetto_trace_statsd_zero",
+ srcs: [
+ "protos/perfetto/trace/statsd/statsd_atom.proto",
+ ],
+}
+
+// GN: //protos/perfetto/trace/statsd:zero
genrule {
name: "perfetto_protos_perfetto_trace_statsd_zero_gen",
srcs: [
- "protos/perfetto/trace/statsd/statsd_atom.proto",
+ ":perfetto_protos_perfetto_common_zero",
+ ":perfetto_protos_perfetto_trace_statsd_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_statsd_zero)",
out: [
"external/perfetto/protos/perfetto/trace/statsd/statsd_atom.pbzero.cc",
],
@@ -7726,13 +8711,14 @@
genrule {
name: "perfetto_protos_perfetto_trace_statsd_zero_gen_headers",
srcs: [
- "protos/perfetto/trace/statsd/statsd_atom.proto",
+ ":perfetto_protos_perfetto_common_zero",
+ ":perfetto_protos_perfetto_trace_statsd_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_statsd_zero)",
out: [
"external/perfetto/protos/perfetto/trace/statsd/statsd_atom.pbzero.h",
],
@@ -7743,16 +8729,25 @@
}
// GN: //protos/perfetto/trace/sys_stats:cpp
+filegroup {
+ name: "perfetto_protos_perfetto_trace_sys_stats_cpp",
+ srcs: [
+ "protos/perfetto/trace/sys_stats/sys_stats.proto",
+ ],
+}
+
+// GN: //protos/perfetto/trace/sys_stats:cpp
genrule {
name: "perfetto_protos_perfetto_trace_sys_stats_cpp_gen",
srcs: [
- "protos/perfetto/trace/sys_stats/sys_stats.proto",
+ ":perfetto_protos_perfetto_common_cpp",
+ ":perfetto_protos_perfetto_trace_sys_stats_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_sys_stats_cpp)",
out: [
"external/perfetto/protos/perfetto/trace/sys_stats/sys_stats.gen.cc",
],
@@ -7762,13 +8757,14 @@
genrule {
name: "perfetto_protos_perfetto_trace_sys_stats_cpp_gen_headers",
srcs: [
- "protos/perfetto/trace/sys_stats/sys_stats.proto",
+ ":perfetto_protos_perfetto_common_cpp",
+ ":perfetto_protos_perfetto_trace_sys_stats_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_sys_stats_cpp)",
out: [
"external/perfetto/protos/perfetto/trace/sys_stats/sys_stats.gen.h",
],
@@ -7779,15 +8775,24 @@
}
// GN: //protos/perfetto/trace/sys_stats:lite
+filegroup {
+ name: "perfetto_protos_perfetto_trace_sys_stats_lite",
+ srcs: [
+ "protos/perfetto/trace/sys_stats/sys_stats.proto",
+ ],
+}
+
+// GN: //protos/perfetto/trace/sys_stats:lite
genrule {
name: "perfetto_protos_perfetto_trace_sys_stats_lite_gen",
srcs: [
- "protos/perfetto/trace/sys_stats/sys_stats.proto",
+ ":perfetto_protos_perfetto_common_lite",
+ ":perfetto_protos_perfetto_trace_sys_stats_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_sys_stats_lite)",
out: [
"external/perfetto/protos/perfetto/trace/sys_stats/sys_stats.pb.cc",
],
@@ -7797,12 +8802,13 @@
genrule {
name: "perfetto_protos_perfetto_trace_sys_stats_lite_gen_headers",
srcs: [
- "protos/perfetto/trace/sys_stats/sys_stats.proto",
+ ":perfetto_protos_perfetto_common_lite",
+ ":perfetto_protos_perfetto_trace_sys_stats_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_sys_stats_lite)",
out: [
"external/perfetto/protos/perfetto/trace/sys_stats/sys_stats.pb.h",
],
@@ -7813,16 +8819,25 @@
}
// GN: //protos/perfetto/trace/sys_stats:zero
+filegroup {
+ name: "perfetto_protos_perfetto_trace_sys_stats_zero",
+ srcs: [
+ "protos/perfetto/trace/sys_stats/sys_stats.proto",
+ ],
+}
+
+// GN: //protos/perfetto/trace/sys_stats:zero
genrule {
name: "perfetto_protos_perfetto_trace_sys_stats_zero_gen",
srcs: [
- "protos/perfetto/trace/sys_stats/sys_stats.proto",
+ ":perfetto_protos_perfetto_common_zero",
+ ":perfetto_protos_perfetto_trace_sys_stats_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_sys_stats_zero)",
out: [
"external/perfetto/protos/perfetto/trace/sys_stats/sys_stats.pbzero.cc",
],
@@ -7832,13 +8847,14 @@
genrule {
name: "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
srcs: [
- "protos/perfetto/trace/sys_stats/sys_stats.proto",
+ ":perfetto_protos_perfetto_common_zero",
+ ":perfetto_protos_perfetto_trace_sys_stats_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_sys_stats_zero)",
out: [
"external/perfetto/protos/perfetto/trace/sys_stats/sys_stats.pbzero.h",
],
@@ -7849,16 +8865,24 @@
}
// GN: //protos/perfetto/trace/system_info:cpp
+filegroup {
+ name: "perfetto_protos_perfetto_trace_system_info_cpp",
+ srcs: [
+ "protos/perfetto/trace/system_info/cpu_info.proto",
+ ],
+}
+
+// GN: //protos/perfetto/trace/system_info:cpp
genrule {
name: "perfetto_protos_perfetto_trace_system_info_cpp_gen",
srcs: [
- "protos/perfetto/trace/system_info/cpu_info.proto",
+ ":perfetto_protos_perfetto_trace_system_info_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_system_info_cpp)",
out: [
"external/perfetto/protos/perfetto/trace/system_info/cpu_info.gen.cc",
],
@@ -7868,13 +8892,13 @@
genrule {
name: "perfetto_protos_perfetto_trace_system_info_cpp_gen_headers",
srcs: [
- "protos/perfetto/trace/system_info/cpu_info.proto",
+ ":perfetto_protos_perfetto_trace_system_info_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_system_info_cpp)",
out: [
"external/perfetto/protos/perfetto/trace/system_info/cpu_info.gen.h",
],
@@ -7885,15 +8909,23 @@
}
// GN: //protos/perfetto/trace/system_info:lite
+filegroup {
+ name: "perfetto_protos_perfetto_trace_system_info_lite",
+ srcs: [
+ "protos/perfetto/trace/system_info/cpu_info.proto",
+ ],
+}
+
+// GN: //protos/perfetto/trace/system_info:lite
genrule {
name: "perfetto_protos_perfetto_trace_system_info_lite_gen",
srcs: [
- "protos/perfetto/trace/system_info/cpu_info.proto",
+ ":perfetto_protos_perfetto_trace_system_info_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_system_info_lite)",
out: [
"external/perfetto/protos/perfetto/trace/system_info/cpu_info.pb.cc",
],
@@ -7903,12 +8935,12 @@
genrule {
name: "perfetto_protos_perfetto_trace_system_info_lite_gen_headers",
srcs: [
- "protos/perfetto/trace/system_info/cpu_info.proto",
+ ":perfetto_protos_perfetto_trace_system_info_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_system_info_lite)",
out: [
"external/perfetto/protos/perfetto/trace/system_info/cpu_info.pb.h",
],
@@ -7919,16 +8951,24 @@
}
// GN: //protos/perfetto/trace/system_info:zero
+filegroup {
+ name: "perfetto_protos_perfetto_trace_system_info_zero",
+ srcs: [
+ "protos/perfetto/trace/system_info/cpu_info.proto",
+ ],
+}
+
+// GN: //protos/perfetto/trace/system_info:zero
genrule {
name: "perfetto_protos_perfetto_trace_system_info_zero_gen",
srcs: [
- "protos/perfetto/trace/system_info/cpu_info.proto",
+ ":perfetto_protos_perfetto_trace_system_info_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_system_info_zero)",
out: [
"external/perfetto/protos/perfetto/trace/system_info/cpu_info.pbzero.cc",
],
@@ -7938,13 +8978,13 @@
genrule {
name: "perfetto_protos_perfetto_trace_system_info_zero_gen_headers",
srcs: [
- "protos/perfetto/trace/system_info/cpu_info.proto",
+ ":perfetto_protos_perfetto_trace_system_info_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_system_info_zero)",
out: [
"external/perfetto/protos/perfetto/trace/system_info/cpu_info.pbzero.h",
],
@@ -7955,8 +8995,8 @@
}
// GN: //protos/perfetto/trace/track_event:cpp
-genrule {
- name: "perfetto_protos_perfetto_trace_track_event_cpp_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_trace_track_event_cpp",
srcs: [
"protos/perfetto/trace/track_event/chrome_active_processes.proto",
"protos/perfetto/trace/track_event/chrome_application_state_info.proto",
@@ -7986,11 +9026,19 @@
"protos/perfetto/trace/track_event/track_descriptor.proto",
"protos/perfetto/trace/track_event/track_event.proto",
],
+}
+
+// GN: //protos/perfetto/trace/track_event:cpp
+genrule {
+ name: "perfetto_protos_perfetto_trace_track_event_cpp_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_trace_track_event_cpp",
+ ],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_track_event_cpp)",
out: [
"external/perfetto/protos/perfetto/trace/track_event/chrome_active_processes.gen.cc",
"external/perfetto/protos/perfetto/trace/track_event/chrome_application_state_info.gen.cc",
@@ -8026,39 +9074,13 @@
genrule {
name: "perfetto_protos_perfetto_trace_track_event_cpp_gen_headers",
srcs: [
- "protos/perfetto/trace/track_event/chrome_active_processes.proto",
- "protos/perfetto/trace/track_event/chrome_application_state_info.proto",
- "protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.proto",
- "protos/perfetto/trace/track_event/chrome_content_settings_event_info.proto",
- "protos/perfetto/trace/track_event/chrome_frame_reporter.proto",
- "protos/perfetto/trace/track_event/chrome_histogram_sample.proto",
- "protos/perfetto/trace/track_event/chrome_keyed_service.proto",
- "protos/perfetto/trace/track_event/chrome_latency_info.proto",
- "protos/perfetto/trace/track_event/chrome_legacy_ipc.proto",
- "protos/perfetto/trace/track_event/chrome_message_pump.proto",
- "protos/perfetto/trace/track_event/chrome_mojo_event_info.proto",
- "protos/perfetto/trace/track_event/chrome_process_descriptor.proto",
- "protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.proto",
- "protos/perfetto/trace/track_event/chrome_thread_descriptor.proto",
- "protos/perfetto/trace/track_event/chrome_user_event.proto",
- "protos/perfetto/trace/track_event/chrome_window_handle_event_info.proto",
- "protos/perfetto/trace/track_event/counter_descriptor.proto",
- "protos/perfetto/trace/track_event/debug_annotation.proto",
- "protos/perfetto/trace/track_event/log_message.proto",
- "protos/perfetto/trace/track_event/process_descriptor.proto",
- "protos/perfetto/trace/track_event/range_of_interest.proto",
- "protos/perfetto/trace/track_event/screenshot.proto",
- "protos/perfetto/trace/track_event/source_location.proto",
- "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_event.proto",
+ ":perfetto_protos_perfetto_trace_track_event_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_track_event_cpp)",
out: [
"external/perfetto/protos/perfetto/trace/track_event/chrome_active_processes.gen.h",
"external/perfetto/protos/perfetto/trace/track_event/chrome_application_state_info.gen.h",
@@ -8136,8 +9158,8 @@
}
// GN: //protos/perfetto/trace/track_event:lite
-genrule {
- name: "perfetto_protos_perfetto_trace_track_event_lite_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_trace_track_event_lite",
srcs: [
"protos/perfetto/trace/track_event/chrome_active_processes.proto",
"protos/perfetto/trace/track_event/chrome_application_state_info.proto",
@@ -8167,10 +9189,18 @@
"protos/perfetto/trace/track_event/track_descriptor.proto",
"protos/perfetto/trace/track_event/track_event.proto",
],
+}
+
+// GN: //protos/perfetto/trace/track_event:lite
+genrule {
+ name: "perfetto_protos_perfetto_trace_track_event_lite_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_trace_track_event_lite",
+ ],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_track_event_lite)",
out: [
"external/perfetto/protos/perfetto/trace/track_event/chrome_active_processes.pb.cc",
"external/perfetto/protos/perfetto/trace/track_event/chrome_application_state_info.pb.cc",
@@ -8206,38 +9236,12 @@
genrule {
name: "perfetto_protos_perfetto_trace_track_event_lite_gen_headers",
srcs: [
- "protos/perfetto/trace/track_event/chrome_active_processes.proto",
- "protos/perfetto/trace/track_event/chrome_application_state_info.proto",
- "protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.proto",
- "protos/perfetto/trace/track_event/chrome_content_settings_event_info.proto",
- "protos/perfetto/trace/track_event/chrome_frame_reporter.proto",
- "protos/perfetto/trace/track_event/chrome_histogram_sample.proto",
- "protos/perfetto/trace/track_event/chrome_keyed_service.proto",
- "protos/perfetto/trace/track_event/chrome_latency_info.proto",
- "protos/perfetto/trace/track_event/chrome_legacy_ipc.proto",
- "protos/perfetto/trace/track_event/chrome_message_pump.proto",
- "protos/perfetto/trace/track_event/chrome_mojo_event_info.proto",
- "protos/perfetto/trace/track_event/chrome_process_descriptor.proto",
- "protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.proto",
- "protos/perfetto/trace/track_event/chrome_thread_descriptor.proto",
- "protos/perfetto/trace/track_event/chrome_user_event.proto",
- "protos/perfetto/trace/track_event/chrome_window_handle_event_info.proto",
- "protos/perfetto/trace/track_event/counter_descriptor.proto",
- "protos/perfetto/trace/track_event/debug_annotation.proto",
- "protos/perfetto/trace/track_event/log_message.proto",
- "protos/perfetto/trace/track_event/process_descriptor.proto",
- "protos/perfetto/trace/track_event/range_of_interest.proto",
- "protos/perfetto/trace/track_event/screenshot.proto",
- "protos/perfetto/trace/track_event/source_location.proto",
- "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_event.proto",
+ ":perfetto_protos_perfetto_trace_track_event_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_track_event_lite)",
out: [
"external/perfetto/protos/perfetto/trace/track_event/chrome_active_processes.pb.h",
"external/perfetto/protos/perfetto/trace/track_event/chrome_application_state_info.pb.h",
@@ -8274,8 +9278,8 @@
}
// GN: //protos/perfetto/trace/track_event:zero
-genrule {
- name: "perfetto_protos_perfetto_trace_track_event_zero_gen",
+filegroup {
+ name: "perfetto_protos_perfetto_trace_track_event_zero",
srcs: [
"protos/perfetto/trace/track_event/chrome_active_processes.proto",
"protos/perfetto/trace/track_event/chrome_application_state_info.proto",
@@ -8305,11 +9309,19 @@
"protos/perfetto/trace/track_event/track_descriptor.proto",
"protos/perfetto/trace/track_event/track_event.proto",
],
+}
+
+// GN: //protos/perfetto/trace/track_event:zero
+genrule {
+ name: "perfetto_protos_perfetto_trace_track_event_zero_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_trace_track_event_zero",
+ ],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_track_event_zero)",
out: [
"external/perfetto/protos/perfetto/trace/track_event/chrome_active_processes.pbzero.cc",
"external/perfetto/protos/perfetto/trace/track_event/chrome_application_state_info.pbzero.cc",
@@ -8345,39 +9357,13 @@
genrule {
name: "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
srcs: [
- "protos/perfetto/trace/track_event/chrome_active_processes.proto",
- "protos/perfetto/trace/track_event/chrome_application_state_info.proto",
- "protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.proto",
- "protos/perfetto/trace/track_event/chrome_content_settings_event_info.proto",
- "protos/perfetto/trace/track_event/chrome_frame_reporter.proto",
- "protos/perfetto/trace/track_event/chrome_histogram_sample.proto",
- "protos/perfetto/trace/track_event/chrome_keyed_service.proto",
- "protos/perfetto/trace/track_event/chrome_latency_info.proto",
- "protos/perfetto/trace/track_event/chrome_legacy_ipc.proto",
- "protos/perfetto/trace/track_event/chrome_message_pump.proto",
- "protos/perfetto/trace/track_event/chrome_mojo_event_info.proto",
- "protos/perfetto/trace/track_event/chrome_process_descriptor.proto",
- "protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.proto",
- "protos/perfetto/trace/track_event/chrome_thread_descriptor.proto",
- "protos/perfetto/trace/track_event/chrome_user_event.proto",
- "protos/perfetto/trace/track_event/chrome_window_handle_event_info.proto",
- "protos/perfetto/trace/track_event/counter_descriptor.proto",
- "protos/perfetto/trace/track_event/debug_annotation.proto",
- "protos/perfetto/trace/track_event/log_message.proto",
- "protos/perfetto/trace/track_event/process_descriptor.proto",
- "protos/perfetto/trace/track_event/range_of_interest.proto",
- "protos/perfetto/trace/track_event/screenshot.proto",
- "protos/perfetto/trace/track_event/source_location.proto",
- "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_event.proto",
+ ":perfetto_protos_perfetto_trace_track_event_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_track_event_zero)",
out: [
"external/perfetto/protos/perfetto/trace/track_event/chrome_active_processes.pbzero.h",
"external/perfetto/protos/perfetto/trace/track_event/chrome_application_state_info.pbzero.h",
@@ -8414,16 +9400,24 @@
}
// GN: //protos/perfetto/trace/translation:cpp
+filegroup {
+ name: "perfetto_protos_perfetto_trace_translation_cpp",
+ srcs: [
+ "protos/perfetto/trace/translation/translation_table.proto",
+ ],
+}
+
+// GN: //protos/perfetto/trace/translation:cpp
genrule {
name: "perfetto_protos_perfetto_trace_translation_cpp_gen",
srcs: [
- "protos/perfetto/trace/translation/translation_table.proto",
+ ":perfetto_protos_perfetto_trace_translation_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_translation_cpp)",
out: [
"external/perfetto/protos/perfetto/trace/translation/translation_table.gen.cc",
],
@@ -8433,13 +9427,13 @@
genrule {
name: "perfetto_protos_perfetto_trace_translation_cpp_gen_headers",
srcs: [
- "protos/perfetto/trace/translation/translation_table.proto",
+ ":perfetto_protos_perfetto_trace_translation_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_translation_cpp)",
out: [
"external/perfetto/protos/perfetto/trace/translation/translation_table.gen.h",
],
@@ -8450,15 +9444,23 @@
}
// GN: //protos/perfetto/trace/translation:lite
+filegroup {
+ name: "perfetto_protos_perfetto_trace_translation_lite",
+ srcs: [
+ "protos/perfetto/trace/translation/translation_table.proto",
+ ],
+}
+
+// GN: //protos/perfetto/trace/translation:lite
genrule {
name: "perfetto_protos_perfetto_trace_translation_lite_gen",
srcs: [
- "protos/perfetto/trace/translation/translation_table.proto",
+ ":perfetto_protos_perfetto_trace_translation_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_translation_lite)",
out: [
"external/perfetto/protos/perfetto/trace/translation/translation_table.pb.cc",
],
@@ -8468,12 +9470,12 @@
genrule {
name: "perfetto_protos_perfetto_trace_translation_lite_gen_headers",
srcs: [
- "protos/perfetto/trace/translation/translation_table.proto",
+ ":perfetto_protos_perfetto_trace_translation_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_translation_lite)",
out: [
"external/perfetto/protos/perfetto/trace/translation/translation_table.pb.h",
],
@@ -8484,16 +9486,24 @@
}
// GN: //protos/perfetto/trace/translation:zero
+filegroup {
+ name: "perfetto_protos_perfetto_trace_translation_zero",
+ srcs: [
+ "protos/perfetto/trace/translation/translation_table.proto",
+ ],
+}
+
+// GN: //protos/perfetto/trace/translation:zero
genrule {
name: "perfetto_protos_perfetto_trace_translation_zero_gen",
srcs: [
- "protos/perfetto/trace/translation/translation_table.proto",
+ ":perfetto_protos_perfetto_trace_translation_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_translation_zero)",
out: [
"external/perfetto/protos/perfetto/trace/translation/translation_table.pbzero.cc",
],
@@ -8503,13 +9513,13 @@
genrule {
name: "perfetto_protos_perfetto_trace_translation_zero_gen_headers",
srcs: [
- "protos/perfetto/trace/translation/translation_table.proto",
+ ":perfetto_protos_perfetto_trace_translation_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_perfetto_trace_translation_zero)",
out: [
"external/perfetto/protos/perfetto/trace/translation/translation_table.pbzero.h",
],
@@ -8562,16 +9572,24 @@
}
// GN: //protos/third_party/pprof:zero
+filegroup {
+ name: "perfetto_protos_third_party_pprof_zero",
+ srcs: [
+ "protos/third_party/pprof/profile.proto",
+ ],
+}
+
+// GN: //protos/third_party/pprof:zero
genrule {
name: "perfetto_protos_third_party_pprof_zero_gen",
srcs: [
- "protos/third_party/pprof/profile.proto",
+ ":perfetto_protos_third_party_pprof_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_third_party_pprof_zero)",
out: [
"external/perfetto/protos/third_party/pprof/profile.pbzero.cc",
],
@@ -8581,13 +9599,13 @@
genrule {
name: "perfetto_protos_third_party_pprof_zero_gen_headers",
srcs: [
- "protos/third_party/pprof/profile.proto",
+ ":perfetto_protos_third_party_pprof_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_third_party_pprof_zero)",
out: [
"external/perfetto/protos/third_party/pprof/profile.pbzero.h",
],
@@ -8598,17 +9616,25 @@
}
// GN: //protos/third_party/statsd:config_zero
-genrule {
- name: "perfetto_protos_third_party_statsd_config_zero_gen",
+filegroup {
+ name: "perfetto_protos_third_party_statsd_config_zero",
srcs: [
"protos/third_party/statsd/shell_config.proto",
"protos/third_party/statsd/shell_data.proto",
],
+}
+
+// GN: //protos/third_party/statsd:config_zero
+genrule {
+ name: "perfetto_protos_third_party_statsd_config_zero_gen",
+ srcs: [
+ ":perfetto_protos_third_party_statsd_config_zero",
+ ],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_third_party_statsd_config_zero)",
out: [
"external/perfetto/protos/third_party/statsd/shell_config.pbzero.cc",
"external/perfetto/protos/third_party/statsd/shell_data.pbzero.cc",
@@ -8619,14 +9645,13 @@
genrule {
name: "perfetto_protos_third_party_statsd_config_zero_gen_headers",
srcs: [
- "protos/third_party/statsd/shell_config.proto",
- "protos/third_party/statsd/shell_data.proto",
+ ":perfetto_protos_third_party_statsd_config_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_protos_third_party_statsd_config_zero)",
out: [
"external/perfetto/protos/third_party/statsd/shell_config.pbzero.h",
"external/perfetto/protos/third_party/statsd/shell_data.pbzero.h",
@@ -8872,18 +9897,26 @@
}
// GN: //src/ipc:test_messages_cpp
-genrule {
- name: "perfetto_src_ipc_test_messages_cpp_gen",
+filegroup {
+ name: "perfetto_src_ipc_test_messages_cpp",
srcs: [
"src/ipc/test/client_unittest_messages.proto",
"src/ipc/test/deferred_unittest_messages.proto",
"src/ipc/test/greeter_service.proto",
],
+}
+
+// GN: //src/ipc:test_messages_cpp
+genrule {
+ name: "perfetto_src_ipc_test_messages_cpp_gen",
+ srcs: [
+ ":perfetto_src_ipc_test_messages_cpp",
+ ],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_src_ipc_test_messages_cpp)",
out: [
"external/perfetto/src/ipc/test/client_unittest_messages.gen.cc",
"external/perfetto/src/ipc/test/deferred_unittest_messages.gen.cc",
@@ -8895,15 +9928,13 @@
genrule {
name: "perfetto_src_ipc_test_messages_cpp_gen_headers",
srcs: [
- "src/ipc/test/client_unittest_messages.proto",
- "src/ipc/test/deferred_unittest_messages.proto",
- "src/ipc/test/greeter_service.proto",
+ ":perfetto_src_ipc_test_messages_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_src_ipc_test_messages_cpp)",
out: [
"external/perfetto/src/ipc/test/client_unittest_messages.gen.h",
"external/perfetto/src/ipc/test/deferred_unittest_messages.gen.h",
@@ -8916,18 +9947,28 @@
}
// GN: //src/ipc:test_messages_ipc
-genrule {
- name: "perfetto_src_ipc_test_messages_ipc_gen",
+filegroup {
+ name: "perfetto_src_ipc_test_messages_ipc",
srcs: [
"src/ipc/test/client_unittest_messages.proto",
"src/ipc/test/deferred_unittest_messages.proto",
"src/ipc/test/greeter_service.proto",
],
+}
+
+// GN: //src/ipc:test_messages_ipc
+genrule {
+ name: "perfetto_src_ipc_test_messages_ipc_gen",
+ srcs: [
+ ":perfetto_protos_perfetto_ipc_wire_protocol_cpp",
+ ":perfetto_src_ipc_test_messages_cpp",
+ ":perfetto_src_ipc_test_messages_ipc",
+ ],
tools: [
"aprotoc",
"ipc_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location ipc_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location ipc_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_src_ipc_test_messages_ipc)",
out: [
"external/perfetto/src/ipc/test/client_unittest_messages.ipc.cc",
"external/perfetto/src/ipc/test/deferred_unittest_messages.ipc.cc",
@@ -8939,15 +9980,15 @@
genrule {
name: "perfetto_src_ipc_test_messages_ipc_gen_headers",
srcs: [
- "src/ipc/test/client_unittest_messages.proto",
- "src/ipc/test/deferred_unittest_messages.proto",
- "src/ipc/test/greeter_service.proto",
+ ":perfetto_protos_perfetto_ipc_wire_protocol_cpp",
+ ":perfetto_src_ipc_test_messages_cpp",
+ ":perfetto_src_ipc_test_messages_ipc",
],
tools: [
"aprotoc",
"ipc_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location ipc_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location ipc_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_src_ipc_test_messages_ipc)",
out: [
"external/perfetto/src/ipc/test/client_unittest_messages.ipc.h",
"external/perfetto/src/ipc/test/deferred_unittest_messages.ipc.h",
@@ -9038,16 +10079,24 @@
}
// GN: //src/perfetto_cmd:protos_cpp
+filegroup {
+ name: "perfetto_src_perfetto_cmd_protos_cpp",
+ srcs: [
+ "src/perfetto_cmd/perfetto_cmd_state.proto",
+ ],
+}
+
+// GN: //src/perfetto_cmd:protos_cpp
genrule {
name: "perfetto_src_perfetto_cmd_protos_cpp_gen",
srcs: [
- "src/perfetto_cmd/perfetto_cmd_state.proto",
+ ":perfetto_src_perfetto_cmd_protos_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_src_perfetto_cmd_protos_cpp)",
out: [
"external/perfetto/src/perfetto_cmd/perfetto_cmd_state.gen.cc",
],
@@ -9057,13 +10106,13 @@
genrule {
name: "perfetto_src_perfetto_cmd_protos_cpp_gen_headers",
srcs: [
- "src/perfetto_cmd/perfetto_cmd_state.proto",
+ ":perfetto_src_perfetto_cmd_protos_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_src_perfetto_cmd_protos_cpp)",
out: [
"external/perfetto/src/perfetto_cmd/perfetto_cmd_state.gen.h",
],
@@ -9533,8 +10582,8 @@
}
// GN: //src/protozero:testing_messages_cpp
-genrule {
- name: "perfetto_src_protozero_testing_messages_cpp_gen",
+filegroup {
+ name: "perfetto_src_protozero_testing_messages_cpp",
srcs: [
"src/protozero/test/example_proto/extensions.proto",
"src/protozero/test/example_proto/library.proto",
@@ -9542,11 +10591,19 @@
"src/protozero/test/example_proto/test_messages.proto",
"src/protozero/test/example_proto/upper_import.proto",
],
+}
+
+// GN: //src/protozero:testing_messages_cpp
+genrule {
+ name: "perfetto_src_protozero_testing_messages_cpp_gen",
+ srcs: [
+ ":perfetto_src_protozero_testing_messages_cpp",
+ ],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_src_protozero_testing_messages_cpp)",
out: [
"external/perfetto/src/protozero/test/example_proto/extensions.gen.cc",
"external/perfetto/src/protozero/test/example_proto/library.gen.cc",
@@ -9560,17 +10617,13 @@
genrule {
name: "perfetto_src_protozero_testing_messages_cpp_gen_headers",
srcs: [
- "src/protozero/test/example_proto/extensions.proto",
- "src/protozero/test/example_proto/library.proto",
- "src/protozero/test/example_proto/library_internals/galaxies.proto",
- "src/protozero/test/example_proto/test_messages.proto",
- "src/protozero/test/example_proto/upper_import.proto",
+ ":perfetto_src_protozero_testing_messages_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_src_protozero_testing_messages_cpp)",
out: [
"external/perfetto/src/protozero/test/example_proto/extensions.gen.h",
"external/perfetto/src/protozero/test/example_proto/library.gen.h",
@@ -9585,8 +10638,8 @@
}
// GN: //src/protozero:testing_messages_lite
-genrule {
- name: "perfetto_src_protozero_testing_messages_lite_gen",
+filegroup {
+ name: "perfetto_src_protozero_testing_messages_lite",
srcs: [
"src/protozero/test/example_proto/extensions.proto",
"src/protozero/test/example_proto/library.proto",
@@ -9594,10 +10647,18 @@
"src/protozero/test/example_proto/test_messages.proto",
"src/protozero/test/example_proto/upper_import.proto",
],
+}
+
+// GN: //src/protozero:testing_messages_lite
+genrule {
+ name: "perfetto_src_protozero_testing_messages_lite_gen",
+ srcs: [
+ ":perfetto_src_protozero_testing_messages_lite",
+ ],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_src_protozero_testing_messages_lite)",
out: [
"external/perfetto/src/protozero/test/example_proto/extensions.pb.cc",
"external/perfetto/src/protozero/test/example_proto/library.pb.cc",
@@ -9611,16 +10672,12 @@
genrule {
name: "perfetto_src_protozero_testing_messages_lite_gen_headers",
srcs: [
- "src/protozero/test/example_proto/extensions.proto",
- "src/protozero/test/example_proto/library.proto",
- "src/protozero/test/example_proto/library_internals/galaxies.proto",
- "src/protozero/test/example_proto/test_messages.proto",
- "src/protozero/test/example_proto/upper_import.proto",
+ ":perfetto_src_protozero_testing_messages_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_src_protozero_testing_messages_lite)",
out: [
"external/perfetto/src/protozero/test/example_proto/extensions.pb.h",
"external/perfetto/src/protozero/test/example_proto/library.pb.h",
@@ -9635,8 +10692,8 @@
}
// GN: //src/protozero:testing_messages_zero
-genrule {
- name: "perfetto_src_protozero_testing_messages_zero_gen",
+filegroup {
+ name: "perfetto_src_protozero_testing_messages_zero",
srcs: [
"src/protozero/test/example_proto/extensions.proto",
"src/protozero/test/example_proto/library.proto",
@@ -9644,11 +10701,19 @@
"src/protozero/test/example_proto/test_messages.proto",
"src/protozero/test/example_proto/upper_import.proto",
],
+}
+
+// GN: //src/protozero:testing_messages_zero
+genrule {
+ name: "perfetto_src_protozero_testing_messages_zero_gen",
+ srcs: [
+ ":perfetto_src_protozero_testing_messages_zero",
+ ],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_src_protozero_testing_messages_zero)",
out: [
"external/perfetto/src/protozero/test/example_proto/extensions.pbzero.cc",
"external/perfetto/src/protozero/test/example_proto/library.pbzero.cc",
@@ -9662,17 +10727,13 @@
genrule {
name: "perfetto_src_protozero_testing_messages_zero_gen_headers",
srcs: [
- "src/protozero/test/example_proto/extensions.proto",
- "src/protozero/test/example_proto/library.proto",
- "src/protozero/test/example_proto/library_internals/galaxies.proto",
- "src/protozero/test/example_proto/test_messages.proto",
- "src/protozero/test/example_proto/upper_import.proto",
+ ":perfetto_src_protozero_testing_messages_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_src_protozero_testing_messages_zero)",
out: [
"external/perfetto/src/protozero/test/example_proto/extensions.pbzero.h",
"external/perfetto/src/protozero/test/example_proto/library.pbzero.h",
@@ -9817,6 +10878,7 @@
filegroup {
name: "perfetto_src_trace_processor_db_storage_storage",
srcs: [
+ "src/trace_processor/db/storage/dummy_storage.cc",
"src/trace_processor/db/storage/id_storage.cc",
"src/trace_processor/db/storage/numeric_storage.cc",
"src/trace_processor/db/storage/storage.cc",
@@ -10430,6 +11492,7 @@
genrule {
name: "perfetto_src_trace_processor_metrics_sql_gen_amalgamated_sql_metrics",
srcs: [
+ "src/trace_processor/metrics/sql/android/ad_services_metric.sql",
"src/trace_processor/metrics/sql/android/android_anr.sql",
"src/trace_processor/metrics/sql/android/android_batt.sql",
"src/trace_processor/metrics/sql/android/android_binder.sql",
@@ -10802,7 +11865,9 @@
"src/trace_processor/perfetto_sql/stdlib/chrome/chrome_scrolls.sql",
"src/trace_processor/perfetto_sql/stdlib/chrome/cpu_powerups.sql",
"src/trace_processor/perfetto_sql/stdlib/chrome/histograms.sql",
+ "src/trace_processor/perfetto_sql/stdlib/chrome/interactions.sql",
"src/trace_processor/perfetto_sql/stdlib/chrome/metadata.sql",
+ "src/trace_processor/perfetto_sql/stdlib/chrome/page_loads.sql",
"src/trace_processor/perfetto_sql/stdlib/chrome/scroll_jank/scroll_jank_intervals.sql",
"src/trace_processor/perfetto_sql/stdlib/chrome/scroll_jank/scroll_jank_v3.sql",
"src/trace_processor/perfetto_sql/stdlib/chrome/scroll_jank/scroll_jank_v3_cause.sql",
@@ -10817,6 +11882,7 @@
"src/trace_processor/perfetto_sql/stdlib/common/metadata.sql",
"src/trace_processor/perfetto_sql/stdlib/common/percentiles.sql",
"src/trace_processor/perfetto_sql/stdlib/common/slices.sql",
+ "src/trace_processor/perfetto_sql/stdlib/common/thread_states.sql",
"src/trace_processor/perfetto_sql/stdlib/common/timestamps.sql",
"src/trace_processor/perfetto_sql/stdlib/experimental/android_broadcast.sql",
"src/trace_processor/perfetto_sql/stdlib/experimental/flat_slices.sql",
@@ -11472,16 +12538,24 @@
}
// GN: //src/traced/probes/ftrace:test_messages_cpp
+filegroup {
+ name: "perfetto_src_traced_probes_ftrace_test_messages_cpp",
+ srcs: [
+ "src/traced/probes/ftrace/test/test_messages.proto",
+ ],
+}
+
+// GN: //src/traced/probes/ftrace:test_messages_cpp
genrule {
name: "perfetto_src_traced_probes_ftrace_test_messages_cpp_gen",
srcs: [
- "src/traced/probes/ftrace/test/test_messages.proto",
+ ":perfetto_src_traced_probes_ftrace_test_messages_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_src_traced_probes_ftrace_test_messages_cpp)",
out: [
"external/perfetto/src/traced/probes/ftrace/test/test_messages.gen.cc",
],
@@ -11491,13 +12565,13 @@
genrule {
name: "perfetto_src_traced_probes_ftrace_test_messages_cpp_gen_headers",
srcs: [
- "src/traced/probes/ftrace/test/test_messages.proto",
+ ":perfetto_src_traced_probes_ftrace_test_messages_cpp",
],
tools: [
"aprotoc",
"perfetto_src_protozero_protoc_plugin_cppgen_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(locations :perfetto_src_traced_probes_ftrace_test_messages_cpp)",
out: [
"external/perfetto/src/traced/probes/ftrace/test/test_messages.gen.h",
],
@@ -11508,15 +12582,23 @@
}
// GN: //src/traced/probes/ftrace:test_messages_lite
+filegroup {
+ name: "perfetto_src_traced_probes_ftrace_test_messages_lite",
+ srcs: [
+ "src/traced/probes/ftrace/test/test_messages.proto",
+ ],
+}
+
+// GN: //src/traced/probes/ftrace:test_messages_lite
genrule {
name: "perfetto_src_traced_probes_ftrace_test_messages_lite_gen",
srcs: [
- "src/traced/probes/ftrace/test/test_messages.proto",
+ ":perfetto_src_traced_probes_ftrace_test_messages_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_src_traced_probes_ftrace_test_messages_lite)",
out: [
"external/perfetto/src/traced/probes/ftrace/test/test_messages.pb.cc",
],
@@ -11526,12 +12608,12 @@
genrule {
name: "perfetto_src_traced_probes_ftrace_test_messages_lite_gen_headers",
srcs: [
- "src/traced/probes/ftrace/test/test_messages.proto",
+ ":perfetto_src_traced_probes_ftrace_test_messages_lite",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(locations :perfetto_src_traced_probes_ftrace_test_messages_lite)",
out: [
"external/perfetto/src/traced/probes/ftrace/test/test_messages.pb.h",
],
@@ -11542,16 +12624,24 @@
}
// GN: //src/traced/probes/ftrace:test_messages_zero
+filegroup {
+ name: "perfetto_src_traced_probes_ftrace_test_messages_zero",
+ srcs: [
+ "src/traced/probes/ftrace/test/test_messages.proto",
+ ],
+}
+
+// GN: //src/traced/probes/ftrace:test_messages_zero
genrule {
name: "perfetto_src_traced_probes_ftrace_test_messages_zero_gen",
srcs: [
- "src/traced/probes/ftrace/test/test_messages.proto",
+ ":perfetto_src_traced_probes_ftrace_test_messages_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_src_traced_probes_ftrace_test_messages_zero)",
out: [
"external/perfetto/src/traced/probes/ftrace/test/test_messages.pbzero.cc",
],
@@ -11561,13 +12651,13 @@
genrule {
name: "perfetto_src_traced_probes_ftrace_test_messages_zero_gen_headers",
srcs: [
- "src/traced/probes/ftrace/test/test_messages.proto",
+ ":perfetto_src_traced_probes_ftrace_test_messages_zero",
],
tools: [
"aprotoc",
"protozero_plugin",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(locations :perfetto_src_traced_probes_ftrace_test_messages_zero)",
out: [
"external/perfetto/src/traced/probes/ftrace/test/test_messages.pbzero.h",
],
@@ -11755,6 +12845,32 @@
name: "perfetto_src_traced_probes_unittests",
}
+// GN: //src/traced_relay:integrationtests
+filegroup {
+ name: "perfetto_src_traced_relay_integrationtests",
+ srcs: [
+ "src/traced_relay/relay_service_integrationtest.cc",
+ ],
+}
+
+// GN: //src/traced_relay:lib
+filegroup {
+ name: "perfetto_src_traced_relay_lib",
+ srcs: [
+ "src/traced_relay/relay_service.cc",
+ "src/traced_relay/socket_relay_handler.cc",
+ ],
+}
+
+// GN: //src/traced_relay:unittests
+filegroup {
+ name: "perfetto_src_traced_relay_unittests",
+ srcs: [
+ "src/traced_relay/relay_service_unittest.cc",
+ "src/traced_relay/socket_relay_handler_unittest.cc",
+ ],
+}
+
// GN: //src/traced/service:service
filegroup {
name: "perfetto_src_traced_service_service",
@@ -12091,6 +13207,9 @@
"protos/perfetto/trace/chrome/chrome_metadata.proto",
"protos/perfetto/trace/chrome/chrome_trace_event.proto",
"protos/perfetto/trace/clock_snapshot.proto",
+ "protos/perfetto/trace/etw/etw.proto",
+ "protos/perfetto/trace/etw/etw_event.proto",
+ "protos/perfetto/trace/etw/etw_event_bundle.proto",
"protos/perfetto/trace/extension_descriptor.proto",
"protos/perfetto/trace/filesystem/inode_file_map.proto",
"protos/perfetto/trace/ftrace/android_fs.proto",
@@ -12246,6 +13365,7 @@
":perfetto_protos_perfetto_config_track_event_lite_gen",
":perfetto_protos_perfetto_trace_android_lite_gen",
":perfetto_protos_perfetto_trace_chrome_lite_gen",
+ ":perfetto_protos_perfetto_trace_etw_lite_gen",
":perfetto_protos_perfetto_trace_filesystem_lite_gen",
":perfetto_protos_perfetto_trace_ftrace_lite_gen",
":perfetto_protos_perfetto_trace_gpu_lite_gen",
@@ -12283,6 +13403,7 @@
"perfetto_protos_perfetto_config_track_event_lite_gen_headers",
"perfetto_protos_perfetto_trace_android_lite_gen_headers",
"perfetto_protos_perfetto_trace_chrome_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_etw_lite_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_lite_gen_headers",
"perfetto_protos_perfetto_trace_ftrace_lite_gen_headers",
"perfetto_protos_perfetto_trace_gpu_lite_gen_headers",
@@ -12316,6 +13437,7 @@
"perfetto_protos_perfetto_config_track_event_lite_gen_headers",
"perfetto_protos_perfetto_trace_android_lite_gen_headers",
"perfetto_protos_perfetto_trace_chrome_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_etw_lite_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_lite_gen_headers",
"perfetto_protos_perfetto_trace_ftrace_lite_gen_headers",
"perfetto_protos_perfetto_trace_gpu_lite_gen_headers",
@@ -12434,6 +13556,9 @@
":perfetto_protos_perfetto_trace_chrome_cpp_gen",
":perfetto_protos_perfetto_trace_chrome_lite_gen",
":perfetto_protos_perfetto_trace_chrome_zero_gen",
+ ":perfetto_protos_perfetto_trace_etw_cpp_gen",
+ ":perfetto_protos_perfetto_trace_etw_lite_gen",
+ ":perfetto_protos_perfetto_trace_etw_zero_gen",
":perfetto_protos_perfetto_trace_filesystem_cpp_gen",
":perfetto_protos_perfetto_trace_filesystem_lite_gen",
":perfetto_protos_perfetto_trace_filesystem_zero_gen",
@@ -12502,6 +13627,7 @@
":perfetto_src_ipc_client",
":perfetto_src_ipc_common",
":perfetto_src_ipc_host",
+ ":perfetto_src_ipc_perfetto_ipc",
":perfetto_src_ipc_test_messages_cpp_gen",
":perfetto_src_ipc_test_messages_ipc_gen",
":perfetto_src_ipc_unittests",
@@ -12689,6 +13815,8 @@
":perfetto_src_traced_probes_system_info_system_info",
":perfetto_src_traced_probes_system_info_unittests",
":perfetto_src_traced_probes_unittests",
+ ":perfetto_src_traced_relay_lib",
+ ":perfetto_src_traced_relay_unittests",
":perfetto_src_traced_service_service",
":perfetto_src_traced_service_unittests",
":perfetto_src_tracing_client_api_without_backends",
@@ -12783,6 +13911,9 @@
"perfetto_protos_perfetto_trace_chrome_cpp_gen_headers",
"perfetto_protos_perfetto_trace_chrome_lite_gen_headers",
"perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_etw_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_etw_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_etw_zero_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_cpp_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_lite_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
@@ -12947,6 +14078,8 @@
":perfetto_protos_perfetto_trace_android_zero_gen",
":perfetto_protos_perfetto_trace_chrome_cpp_gen",
":perfetto_protos_perfetto_trace_chrome_zero_gen",
+ ":perfetto_protos_perfetto_trace_etw_cpp_gen",
+ ":perfetto_protos_perfetto_trace_etw_zero_gen",
":perfetto_protos_perfetto_trace_filesystem_cpp_gen",
":perfetto_protos_perfetto_trace_filesystem_zero_gen",
":perfetto_protos_perfetto_trace_ftrace_cpp_gen",
@@ -13070,6 +14203,8 @@
"perfetto_protos_perfetto_trace_android_zero_gen_headers",
"perfetto_protos_perfetto_trace_chrome_cpp_gen_headers",
"perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_etw_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_etw_zero_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_cpp_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
"perfetto_protos_perfetto_trace_ftrace_cpp_gen_headers",
@@ -13139,6 +14274,8 @@
"perfetto_protos_perfetto_trace_android_zero_gen_headers",
"perfetto_protos_perfetto_trace_chrome_cpp_gen_headers",
"perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_etw_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_etw_zero_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_cpp_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
"perfetto_protos_perfetto_trace_ftrace_cpp_gen_headers",
@@ -13238,6 +14375,7 @@
":perfetto_protos_perfetto_config_zero_gen",
":perfetto_protos_perfetto_trace_android_zero_gen",
":perfetto_protos_perfetto_trace_chrome_zero_gen",
+ ":perfetto_protos_perfetto_trace_etw_zero_gen",
":perfetto_protos_perfetto_trace_filesystem_zero_gen",
":perfetto_protos_perfetto_trace_ftrace_zero_gen",
":perfetto_protos_perfetto_trace_gpu_zero_gen",
@@ -13354,6 +14492,7 @@
"perfetto_protos_perfetto_config_zero_gen_headers",
"perfetto_protos_perfetto_trace_android_zero_gen_headers",
"perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_etw_zero_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
"perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
"perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
@@ -13471,6 +14610,7 @@
":perfetto_protos_perfetto_config_zero_gen",
":perfetto_protos_perfetto_trace_android_zero_gen",
":perfetto_protos_perfetto_trace_chrome_zero_gen",
+ ":perfetto_protos_perfetto_trace_etw_zero_gen",
":perfetto_protos_perfetto_trace_filesystem_zero_gen",
":perfetto_protos_perfetto_trace_ftrace_zero_gen",
":perfetto_protos_perfetto_trace_gpu_zero_gen",
@@ -13588,6 +14728,7 @@
"perfetto_protos_perfetto_config_zero_gen_headers",
"perfetto_protos_perfetto_trace_android_zero_gen_headers",
"perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_etw_zero_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
"perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
"perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
@@ -13715,6 +14856,7 @@
":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
":perfetto_protos_perfetto_trace_android_zero_gen",
":perfetto_protos_perfetto_trace_chrome_zero_gen",
+ ":perfetto_protos_perfetto_trace_etw_zero_gen",
":perfetto_protos_perfetto_trace_filesystem_zero_gen",
":perfetto_protos_perfetto_trace_ftrace_zero_gen",
":perfetto_protos_perfetto_trace_gpu_zero_gen",
@@ -13813,6 +14955,7 @@
"perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
"perfetto_protos_perfetto_trace_android_zero_gen_headers",
"perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_etw_zero_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
"perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
"perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
@@ -13920,6 +15063,7 @@
":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
":perfetto_protos_perfetto_trace_android_zero_gen",
":perfetto_protos_perfetto_trace_chrome_zero_gen",
+ ":perfetto_protos_perfetto_trace_etw_zero_gen",
":perfetto_protos_perfetto_trace_filesystem_zero_gen",
":perfetto_protos_perfetto_trace_ftrace_zero_gen",
":perfetto_protos_perfetto_trace_gpu_zero_gen",
@@ -13993,6 +15137,7 @@
"perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
"perfetto_protos_perfetto_trace_android_zero_gen_headers",
"perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_etw_zero_gen_headers",
"perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
"perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
"perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
diff --git a/BUILD b/BUILD
index 42122bd..25902af 100644
--- a/BUILD
+++ b/BUILD
@@ -315,6 +315,7 @@
":protos_perfetto_config_zero",
":protos_perfetto_trace_android_zero",
":protos_perfetto_trace_chrome_zero",
+ ":protos_perfetto_trace_etw_zero",
":protos_perfetto_trace_filesystem_zero",
":protos_perfetto_trace_ftrace_zero",
":protos_perfetto_trace_gpu_zero",
@@ -402,6 +403,7 @@
":protos_perfetto_config_zero",
":protos_perfetto_trace_android_zero",
":protos_perfetto_trace_chrome_zero",
+ ":protos_perfetto_trace_etw_zero",
":protos_perfetto_trace_filesystem_zero",
":protos_perfetto_trace_ftrace_zero",
":protos_perfetto_trace_gpu_zero",
@@ -516,6 +518,7 @@
":protos_perfetto_ipc_ipc",
":protos_perfetto_trace_android_zero",
":protos_perfetto_trace_chrome_zero",
+ ":protos_perfetto_trace_etw_zero",
":protos_perfetto_trace_filesystem_zero",
":protos_perfetto_trace_ftrace_zero",
":protos_perfetto_trace_gpu_zero",
@@ -1303,6 +1306,8 @@
perfetto_filegroup(
name = "src_trace_processor_db_storage_storage",
srcs = [
+ "src/trace_processor/db/storage/dummy_storage.cc",
+ "src/trace_processor/db/storage/dummy_storage.h",
"src/trace_processor/db/storage/id_storage.cc",
"src/trace_processor/db/storage/id_storage.h",
"src/trace_processor/db/storage/numeric_storage.cc",
@@ -1787,6 +1792,7 @@
perfetto_filegroup(
name = "src_trace_processor_metrics_sql_android_android",
srcs = [
+ "src/trace_processor/metrics/sql/android/ad_services_metric.sql",
"src/trace_processor/metrics/sql/android/android_anr.sql",
"src/trace_processor/metrics/sql/android/android_batt.sql",
"src/trace_processor/metrics/sql/android/android_binder.sql",
@@ -2238,7 +2244,9 @@
"src/trace_processor/perfetto_sql/stdlib/chrome/chrome_scrolls.sql",
"src/trace_processor/perfetto_sql/stdlib/chrome/cpu_powerups.sql",
"src/trace_processor/perfetto_sql/stdlib/chrome/histograms.sql",
+ "src/trace_processor/perfetto_sql/stdlib/chrome/interactions.sql",
"src/trace_processor/perfetto_sql/stdlib/chrome/metadata.sql",
+ "src/trace_processor/perfetto_sql/stdlib/chrome/page_loads.sql",
"src/trace_processor/perfetto_sql/stdlib/chrome/speedometer.sql",
"src/trace_processor/perfetto_sql/stdlib/chrome/tasks.sql",
"src/trace_processor/perfetto_sql/stdlib/chrome/vsync_intervals.sql",
@@ -2255,6 +2263,7 @@
"src/trace_processor/perfetto_sql/stdlib/common/metadata.sql",
"src/trace_processor/perfetto_sql/stdlib/common/percentiles.sql",
"src/trace_processor/perfetto_sql/stdlib/common/slices.sql",
+ "src/trace_processor/perfetto_sql/stdlib/common/thread_states.sql",
"src/trace_processor/perfetto_sql/stdlib/common/timestamps.sql",
],
)
@@ -3201,6 +3210,7 @@
":protos_perfetto_config_track_event_protos",
":protos_perfetto_trace_android_protos",
":protos_perfetto_trace_chrome_protos",
+ ":protos_perfetto_trace_etw_protos",
":protos_perfetto_trace_filesystem_protos",
":protos_perfetto_trace_ftrace_protos",
":protos_perfetto_trace_gpu_protos",
@@ -4030,6 +4040,7 @@
perfetto_proto_library(
name = "protos_perfetto_metrics_android_protos",
srcs = [
+ "protos/perfetto/metrics/android/ad_services_metric.proto",
"protos/perfetto/metrics/android/android_blocking_call.proto",
"protos/perfetto/metrics/android/android_blocking_calls_cuj_metric.proto",
"protos/perfetto/metrics/android/android_boot.proto",
@@ -4283,6 +4294,27 @@
],
)
+# GN target: //protos/perfetto/trace/etw:source_set
+perfetto_proto_library(
+ name = "protos_perfetto_trace_etw_protos",
+ srcs = [
+ "protos/perfetto/trace/etw/etw.proto",
+ "protos/perfetto/trace/etw/etw_event.proto",
+ "protos/perfetto/trace/etw/etw_event_bundle.proto",
+ ],
+ visibility = [
+ PERFETTO_CONFIG.proto_library_visibility,
+ ],
+)
+
+# GN target: //protos/perfetto/trace/etw:zero
+perfetto_cc_protozero_library(
+ name = "protos_perfetto_trace_etw_zero",
+ deps = [
+ ":protos_perfetto_trace_etw_protos",
+ ],
+)
+
# GN target: //protos/perfetto/trace/filesystem:source_set
perfetto_proto_library(
name = "protos_perfetto_trace_filesystem_protos",
@@ -4529,6 +4561,7 @@
":protos_perfetto_config_track_event_protos",
":protos_perfetto_trace_android_protos",
":protos_perfetto_trace_chrome_protos",
+ ":protos_perfetto_trace_etw_protos",
":protos_perfetto_trace_filesystem_protos",
":protos_perfetto_trace_ftrace_protos",
":protos_perfetto_trace_gpu_protos",
@@ -4569,6 +4602,7 @@
":protos_perfetto_config_zero",
":protos_perfetto_trace_android_zero",
":protos_perfetto_trace_chrome_zero",
+ ":protos_perfetto_trace_etw_zero",
":protos_perfetto_trace_filesystem_zero",
":protos_perfetto_trace_ftrace_zero",
":protos_perfetto_trace_gpu_zero",
@@ -5046,6 +5080,7 @@
":protos_perfetto_ipc_ipc",
":protos_perfetto_trace_android_zero",
":protos_perfetto_trace_chrome_zero",
+ ":protos_perfetto_trace_etw_zero",
":protos_perfetto_trace_filesystem_zero",
":protos_perfetto_trace_ftrace_zero",
":protos_perfetto_trace_gpu_zero",
@@ -5137,6 +5172,7 @@
":protos_perfetto_ipc_ipc",
":protos_perfetto_trace_android_zero",
":protos_perfetto_trace_chrome_zero",
+ ":protos_perfetto_trace_etw_zero",
":protos_perfetto_trace_filesystem_zero",
":protos_perfetto_trace_ftrace_zero",
":protos_perfetto_trace_gpu_zero",
@@ -5266,6 +5302,7 @@
":protos_perfetto_config_zero",
":protos_perfetto_trace_android_zero",
":protos_perfetto_trace_chrome_zero",
+ ":protos_perfetto_trace_etw_zero",
":protos_perfetto_trace_filesystem_zero",
":protos_perfetto_trace_ftrace_zero",
":protos_perfetto_trace_gpu_zero",
@@ -5418,6 +5455,7 @@
":protos_perfetto_config_zero",
":protos_perfetto_trace_android_zero",
":protos_perfetto_trace_chrome_zero",
+ ":protos_perfetto_trace_etw_zero",
":protos_perfetto_trace_filesystem_zero",
":protos_perfetto_trace_ftrace_zero",
":protos_perfetto_trace_gpu_zero",
@@ -5505,6 +5543,7 @@
":protos_perfetto_config_zero",
":protos_perfetto_trace_android_zero",
":protos_perfetto_trace_chrome_zero",
+ ":protos_perfetto_trace_etw_zero",
":protos_perfetto_trace_filesystem_zero",
":protos_perfetto_trace_ftrace_zero",
":protos_perfetto_trace_gpu_zero",
@@ -5639,6 +5678,7 @@
":protos_perfetto_config_zero",
":protos_perfetto_trace_android_zero",
":protos_perfetto_trace_chrome_zero",
+ ":protos_perfetto_trace_etw_zero",
":protos_perfetto_trace_filesystem_zero",
":protos_perfetto_trace_ftrace_zero",
":protos_perfetto_trace_gpu_zero",
diff --git a/CHANGELOG b/CHANGELOG
index bec63e0..777d115 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,10 +1,10 @@
Unreleased:
Tracing service and probes:
- *
+ * Added reporting of TZ offset under system_info.timezone_off_mins .
Trace Processor:
*
UI:
- *
+ * Add a new type of debug tracks: counter.
SDK:
*
diff --git a/docs/analysis/trace-processor.md b/docs/analysis/trace-processor.md
index 3fb44b5..a459566 100644
--- a/docs/analysis/trace-processor.md
+++ b/docs/analysis/trace-processor.md
@@ -600,53 +600,46 @@
every change to trace processor code or builtin metrics.
#### Choosing where to add diff tests
-Choosing a folder with a diff tests often can be confusing
-as a test can fall into more than one category. This section is a guide
-to decide which folder to choose.
+`diff_tests/` folder contains four directories corresponding to different
+areas of trace processor.
+1. __stdlib__: Tests focusing on testing Perfetto Standard Library, both
+ prelude and the regular modules. The subdirectories in this folder
+ should generally correspond to directories in `perfetto_sql/stdlib`.
+2. __parser__: Tests focusing on ensuring that different trace files are
+ parsed correctly and the corresponding built-in tables are populated.
+3. __metrics__: Tests focusing on testing metrics located in
+ `trace_processor/metrics/sql`. This organisation is mostly historical
+ and code (and corresponding tests) is expected to move to `stdlib` over time.
+4. __syntax__: Tests focusing on testing the core syntax of PerfettoSQL
+ (i.e. `CREATE PERFETTO TABLE` or `CREATE PERFETTO FUNCTION`).
-Broadly, there are two categories which all folders fall into:
-1. __"Area" folders__ which encompass a "vertical" area of interest
- e.g. startup/ contains Android app startup related tests or chrome/
- contains all Chrome related tests.
-2. __"Feature" folders__ which encompass a particular feature of
- trace processor e.g. process_tracking/ tests the lifetime tracking of
- processes, span_join/ tests the span join operator.
+__Scenario__: A new stdlib module `foo/bar.sql` is being added.
-"Area" folders should be preferred for adding tests unless the test is
-applicable to more than one "area"; in this case, one of "feature" folders
-can be used instead.
-
-Here are some common scenarios in which new tests may be added and
-answers on where to add the test:
+_Answer_: Add the test to the `stdlib/foo/bar_tests.py` file.
__Scenario__: A new event is being parsed, the focus of the test is to ensure
-the event is being parsed correctly and the event is focused on a single
-vertical "Area".
+the event is being parsed correctly.
-_Answer_: Add the test in one of the "Area" folders.
-
-__Scenario__: A new event is being parsed and the focus of the test is to ensure
-the event is being parsed correctly and the event is applicable to more than one
-vertical "Area".
-
-_Answer_: Add the test to the parsing/ folder.
+_Answer_: Add the test in one of the `parser` subdirectories. Prefer adding a
+test to an existing related directory (i.e. `sched`, `power`) if one exists.
__Scenario__: A new metric is being added and the focus of the test is to
ensure the metric is being correctly computed.
-_Answer_: Add the test in one of the "Area" folders.
+_Answer_: Add the test in one of the `metrics` subdirectories. Prefer adding a
+test to an existing related directory if one exists. Also consider adding the
+code in question to stdlib.
__Scenario__: A new dynamic table is being added and the focus of the test is to
ensure the dynamic table is being correctly computed...
-_Answer_: Add the test to the dynamic/ folder
+_Answer_: Add the test to the `stdlib/dynamic_tables` folder
__Scenario__: The interals of trace processor are being modified and the test
is to ensure the trace processor is correctly filtering/sorting important
built-in tables.
-_Answer_: Add the test to the tables/ folder.
-
+_Answer_: Add the test to the `parser/core_tables` folder.
## Appendix: table inheritance
diff --git a/docs/contributing/ui-plugins.md b/docs/contributing/ui-plugins.md
index 241e0a7..23fbe25 100644
--- a/docs/contributing/ui-plugins.md
+++ b/docs/contributing/ui-plugins.md
@@ -176,58 +176,73 @@
}
```
-This interface will be used as type parameter to the `Plugin` and
-`TracePluginContext` interfaces.
+To access permalink state, call `mountStore()` on your `TracePluginContext`
+object, passing in a migration function.
```typescript
-class MyPlugin implements Plugin<MyState> {
-
- migrate(initialState: unknown): MyState {
- // ...
+class MyPlugin implements Plugin {
+ async onTraceLoad(ctx: TracePluginContext): Promise<void> {
+ const store = ctx.mountStore(migrate);
}
+}
- async onTraceLoad(ctx: TracePluginContext<MyState>): Promise<void> {
- // You can access the store on ctx.store
- }
-
- async onTraceUnload(ctx: TracePluginContext<MyState>): Promise<void> {
- // You can access the store on ctx.store
- }
-
+function migrate(initialState: unknown): MyState {
// ...
}
```
-`migrate()` is called after `onActivate()` just before `onTraceLoad()`. There
-are two cases to consider:
+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 `migrate()` is called with `undefined`. In this
-case you should return a default version of `MyState`:
+In case of a new trace, your migration function is called with `undefined`. In
+this case you should return a default version of `MyState`:
```typescript
-class MyPlugin implements Plugin<MyState> {
+const DEFAULT = {favouriteSlices: []};
- migrate(initialState: unknown): MyState {
- if (initialState === undefined) {
- return {
- favouriteSlices: [];
- };
- }
- // ...
+function migrate(initialState: unknown): MyState {
+ if (initialState === undefined) {
+ // Return default version of MyState.
+ return DEFAULT;
+ } else {
+ // Migrate old version here.
}
-
- // ...
}
```
-In the permalink case `migrate()` is called with the state of the plugin
-store at the time the permalink was generated. This may be from a
-older or newer version of the plugin.
-**Plugin's must not make assumptions about the contents of `initialState`**.
+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.
-In this case you need to carefully validate the state object.
+**Plugins must not make assumptions about the contents of `initialState`!**
-TODO: Add validation example.
+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!
+
+One brute force way would be to use a version number.
+
+```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;
+ }
+}
+```
+
+You'll need to remember to update your version number when making changes!
+Migration should be unit-tested to ensure compatibility.
Examples:
- [dev.perfetto.ExampleState](https://cs.android.com/android/platform/superproject/main/+/main:external/perfetto/ui/src/plugins/dev.perfetto.ExampleState/index.ts).
diff --git a/docs/toc.md b/docs/toc.md
index d7c34e3..2ac2751 100644
--- a/docs/toc.md
+++ b/docs/toc.md
@@ -72,6 +72,7 @@
* [Trace Packet proto](reference/trace-packet-proto.autogen)
* [perfetto cmdline](reference/perfetto-cli.md)
* [heap_profile cmdline](reference/heap_profile-cli.md)
+ * [UI Plugin API](reference/ui-plugin-api.autogen)
* [Synthetic TrackEvent](reference/synthetic-track-event.md)
* [Android Version Notes](reference/android-version-notes.md)
* [Stats table](analysis/sql-stats.autogen)
diff --git a/gn/BUILD.gn b/gn/BUILD.gn
index bb01ea1..6c1775a 100644
--- a/gn/BUILD.gn
+++ b/gn/BUILD.gn
@@ -14,6 +14,7 @@
import("perfetto.gni")
import("perfetto_python.gni")
+import("pkg_config.gni")
import("proto_library.gni")
if (perfetto_root_path == "//") {
@@ -227,8 +228,19 @@
libs = [ "protoc" ] # This will link against libprotoc.so
}
+# pkg_deps selects the appropriate pkg-config based on current_toolchain and
+# this is a no-op if |perfetto_use_pkgconfig| is false.
+pkg_config("pkgconfig_protobuf") {
+ pkg_deps = [ "protobuf" ]
+}
+
config("system_protobuf") {
- libs = [ "protobuf" ] # This will link against libprotobuf.so
+ if (perfetto_use_pkgconfig) {
+ configs = [ ":pkgconfig_protobuf" ]
+ } else {
+ # Fallback if pkg-config isn't enabled.
+ libs = [ "protobuf" ] # This will link against libprotobuf.so
+ }
}
# protoc compiler library, it's used for building protoc plugins.
diff --git a/gn/perfetto.gni b/gn/perfetto.gni
index ecc7252..d8f8c55 100644
--- a/gn/perfetto.gni
+++ b/gn/perfetto.gni
@@ -338,6 +338,13 @@
# Skip buildtools dependency checks (needed for ChromeOS).
skip_buildtools_check = false
+ # Used by CrOS builds. Uses pkg-config to determine the appropriate flags
+ # for including and linking system libraries.
+ # set `pkg_config` to the `BUILD_PKG_CONFIG` and
+ # set `target_pkg_config` to the target `PKG_CONFIG`.
+ # Note: that if this is enabled `perfetto_use_system_protobuf` should be also.
+ perfetto_use_pkgconfig = false
+
# Used by CrOS system builds. Uses the system version of protobuf
# from /usr/include instead of the hermetic one.
perfetto_use_system_protobuf = false
@@ -393,3 +400,9 @@
# must be set as well. Doesn't make sense to build traced_probes without the
# rest. traced_probes integration tests depend on traced.
assert(!enable_perfetto_traced_probes || enable_perfetto_platform_services)
+
+# |perfetto_use_pkgconfig| changes the behavior of
+# |perfetto_use_system_protobuf|, so if perfetto_use_pkgconfig is set,
+# |perfetto_use_system_protobuf| must be set.
+assert(!perfetto_use_pkgconfig || perfetto_use_system_protobuf,
+ "perfetto_use_pkgconfig requires perfetto_use_system_protobuf")
diff --git a/gn/perfetto_integrationtests.gni b/gn/perfetto_integrationtests.gni
index ff7bb7f..3e65e20 100644
--- a/gn/perfetto_integrationtests.gni
+++ b/gn/perfetto_integrationtests.gni
@@ -49,3 +49,7 @@
perfetto_integrationtests_targets +=
[ "src/trace_processor:integrationtests" ]
}
+
+if (enable_perfetto_traced_relay) {
+ perfetto_integrationtests_targets += [ "src/traced_relay:integrationtests" ]
+}
diff --git a/gn/perfetto_unittests.gni b/gn/perfetto_unittests.gni
index cc51910..91e8d5d 100644
--- a/gn/perfetto_unittests.gni
+++ b/gn/perfetto_unittests.gni
@@ -80,3 +80,7 @@
perfetto_unittests_targets += [ "src/bigtrace:unittests" ]
}
}
+
+if (enable_perfetto_traced_relay) {
+ perfetto_unittests_targets += [ "src/traced_relay:unittests" ]
+}
diff --git a/gn/pkg-config_wrapper.py b/gn/pkg-config_wrapper.py
new file mode 100755
index 0000000..3fc33cd
--- /dev/null
+++ b/gn/pkg-config_wrapper.py
@@ -0,0 +1,72 @@
+#!/usr/bin/env python3
+# 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.
+
+"""Wrapper of pkg-config command line to format output for gn.
+
+Parses the pkg-config output and format it into json,
+so that it can be used in GN files easily.
+
+Usage:
+ pkg-config_wrapper.py pkg-config pkg1 pkg2 ...
+
+Specifically, this script does not expect any additional flags.
+"""
+
+import json
+import shlex
+import subprocess
+import sys
+
+
+def get_shell_output(cmd):
+ """Run |cmd| and return output as a list."""
+ result = subprocess.run(
+ cmd, encoding="utf-8", stdout=subprocess.PIPE, check=False
+ )
+ if result.returncode:
+ sys.exit(result.returncode)
+ return shlex.split(result.stdout)
+
+
+def main(argv):
+ if len(argv) < 2:
+ sys.exit(f"Usage: {sys.argv[0]} <pkg-config> <modules>")
+
+ cflags = get_shell_output(argv + ["--cflags"])
+ libs = []
+ lib_dirs = []
+ ldflags = []
+ for ldflag in get_shell_output(argv + ["--libs"]):
+ if ldflag.startswith("-l"):
+ # Strip -l.
+ libs.append(ldflag[2:])
+ elif ldflag.startswith("-L"):
+ # Strip -L.
+ lib_dirs.append(ldflag[2:])
+ else:
+ ldflags.append(ldflag)
+
+ # Set sort_keys=True for stabilization.
+ result = {
+ "cflags": cflags,
+ "libs": libs,
+ "lib_dirs": lib_dirs,
+ "ldflags": ldflags,
+ }
+ json.dump(result, sys.stdout, sort_keys=True)
+
+
+if __name__ == "__main__":
+ sys.exit(main(sys.argv[1:]))
diff --git a/gn/pkg_config.gni b/gn/pkg_config.gni
new file mode 100644
index 0000000..b77d3de
--- /dev/null
+++ b/gn/pkg_config.gni
@@ -0,0 +1,67 @@
+# 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("perfetto.gni")
+
+declare_args() {
+ pkg_config = "pkg-config"
+ target_pkg_config = "pkg-config"
+}
+
+# Defines a config specifying the result of running pkg-config for the given
+# packages. Put the package names you want to query in the "pkg_deps" variable
+# inside the template invocation.
+template("pkg_config") {
+ config(target_name) {
+ assert(defined(invoker.pkg_deps), "pkg_deps must be set")
+ if (perfetto_use_pkgconfig) {
+ forward_variables_from(invoker, "*")
+
+ if (current_toolchain == host_toolchain) {
+ _cmd = pkg_config
+ } else {
+ _cmd = target_pkg_config
+ }
+ _pkg_config_result =
+ exec_script("//gn/pkg-config_wrapper.py", [ _cmd ] + pkg_deps, "json")
+
+ if (_pkg_config_result.cflags != []) {
+ if (!defined(cflags)) {
+ cflags = []
+ }
+ cflags += _pkg_config_result.cflags
+ }
+ if (_pkg_config_result.libs != []) {
+ if (!defined(libs)) {
+ libs = []
+ }
+ libs += _pkg_config_result.libs
+ }
+ if (_pkg_config_result.lib_dirs != []) {
+ if (!defined(lib_dirs)) {
+ lib_dirs = []
+ }
+ lib_dirs += _pkg_config_result.lib_dirs
+ }
+ if (_pkg_config_result.ldflags != []) {
+ if (!defined(ldflags)) {
+ ldflags = []
+ }
+ ldflags += _pkg_config_result.ldflags
+ }
+ } else { # !perfetto_use_pkgconfig
+ not_needed(invoker, "*")
+ }
+ }
+}
diff --git a/include/perfetto/base/time.h b/include/perfetto/base/time.h
index f8161ab..ea15dae 100644
--- a/include/perfetto/base/time.h
+++ b/include/perfetto/base/time.h
@@ -20,6 +20,7 @@
#include <time.h>
#include <chrono>
+#include <optional>
#include <string>
#include "perfetto/base/build_config.h"
@@ -245,6 +246,8 @@
return TimeGm(&tms);
}
+std::optional<int32_t> GetTimezoneOffsetMins();
+
} // namespace base
} // namespace perfetto
diff --git a/include/perfetto/ext/base/string_utils.h b/include/perfetto/ext/base/string_utils.h
index 20e5799..c8264a2 100644
--- a/include/perfetto/ext/base/string_utils.h
+++ b/include/perfetto/ext/base/string_utils.h
@@ -130,6 +130,11 @@
const std::string& to_replace,
const std::string& replacement);
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+bool WideToUTF8(const std::wstring& source, std::string& output);
+bool UTF8ToWide(const std::string& source, std::wstring& output);
+#endif // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
// A BSD-style strlcpy without the return value.
// Copies at most |dst_size|-1 characters. Unlike strncpy, it always \0
// terminates |dst|, as long as |dst_size| is not 0.
diff --git a/include/perfetto/ext/base/thread_utils.h b/include/perfetto/ext/base/thread_utils.h
index 4a1f0b6..9281fa0 100644
--- a/include/perfetto/ext/base/thread_utils.h
+++ b/include/perfetto/ext/base/thread_utils.h
@@ -21,6 +21,7 @@
#include "perfetto/base/build_config.h"
#include "perfetto/ext/base/string_utils.h"
+#include "perfetto/base/export.h"
#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
@@ -69,6 +70,11 @@
return true;
}
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+PERFETTO_EXPORT_COMPONENT bool MaybeSetThreadName(const std::string& name);
+PERFETTO_EXPORT_COMPONENT bool GetThreadName(std::string& out_result);
+
#else
inline bool MaybeSetThreadName(const std::string&) {
return false;
diff --git a/include/perfetto/ext/tracing/core/shared_memory_abi.h b/include/perfetto/ext/tracing/core/shared_memory_abi.h
index 451cafb..4e05599 100644
--- a/include/perfetto/ext/tracing/core/shared_memory_abi.h
+++ b/include/perfetto/ext/tracing/core/shared_memory_abi.h
@@ -424,7 +424,7 @@
ChunkHeader* chunk_header = header();
auto packets = chunk_header->packets.load(std::memory_order_relaxed);
if (packets.count < packet_count)
- packets.count = packet_count;
+ packets.count = packet_count & ChunkHeader::Packets::kMaxCount;
chunk_header->packets.store(packets, std::memory_order_release);
return packets.count;
}
diff --git a/include/perfetto/protozero/field.h b/include/perfetto/protozero/field.h
index d0163b1..e601e06 100644
--- a/include/perfetto/protozero/field.h
+++ b/include/perfetto/protozero/field.h
@@ -156,7 +156,7 @@
uint8_t type,
uint64_t int_value,
uint32_t size) {
- id_ = id;
+ id_ = id & kMaxId;
type_ = type;
int_value_ = int_value;
size_ = size;
diff --git a/include/perfetto/protozero/scattered_stream_writer.h b/include/perfetto/protozero/scattered_stream_writer.h
index 96329e9..719c490 100644
--- a/include/perfetto/protozero/scattered_stream_writer.h
+++ b/include/perfetto/protozero/scattered_stream_writer.h
@@ -22,6 +22,8 @@
#include <stdint.h>
#include <string.h>
+#include <algorithm>
+
#include "perfetto/base/compiler.h"
#include "perfetto/base/export.h"
#include "perfetto/base/logging.h"
@@ -76,13 +78,13 @@
// Assumes that the caller checked that there is enough headroom.
// TODO(primiano): perf optimization, this is a tracing hot path. The
- // compiler can make strong optimization on memcpy if the size arg is a
+ // compiler can make strong optimization on std::copy if the size arg is a
// constexpr. Make a templated variant of this for fixed-size writes.
// TODO(primiano): restrict / noalias might also help.
inline void WriteBytesUnsafe(const uint8_t* src, size_t size) {
uint8_t* const end = write_ptr_ + size;
assert(end <= cur_range_.end);
- memcpy(write_ptr_, src, size);
+ std::copy(src, src + size, write_ptr_);
write_ptr_ = end;
}
diff --git a/infra/perfetto.dev/BUILD.gn b/infra/perfetto.dev/BUILD.gn
index 75f69b7..7b9d1f5 100644
--- a/infra/perfetto.dev/BUILD.gn
+++ b/infra/perfetto.dev/BUILD.gn
@@ -37,6 +37,7 @@
":gen_toc",
":gen_trace_config_proto",
":gen_trace_packet_proto",
+ ":gen_ui_plugin_api_html",
":node_assets",
":readme",
":style_scss",
@@ -190,6 +191,31 @@
out_html = "docs/analysis/sql-stats"
}
+ui_plugin_api_md = "${target_gen_dir}/ui-plugin-api.md"
+
+nodejs_script("gen_ui_plugin_api_md") {
+ script = "src/gen_ui_reference.js"
+ input = "../../ui/src/public/index.ts"
+ inputs = [ input ]
+ outputs = [ ui_plugin_api_md ]
+ args = [
+ "-i",
+ rebase_path(input, root_build_dir),
+ "-o",
+ rebase_path(ui_plugin_api_md, root_build_dir),
+ ]
+}
+
+md_to_html("gen_ui_plugin_api_html") {
+ markdown = ui_plugin_api_md
+ html_template = "src/template_markdown.html"
+ deps = [
+ ":gen_toc",
+ ":gen_ui_plugin_api_md",
+ ]
+ out_html = "docs/reference/ui-plugin-api"
+}
+
# Generates a html reference for a proto
# Args:
# * proto: The path to a .proto file
diff --git a/infra/perfetto.dev/src/gen_ui_reference.js b/infra/perfetto.dev/src/gen_ui_reference.js
new file mode 100644
index 0000000..f6c2571
--- /dev/null
+++ b/infra/perfetto.dev/src/gen_ui_reference.js
@@ -0,0 +1,46 @@
+// 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.
+
+// Generation of UI API references
+
+'use strict';
+
+const fs = require('fs');
+const path = require('path');
+const argv = require('yargs').argv
+
+const PROJECT_ROOT =
+ path.dirname(path.dirname(path.dirname(path.dirname(__filename))));
+
+function main() {
+ const inputPath = argv['i'];
+ const outputPath = argv['o'];
+ if (!inputPath) {
+ console.error('Usage: -i ui/src/public/index.ts [-o out.md]');
+ process.exit(1);
+ }
+
+ const text = fs.readFileSync(inputPath, 'UTF8');
+
+ const generatedMd = '```\n' + text + '```\n';
+
+ if (outputPath) {
+ fs.writeFileSync(outputPath, generatedMd);
+ } else {
+ console.log(generatedMd);
+ }
+ process.exit(0);
+}
+
+main();
diff --git a/protos/perfetto/config/chrome/scenario_config.proto b/protos/perfetto/config/chrome/scenario_config.proto
index 5094f82..e90d6db 100644
--- a/protos/perfetto/config/chrome/scenario_config.proto
+++ b/protos/perfetto/config/chrome/scenario_config.proto
@@ -29,9 +29,16 @@
// triggered.
optional float trigger_chance = 2;
- // Additional delay on the trigger below.
+ // Additional delay *after* the trigger below. This is mostly useful
+ // to trace beyond a triggered event in upload rules. Other triggers
+ // can still be serviced during this period.
optional uint64 delay_ms = 3;
+ // Delay *before* which the rule is activated. Trigger events during this
+ // period are ignored by this rule. This is mostly useful to trace for a
+ // minimum duration before watching trigger events.
+ optional uint64 activation_delay_ms = 8;
+
// Triggers when a value within the specified bounds [min_value,
// max_value] is emitted into a Chrome histogram.
message HistogramTrigger {
diff --git a/protos/perfetto/config/interceptor_config.proto b/protos/perfetto/config/interceptor_config.proto
index 7ecc13b..9263bb5 100644
--- a/protos/perfetto/config/interceptor_config.proto
+++ b/protos/perfetto/config/interceptor_config.proto
@@ -27,5 +27,5 @@
// Matches the name given to RegisterInterceptor().
optional string name = 1;
- optional ConsoleConfig console_config = 100 [lazy = true];
+ optional ConsoleConfig console_config = 100;
}
diff --git a/protos/perfetto/config/perfetto_config.proto b/protos/perfetto/config/perfetto_config.proto
index bf19bbb..ade9e6b 100644
--- a/protos/perfetto/config/perfetto_config.proto
+++ b/protos/perfetto/config/perfetto_config.proto
@@ -901,7 +901,7 @@
// Matches the name given to RegisterInterceptor().
optional string name = 1;
- optional ConsoleConfig console_config = 100 [lazy = true];
+ optional ConsoleConfig console_config = 100;
}
// End of protos/perfetto/config/interceptor_config.proto
diff --git a/protos/perfetto/metrics/android/BUILD.gn b/protos/perfetto/metrics/android/BUILD.gn
index a2ae264..2504f4c 100644
--- a/protos/perfetto/metrics/android/BUILD.gn
+++ b/protos/perfetto/metrics/android/BUILD.gn
@@ -20,6 +20,7 @@
"source_set",
]
sources = [
+ "ad_services_metric.proto",
"android_blocking_call.proto",
"android_blocking_calls_cuj_metric.proto",
"android_boot.proto",
diff --git a/protos/perfetto/metrics/android/ad_services_metric.proto b/protos/perfetto/metrics/android/ad_services_metric.proto
new file mode 100644
index 0000000..c2ddcfd
--- /dev/null
+++ b/protos/perfetto/metrics/android/ad_services_metric.proto
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package perfetto.protos;
+
+// Next: 2
+message AdServicesUiMetric {
+ optional double latency = 1;
+}
+
+// Next: 2
+message AdServicesAdIdMetric {
+ optional double latency = 1;
+}
+
+// Next: 2
+message AdServicesAppSetIdMetric {
+ optional double latency = 1;
+}
+
+// Next: 4
+message AdServicesMetric {
+ repeated AdServicesUiMetric ui_metric = 1;
+ repeated AdServicesAdIdMetric ad_id_metric = 2;
+ repeated AdServicesAppSetIdMetric app_set_id_metric = 3;
+}
\ No newline at end of file
diff --git a/protos/perfetto/metrics/android/android_boot.proto b/protos/perfetto/metrics/android/android_boot.proto
index 820b4e0..53de221 100644
--- a/protos/perfetto/metrics/android/android_boot.proto
+++ b/protos/perfetto/metrics/android/android_boot.proto
@@ -29,4 +29,10 @@
optional ProcessStateDurations systemui_durations = 2;
optional ProcessStateDurations launcher_durations = 3;
optional ProcessStateDurations gms_durations = 4;
+ // Launcher related boot metrics
+ message LauncherBreakdown {
+ // reports cold start time of NexusLauncher
+ optional int64 cold_start_dur = 1;
+ }
+ optional LauncherBreakdown launcher_breakdown = 5;
}
diff --git a/protos/perfetto/metrics/metrics.proto b/protos/perfetto/metrics/metrics.proto
index 95fd3b4..4aaba30 100644
--- a/protos/perfetto/metrics/metrics.proto
+++ b/protos/perfetto/metrics/metrics.proto
@@ -18,6 +18,7 @@
package perfetto.protos;
+import "protos/perfetto/metrics/android/ad_services_metric.proto";
import "protos/perfetto/metrics/android/android_boot.proto";
import "protos/perfetto/metrics/android/android_frame_timeline_metric.proto";
import "protos/perfetto/metrics/android/anr_metric.proto";
@@ -77,6 +78,7 @@
optional string unique_session_name = 8;
optional string trace_config_pbtxt = 9;
optional int64 sched_duration_ns = 10;
+ optional int64 tracing_started_ns = 11;
}
// Stats counters for the trace.
@@ -109,7 +111,7 @@
// Root message for all Perfetto-based metrics.
//
-// Next id: 58
+// Next id: 59
message TraceMetrics {
reserved 4, 10, 13, 14, 16, 19;
@@ -261,11 +263,15 @@
// Metrics for App Not Responding (ANR) errors.
optional AndroidAnrMetric android_anr = 55;
+
// Aggregated Android Monitor Contention metrics
optional AndroidMonitorContentionAggMetric android_monitor_contention_agg = 56;
optional AndroidBootMetric android_boot = 57;
+ // Metric for AdServices module.
+ optional AdServicesMetric ad_services_metric = 58;
+
// Demo extensions.
extensions 450 to 499;
diff --git a/protos/perfetto/metrics/perfetto_merged_metrics.proto b/protos/perfetto/metrics/perfetto_merged_metrics.proto
index e940682..c518c7f 100644
--- a/protos/perfetto/metrics/perfetto_merged_metrics.proto
+++ b/protos/perfetto/metrics/perfetto_merged_metrics.proto
@@ -13,6 +13,31 @@
option go_package = "github.com/google/perfetto/perfetto_proto";
+// Begin of protos/perfetto/metrics/android/ad_services_metric.proto
+
+// Next: 2
+message AdServicesUiMetric {
+ optional double latency = 1;
+}
+
+// Next: 2
+message AdServicesAdIdMetric {
+ optional double latency = 1;
+}
+
+// Next: 2
+message AdServicesAppSetIdMetric {
+ optional double latency = 1;
+}
+
+// Next: 4
+message AdServicesMetric {
+ repeated AdServicesUiMetric ui_metric = 1;
+ repeated AdServicesAdIdMetric ad_id_metric = 2;
+ repeated AdServicesAppSetIdMetric app_set_id_metric = 3;
+}
+// End of protos/perfetto/metrics/android/ad_services_metric.proto
+
// Begin of protos/perfetto/metrics/android/android_blocking_call.proto
// Blocking call on the main thread.
@@ -118,6 +143,12 @@
optional ProcessStateDurations systemui_durations = 2;
optional ProcessStateDurations launcher_durations = 3;
optional ProcessStateDurations gms_durations = 4;
+ // Launcher related boot metrics
+ message LauncherBreakdown {
+ // reports cold start time of NexusLauncher
+ optional int64 cold_start_dur = 1;
+ }
+ optional LauncherBreakdown launcher_breakdown = 5;
}
// End of protos/perfetto/metrics/android/android_boot.proto
@@ -2251,6 +2282,7 @@
optional string unique_session_name = 8;
optional string trace_config_pbtxt = 9;
optional int64 sched_duration_ns = 10;
+ optional int64 tracing_started_ns = 11;
}
// Stats counters for the trace.
@@ -2283,7 +2315,7 @@
// Root message for all Perfetto-based metrics.
//
-// Next id: 58
+// Next id: 59
message TraceMetrics {
reserved 4, 10, 13, 14, 16, 19;
@@ -2435,11 +2467,15 @@
// Metrics for App Not Responding (ANR) errors.
optional AndroidAnrMetric android_anr = 55;
+
// Aggregated Android Monitor Contention metrics
optional AndroidMonitorContentionAggMetric android_monitor_contention_agg = 56;
optional AndroidBootMetric android_boot = 57;
+ // Metric for AdServices module.
+ optional AdServicesMetric ad_services_metric = 58;
+
// Demo extensions.
extensions 450 to 499;
diff --git a/protos/perfetto/trace/BUILD.gn b/protos/perfetto/trace/BUILD.gn
index f81b05c..c808a93 100644
--- a/protos/perfetto/trace/BUILD.gn
+++ b/protos/perfetto/trace/BUILD.gn
@@ -93,6 +93,7 @@
"../config:@TYPE@",
"android:@TYPE@",
"chrome:@TYPE@",
+ "etw:@TYPE@",
"filesystem:@TYPE@",
"ftrace:@TYPE@",
"gpu:@TYPE@",
diff --git a/protos/perfetto/trace/etw/BUILD.gn b/protos/perfetto/trace/etw/BUILD.gn
new file mode 100644
index 0000000..f22514c
--- /dev/null
+++ b/protos/perfetto/trace/etw/BUILD.gn
@@ -0,0 +1,29 @@
+# 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("../../../../gn/perfetto.gni")
+import("../../../../gn/proto_library.gni")
+import("all_protos.gni")
+
+perfetto_proto_library("@TYPE@") {
+ sources = etw_proto_names
+}
+
+if (perfetto_build_standalone) {
+ perfetto_proto_library("descriptor") {
+ proto_generators = [ "descriptor" ]
+ generate_descriptor = "etw.descriptor"
+ sources = [ "etw_event_bundle.proto" ]
+ }
+}
diff --git a/protos/perfetto/trace/etw/all_protos.gni b/protos/perfetto/trace/etw/all_protos.gni
new file mode 100644
index 0000000..e6c9e9a
--- /dev/null
+++ b/protos/perfetto/trace/etw/all_protos.gni
@@ -0,0 +1,19 @@
+# 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.
+
+etw_proto_names = [
+ "etw.proto",
+ "etw_event.proto",
+ "etw_event_bundle.proto",
+]
diff --git a/protos/perfetto/trace/etw/etw.proto b/protos/perfetto/trace/etw/etw.proto
new file mode 100644
index 0000000..c008be2
--- /dev/null
+++ b/protos/perfetto/trace/etw/etw.proto
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+package perfetto.protos;
+
+// Proto definition based on the Thread_v2 CSwitch class definition
+// See: https://learn.microsoft.com/en-us/windows/win32/etw/cswitch
+message CSwitchEtwEvent {
+ // New thread ID after the switch.
+ optional uint32 new_thread_id = 1;
+
+ // Previous thread ID.
+ optional uint32 old_thread_id = 2;
+
+ // Thread priority of the new thread.
+ optional sint32 new_thread_priority = 3;
+
+ // Thread priority of the previous thread.
+ optional sint32 old_thread_priority = 4;
+
+ // The index of the C-state that was last used by the processor. A value of 0
+ // represents the lightest idle state with higher values representing deeper
+ // C-states.
+ optional uint32 previous_c_state = 5;
+
+ // Wait reason for the previous thread. The ordering is important as based on
+ // the OldThreadWaitReason definition from the link above. The following are
+ // the possible values:
+ enum OldThreadWaitReason {
+ EXECUTIVE = 0;
+ FREE_PAGE = 1;
+ PAGE_IN = 2;
+ POOL_ALLOCATION = 3;
+ DELAY_EXECUTION = 4;
+ SUSPEND = 5;
+ USER_REQUEST = 6;
+ WR_EXECUTIVE = 7;
+ WR_FREE_PAGE = 8;
+ WR_PAGE_IN = 9;
+ WR_POOL_ALLOCATION = 10;
+ WR_DELAY_EXECUTION = 11;
+ WR_SUSPENDED = 12;
+ WR_USER_REQUEST = 13;
+ WR_EVENT_PAIR = 14;
+ WR_QUEUE = 15;
+ WR_LPC_RECEIVER = 16;
+ WR_LPC_REPLY = 17;
+ WR_VIRTUAL_MEMORY = 18;
+ WR_PAGE_OUT = 19;
+ WR_RENDEZ_VOUS = 20;
+ WR_KEYED_EVENT = 21;
+ WR_TERMINATED = 22;
+ WR_PROCESS_IN_SWAP = 23;
+ WR_CPU_RATE_CONTROL = 24;
+ WR_CALLOUT_STACK = 25;
+ WR_KERNEL = 26;
+ WR_RESOURCE = 27;
+ WR_PUSH_LOCK = 28;
+ WR_MUTEX = 29;
+ WR_QUANTUM_END = 30;
+ WR_DISPATCH_INT = 31;
+ WR_PREEMPTED = 32;
+ WR_YIELD_EXECUTION = 33;
+ WR_FAST_MUTEX = 34;
+ WR_GUARD_MUTEX = 35;
+ WR_RUNDOWN = 36;
+ MAXIMUM_WAIT_REASON = 37;
+ }
+
+ optional OldThreadWaitReason old_thread_wait_reason = 6;
+
+ // Wait mode for the previous thread. The ordering is important as based on
+ // the OldThreadWaitMode definition from the link above. The following are the
+ // possible values:
+ enum OldThreadWaitMode {
+ KERNEL_MODE = 0;
+ USER_MODE = 1;
+ }
+
+ optional OldThreadWaitMode old_thread_wait_mode = 7;
+
+ // State of the previous thread. The ordering is important as based on the
+ // OldThreadState definition from the link above. The following are the
+ // possible state values:
+ enum OldThreadState {
+ INITIALIZED = 0;
+ READY = 1;
+ RUNNING = 2;
+ STANDBY = 3;
+ TERMINATED = 4;
+ WAITING = 5;
+ TRANSITION = 6;
+ DEFERRED_READY = 7;
+ }
+
+ optional OldThreadState old_thread_state = 8;
+
+ // Ideal wait time of the previous thread.
+ optional sint32 old_thread_wait_ideal_processor = 9;
+
+ // Wait time for the new thread.
+ optional uint32 new_thread_wait_time = 10;
+}
+
+// Proto definition based on the Thread_v2 CSwitch class definition
+// See: https://learn.microsoft.com/en-us/windows/win32/etw/readythread
+message ReadyThreadEtwEvent {
+ // The thread identifier of the thread being readied for execution.
+ optional uint32 t_thread_id = 1;
+
+ // The reason for the priority boost. The ordering is important as based on
+ // the AdjustReason definition from the link above.
+ enum AdjustReason {
+ IGNORE_THE_INCREMENT = 0;
+ // Apply the increment, which will decay incrementally at the end of each
+ // quantum.
+ APPLY_INCREMENT = 1;
+ // Apply the increment as a boost that will decay in its entirety at quantum
+ // (typically for priority donation).
+ APPLY_INCREMENT_BOOST = 2;
+ }
+
+ optional AdjustReason adjust_reason = 2;
+
+ // The value by which the priority is being adjusted.
+ optional sint32 adjust_increment = 3;
+
+ enum TraceFlag {
+ TRACE_FLAG_UNSPECIFIED = 0;
+ // The thread has been readied from DPC (deferred procedure call).
+ THREAD_READIED = 0x1;
+ // The kernel stack is currently swapped out.
+ KERNEL_STACK_SWAPPED_OUT = 0x2;
+ // The process address space is swapped out.
+ PROCESS_ADDRESS_SWAPPED_OUT = 0x4;
+ }
+
+ optional TraceFlag flag = 4;
+}
\ No newline at end of file
diff --git a/protos/perfetto/trace/etw/etw_event.proto b/protos/perfetto/trace/etw/etw_event.proto
new file mode 100644
index 0000000..9ef1b4e
--- /dev/null
+++ b/protos/perfetto/trace/etw/etw_event.proto
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+package perfetto.protos;
+
+import "protos/perfetto/trace/etw/etw.proto";
+
+message EtwTraceEvent {
+ optional uint64 timestamp = 1;
+
+ oneof event {
+ CSwitchEtwEvent c_switch = 2;
+ ReadyThreadEtwEvent ready_thread = 3;
+ }
+}
\ No newline at end of file
diff --git a/protos/perfetto/trace/etw/etw_event_bundle.proto b/protos/perfetto/trace/etw/etw_event_bundle.proto
new file mode 100644
index 0000000..3ea3916
--- /dev/null
+++ b/protos/perfetto/trace/etw/etw_event_bundle.proto
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+import "protos/perfetto/trace/etw/etw_event.proto";
+
+package perfetto.protos;
+
+// The result of tracing one or more etw event uses per-processor buffers where
+// an in-use buffer is assigned to each processor at all times. Therefore,
+// collecting multiple events they should already be synchronized.
+message EtwTraceEventBundle {
+ optional uint32 cpu = 1;
+ repeated EtwTraceEvent event = 2;
+}
\ No newline at end of file
diff --git a/protos/perfetto/trace/perfetto_trace.proto b/protos/perfetto/trace/perfetto_trace.proto
index 16112ab..6470fdb 100644
--- a/protos/perfetto/trace/perfetto_trace.proto
+++ b/protos/perfetto/trace/perfetto_trace.proto
@@ -901,7 +901,7 @@
// Matches the name given to RegisterInterceptor().
optional string name = 1;
- optional ConsoleConfig console_config = 100 [lazy = true];
+ optional ConsoleConfig console_config = 100;
}
// End of protos/perfetto/config/interceptor_config.proto
@@ -5166,6 +5166,167 @@
// End of protos/perfetto/trace/clock_snapshot.proto
+// Begin of protos/perfetto/trace/etw/etw.proto
+
+// Proto definition based on the Thread_v2 CSwitch class definition
+// See: https://learn.microsoft.com/en-us/windows/win32/etw/cswitch
+message CSwitchEtwEvent {
+ // New thread ID after the switch.
+ optional uint32 new_thread_id = 1;
+
+ // Previous thread ID.
+ optional uint32 old_thread_id = 2;
+
+ // Thread priority of the new thread.
+ optional sint32 new_thread_priority = 3;
+
+ // Thread priority of the previous thread.
+ optional sint32 old_thread_priority = 4;
+
+ // The index of the C-state that was last used by the processor. A value of 0
+ // represents the lightest idle state with higher values representing deeper
+ // C-states.
+ optional uint32 previous_c_state = 5;
+
+ // Wait reason for the previous thread. The ordering is important as based on
+ // the OldThreadWaitReason definition from the link above. The following are
+ // the possible values:
+ enum OldThreadWaitReason {
+ EXECUTIVE = 0;
+ FREE_PAGE = 1;
+ PAGE_IN = 2;
+ POOL_ALLOCATION = 3;
+ DELAY_EXECUTION = 4;
+ SUSPEND = 5;
+ USER_REQUEST = 6;
+ WR_EXECUTIVE = 7;
+ WR_FREE_PAGE = 8;
+ WR_PAGE_IN = 9;
+ WR_POOL_ALLOCATION = 10;
+ WR_DELAY_EXECUTION = 11;
+ WR_SUSPENDED = 12;
+ WR_USER_REQUEST = 13;
+ WR_EVENT_PAIR = 14;
+ WR_QUEUE = 15;
+ WR_LPC_RECEIVER = 16;
+ WR_LPC_REPLY = 17;
+ WR_VIRTUAL_MEMORY = 18;
+ WR_PAGE_OUT = 19;
+ WR_RENDEZ_VOUS = 20;
+ WR_KEYED_EVENT = 21;
+ WR_TERMINATED = 22;
+ WR_PROCESS_IN_SWAP = 23;
+ WR_CPU_RATE_CONTROL = 24;
+ WR_CALLOUT_STACK = 25;
+ WR_KERNEL = 26;
+ WR_RESOURCE = 27;
+ WR_PUSH_LOCK = 28;
+ WR_MUTEX = 29;
+ WR_QUANTUM_END = 30;
+ WR_DISPATCH_INT = 31;
+ WR_PREEMPTED = 32;
+ WR_YIELD_EXECUTION = 33;
+ WR_FAST_MUTEX = 34;
+ WR_GUARD_MUTEX = 35;
+ WR_RUNDOWN = 36;
+ MAXIMUM_WAIT_REASON = 37;
+ }
+
+ optional OldThreadWaitReason old_thread_wait_reason = 6;
+
+ // Wait mode for the previous thread. The ordering is important as based on
+ // the OldThreadWaitMode definition from the link above. The following are the
+ // possible values:
+ enum OldThreadWaitMode {
+ KERNEL_MODE = 0;
+ USER_MODE = 1;
+ }
+
+ optional OldThreadWaitMode old_thread_wait_mode = 7;
+
+ // State of the previous thread. The ordering is important as based on the
+ // OldThreadState definition from the link above. The following are the
+ // possible state values:
+ enum OldThreadState {
+ INITIALIZED = 0;
+ READY = 1;
+ RUNNING = 2;
+ STANDBY = 3;
+ TERMINATED = 4;
+ WAITING = 5;
+ TRANSITION = 6;
+ DEFERRED_READY = 7;
+ }
+
+ optional OldThreadState old_thread_state = 8;
+
+ // Ideal wait time of the previous thread.
+ optional sint32 old_thread_wait_ideal_processor = 9;
+
+ // Wait time for the new thread.
+ optional uint32 new_thread_wait_time = 10;
+}
+
+// Proto definition based on the Thread_v2 CSwitch class definition
+// See: https://learn.microsoft.com/en-us/windows/win32/etw/readythread
+message ReadyThreadEtwEvent {
+ // The thread identifier of the thread being readied for execution.
+ optional uint32 t_thread_id = 1;
+
+ // The reason for the priority boost. The ordering is important as based on
+ // the AdjustReason definition from the link above.
+ enum AdjustReason {
+ IGNORE_THE_INCREMENT = 0;
+ // Apply the increment, which will decay incrementally at the end of each
+ // quantum.
+ APPLY_INCREMENT = 1;
+ // Apply the increment as a boost that will decay in its entirety at quantum
+ // (typically for priority donation).
+ APPLY_INCREMENT_BOOST = 2;
+ }
+
+ optional AdjustReason adjust_reason = 2;
+
+ // The value by which the priority is being adjusted.
+ optional sint32 adjust_increment = 3;
+
+ enum TraceFlag {
+ TRACE_FLAG_UNSPECIFIED = 0;
+ // The thread has been readied from DPC (deferred procedure call).
+ THREAD_READIED = 0x1;
+ // The kernel stack is currently swapped out.
+ KERNEL_STACK_SWAPPED_OUT = 0x2;
+ // The process address space is swapped out.
+ PROCESS_ADDRESS_SWAPPED_OUT = 0x4;
+ }
+
+ optional TraceFlag flag = 4;
+}
+// End of protos/perfetto/trace/etw/etw.proto
+
+// Begin of protos/perfetto/trace/etw/etw_event.proto
+
+message EtwTraceEvent {
+ optional uint64 timestamp = 1;
+
+ oneof event {
+ CSwitchEtwEvent c_switch = 2;
+ ReadyThreadEtwEvent ready_thread = 3;
+ }
+}
+// End of protos/perfetto/trace/etw/etw_event.proto
+
+// Begin of protos/perfetto/trace/etw/etw_event_bundle.proto
+
+// The result of tracing one or more etw event uses per-processor buffers where
+// an in-use buffer is assigned to each processor at all times. Therefore,
+// collecting multiple events they should already be synchronized.
+message EtwTraceEventBundle {
+ optional uint32 cpu = 1;
+ repeated EtwTraceEvent event = 2;
+}
+// End of protos/perfetto/trace/etw/etw_event_bundle.proto
+
// Begin of protos/perfetto/common/descriptor.proto
// The protocol compiler can output a FileDescriptorSet containing the .proto
@@ -12334,7 +12495,7 @@
optional uint64 user_ns = 2;
// Time spent in user mode (low prio).
- optional uint64 user_ice_ns = 3;
+ optional uint64 user_nice_ns = 3;
// Time spent in system mode.
optional uint64 system_mode_ns = 4;
@@ -12452,6 +12613,10 @@
// Kernel page size - sysconf(_SC_PAGESIZE).
optional uint32 page_size = 6;
+
+ // The timezone offset from UTC, as per strftime("%z"), in minutes.
+ // Introduced in v38 / Android V.
+ optional int32 timezone_off_mins = 7;
}
// End of protos/perfetto/trace/system_info.proto
@@ -13081,7 +13246,7 @@
// See the [Buffers and Dataflow](/docs/concepts/buffers.md) doc for details.
//
// Next reserved id: 14 (up to 15).
-// Next id: 95.
+// Next id: 96.
message TracePacket {
// The timestamp of the TracePacket.
// By default this timestamps refers to the trace clock (CLOCK_BOOTTIME on
@@ -13201,6 +13366,9 @@
LayersSnapshotProto surfaceflinger_layers_snapshot = 93;
TransactionTraceEntry surfaceflinger_transactions = 94;
+ // Events from the Windows etw infrastructure.
+ EtwTraceEventBundle etw_events = 95;
+
// This field is only used for testing.
// In previous versions of this proto this field had the id 268435455
// This caused many problems:
diff --git a/protos/perfetto/trace/sys_stats/sys_stats.proto b/protos/perfetto/trace/sys_stats/sys_stats.proto
index 2aad34c..4bc538d 100644
--- a/protos/perfetto/trace/sys_stats/sys_stats.proto
+++ b/protos/perfetto/trace/sys_stats/sys_stats.proto
@@ -45,7 +45,7 @@
optional uint64 user_ns = 2;
// Time spent in user mode (low prio).
- optional uint64 user_ice_ns = 3;
+ optional uint64 user_nice_ns = 3;
// Time spent in system mode.
optional uint64 system_mode_ns = 4;
diff --git a/protos/perfetto/trace/system_info.proto b/protos/perfetto/trace/system_info.proto
index f4c0507..9a75773 100644
--- a/protos/perfetto/trace/system_info.proto
+++ b/protos/perfetto/trace/system_info.proto
@@ -44,4 +44,8 @@
// Kernel page size - sysconf(_SC_PAGESIZE).
optional uint32 page_size = 6;
+
+ // The timezone offset from UTC, as per strftime("%z"), in minutes.
+ // Introduced in v38 / Android V.
+ optional int32 timezone_off_mins = 7;
}
diff --git a/protos/perfetto/trace/test_extensions.proto b/protos/perfetto/trace/test_extensions.proto
index 0d33c09..2d21e92 100644
--- a/protos/perfetto/trace/test_extensions.proto
+++ b/protos/perfetto/trace/test_extensions.proto
@@ -28,6 +28,7 @@
message TestExtension {
extend TrackEvent {
optional string string_extension_for_testing = 9900;
+ optional string string_extension_for_testing2 = 9905;
repeated int32 int_extension_for_testing = 9901;
optional string omitted_extension_for_testing = 9902;
optional TestExtensionChild nested_message_extension_for_testing = 9903;
diff --git a/protos/perfetto/trace/trace_packet.proto b/protos/perfetto/trace/trace_packet.proto
index b47981b..0c60cf6 100644
--- a/protos/perfetto/trace/trace_packet.proto
+++ b/protos/perfetto/trace/trace_packet.proto
@@ -35,6 +35,7 @@
import "protos/perfetto/trace/chrome/chrome_metadata.proto";
import "protos/perfetto/trace/chrome/chrome_trace_event.proto";
import "protos/perfetto/trace/clock_snapshot.proto";
+import "protos/perfetto/trace/etw/etw_event_bundle.proto";
import "protos/perfetto/trace/filesystem/inode_file_map.proto";
import "protos/perfetto/trace/ftrace/ftrace_event_bundle.proto";
import "protos/perfetto/trace/ftrace/ftrace_stats.proto";
@@ -96,7 +97,7 @@
// See the [Buffers and Dataflow](/docs/concepts/buffers.md) doc for details.
//
// Next reserved id: 14 (up to 15).
-// Next id: 95.
+// Next id: 96.
message TracePacket {
// The timestamp of the TracePacket.
// By default this timestamps refers to the trace clock (CLOCK_BOOTTIME on
@@ -216,6 +217,9 @@
LayersSnapshotProto surfaceflinger_layers_snapshot = 93;
TransactionTraceEntry surfaceflinger_transactions = 94;
+ // Events from the Windows etw infrastructure.
+ EtwTraceEventBundle etw_events = 95;
+
// This field is only used for testing.
// In previous versions of this proto this field had the id 268435455
// This caused many problems:
diff --git a/protos/perfetto/trace_processor/trace_processor.proto b/protos/perfetto/trace_processor/trace_processor.proto
index fbf1987..8a6f511 100644
--- a/protos/perfetto/trace_processor/trace_processor.proto
+++ b/protos/perfetto/trace_processor/trace_processor.proto
@@ -45,7 +45,8 @@
// Changes:
// 7. Introduce GUESS_CPU_SIZE
// 8. Add 'json' option to ComputeMetricArgs
- TRACE_PROCESSOR_CURRENT_API_VERSION = 8;
+ // 9. Add get_thread_state_summary_for_interval.
+ TRACE_PROCESSOR_CURRENT_API_VERSION = 9;
}
// At lowest level, the wire-format of the RPC procol is a linear sequence of
diff --git a/python/generators/diff_tests/testing.py b/python/generators/diff_tests/testing.py
index 89aea8a..9bd6d84 100644
--- a/python/generators/diff_tests/testing.py
+++ b/python/generators/diff_tests/testing.py
@@ -177,7 +177,7 @@
self.name = name
self.blueprint = blueprint
self.index_dir = index_dir
- self.test_dir = os.path.dirname(os.path.dirname(os.path.dirname(index_dir)))
+ self.test_dir = os.path.abspath(os.path.join(__file__, '../../../../test'))
if blueprint.is_metric():
self.type = TestType.METRIC
diff --git a/python/generators/sql_processing/docs_parse.py b/python/generators/sql_processing/docs_parse.py
index cd940e1..55ba205 100644
--- a/python/generators/sql_processing/docs_parse.py
+++ b/python/generators/sql_processing/docs_parse.py
@@ -17,10 +17,10 @@
from dataclasses import dataclass
import re
import sys
-from typing import Any, Dict, List, Optional, Set, Tuple
+from typing import Any, Dict, List, Optional, Set, Tuple, NamedTuple
from python.generators.sql_processing.docs_extractor import DocsExtractor
-from python.generators.sql_processing.utils import ObjKind
+from python.generators.sql_processing.utils import ANY_PATTERN, ARG_DEFINITION_PATTERN, ObjKind
from python.generators.sql_processing.utils import ARG_ANNOTATION_PATTERN
from python.generators.sql_processing.utils import NAME_AND_TYPE_PATTERN
from python.generators.sql_processing.utils import FUNCTION_RETURN_PATTERN
@@ -36,6 +36,13 @@
return re.fullmatch(r'^[a-z_0-9]*$', s) is not None
+class Arg(NamedTuple):
+ # TODO(b/307926059): the type is missing on old-style documentation for
+ # tables. Make it "str" after stdlib is migrated.
+ type: Optional[str]
+ description: str
+
+
class AbstractDocParser(ABC):
@dataclass
@@ -78,8 +85,8 @@
self._error(f'Unknown documentation annotation {type}')
def _parse_columns(self, ans: List[DocsExtractor.Annotation],
- sql_cols_str: str) -> Dict[str, str]:
- cols = {}
+ schema: Optional[str]) -> Dict[str, Arg]:
+ column_annotations = {}
for t in ans:
if t.key != '@column':
continue
@@ -88,21 +95,44 @@
self._error(f'@column annotation value {t.value} does not match '
f'pattern {COLUMN_ANNOTATION_PATTERN}')
continue
- cols[m.group(1)] = m.group(2).strip()
+ column_annotations[m.group(1)] = Arg(None, m.group(2).strip())
- sql_cols = self._parse_name_and_types_str(sql_cols_str)
- if sql_cols:
- for col in set(cols.keys()).difference(sql_cols.keys()):
- self._error(f'@column "{col}" documented but does not exist in '
- 'function definition')
- for col in set(sql_cols.keys()).difference(cols):
- self._error(f'Column "{col}" defined in SQL but is not documented with '
- '@column')
- return cols
+ if not schema:
+ # If we don't have schema, we have to accept annotations as the source of
+ # truth.
+ return column_annotations
+
+ columns = self._parse_args_definition(schema)
+
+ for column in columns:
+ inline_comment = columns[column].description
+ if not inline_comment and column not in column_annotations:
+ self._error(f'Column "{column}" is missing a description. Please add a '
+ 'comment in front of the column definition')
+ continue
+
+ if column not in column_annotations:
+ continue
+ annotation = column_annotations[column].description
+ if inline_comment and annotation:
+ self._error(f'Column "{column}" is documented twice. Please remove the '
+ '@column annotation')
+ if not inline_comment and annotation:
+ # Absorb old-style annotations.
+ columns[column] = Arg(columns[column].type, annotation)
+
+ # Check that the annotations match existing columns.
+ for annotation in column_annotations:
+ if annotation not in columns:
+ self._error(f'Column "{annotation}" is documented but does not exist '
+ 'in table definition')
+ return columns
def _parse_args(self, ans: List[DocsExtractor.Annotation],
- sql_args_str: str) -> Dict[str, Any]:
- args = {}
+ sql_args_str: str) -> Dict[str, Arg]:
+ args = self._parse_args_definition(sql_args_str)
+
+ arg_annotations = {}
for an in ans:
if an.key != '@arg':
continue
@@ -111,16 +141,24 @@
self._error(f'Expected arg documentation "{an.value}" to match pattern '
f'{ARG_ANNOTATION_PATTERN}')
continue
- args[m.group(1)] = {'type': m.group(2), 'desc': m.group(3).strip()}
+ arg_annotations[m.group(1)] = Arg(m.group(2), m.group(3).strip())
- sql_args = self._parse_name_and_types_str(sql_args_str)
- if sql_args:
- for col in set(args.keys()).difference(sql_args.keys()):
- self._error(f'Arg "{col}" documented with @arg but does not exist '
- 'in function definition')
- for arg in set(sql_args.keys()).difference(args.keys()):
- self._error(f'Arg "{arg}" defined in SQL but is not documented with '
- '@arg')
+ for arg in args:
+ if not args[arg].description and arg not in arg_annotations:
+ self._error(f'Arg "{arg}" is missing a description. '
+ 'Please add a comment in front of the arg definition.')
+ if args[arg].description and arg in arg_annotations:
+ self._error(f'Arg "{arg}" is documented twice. '
+ 'Please remove the @arg annotation')
+ if not args[arg].description and arg in arg_annotations:
+ # Absorb old-style annotations.
+ # TODO(b/307926059): Remove it once stdlib is migrated.
+ args[arg] = Arg(args[arg].type, arg_annotations[arg].description)
+
+ for arg in arg_annotations:
+ if arg not in args:
+ self._error(
+ f'Arg "{arg}" is documented but not found in function definition.')
return args
def _parse_ret(self, ans: List[DocsExtractor.Annotation],
@@ -144,23 +182,32 @@
return '', ''
return ret_type, ret_desc.strip()
- def _parse_name_and_types_str(self, args_str: str) -> Dict[str, str]:
- if not args_str:
- return {}
+ # Parse function argument definition list or a table schema, e.g.
+ # arg1 INT, arg2 STRING, including their comments.
+ def _parse_args_definition(self, args_str: str) -> Dict[str, Arg]:
+ result = {}
+ remaining_args = args_str.strip()
+ while remaining_args:
+ m = re.match(fr'^{ARG_DEFINITION_PATTERN}({ANY_PATTERN})', remaining_args)
+ if not m:
+ self._error(f'Expected "{args_str}" to correspond to '
+ '"-- Comment\n arg_name TYPE" format '
+ '({ARG_DEFINITION_PATTERN})')
+ return result
+ groups = m.groups()
+ comment = None if groups[0] is None else ' '.join(
+ line.strip().lstrip('--').lstrip() for line in groups[0].split('\n'))
+ name = groups[-3]
+ type = groups[-2]
+ result[name] = Arg(type, comment)
+ # Strip whitespace and comma and parse the next arg.
+ remaining_args = groups[-1].lstrip().lstrip(',').lstrip()
- args = {}
- for arg_str in args_str.split(","):
- m = re.match(NAME_AND_TYPE_PATTERN, arg_str)
- if m is None:
- self._error(f'Expected "{arg_str}" to match pattern '
- f'{NAME_AND_TYPE_PATTERN}')
- continue
- args[m.group(1)] = m.group(2).strip()
- return args
+ return result
def _error(self, error: str):
self.errors.append(
- f'Error while parsing documentation for {self.name} in {self.path}: '
+ f'Error while parsing documentation for "{self.name}" in {self.path}: '
f'{error}')
@@ -168,7 +215,7 @@
name: str
type: str
desc: str
- cols: Dict[str, str]
+ cols: Dict[str, Arg]
def __init__(self, name, type, desc, cols):
self.name = name
@@ -186,23 +233,27 @@
def parse(self, doc: DocsExtractor.Extract) -> Optional[TableOrView]:
assert doc.obj_kind == ObjKind.table_view
- self.name = doc.obj_match[1]
+ or_replace, type, self.name, schema = doc.obj_match
+
+ if or_replace is not None:
+ self._error(
+ f'{type} "{self.name}": CREATE OR REPLACE is not allowed in stdlib')
if is_internal(self.name):
return None
self._validate_only_contains_annotations(doc.annotations, {'@column'})
return TableOrView(
name=self._parse_name(),
- type=doc.obj_match[0],
+ type=type,
desc=self._parse_desc_not_empty(doc.description),
- cols=self._parse_columns(doc.annotations, ''),
+ cols=self._parse_columns(doc.annotations, schema),
)
class Function:
name: str
desc: str
- args: Dict[str, Any]
+ args: Dict[str, Arg]
return_type: str
return_desc: str
@@ -221,7 +272,11 @@
super().__init__(path, module)
def parse(self, doc: DocsExtractor.Extract) -> Optional[Function]:
- self.name, args, ret, _ = doc.obj_match
+ or_replace, self.name, args, ret = doc.obj_match
+
+ if or_replace is not None:
+ self._error(
+ f'Function "{self.name}": CREATE OR REPLACE is not allowed in stdlib')
# Ignore internal functions.
if is_internal(self.name):
@@ -233,8 +288,8 @@
name = self._parse_name()
if not is_snake_case(name):
- self._error('Function name %s is not snake_case (should be %s) ' %
- (name, name.casefold()))
+ self._error(f'Function name "{name}" is not snake_case'
+ f' (should be {name.casefold()})')
return Function(
name=name,
@@ -248,8 +303,8 @@
class TableFunction:
name: str
desc: str
- cols: Dict[str, str]
- args: Dict[str, Any]
+ cols: Dict[str, Arg]
+ args: Dict[str, Arg]
def __init__(self, name, desc, cols, args):
self.name = name
@@ -265,7 +320,11 @@
super().__init__(path, module)
def parse(self, doc: DocsExtractor.Extract) -> Optional[TableFunction]:
- self.name, args, columns, _ = doc.obj_match
+ or_replace, self.name, args, columns = doc.obj_match
+
+ if or_replace is not None:
+ self._error(
+ f'Function "{self.name}": CREATE OR REPLACE is not allowed in stdlib')
# Ignore internal functions.
if is_internal(self.name):
@@ -276,8 +335,8 @@
name = self._parse_name()
if not is_snake_case(name):
- self._error('Function name %s is not snake_case (should be %s) ' %
- (name, name.casefold()))
+ self._error(f'Function name "{name}" is not snake_case'
+ f' (should be "{name.casefold()}")')
return TableFunction(
name=name,
diff --git a/python/generators/sql_processing/utils.py b/python/generators/sql_processing/utils.py
index f4ee20c..fa9e73d 100644
--- a/python/generators/sql_processing/utils.py
+++ b/python/generators/sql_processing/utils.py
@@ -17,53 +17,67 @@
from typing import Dict, List
NAME = r'[a-zA-Z_\d\{\}]+'
+ARGS = '[^\)]*'
ANY_WORDS = r'[^\s].*'
ANY_NON_QUOTE = r'[^\']*.*'
TYPE = r'[A-Z]+'
SQL = r'[\s\S]*?'
WS = r'\s*'
+COMMENT = r'--[^\n]*'
+NEW_STYLE_ARG = rf'((?: {COMMENT})*) ({NAME}) ({TYPE})'
-CREATE_TABLE_VIEW_PATTERN = (
+
+# Make the pattern more readable by allowing the use of spaces
+# and replace then with a wildcard in a separate step.
+def update_pattern(pattern):
+ return pattern.replace(' ', WS)
+
+
+CREATE_TABLE_VIEW_PATTERN = update_pattern(
# Match create table/view and catch type
- fr'^CREATE{WS}(?:VIRTUAL|PERFETTO)?{WS}(TABLE|VIEW){WS}(?:IF NOT EXISTS)?'
- # Catch the name
- fr'{WS}({NAME}){WS}(?:AS|USING)?{WS}.*')
+ fr'^CREATE (OR REPLACE)? (?:VIRTUAL|PERFETTO)?'
+ fr' (TABLE|VIEW) (?:IF NOT EXISTS)?'
+ # Catch the name and optional schema.
+ fr' ({NAME}) (?: \( ({ARGS}) \) )? (?:AS|USING)? .*')
-CREATE_TABLE_AS_PATTERN = (fr'^CREATE{WS}TABLE{WS}({NAME}){WS}AS')
+CREATE_TABLE_AS_PATTERN = update_pattern(fr'^CREATE TABLE ({NAME}) AS')
-DROP_TABLE_VIEW_PATTERN = (fr'^DROP{WS}(TABLE|VIEW){WS}IF{WS}EXISTS{WS}'
- fr'({NAME});$')
+DROP_TABLE_VIEW_PATTERN = update_pattern(fr'^DROP (TABLE|VIEW) IF EXISTS '
+ fr'({NAME});$')
-CREATE_PERFETTO_TABLE_PATTERN = (
- # Match `CREATE PERFETTO TABLE {name} AS` string
- fr'^CREATE{WS}PERFETTO{WS}TABLE{WS}({NAME}){WS}AS{WS}.*')
-
-CREATE_FUNCTION_PATTERN = (
+CREATE_FUNCTION_PATTERN = update_pattern(
# Function name.
- fr"CREATE{WS}PERFETTO{WS}FUNCTION{WS}({NAME}){WS}"
+ fr"CREATE (OR REPLACE)? PERFETTO FUNCTION ({NAME}) "
# Args: anything in the brackets.
- fr"{WS}\({WS}({ANY_WORDS}){WS}\){WS}"
+ fr" \( ({ARGS}) \) "
# Type: word after RETURNS.
- fr"{WS}RETURNS{WS}({TYPE}){WS}AS{WS}"
- # Sql: Anything between ' and ');. We are catching \'.
- fr"{WS}({SQL});")
+ fr" RETURNS ({TYPE}) AS ")
-CREATE_TABLE_FUNCTION_PATTERN = (
- fr"CREATE{WS}PERFETTO{WS}FUNCTION{WS}({NAME}){WS}"
+CREATE_TABLE_FUNCTION_PATTERN = update_pattern(
+ fr"CREATE (OR REPLACE)? PERFETTO FUNCTION ({NAME}) "
# Args: anything in the brackets.
- fr"{WS}\({WS}({ANY_WORDS}){WS}\){WS}"
+ fr" \( ({ARGS}) \) "
# Type: word after RETURNS.
- fr"{WS}RETURNS{WS}TABLE\({WS}({ANY_WORDS}){WS}\){WS}AS{WS}"
- # Sql: Anything between ' and ');. We are catching \'.
- fr"{WS}({SQL});")
+ fr" RETURNS TABLE\( ({ANY_WORDS}) \) AS ")
-COLUMN_ANNOTATION_PATTERN = fr'^\s*({NAME})\s*({ANY_WORDS})'
+CREATE_MACRO_PATTERN = update_pattern(
+ fr"CREATE (OR REPLACE)? PERFETTO MACRO ({NAME}) "
+ # Args: anything in the brackets.
+ fr" \( ({ARGS}) \) "
+ # Type: word after RETURNS.
+ fr" RETURNS")
-NAME_AND_TYPE_PATTERN = fr'\s*({NAME})\s+({TYPE})\s*'
+COLUMN_ANNOTATION_PATTERN = update_pattern(fr'^ ({NAME}) ({ANY_WORDS})')
+
+NAME_AND_TYPE_PATTERN = update_pattern(fr' ({NAME})\s+({TYPE}) ')
ARG_ANNOTATION_PATTERN = fr'\s*{NAME_AND_TYPE_PATTERN}\s+({ANY_WORDS})'
-FUNCTION_RETURN_PATTERN = fr'^\s*({TYPE})\s+({ANY_WORDS})'
+ARG_DEFINITION_PATTERN = update_pattern(NEW_STYLE_ARG)
+
+FUNCTION_RETURN_PATTERN = update_pattern(fr'^ ({TYPE})\s+({ANY_WORDS})')
+
+ANY_PATTERN = r'(?:\s|.)*'
class ObjKind(str, Enum):
@@ -82,7 +96,9 @@
# Given a regex pattern and a string to match against, returns all the
# matching positions. Specifically, it returns a dictionary from the line
# number of the match to the regex match object.
-def match_pattern(pattern: str, file_str: str) -> Dict[int, re.Match]:
+# Note: this resuts a dict[int, re.Match], but re.Match exists only in later
+# versions of python3, prior to that it was _sre.SRE_Match.
+def match_pattern(pattern: str, file_str: str) -> Dict[int, object]:
line_number_to_matches = {}
for match in re.finditer(pattern, file_str, re.MULTILINE):
line_id = file_str[:match.start()].count('\n')
diff --git a/python/perfetto/trace_processor/metrics.descriptor b/python/perfetto/trace_processor/metrics.descriptor
index 926dee9..b989e77 100644
--- a/python/perfetto/trace_processor/metrics.descriptor
+++ b/python/perfetto/trace_processor/metrics.descriptor
Binary files differ
diff --git a/python/perfetto/trace_processor/trace_processor.descriptor b/python/perfetto/trace_processor/trace_processor.descriptor
index 33ca764..8b8383f 100644
--- a/python/perfetto/trace_processor/trace_processor.descriptor
+++ b/python/perfetto/trace_processor/trace_processor.descriptor
Binary files differ
diff --git a/python/test/stdlib_unittest.py b/python/test/stdlib_unittest.py
index 93f68b5..0a19caf 100644
--- a/python/test/stdlib_unittest.py
+++ b/python/test/stdlib_unittest.py
@@ -20,30 +20,7 @@
os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
sys.path.append(os.path.join(ROOT_DIR))
-from python.generators.sql_processing.docs_parse import parse_file
-
-DESC = """--
--- First line.
--- Second line."""
-
-COLS_STR = """--
--- @column slice_id Id of slice.
--- @column slice_name Name of slice."""
-
-COLS_SQL_STR = "slice_id INT, slice_name STRING"
-
-ARGS_STR = """--
--- @arg utid INT Utid of thread.
--- @arg name STRING String name."""
-
-ARGS_SQL_STR = "utid INT, name STRING"
-
-RET_STR = """--
--- @ret BOOL Exists."""
-
-RET_SQL_STR = "BOOL"
-
-SQL_STR = "SELECT * FROM slice"
+from python.generators.sql_processing.docs_parse import Arg, parse_file
class TestStdlib(unittest.TestCase):
@@ -51,10 +28,12 @@
def test_valid_table(self):
res = parse_file(
'foo/bar.sql', f'''
-{DESC}
-{COLS_STR}
+-- First line.
+-- Second line.
+-- @column slice_id Id of slice.
+-- @column slice_name Name of slice.
CREATE TABLE foo_table AS
-{SQL_STR};
+SELECT 1;
'''.strip())
self.assertListEqual(res.errors, [])
@@ -62,21 +41,24 @@
self.assertEqual(table.name, 'foo_table')
self.assertEqual(table.desc, 'First line. Second line.')
self.assertEqual(table.type, 'TABLE')
- self.assertEqual(table.cols, {
- 'slice_id': 'Id of slice.',
- 'slice_name': 'Name of slice.'
- })
+ self.assertEqual(
+ table.cols, {
+ 'slice_id': Arg(None, 'Id of slice.'),
+ 'slice_name': Arg(None, 'Name of slice.'),
+ })
def test_valid_function(self):
res = parse_file(
'foo/bar.sql', f'''
-{DESC}
-{ARGS_STR}
-{RET_STR}
-CREATE PERFETTO FUNCTION foo_fn({ARGS_SQL_STR})
-RETURNS {RET_SQL_STR}
+-- First line.
+-- Second line.
+-- @arg utid INT Utid of thread.
+-- @arg name STRING String name.
+-- @ret BOOL Exists.
+CREATE PERFETTO FUNCTION foo_fn(utid INT, name STRING)
+RETURNS BOOL
AS
-{SQL_STR};
+SELECT 1;
'''.strip())
self.assertListEqual(res.errors, [])
@@ -85,14 +67,8 @@
self.assertEqual(fn.desc, 'First line. Second line.')
self.assertEqual(
fn.args, {
- 'utid': {
- 'type': 'INT',
- 'desc': 'Utid of thread.',
- },
- 'name': {
- 'type': 'STRING',
- 'desc': 'String name.',
- },
+ 'utid': Arg('INT', 'Utid of thread.'),
+ 'name': Arg('STRING', 'String name.'),
})
self.assertEqual(fn.return_type, 'BOOL')
self.assertEqual(fn.return_desc, 'Exists.')
@@ -100,41 +76,38 @@
def test_valid_table_function(self):
res = parse_file(
'foo/bar.sql', f'''
-{DESC}
-{ARGS_STR}
-{COLS_STR}
-CREATE PERFETTO FUNCTION foo_view_fn({ARGS_SQL_STR})
-RETURNS TABLE({COLS_SQL_STR})
-AS {SQL_STR};
+-- Table comment.
+-- @arg utid INT Utid of thread.
+-- @arg name STRING String name.
+-- @column slice_id Id of slice.
+-- @column slice_name Name of slice.
+CREATE PERFETTO FUNCTION foo_view_fn(utid INT, name STRING)
+RETURNS TABLE(slice_id INT, slice_name STRING)
+AS SELECT 1;
'''.strip())
self.assertListEqual(res.errors, [])
fn = res.table_functions[0]
self.assertEqual(fn.name, 'foo_view_fn')
- self.assertEqual(fn.desc, 'First line. Second line.')
+ self.assertEqual(fn.desc, 'Table comment.')
self.assertEqual(
fn.args, {
- 'utid': {
- 'type': 'INT',
- 'desc': 'Utid of thread.',
- },
- 'name': {
- 'type': 'STRING',
- 'desc': 'String name.',
- },
+ 'utid': Arg('INT', 'Utid of thread.'),
+ 'name': Arg('STRING', 'String name.'),
})
- self.assertEqual(fn.cols, {
- 'slice_id': 'Id of slice.',
- 'slice_name': 'Name of slice.'
- })
+ self.assertEqual(
+ fn.cols, {
+ 'slice_id': Arg('INT', 'Id of slice.'),
+ 'slice_name': Arg('STRING', 'Name of slice.'),
+ })
def test_missing_module_name(self):
res = parse_file(
'foo/bar.sql', f'''
-{DESC}
-{COLS_STR}
+-- Comment
+-- @column slice_id Id of slice.
CREATE TABLE bar_table AS
-{SQL_STR};
+SELECT 1;
'''.strip())
# Expecting an error: function prefix (bar) not matching module name (foo).
self.assertEqual(len(res.errors), 1)
@@ -142,10 +115,10 @@
def test_common_does_not_include_module_name(self):
res = parse_file(
'common/bar.sql', f'''
-{DESC}
-{COLS_STR}
+-- Comment.
+-- @column slice_id Id of slice.
CREATE TABLE common_table AS
-{SQL_STR};
+SELECT 1;
'''.strip())
# Expecting an error: functions in common/ should not have a module prefix.
self.assertEqual(len(res.errors), 1)
@@ -153,12 +126,12 @@
def test_cols_typo(self):
res = parse_file(
'foo/bar.sql', f'''
-{DESC}
+-- Comment.
--
-- @column slice_id2 Foo.
-- @column slice_name Bar.
CREATE TABLE bar_table AS
-{SQL_STR};
+SELECT 1;
'''.strip())
# Expecting an error: column slice_id2 not found in the table.
self.assertEqual(len(res.errors), 1)
@@ -166,12 +139,12 @@
def test_cols_no_desc(self):
res = parse_file(
'foo/bar.sql', f'''
-{DESC}
+-- Comment.
--
-- @column slice_id
-- @column slice_name Bar.
CREATE TABLE bar_table AS
-{SQL_STR};
+SELECT 1;
'''.strip())
# Expecting an error: column slice_id is missing a description.
self.assertEqual(len(res.errors), 1)
@@ -179,15 +152,15 @@
def test_args_typo(self):
res = parse_file(
'foo/bar.sql', f'''
-{DESC}
+-- Comment.
--
-- @arg utid2 INT Uint.
-- @arg name STRING String name.
-{RET_STR}
-CREATE PERFETTO FUNCTION foo_fn({ARGS_SQL_STR})
-RETURNS {RET_SQL_STR}
+-- @ret BOOL Exists.
+CREATE PERFETTO FUNCTION foo_fn(utid INT, name STRING)
+RETURNS BOOL
AS
-{SQL_STR};
+SELECT 1;
'''.strip())
# Expecting 2 errors:
# - arg utid2 not found in the function (should be utid);
@@ -197,15 +170,15 @@
def test_args_no_desc(self):
res = parse_file(
'foo/bar.sql', f'''
-{DESC}
+-- Comment.
--
-- @arg utid INT
-- @arg name STRING String name.
-{RET_STR}
-CREATE PERFETTO FUNCTION foo_fn({ARGS_SQL_STR})
-RETURNS {RET_SQL_STR}
+-- @ret BOOL Exists.
+CREATE PERFETTO FUNCTION foo_fn(utid INT, name STRING)
+RETURNS BOOL
AS
-{SQL_STR};
+SELECT 1;
'''.strip())
# Expecting 2 errors:
# - arg utid is missing a description;
@@ -215,14 +188,13 @@
def test_ret_no_desc(self):
res = parse_file(
'foo/bar.sql', f'''
-{DESC}
-{ARGS_STR}
+-- Comment
--
-- @ret BOOL
-CREATE PERFETTO FUNCTION foo_fn({ARGS_SQL_STR})
-RETURNS {RET_SQL_STR}
+CREATE PERFETTO FUNCTION foo_fn()
+RETURNS BOOL
AS
-{SQL_STR};
+SELECT TRUE;
'''.strip())
# Expecting an error: return value is missing a description.
self.assertEqual(len(res.errors), 1)
@@ -239,12 +211,11 @@
-- long
--
-- description.
-{ARGS_STR}
-{RET_STR}
-CREATE PERFETTO FUNCTION foo_fn({ARGS_SQL_STR})
-RETURNS {RET_SQL_STR}
+-- @ret BOOL Exists.
+CREATE PERFETTO FUNCTION foo_fn()
+RETURNS BOOL
AS
-{SQL_STR};
+SELECT 1;
'''.strip())
self.assertListEqual(res.errors, [])
@@ -254,7 +225,7 @@
def test_multiline_arg_desc(self):
res = parse_file(
'foo/bar.sql', f'''
-{DESC}
+-- Comment.
--
-- @arg utid INT Uint
-- spread
@@ -263,37 +234,174 @@
-- @arg name STRING String name
-- which spans across multiple lines
-- inconsistently.
-{RET_STR}
-CREATE PERFETTO FUNCTION foo_fn({ARGS_SQL_STR})
-RETURNS {RET_SQL_STR}
+-- @ret BOOL Exists.
+CREATE PERFETTO FUNCTION foo_fn(utid INT, name STRING)
+RETURNS BOOL
AS
-{SQL_STR};
+SELECT 1;
'''.strip())
fn = res.functions[0]
self.assertEqual(
fn.args, {
- 'utid': {
- 'type': 'INT',
- 'desc': 'Uint spread across lines.',
- },
- 'name': {
- 'type': 'STRING',
- 'desc': 'String name which spans across multiple lines '
- 'inconsistently.',
- },
+ 'utid':
+ Arg('INT', 'Uint spread across lines.'),
+ 'name':
+ Arg(
+ 'STRING', 'String name which spans across multiple lines '
+ 'inconsistently.'),
})
def test_function_name_style(self):
res = parse_file(
'foo/bar.sql', f'''
-{DESC}
-{ARGS_STR}
-{RET_STR}
-CREATE PERFETTO FUNCTION foo_SnakeCase({ARGS_SQL_STR})
-RETURNS {RET_SQL_STR}
+-- Function comment.
+-- @ret BOOL Exists.
+CREATE PERFETTO FUNCTION foo_SnakeCase()
+RETURNS BOOL
AS
-{SQL_STR};
+SELECT 1;
'''.strip())
# Expecting an error: function name should be using hacker_style.
- self.assertEqual(len(res.errors), 1)
\ No newline at end of file
+ self.assertEqual(len(res.errors), 1)
+
+ def test_table_with_schema(self):
+ res = parse_file(
+ 'foo/bar.sql', f'''
+-- Table comment.
+CREATE PERFETTO TABLE foo_table(
+ -- Id of slice.
+ id INT
+) AS
+SELECT 1 as id;
+ '''.strip())
+ self.assertListEqual(res.errors, [])
+
+ table = res.table_views[0]
+ self.assertEqual(table.name, 'foo_table')
+ self.assertEqual(table.desc, 'Table comment.')
+ self.assertEqual(table.type, 'TABLE')
+ self.assertEqual(table.cols, {
+ 'id': Arg('INT', 'Id of slice.'),
+ })
+
+ def test_perfetto_view_with_schema(self):
+ res = parse_file(
+ 'foo/bar.sql', f'''
+-- View comment.
+CREATE PERFETTO VIEW foo_table(
+ -- Foo.
+ foo INT,
+ -- Bar.
+ bar STRING
+) AS
+SELECT 1;
+ '''.strip())
+ self.assertListEqual(res.errors, [])
+
+ table = res.table_views[0]
+ self.assertEqual(table.name, 'foo_table')
+ self.assertEqual(table.desc, 'View comment.')
+ self.assertEqual(table.type, 'VIEW')
+ self.assertEqual(table.cols, {
+ 'foo': Arg('INT', 'Foo.'),
+ 'bar': Arg('STRING', 'Bar.'),
+ })
+
+ def test_function_with_new_style_docs(self):
+ res = parse_file(
+ 'foo/bar.sql', f'''
+-- Function foo.
+-- @ret BOOL Exists.
+CREATE PERFETTO FUNCTION foo_fn(
+ -- Utid of thread.
+ utid INT,
+ -- String name.
+ name STRING)
+RETURNS BOOL
+AS
+SELECT 1;
+ '''.strip())
+ self.assertListEqual(res.errors, [])
+
+ fn = res.functions[0]
+ self.assertEqual(fn.name, 'foo_fn')
+ self.assertEqual(fn.desc, 'Function foo.')
+ self.assertEqual(
+ fn.args, {
+ 'utid': Arg('INT', 'Utid of thread.'),
+ 'name': Arg('STRING', 'String name.'),
+ })
+ self.assertEqual(fn.return_type, 'BOOL')
+ self.assertEqual(fn.return_desc, 'Exists.')
+
+ def test_function_with_new_style_docs_multiline_comment(self):
+ res = parse_file(
+ 'foo/bar.sql', f'''
+-- Function foo.
+-- @ret BOOL Exists.
+CREATE PERFETTO FUNCTION foo_fn(
+ -- Multi
+ -- line
+ --
+ -- comment.
+ arg INT)
+RETURNS BOOL
+AS
+SELECT 1;
+ '''.strip())
+ self.assertListEqual(res.errors, [])
+
+ fn = res.functions[0]
+ self.assertEqual(fn.name, 'foo_fn')
+ self.assertEqual(fn.desc, 'Function foo.')
+ self.assertEqual(fn.args, {
+ 'arg': Arg('INT', 'Multi line comment.'),
+ })
+ self.assertEqual(fn.return_type, 'BOOL')
+ self.assertEqual(fn.return_desc, 'Exists.')
+
+ def test_create_or_replace_table_banned(self):
+ res = parse_file(
+ 'common/bar.sql', f'''
+-- Table.
+CREATE OR REPLACE PERFETTO TABLE foo(
+ -- Column.
+ x INT,
+)
+RETURNS BOOL
+AS
+SELECT 1;
+
+ '''.strip())
+ # Expecting an error: CREATE OR REPLACE is not allowed in stdlib.
+ self.assertEqual(len(res.errors), 1)
+
+ def test_create_or_replace_view_banned(self):
+ res = parse_file(
+ 'common/bar.sql', f'''
+-- Table.
+CREATE OR REPLACE PERFETTO VIEW foo(
+ -- Column.
+ x INT,
+)
+RETURNS BOOL
+AS
+SELECT 1;
+
+ '''.strip())
+ # Expecting an error: CREATE OR REPLACE is not allowed in stdlib.
+ self.assertEqual(len(res.errors), 1)
+
+ def test_create_or_replace_function_banned(self):
+ res = parse_file(
+ 'foo/bar.sql', f'''
+-- Function foo.
+-- @ret BOOL Exists.
+CREATE OR REPLACE PERFETTO FUNCTION foo_fn()
+RETURNS BOOL
+AS
+SELECT 1;
+ '''.strip())
+ # Expecting an error: CREATE OR REPLACE is not allowed in stdlib.
+ self.assertEqual(len(res.errors), 1)
diff --git a/python/tools/check_imports.py b/python/tools/check_imports.py
index ef4ff29..dd096fb 100755
--- a/python/tools/check_imports.py
+++ b/python/tools/check_imports.py
@@ -37,6 +37,91 @@
os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
UI_SRC_DIR = os.path.join(ROOT_DIR, 'ui', 'src')
+# Current plan for the dependency tree of the UI code (2023-09-21)
+# black = current
+# red = planning to remove
+# green = planning to add
+PLAN_DOT = """
+digraph g {
+ mithril [shape=rectangle, label="mithril"];
+ protos [shape=rectangle, label="//protos/perfetto"];
+
+ _gen [shape=ellipse, label="/gen"];
+ _base [shape=ellipse, label="/base"];
+ _core [shape=ellipse, label="/core"];
+ _engine [shape=ellipse, label="/engine"];
+
+ _frontend [shape=ellipse, label="/frontend" color=red];
+ _common [shape=ellipse, label="/common" color=red];
+ _controller [shape=ellipse, label="/controller" color=red];
+ _tracks [shape=ellipse, label="/tracks" color=red];
+
+ _widgets [shape=ellipse, label="/widgets"];
+
+ _public [shape=ellipse, label="/public"];
+ _plugins [shape=ellipse, label="/plugins"];
+ _chrome_extension [shape=ellipse, label="/chrome_extension"];
+ _trace_processor [shape=ellipse, label="/trace_processor" color="green"];
+ _protos [shape=ellipse, label="/protos" color="green"];
+ engine_worker_bundle [shape=cds, label="Engine worker bundle"];
+ frontend_bundle [shape=cds, label="Frontend bundle"];
+
+ engine_worker_bundle -> _engine;
+ frontend_bundle -> _core [color=green];
+ frontend_bundle -> _frontend [color=red];
+
+ _core -> _public;
+ _plugins -> _public;
+
+ _widgets -> _base;
+ _core -> _base;
+ _core -> _widgets;
+
+
+ _widgets -> mithril;
+ _plugins -> mithril;
+ _core -> mithril
+
+ _plugins -> _widgets;
+
+ _core -> _chrome_extension;
+
+ _frontend -> _widgets [color=red];
+ _common -> _core [color=red];
+ _frontend -> _core [color=red];
+ _controller -> _core [color=red];
+
+ _frontend -> _controller [color=red];
+ _frontend -> _common [color=red];
+ _controller -> _frontend [color=red];
+ _controller -> _common [color=red];
+ _common -> _controller [color=red];
+ _common -> _frontend [color=red];
+ _tracks -> _frontend [color=red];
+ _tracks -> _controller [color=red];
+ _common -> _chrome_extension [color=red];
+
+ _core -> _trace_processor [color=green];
+
+ _engine -> _trace_processor [color=green];
+ _engine -> _common [color=red];
+ _engine -> _base;
+
+ _gen -> protos;
+ _core -> _gen [color=red];
+
+ _core -> _protos [color=green];
+ _protos -> _gen [color=green];
+ _trace_processor -> _protos [color=green];
+
+ _trace_processor -> _public [color=green];
+
+ npm_trace_processor [shape=cds, label="npm trace_processor" color="green"];
+ npm_trace_processor -> engine_worker_bundle [color="green"];
+ npm_trace_processor -> _trace_processor [color="green"];
+}
+"""
+
class Failure(object):
@@ -183,6 +268,23 @@
'chrome_extension must be a leaf',
),
+ # Widgets
+ NoDep(
+ r'/widgets/.*',
+ r'/frontend/.*',
+ 'widgets should only depend on base',
+ ),
+ NoDep(
+ r'/widgets/.*',
+ r'/core/.*',
+ 'widgets should only depend on base',
+ ),
+ NoDep(
+ r'/widgets/.*',
+ r'/plugins/.*',
+ 'widgets should only depend on base',
+ ),
+
# Fails at the moment as we have several circular dependencies. One
# example:
# ui/src/frontend/cookie_consent.ts
@@ -340,6 +442,11 @@
return 0
+def do_plan_dot(options, _):
+ print(PLAN_DOT, file=sys.stdout)
+ return 0
+
+
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.set_defaults(func=do_check)
@@ -371,6 +478,12 @@
help='Don\'t show external dependencies',
)
+ plan_dot_command = subparsers.add_parser(
+ 'plan-dot',
+ help='Output planned dependency graph in dot format suitble for use in graphviz (e.g. ./tools/check_imports plan-dot | dot -Tpng -ograph.png)'
+ )
+ plan_dot_command.set_defaults(func=do_plan_dot)
+
graph = collections.defaultdict(set)
for path in all_source_files():
for src, target in find_imports(path):
diff --git a/python/tools/heap_profile.py b/python/tools/heap_profile.py
index 06e7043..463f1b1 100644
--- a/python/tools/heap_profile.py
+++ b/python/tools/heap_profile.py
@@ -491,7 +491,7 @@
if binary_path is None:
binary_path = product_out_symbols
elif product_out_symbols is not None:
- binary_path += ":" + product_out_symbols
+ binary_path += os.pathsep + product_out_symbols
trace_file = os.path.join(profile_target, 'raw-trace')
concat_files = [trace_file]
diff --git a/src/base/paged_memory.cc b/src/base/paged_memory.cc
index 957a2dd..c009672 100644
--- a/src/base/paged_memory.cc
+++ b/src/base/paged_memory.cc
@@ -138,7 +138,6 @@
#if TRACK_COMMITTED_SIZE()
void PagedMemory::EnsureCommitted(size_t committed_size) {
- PERFETTO_DCHECK(committed_size > 0u);
PERFETTO_DCHECK(committed_size <= size_);
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
if (committed_size_ >= committed_size)
diff --git a/src/base/string_utils.cc b/src/base/string_utils.cc
index ba6e52b..bc32301 100644
--- a/src/base/string_utils.cc
+++ b/src/base/string_utils.cc
@@ -24,6 +24,8 @@
#if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
#include <xlocale.h>
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <windows.h>
#endif
#include <cinttypes>
@@ -217,6 +219,41 @@
return str;
}
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+bool WideToUTF8(const std::wstring& source, std::string& output) {
+ if (source.empty() ||
+ static_cast<int>(source.size()) > std::numeric_limits<int>::max()) {
+ return false;
+ }
+ int size = ::WideCharToMultiByte(CP_UTF8, 0, &source[0],
+ static_cast<int>(source.size()), nullptr, 0,
+ nullptr, nullptr);
+ output.assign(size, '\0');
+ if (::WideCharToMultiByte(CP_UTF8, 0, &source[0],
+ static_cast<int>(source.size()), &output[0], size,
+ nullptr, nullptr) != size) {
+ return false;
+ }
+ return true;
+}
+
+bool UTF8ToWide(const std::string& source, std::wstring& output) {
+ if (source.empty() ||
+ static_cast<int>(source.size()) > std::numeric_limits<int>::max()) {
+ return false;
+ }
+ int size = ::MultiByteToWideChar(CP_UTF8, 0, &source[0],
+ static_cast<int>(source.size()), nullptr, 0);
+ output.assign(size, L'\0');
+ if (::MultiByteToWideChar(CP_UTF8, 0, &source[0],
+ static_cast<int>(source.size()), &output[0],
+ size) != size) {
+ return false;
+ }
+ return true;
+}
+#endif // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
size_t SprintfTrunc(char* dst, size_t dst_size, const char* fmt, ...) {
if (PERFETTO_UNLIKELY(dst_size) == 0)
return 0;
diff --git a/src/base/string_utils_unittest.cc b/src/base/string_utils_unittest.cc
index f65da9f..0138bf1 100644
--- a/src/base/string_utils_unittest.cc
+++ b/src/base/string_utils_unittest.cc
@@ -96,6 +96,8 @@
TEST(StringUtilsTest, StringToInt32) {
EXPECT_EQ(StringToInt32("0"), std::make_optional<int32_t>(0));
EXPECT_EQ(StringToInt32("1"), std::make_optional<int32_t>(1));
+ EXPECT_EQ(StringToInt32("+42"), std::make_optional<int32_t>(42));
+ EXPECT_EQ(StringToInt32("+0042"), std::make_optional<int32_t>(42));
EXPECT_EQ(StringToInt32("-42"), std::make_optional<int32_t>(-42));
EXPECT_EQ(StringToInt32("42", 16), std::make_optional<int32_t>(0x42));
EXPECT_EQ(StringToInt32("7ffffffe", 16),
diff --git a/src/base/thread_utils.cc b/src/base/thread_utils.cc
index bc28f0f..f0c4e35 100644
--- a/src/base/thread_utils.cc
+++ b/src/base/thread_utils.cc
@@ -15,6 +15,7 @@
*/
#include "perfetto/base/thread_utils.h"
+#include "perfetto/ext/base/thread_utils.h"
#include "perfetto/base/build_config.h"
@@ -22,7 +23,9 @@
#include <zircon/process.h>
#include <zircon/syscalls.h>
#include <zircon/types.h>
-#endif // PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <windows.h>
+#endif
namespace perfetto {
namespace base {
@@ -39,6 +42,52 @@
thread_local static PlatformThreadId thread_id = ResolveThreadId();
return thread_id;
}
+
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+// The SetThreadDescription API was brought in version 1607 of Windows 10.
+typedef HRESULT(WINAPI* SetThreadDescription)(HANDLE hThread,
+ PCWSTR lpThreadDescription);
+
+// The SetThreadDescription API was brought in version 1607 of Windows 10.
+typedef HRESULT(WINAPI* GetThreadDescription)(HANDLE hThread,
+ PWSTR* ppszThreadDescription);
+
+bool MaybeSetThreadName(const std::string& name) {
+ // The SetThreadDescription API works even if no debugger is attached.
+ static auto set_thread_description_func =
+ reinterpret_cast<SetThreadDescription>(::GetProcAddress(
+ ::GetModuleHandle(L"Kernel32.dll"), "SetThreadDescription"));
+ if (!set_thread_description_func) {
+ return false;
+ }
+ std::wstring wide_thread_name;
+ if (!UTF8ToWide(name, wide_thread_name)) {
+ return false;
+ }
+ HRESULT result = set_thread_description_func(::GetCurrentThread(),
+ wide_thread_name.c_str());
+ return !FAILED(result);
+}
+
+bool GetThreadName(std::string& out_result) {
+ static auto get_thread_description_func =
+ reinterpret_cast<GetThreadDescription>(::GetProcAddress(
+ ::GetModuleHandle(L"Kernel32.dll"), "GetThreadDescription"));
+ if (!get_thread_description_func) {
+ return false;
+ }
+ wchar_t* wide_thread_name;
+ HRESULT result =
+ get_thread_description_func(::GetCurrentThread(), &wide_thread_name);
+ if (SUCCEEDED(result)) {
+ bool success = WideToUTF8(std::wstring(wide_thread_name), out_result);
+ LocalFree(wide_thread_name);
+ return success;
+ }
+ return false;
+}
+
#endif // PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
} // namespace base
diff --git a/src/base/time.cc b/src/base/time.cc
index a02c9d6..1507916 100644
--- a/src/base/time.cc
+++ b/src/base/time.cc
@@ -18,6 +18,7 @@
#include "perfetto/base/build_config.h"
#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/string_utils.h"
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <Windows.h>
@@ -78,5 +79,17 @@
return buf;
}
+std::optional<int32_t> GetTimezoneOffsetMins() {
+ std::string tz = GetTimeFmt("%z");
+ if (tz.size() != 5 || (tz[0] != '+' && tz[0] != '-'))
+ return std::nullopt;
+ char sign = '\0';
+ int32_t hh = 0;
+ int32_t mm = 0;
+ if (sscanf(tz.c_str(), "%c%2d%2d", &sign, &hh, &mm) != 3)
+ return std::nullopt;
+ return (hh * 60 + mm) * (sign == '-' ? -1 : 1);
+}
+
} // namespace base
} // namespace perfetto
diff --git a/src/base/time_unittest.cc b/src/base/time_unittest.cc
index 62c8566..a5b9d78 100644
--- a/src/base/time_unittest.cc
+++ b/src/base/time_unittest.cc
@@ -16,6 +16,7 @@
#include "perfetto/base/time.h"
+#include "perfetto/ext/base/utils.h"
#include "test/gtest_and_gmock.h"
namespace perfetto {
@@ -72,6 +73,32 @@
EXPECT_LE(elapsed_cputime.count(), 50 * ns_in_ms);
}
+// This test can work only on Posix platforms which respect the TZ env var.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+ PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+ PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+TEST(TimeTest, GetTimezoneOffsetMins) {
+ const char* tz = getenv("TZ");
+ std::string tz_save(tz ? tz : "");
+ auto reset_tz_on_exit = OnScopeExit([&] {
+ if (!tz_save.empty())
+ base::SetEnv("TZ", tz_save.c_str());
+ });
+
+ // Note: the sign is reversed in the semantic of the TZ env var.
+ // UTC+2 means "2 hours to reach UTC", not "2 hours ahead of UTC".
+
+ base::SetEnv("TZ", "UTC+2");
+ EXPECT_EQ(GetTimezoneOffsetMins(), -2 * 60);
+
+ base::SetEnv("TZ", "UTC-2");
+ EXPECT_EQ(GetTimezoneOffsetMins(), 2 * 60);
+
+ base::SetEnv("TZ", "UTC-07:45");
+ EXPECT_EQ(GetTimezoneOffsetMins(), 7 * 60 + 45);
+}
+#endif
+
} // namespace
} // namespace base
} // namespace perfetto
diff --git a/src/perfetto_cmd/perfetto_cmd.cc b/src/perfetto_cmd/perfetto_cmd.cc
index 2ddbf04..323d7bc 100644
--- a/src/perfetto_cmd/perfetto_cmd.cc
+++ b/src/perfetto_cmd/perfetto_cmd.cc
@@ -236,8 +236,9 @@
(e.g., file.0, file.1, file.2).
--txt : Parse config as pbtxt. Not for production use.
Not a stable API.
- --query : Queries the service state and prints it as
- human-readable text.
+ --query [--long] : Queries the service state and prints it as
+ human-readable text. --long allows the output to
+ extend past 80 chars.
--query-raw : Like --query, but prints raw proto-encoded bytes
of tracing_service_state.proto.
--help -h
@@ -298,6 +299,7 @@
OPT_IS_DETACHED,
OPT_STOP,
OPT_QUERY,
+ OPT_LONG,
OPT_QUERY_RAW,
OPT_VERSION,
};
@@ -326,6 +328,7 @@
{"is_detached", required_argument, nullptr, OPT_IS_DETACHED},
{"stop", no_argument, nullptr, OPT_STOP},
{"query", no_argument, nullptr, OPT_QUERY},
+ {"long", no_argument, nullptr, OPT_LONG},
{"query-raw", no_argument, nullptr, OPT_QUERY_RAW},
{"version", no_argument, nullptr, OPT_VERSION},
{"save-for-bugreport", no_argument, nullptr, OPT_BUGREPORT},
@@ -520,6 +523,11 @@
continue;
}
+ if (option == OPT_LONG) {
+ query_service_long_ = true;
+ continue;
+ }
+
if (option == OPT_QUERY_RAW) {
query_service_ = true;
query_service_output_raw_ = true;
@@ -550,6 +558,11 @@
return 1;
}
+ if (query_service_long_ && !query_service_) {
+ PERFETTO_ELOG("--long can only be used with --query");
+ return 1;
+ }
+
if (is_detach() && is_attach()) {
PERFETTO_ELOG("--attach and --detach are mutually exclusive");
return 1;
@@ -1396,15 +1409,17 @@
}
}
- printf("%-40s %-40s ", ds.ds_descriptor().name().c_str(),
+ printf("%-40s %-28s ", ds.ds_descriptor().name().c_str(),
producer_id_and_name);
// Print the category names for clients using the track event SDK.
+ std::string cats;
if (!ds.ds_descriptor().track_event_descriptor_raw().empty()) {
const std::string& raw = ds.ds_descriptor().track_event_descriptor_raw();
protos::gen::TrackEventDescriptor desc;
if (desc.ParseFromArray(raw.data(), raw.size())) {
for (const auto& cat : desc.available_categories()) {
- printf("%s,", cat.name().c_str());
+ cats.append(cats.empty() ? "" : ",");
+ cats.append(cat.name());
}
}
} else if (!ds.ds_descriptor().ftrace_descriptor_raw().empty()) {
@@ -1412,11 +1427,17 @@
protos::gen::FtraceDescriptor desc;
if (desc.ParseFromArray(raw.data(), raw.size())) {
for (const auto& cat : desc.atrace_categories()) {
- printf("%s,", cat.name().c_str());
+ cats.append(cats.empty() ? "" : ",");
+ cats.append(cat.name());
}
}
}
- printf("\n");
+ const size_t kCatsShortLen = 40;
+ if (!query_service_long_ && cats.length() > kCatsShortLen) {
+ cats = cats.substr(0, kCatsShortLen);
+ cats.append("... (use --long to expand)");
+ }
+ printf("%s\n", cats.c_str());
} // for data_sources()
if (svc_state.supports_tracing_sessions()) {
diff --git a/src/perfetto_cmd/perfetto_cmd.h b/src/perfetto_cmd/perfetto_cmd.h
index b55cbc8..7ac090f 100644
--- a/src/perfetto_cmd/perfetto_cmd.h
+++ b/src/perfetto_cmd/perfetto_cmd.h
@@ -153,6 +153,7 @@
bool redetach_once_attached_ = false;
bool query_service_ = false;
bool query_service_output_raw_ = false;
+ bool query_service_long_ = false;
bool bugreport_ = false;
bool background_ = false;
bool background_wait_ = false;
diff --git a/src/profiling/symbolizer/symbolize_database.cc b/src/profiling/symbolizer/symbolize_database.cc
index 36c0e0d..224874b 100644
--- a/src/profiling/symbolizer/symbolize_database.cc
+++ b/src/profiling/symbolizer/symbolize_database.cc
@@ -148,8 +148,14 @@
std::vector<std::string> GetPerfettoBinaryPath() {
const char* root = getenv("PERFETTO_BINARY_PATH");
- if (root != nullptr)
- return base::SplitString(root, ":");
+ if (root != nullptr) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+ const char* delimiter = ";";
+#else
+ const char* delimiter = ":";
+#endif
+ return base::SplitString(root, delimiter);
+ }
return {};
}
diff --git a/src/protozero/protoc_plugin/protozero_plugin.cc b/src/protozero/protoc_plugin/protozero_plugin.cc
index 55c3c9d..e4c691f 100644
--- a/src/protozero/protoc_plugin/protozero_plugin.cc
+++ b/src/protozero/protoc_plugin/protozero_plugin.cc
@@ -108,6 +108,8 @@
void SetOption(const std::string& name, const std::string& value) {
if (name == "wrapper_namespace") {
wrapper_namespace_ = value;
+ } else if (name == "sdk") {
+ sdk_mode_ = (value == "true" || value == "1");
} else {
Abort(std::string() + "Unknown plugin option '" + name + "'.");
}
@@ -468,27 +470,37 @@
"#ifndef $guard$\n"
"#define $guard$\n\n"
"#include <stddef.h>\n"
- "#include <stdint.h>\n\n"
- "#include \"perfetto/protozero/field_writer.h\"\n"
- "#include \"perfetto/protozero/message.h\"\n"
- "#include \"perfetto/protozero/packed_repeated_fields.h\"\n"
- "#include \"perfetto/protozero/proto_decoder.h\"\n"
- "#include \"perfetto/protozero/proto_utils.h\"\n",
+ "#include <stdint.h>\n\n",
"greeting", greeting, "guard", guard);
- // Print includes for public imports.
- for (const FileDescriptor* dependency : public_imports_) {
- // Dependency name could contain slashes but importing from upper-level
- // directories is not possible anyway since build system processes each
- // proto file individually. Hence proto lookup path is always equal to the
- // directory where particular proto file is located and protoc does not
- // allow reference to upper directory (aka ..) in import path.
- //
- // Laconically said:
- // - source_->name() may never have slashes,
- // - dependency->name() may have slashes but always refers to inner path.
- stub_h_->Print("#include \"$name$.h\"\n", "name",
- ProtoStubName(dependency));
+ if (sdk_mode_) {
+ stub_h_->Print("#include \"perfetto.h\"\n");
+ } else {
+ stub_h_->Print(
+ "#include \"perfetto/protozero/field_writer.h\"\n"
+ "#include \"perfetto/protozero/message.h\"\n"
+ "#include \"perfetto/protozero/packed_repeated_fields.h\"\n"
+ "#include \"perfetto/protozero/proto_decoder.h\"\n"
+ "#include \"perfetto/protozero/proto_utils.h\"\n");
+ }
+
+ // Print includes for public imports. In sdk mode, all imports are assumed
+ // to be part of the sdk.
+ if (!sdk_mode_) {
+ for (const FileDescriptor* dependency : public_imports_) {
+ // Dependency name could contain slashes but importing from upper-level
+ // directories is not possible anyway since build system processes each
+ // proto file individually. Hence proto lookup path is always equal to
+ // the directory where particular proto file is located and protoc does
+ // not allow reference to upper directory (aka ..) in import path.
+ //
+ // Laconically said:
+ // - source_->name() may never have slashes,
+ // - dependency->name() may have slashes but always refers to inner
+ // path.
+ stub_h_->Print("#include \"$name$.h\"\n", "name",
+ ProtoStubName(dependency));
+ }
}
stub_h_->Print("\n");
@@ -1003,6 +1015,9 @@
std::vector<const EnumDescriptor*> enums_;
std::map<std::string, std::vector<const FieldDescriptor*>> extensions_;
+ // Generate headers that can be used with the Perfetto SDK.
+ bool sdk_mode_ = false;
+
// The custom *Comp comparators are to ensure determinism of the generator.
std::set<const FileDescriptor*, FileDescriptorComp> public_imports_;
std::set<const FileDescriptor*, FileDescriptorComp> private_imports_;
diff --git a/src/trace_processor/db/query_executor.cc b/src/trace_processor/db/query_executor.cc
index 9193349..b83118d 100644
--- a/src/trace_processor/db/query_executor.cc
+++ b/src/trace_processor/db/query_executor.cc
@@ -28,6 +28,7 @@
#include "src/trace_processor/db/overlays/storage_overlay.h"
#include "src/trace_processor/db/overlays/types.h"
#include "src/trace_processor/db/query_executor.h"
+#include "src/trace_processor/db/storage/dummy_storage.h"
#include "src/trace_processor/db/storage/id_storage.h"
#include "src/trace_processor/db/storage/numeric_storage.h"
#include "src/trace_processor/db/storage/string_storage.h"
@@ -282,9 +283,6 @@
use_legacy =
use_legacy || (col.IsSorted() && col.col_type() == ColumnType::kString);
- // Column types
- use_legacy = use_legacy || col.col_type() == ColumnType::kDummy;
-
// Mismatched types
use_legacy = use_legacy || (overlays::FilterOpToOverlayOp(c.op) ==
overlays::OverlayOp::kOther &&
@@ -311,17 +309,26 @@
// Create storage
std::unique_ptr<Storage> storage;
- if (col.IsId()) {
- storage.reset(new storage::IdStorage(column_size));
- } else if (col.col_type() == ColumnType::kString) {
- storage.reset(new storage::StringStorage(
- table->string_pool(),
- static_cast<const StringPool::Id*>(col.storage_base().data()),
- col.storage_base().non_null_size()));
- } else {
- storage.reset(new storage::NumericStorage(
- col.storage_base().data(), col.storage_base().non_null_size(),
- col.col_type(), col.IsSorted()));
+ switch (col.col_type()) {
+ case ColumnType::kDummy:
+ storage.reset(new storage::DummyStorage());
+ break;
+ case ColumnType::kId:
+ storage.reset(new storage::IdStorage(column_size));
+ break;
+ case ColumnType::kString:
+ storage.reset(new storage::StringStorage(
+ table->string_pool(),
+ static_cast<const StringPool::Id*>(col.storage_base().data()),
+ col.storage_base().non_null_size()));
+ break;
+ case ColumnType::kInt64:
+ case ColumnType::kUint32:
+ case ColumnType::kInt32:
+ case ColumnType::kDouble:
+ storage.reset(new storage::NumericStorage(
+ col.storage_base().data(), col.storage_base().non_null_size(),
+ col.col_type(), col.IsSorted()));
}
s_col.storage = storage.get();
diff --git a/src/trace_processor/db/storage/BUILD.gn b/src/trace_processor/db/storage/BUILD.gn
index f27c9db..152cb71 100644
--- a/src/trace_processor/db/storage/BUILD.gn
+++ b/src/trace_processor/db/storage/BUILD.gn
@@ -16,6 +16,8 @@
source_set("storage") {
sources = [
+ "dummy_storage.cc",
+ "dummy_storage.h",
"id_storage.cc",
"id_storage.h",
"numeric_storage.cc",
diff --git a/src/trace_processor/db/storage/dummy_storage.cc b/src/trace_processor/db/storage/dummy_storage.cc
new file mode 100644
index 0000000..a65a9ae
--- /dev/null
+++ b/src/trace_processor/db/storage/dummy_storage.cc
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+#include "src/trace_processor/db/storage/dummy_storage.h"
+
+namespace perfetto {
+namespace trace_processor {
+namespace storage {
+
+RangeOrBitVector DummyStorage::Search(FilterOp, SqlValue, RowMap::Range) const {
+ PERFETTO_FATAL("Shouldn't be called");
+}
+
+RangeOrBitVector DummyStorage::IndexSearch(FilterOp,
+ SqlValue,
+ uint32_t*,
+ uint32_t,
+ bool) const {
+ PERFETTO_FATAL("Shouldn't be called");
+}
+
+void DummyStorage::StableSort(uint32_t*, uint32_t) const {
+ PERFETTO_FATAL("Shouldn't be called");
+}
+
+void DummyStorage::Sort(uint32_t*, uint32_t) const {
+ PERFETTO_FATAL("Shouldn't be called");
+}
+
+uint32_t DummyStorage::size() const {
+ return 0;
+}
+
+} // namespace storage
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/db/storage/dummy_storage.h b/src/trace_processor/db/storage/dummy_storage.h
new file mode 100644
index 0000000..511383d
--- /dev/null
+++ b/src/trace_processor/db/storage/dummy_storage.h
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+#ifndef SRC_TRACE_PROCESSOR_DB_STORAGE_DUMMY_STORAGE_H_
+#define SRC_TRACE_PROCESSOR_DB_STORAGE_DUMMY_STORAGE_H_
+
+#include <variant>
+
+#include "perfetto/base/logging.h"
+#include "src/trace_processor/containers/row_map.h"
+#include "src/trace_processor/db/storage/storage.h"
+#include "src/trace_processor/db/storage/types.h"
+
+namespace perfetto {
+namespace trace_processor {
+namespace storage {
+
+// Dummy storage. Used for columns that are not supposed to have operations done
+// on them.
+class DummyStorage final : public Storage {
+ public:
+ DummyStorage() = default;
+
+ RangeOrBitVector Search(FilterOp, SqlValue, RowMap::Range) const override;
+
+ RangeOrBitVector IndexSearch(FilterOp,
+ SqlValue,
+ uint32_t*,
+ uint32_t,
+ bool) const override;
+
+ void StableSort(uint32_t*, uint32_t) const override;
+
+ void Sort(uint32_t*, uint32_t) const override;
+
+ uint32_t size() const override;
+};
+
+} // namespace storage
+} // namespace trace_processor
+} // namespace perfetto
+#endif // SRC_TRACE_PROCESSOR_DB_STORAGE_DUMMY_STORAGE_H_
diff --git a/src/trace_processor/db/storage/numeric_storage.cc b/src/trace_processor/db/storage/numeric_storage.cc
index 31f1245..50452ae 100644
--- a/src/trace_processor/db/storage/numeric_storage.cc
+++ b/src/trace_processor/db/storage/numeric_storage.cc
@@ -200,26 +200,6 @@
RangeOrBitVector NumericStorage::Search(FilterOp op,
SqlValue value,
RowMap::Range range) const {
- if (is_sorted_)
- return RangeOrBitVector(BinarySearchIntrinsic(op, value, range));
- return RangeOrBitVector(LinearSearch(op, value, range));
-}
-
-RangeOrBitVector NumericStorage::IndexSearch(FilterOp op,
- SqlValue value,
- uint32_t* indices,
- uint32_t indices_count,
- bool sorted) const {
- if (sorted) {
- return RangeOrBitVector(
- BinarySearchExtrinsic(op, value, indices, indices_count));
- }
- return RangeOrBitVector(IndexSearch(op, value, indices, indices_count));
-}
-
-BitVector NumericStorage::LinearSearch(FilterOp op,
- SqlValue sql_val,
- RowMap::Range range) const {
PERFETTO_TP_TRACE(metatrace::Category::DB, "NumericStorage::LinearSearch",
[&range, op](metatrace::Record* r) {
r->AddArg("Start", std::to_string(range.start));
@@ -227,7 +207,33 @@
r->AddArg("Op",
std::to_string(static_cast<uint32_t>(op)));
});
+ if (is_sorted_)
+ return RangeOrBitVector(BinarySearchIntrinsic(op, value, range));
+ return RangeOrBitVector(LinearSearchInternal(op, value, range));
+}
+RangeOrBitVector NumericStorage::IndexSearch(FilterOp op,
+ SqlValue value,
+ uint32_t* indices,
+ uint32_t indices_count,
+ bool sorted) const {
+ PERFETTO_TP_TRACE(metatrace::Category::DB, "NumericStorage::IndexSearch",
+ [indices_count, op](metatrace::Record* r) {
+ r->AddArg("Count", std::to_string(indices_count));
+ r->AddArg("Op",
+ std::to_string(static_cast<uint32_t>(op)));
+ });
+ if (sorted) {
+ return RangeOrBitVector(
+ BinarySearchExtrinsic(op, value, indices, indices_count));
+ }
+ return RangeOrBitVector(
+ IndexSearchInternal(op, value, indices, indices_count));
+}
+
+BitVector NumericStorage::LinearSearchInternal(FilterOp op,
+ SqlValue sql_val,
+ RowMap::Range range) const {
std::optional<NumericValue> val = GetNumericTypeVariant(type_, sql_val);
if (op == FilterOp::kIsNotNull)
return BitVector(size(), true);
@@ -254,17 +260,10 @@
return std::move(builder).Build();
}
-BitVector NumericStorage::IndexSearch(FilterOp op,
- SqlValue sql_val,
- uint32_t* indices,
- uint32_t indices_count) const {
- PERFETTO_TP_TRACE(metatrace::Category::DB, "NumericStorage::IndexSearch",
- [indices_count, op](metatrace::Record* r) {
- r->AddArg("Count", std::to_string(indices_count));
- r->AddArg("Op",
- std::to_string(static_cast<uint32_t>(op)));
- });
-
+BitVector NumericStorage::IndexSearchInternal(FilterOp op,
+ SqlValue sql_val,
+ uint32_t* indices,
+ uint32_t indices_count) const {
std::optional<NumericValue> val = GetNumericTypeVariant(type_, sql_val);
if (op == FilterOp::kIsNotNull)
return BitVector(indices_count, true);
diff --git a/src/trace_processor/db/storage/numeric_storage.h b/src/trace_processor/db/storage/numeric_storage.h
index a746142..c67fe0e 100644
--- a/src/trace_processor/db/storage/numeric_storage.h
+++ b/src/trace_processor/db/storage/numeric_storage.h
@@ -51,12 +51,14 @@
uint32_t size() const override { return size_; }
private:
- BitVector LinearSearch(FilterOp op, SqlValue val, RowMap::Range) const;
+ BitVector LinearSearchInternal(FilterOp op,
+ SqlValue val,
+ RowMap::Range) const;
- BitVector IndexSearch(FilterOp op,
- SqlValue value,
- uint32_t* indices,
- uint32_t indices_count) const;
+ BitVector IndexSearchInternal(FilterOp op,
+ SqlValue value,
+ uint32_t* indices,
+ uint32_t indices_count) const;
RowMap::Range BinarySearchIntrinsic(FilterOp op,
SqlValue val,
@@ -66,6 +68,7 @@
SqlValue val,
uint32_t* indices,
uint32_t indices_count) const;
+
const ColumnType type_ = ColumnType::kDummy;
const void* data_ = nullptr;
const uint32_t size_ = 0;
diff --git a/src/trace_processor/importers/common/trace_parser.cc b/src/trace_processor/importers/common/trace_parser.cc
index d075a57..6c586e0 100644
--- a/src/trace_processor/importers/common/trace_parser.cc
+++ b/src/trace_processor/importers/common/trace_parser.cc
@@ -16,6 +16,7 @@
#include "src/trace_processor/importers/common/trace_parser.h"
+#include "perfetto/trace_processor/trace_blob_view.h"
#include "src/trace_processor/importers/common/parser_types.h"
#include "src/trace_processor/importers/fuchsia/fuchsia_record.h"
#include "src/trace_processor/importers/systrace/systrace_line.h"
@@ -23,6 +24,9 @@
namespace perfetto {
namespace trace_processor {
+void TraceParser::ParseTraceBlobView(int64_t, TraceBlobView) {
+ PERFETTO_FATAL("Wrong parser type");
+}
void TraceParser::ParseTracePacket(int64_t, TracePacketData) {
PERFETTO_FATAL("Wrong parser type");
}
diff --git a/src/trace_processor/importers/common/trace_parser.h b/src/trace_processor/importers/common/trace_parser.h
index 7766ef3..d948d27 100644
--- a/src/trace_processor/importers/common/trace_parser.h
+++ b/src/trace_processor/importers/common/trace_parser.h
@@ -24,6 +24,7 @@
namespace trace_processor {
class PacketSequenceStateGeneration;
+class TraceBlobView;
struct InlineSchedSwitch;
class FuchsiaRecord;
struct SystraceLine;
@@ -35,6 +36,7 @@
public:
virtual ~TraceParser();
+ virtual void ParseTraceBlobView(int64_t, TraceBlobView);
virtual void ParseTracePacket(int64_t, TracePacketData);
virtual void ParseJsonPacket(int64_t, std::string);
virtual void ParseFuchsiaRecord(int64_t, FuchsiaRecord);
diff --git a/src/trace_processor/importers/proto/proto_trace_reader.cc b/src/trace_processor/importers/proto/proto_trace_reader.cc
index 003f06c..8add6f0 100644
--- a/src/trace_processor/importers/proto/proto_trace_reader.cc
+++ b/src/trace_processor/importers/proto/proto_trace_reader.cc
@@ -447,6 +447,8 @@
metadata::all_data_source_started_ns, Variadic::Integer(ts));
}
if (tse.all_data_sources_flushed()) {
+ context_->metadata_tracker->AppendMetadata(
+ metadata::all_data_source_flushed_ns, Variadic::Integer(ts));
context_->sorter->NotifyFlushEvent();
}
if (tse.read_tracing_buffers_completed()) {
diff --git a/src/trace_processor/importers/proto/system_probes_parser.cc b/src/trace_processor/importers/proto/system_probes_parser.cc
index da6a2d2..aa46613 100644
--- a/src/trace_processor/importers/proto/system_probes_parser.cc
+++ b/src/trace_processor/importers/proto/system_probes_parser.cc
@@ -312,7 +312,7 @@
track = context_->track_tracker->InternCpuCounterTrack(
cpu_times_user_nice_ns_id_, ct.cpu_id());
context_->event_tracker->PushCounter(
- ts, static_cast<double>(ct.user_ice_ns()), track);
+ ts, static_cast<double>(ct.user_nice_ns()), track);
track = context_->track_tracker->InternCpuCounterTrack(
cpu_times_system_mode_ns_id_, ct.cpu_id());
@@ -603,6 +603,12 @@
Variadic::String(machine_id));
}
+ if (packet.has_timezone_off_mins()) {
+ context_->metadata_tracker->SetMetadata(
+ metadata::timezone_off_mins,
+ Variadic::Integer(packet.timezone_off_mins()));
+ }
+
if (packet.has_android_build_fingerprint()) {
context_->metadata_tracker->SetMetadata(
metadata::android_build_fingerprint,
diff --git a/src/trace_processor/metrics/sql/android/BUILD.gn b/src/trace_processor/metrics/sql/android/BUILD.gn
index 6c31943..a2e64da 100644
--- a/src/trace_processor/metrics/sql/android/BUILD.gn
+++ b/src/trace_processor/metrics/sql/android/BUILD.gn
@@ -20,6 +20,7 @@
perfetto_sql_source_set("android") {
sources = [
"android_anr.sql",
+ "ad_services_metric.sql",
"android_batt.sql",
"android_binder.sql",
"android_blocking_calls_cuj_metric.sql",
diff --git a/src/trace_processor/metrics/sql/android/ad_services_metric.sql b/src/trace_processor/metrics/sql/android/ad_services_metric.sql
new file mode 100644
index 0000000..36885fd
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/ad_services_metric.sql
@@ -0,0 +1,59 @@
+--
+-- Copyright 2023 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+CREATE OR REPLACE PERFETTO FUNCTION GET_EVENT_LATENCY_TABLE(event_name STRING)
+RETURNS TABLE (latency LONG) AS
+SELECT
+ dur / 1e6 as latency
+FROM
+ slices
+WHERE
+ name = $event_name;
+
+DROP VIEW IF EXISTS ad_services_metric_output;
+CREATE VIEW ad_services_metric_output AS
+SELECT
+ AdServicesMetric(
+ 'ui_metric',
+ (
+ SELECT
+ RepeatedField(
+ AdServicesUiMetric('latency', latency)
+ )
+ FROM
+ GET_EVENT_LATENCY_TABLE("NotificationTriggerEvent")
+ ),
+ 'app_set_id_metric',
+ (
+ SELECT
+ RepeatedField(
+ AdServicesAppSetIdMetric(
+ 'latency', latency
+ )
+ )
+ FROM
+ GET_EVENT_LATENCY_TABLE("AdIdCacheEvent")
+ ),
+ 'ad_id_metric',
+ (
+ SELECT
+ RepeatedField(
+ AdServicesAdIdMetric('latency', latency)
+ )
+ FROM
+ GET_EVENT_LATENCY_TABLE("AppSetIdEvent")
+ )
+);
diff --git a/src/trace_processor/metrics/sql/android/android_boot.sql b/src/trace_processor/metrics/sql/android/android_boot.sql
index 46caea8..4dc8936 100644
--- a/src/trace_processor/metrics/sql/android/android_boot.sql
+++ b/src/trace_processor/metrics/sql/android/android_boot.sql
@@ -47,5 +47,9 @@
SELECT NULL_IF_EMPTY(ProcessStateDurations(
'total_dur', total_dur,
'uninterruptible_sleep_dur', uint_sleep_dur))
- FROM get_durations('com.google.android.gms.persistent'))
+ FROM get_durations('com.google.android.gms.persistent')),
+ 'launcher_breakdown', (
+ SELECT NULL_IF_EMPTY(AndroidBootMetric_LauncherBreakdown(
+ 'cold_start_dur', dur))
+ FROM slice where name="LauncherColdStartup")
);
diff --git a/src/trace_processor/metrics/sql/chrome/chrome_slice_names.sql b/src/trace_processor/metrics/sql/chrome/chrome_slice_names.sql
index 95ea995..3aa7167 100644
--- a/src/trace_processor/metrics/sql/chrome/chrome_slice_names.sql
+++ b/src/trace_processor/metrics/sql/chrome/chrome_slice_names.sql
@@ -27,6 +27,7 @@
'slice_name', (
SELECT RepeatedField(DISTINCT(name))
FROM slice
+ WHERE name IS NOT NULL
ORDER BY name
)
);
diff --git a/src/trace_processor/metrics/sql/chrome/gesture_jank.sql b/src/trace_processor/metrics/sql/chrome/gesture_jank.sql
index 06343ee..34674a8 100644
--- a/src/trace_processor/metrics/sql/chrome/gesture_jank.sql
+++ b/src/trace_processor/metrics/sql/chrome/gesture_jank.sql
@@ -206,10 +206,10 @@
CREATE VIEW {{prefix}}_jank_maybe_null_prev_and_next AS
SELECT
*,
- is_janky_frame({{id_field}}, prev_{{id_field}},
+ internal_is_janky_frame({{id_field}}, prev_{{id_field}},
prev_ts, begin_ts, maybe_gesture_end,
gesture_frames_exact, prev_gesture_frames_exact) AS prev_jank,
- is_janky_frame({{id_field}}, next_{{id_field}},
+ internal_is_janky_frame({{id_field}}, next_{{id_field}},
next_ts, begin_ts, maybe_gesture_end,
gesture_frames_exact, next_gesture_frames_exact) AS next_jank
FROM {{prefix}}_jank_maybe_null_prev_and_next_without_precompute
@@ -233,7 +233,7 @@
(next_jank IS NOT NULL AND next_jank)
OR (prev_jank IS NOT NULL AND prev_jank)
AS jank,
- jank_budget(gesture_frames_exact, prev_gesture_frames_exact,
+ internal_jank_budget(gesture_frames_exact, prev_gesture_frames_exact,
next_gesture_frames_exact) * avg_vsync_interval AS jank_budget,
*
FROM {{prefix}}_jank_maybe_null_prev_and_next
diff --git a/src/trace_processor/metrics/sql/chrome/scroll_jank_cause_queuing_delay.sql b/src/trace_processor/metrics/sql/chrome/scroll_jank_cause_queuing_delay.sql
index 9257d84..6c246e8 100644
--- a/src/trace_processor/metrics/sql/chrome/scroll_jank_cause_queuing_delay.sql
+++ b/src/trace_processor/metrics/sql/chrome/scroll_jank_cause_queuing_delay.sql
@@ -357,6 +357,8 @@
"TabGroupUiToolbarView"
WHEN $name GLOB "*TabGridThumbnailView*" THEN
"TabGridThumbnailView"
+ WHEN $name GLOB "*TabThumbnailView" THEN
+ "TabThumbnailView"
WHEN $name GLOB "*TabGridDialogView*" THEN
"TabGridDialogView"
WHEN $name GLOB "*BottomContainer*" THEN
diff --git a/src/trace_processor/metrics/sql/trace_metadata.sql b/src/trace_processor/metrics/sql/trace_metadata.sql
index c3cdf88..317b7ab 100644
--- a/src/trace_processor/metrics/sql/trace_metadata.sql
+++ b/src/trace_processor/metrics/sql/trace_metadata.sql
@@ -57,5 +57,9 @@
),
'sched_duration_ns', (
SELECT MAX(ts) - MIN(ts) FROM sched
+ ),
+ 'tracing_started_ns', (
+ SELECT int_value FROM metadata
+ WHERE name='tracing_started_ns'
)
);
diff --git a/src/trace_processor/perfetto_sql/engine/created_function.cc b/src/trace_processor/perfetto_sql/engine/created_function.cc
index 3e88ada..162dbc6 100644
--- a/src/trace_processor/perfetto_sql/engine/created_function.cc
+++ b/src/trace_processor/perfetto_sql/engine/created_function.cc
@@ -37,7 +37,7 @@
base::Status CheckNoMoreRows(sqlite3_stmt* stmt,
sqlite3* db,
- const Prototype& prototype) {
+ const FunctionPrototype& prototype) {
int ret = sqlite3_step(stmt);
RETURN_IF_ERROR(SqliteRetToStatus(db, prototype.function_name, ret));
if (ret == SQLITE_ROW) {
@@ -54,9 +54,10 @@
// Note: if the returned type is string / bytes, it will be invalidated by the
// next call to SQLite, so the caller must take care to either copy or use the
// value before calling SQLite again.
-base::StatusOr<SqlValue> EvaluateScalarStatement(sqlite3_stmt* stmt,
- sqlite3* db,
- const Prototype& prototype) {
+base::StatusOr<SqlValue> EvaluateScalarStatement(
+ sqlite3_stmt* stmt,
+ sqlite3* db,
+ const FunctionPrototype& prototype) {
int ret = sqlite3_step(stmt);
RETURN_IF_ERROR(SqliteRetToStatus(db, prototype.function_name, ret));
if (ret == SQLITE_DONE) {
@@ -89,7 +90,7 @@
}
base::Status BindArguments(sqlite3_stmt* stmt,
- const Prototype& prototype,
+ const FunctionPrototype& prototype,
size_t argc,
sqlite3_value** argv) {
// Bind all the arguments to the appropriate places in the function.
@@ -162,7 +163,7 @@
// Enables memoization.
// Only functions with a single int argument returning ints are supported.
- base::Status EnableMemoization(const Prototype& prototype) {
+ base::Status EnableMemoization(const FunctionPrototype& prototype) {
if (prototype.arguments.size() != 1 ||
TypeToSqlValueType(prototype.arguments[0].type()) !=
SqlValue::Type::kLong) {
@@ -277,7 +278,7 @@
public:
RecursiveCallUnroller(PerfettoSqlEngine* engine,
sqlite3_stmt* stmt,
- const Prototype& prototype,
+ const FunctionPrototype& prototype,
Memoizer& memoizer)
: engine_(engine),
stmt_(stmt),
@@ -394,7 +395,7 @@
PerfettoSqlEngine* engine_;
sqlite3_stmt* stmt_;
- const Prototype& prototype_;
+ const FunctionPrototype& prototype_;
Memoizer& memoizer_;
// Current state of the evaluation.
@@ -441,8 +442,7 @@
// Sets the state of the function. Should be called only when the function
// is invalid (i.e. when it is first created or when the previous statement
// failed to prepare).
- void Reset(Prototype prototype,
- std::string prototype_str,
+ void Reset(FunctionPrototype prototype,
sql_argument::Type return_type,
SqlSource sql) {
// Re-registration of valid functions is not allowed.
@@ -450,7 +450,6 @@
PERFETTO_DCHECK(stmts_.empty());
prototype_ = std::move(prototype);
- prototype_str_ = std::move(prototype_str);
return_type_ = return_type;
sql_ = std::move(sql);
}
@@ -541,7 +540,7 @@
PerfettoSqlEngine* engine() const { return engine_; }
- const Prototype& prototype() const { return prototype_; }
+ const FunctionPrototype& prototype() const { return prototype_; }
sql_argument::Type return_type() const { return return_type_; }
@@ -553,8 +552,7 @@
private:
PerfettoSqlEngine* engine_;
- Prototype prototype_;
- std::string prototype_str_;
+ FunctionPrototype prototype_;
sql_argument::Type return_type_;
std::optional<SqlSource> sql_;
// Perfetto SQL functions support recursion. Given that each function call in
@@ -680,8 +678,7 @@
base::Status CreatedFunction::ValidateOrPrepare(CreatedFunction::Context* ctx,
bool replace,
- Prototype prototype,
- std::string prototype_str,
+ FunctionPrototype prototype,
sql_argument::Type return_type,
std::string return_type_str,
SqlSource source) {
@@ -694,25 +691,25 @@
if (state->prototype() != prototype) {
return base::ErrStatus(
"CREATE_FUNCTION[prototype=%s]: function prototype changed",
- prototype_str.c_str());
+ prototype.ToString().c_str());
}
if (state->return_type() != return_type) {
return base::ErrStatus(
"CREATE_FUNCTION[prototype=%s]: return type changed from %s to %s",
- prototype_str.c_str(),
+ prototype.ToString().c_str(),
sql_argument::TypeToHumanFriendlyString(state->return_type()),
return_type_str.c_str());
}
if (state->sql() != source.sql()) {
return base::ErrStatus(
"CREATE_FUNCTION[prototype=%s]: function SQL changed from %s to %s",
- prototype_str.c_str(), state->sql().c_str(), source.sql().c_str());
+ prototype.ToString().c_str(), state->sql().c_str(),
+ source.sql().c_str());
}
return base::OkStatus();
}
- state->Reset(std::move(prototype), std::move(prototype_str), return_type,
- std::move(source));
+ state->Reset(std::move(prototype), return_type, std::move(source));
// Ideally, we would unregister the function here if the statement prep
// failed, but SQLite doesn't allow unregistering functions inside active
diff --git a/src/trace_processor/perfetto_sql/engine/created_function.h b/src/trace_processor/perfetto_sql/engine/created_function.h
index 44e23de..743a5ad 100644
--- a/src/trace_processor/perfetto_sql/engine/created_function.h
+++ b/src/trace_processor/perfetto_sql/engine/created_function.h
@@ -52,8 +52,7 @@
static std::unique_ptr<Context> MakeContext(PerfettoSqlEngine*);
static base::Status ValidateOrPrepare(Context*,
bool replace,
- Prototype,
- std::string prototype_str,
+ FunctionPrototype,
sql_argument::Type return_type,
std::string return_type_str,
SqlSource sql);
diff --git a/src/trace_processor/perfetto_sql/engine/function_util.cc b/src/trace_processor/perfetto_sql/engine/function_util.cc
index dfba021..ae3edde 100644
--- a/src/trace_processor/perfetto_sql/engine/function_util.cc
+++ b/src/trace_processor/perfetto_sql/engine/function_util.cc
@@ -24,6 +24,10 @@
namespace perfetto {
namespace trace_processor {
+std::string FunctionPrototype::ToString() const {
+ return function_name + "(" + SerializeArguments(arguments) + ")";
+}
+
base::Status ParseFunctionName(base::StringView raw, base::StringView& out) {
size_t function_name_end = raw.find('(');
if (function_name_end == base::StringView::npos)
@@ -38,7 +42,7 @@
return base::OkStatus();
}
-base::Status ParsePrototype(base::StringView raw, Prototype& out) {
+base::Status ParsePrototype(base::StringView raw, FunctionPrototype& out) {
// Examples of function prototypes:
// ANDROID_SDK_LEVEL()
// STARTUP_SLICE(dur_ns INT)
diff --git a/src/trace_processor/perfetto_sql/engine/function_util.h b/src/trace_processor/perfetto_sql/engine/function_util.h
index aa3515f..1467e7e 100644
--- a/src/trace_processor/perfetto_sql/engine/function_util.h
+++ b/src/trace_processor/perfetto_sql/engine/function_util.h
@@ -28,20 +28,24 @@
namespace perfetto {
namespace trace_processor {
-struct Prototype {
+struct FunctionPrototype {
std::string function_name;
std::vector<sql_argument::ArgumentDefinition> arguments;
- bool operator==(const Prototype& other) const {
+ std::string ToString() const;
+
+ bool operator==(const FunctionPrototype& other) const {
return function_name == other.function_name && arguments == other.arguments;
}
- bool operator!=(const Prototype& other) const { return !(*this == other); }
+ bool operator!=(const FunctionPrototype& other) const {
+ return !(*this == other);
+ }
};
base::Status ParseFunctionName(base::StringView raw,
base::StringView& function_name);
-base::Status ParsePrototype(base::StringView raw, Prototype& out);
+base::Status ParsePrototype(base::StringView raw, FunctionPrototype& out);
base::Status SqliteRetToStatus(sqlite3* db,
const std::string& function_name,
diff --git a/src/trace_processor/perfetto_sql/engine/perfetto_sql_engine.cc b/src/trace_processor/perfetto_sql/engine/perfetto_sql_engine.cc
index 1efd12d..2f163a0 100644
--- a/src/trace_processor/perfetto_sql/engine/perfetto_sql_engine.cc
+++ b/src/trace_processor/perfetto_sql/engine/perfetto_sql_engine.cc
@@ -236,6 +236,11 @@
RETURN_IF_ERROR(AddTracebackIfNeeded(
RegisterRuntimeTable(cst->name, cst->sql), parser.statement_sql()));
source = RewriteToDummySql(parser.statement_sql());
+ } else if (auto* create_view = std::get_if<PerfettoSqlParser::CreateView>(
+ &parser.statement())) {
+ RETURN_IF_ERROR(AddTracebackIfNeeded(ExecuteCreateView(*create_view),
+ parser.statement_sql()));
+ source = RewriteToDummySql(parser.statement_sql());
} else if (auto* include = std::get_if<PerfettoSqlParser::Include>(
&parser.statement())) {
RETURN_IF_ERROR(ExecuteInclude(*include, parser));
@@ -317,19 +322,11 @@
return ExecutionResult{std::move(*res), stats};
}
-base::Status PerfettoSqlEngine::RegisterSqlFunction(bool replace,
- std::string prototype_str,
- std::string return_type_str,
- SqlSource sql) {
- // Parse all the arguments into a more friendly form.
- Prototype prototype;
- base::Status status =
- ParsePrototype(base::StringView(prototype_str), prototype);
- if (!status.ok()) {
- return base::ErrStatus("CREATE PERFETTO FUNCTION[prototype=%s]: %s",
- prototype_str.c_str(), status.c_message());
- }
-
+base::Status PerfettoSqlEngine::RegisterSqlFunction(
+ bool replace,
+ const FunctionPrototype& prototype,
+ std::string return_type_str,
+ SqlSource sql) {
// Parse the return type into a enum format.
auto opt_return_type =
sql_argument::ParseType(base::StringView(return_type_str));
@@ -337,7 +334,7 @@
return base::ErrStatus(
"CREATE PERFETTO FUNCTION[prototype=%s, return=%s]: unknown return "
"type specified",
- prototype_str.c_str(), return_type_str.c_str());
+ prototype.ToString().c_str(), return_type_str.c_str());
}
int created_argc = static_cast<int>(prototype.arguments.size());
@@ -356,8 +353,8 @@
std::move(created_fn_ctx)));
}
return CreatedFunction::ValidateOrPrepare(
- ctx, replace, std::move(prototype), std::move(prototype_str),
- std::move(*opt_return_type), std::move(return_type_str), std::move(sql));
+ ctx, replace, std::move(prototype), std::move(*opt_return_type),
+ std::move(return_type_str), std::move(sql));
}
base::Status PerfettoSqlEngine::RegisterRuntimeTable(std::string name,
@@ -434,6 +431,11 @@
.status();
}
+base::Status PerfettoSqlEngine::ExecuteCreateView(
+ const PerfettoSqlParser::CreateView& create_view) {
+ return Execute(create_view.sql).status();
+}
+
base::Status PerfettoSqlEngine::EnableSqlFunctionMemoization(
const std::string& name) {
constexpr size_t kSupportedArgCount = 1;
@@ -489,27 +491,16 @@
return RewriteToDummySql(parser.statement_sql());
}
- RuntimeTableFunction::State state{cf.prototype, cf.sql, {}, {}, std::nullopt};
- base::StringView function_name;
- RETURN_IF_ERROR(
- ParseFunctionName(state.prototype_str.c_str(), function_name));
-
- // Parse all the arguments into a more friendly form.
- base::Status status =
- ParsePrototype(state.prototype_str.c_str(), state.prototype);
- if (!status.ok()) {
- return base::ErrStatus("CREATE PERFETTO FUNCTION[prototype=%s]: %s",
- state.prototype_str.c_str(), status.c_message());
- }
+ RuntimeTableFunction::State state{cf.sql, cf.prototype, {}, std::nullopt};
// Parse the return type into a enum format.
- status =
+ base::Status status =
sql_argument::ParseArgumentDefinitions(cf.returns, state.return_values);
if (!status.ok()) {
return base::ErrStatus(
"CREATE PERFETTO FUNCTION[prototype=%s, return=%s]: unknown return "
"type specified",
- state.prototype_str.c_str(), cf.returns.c_str());
+ state.prototype.ToString().c_str(), cf.returns.c_str());
}
// Verify that the provided SQL prepares to a statement correctly.
diff --git a/src/trace_processor/perfetto_sql/engine/perfetto_sql_engine.h b/src/trace_processor/perfetto_sql/engine/perfetto_sql_engine.h
index 29c8206..a57a588 100644
--- a/src/trace_processor/perfetto_sql/engine/perfetto_sql_engine.h
+++ b/src/trace_processor/perfetto_sql/engine/perfetto_sql_engine.h
@@ -107,7 +107,7 @@
// Registers a function with the prototype |prototype| which returns a value
// of |return_type| and is implemented by executing the SQL statement |sql|.
base::Status RegisterSqlFunction(bool replace,
- std::string prototype,
+ const FunctionPrototype& prototype,
std::string return_type,
SqlSource sql);
@@ -152,6 +152,8 @@
// Registers a SQL-defined trace processor C++ table with SQLite.
base::Status RegisterRuntimeTable(std::string name, SqlSource sql);
+ base::Status ExecuteCreateView(const PerfettoSqlParser::CreateView&);
+
base::Status ExecuteCreateMacro(const PerfettoSqlParser::CreateMacro&);
std::unique_ptr<QueryCache> query_cache_;
diff --git a/src/trace_processor/perfetto_sql/engine/perfetto_sql_engine_unittest.cc b/src/trace_processor/perfetto_sql/engine/perfetto_sql_engine_unittest.cc
index d577ea0..141ff51 100644
--- a/src/trace_processor/perfetto_sql/engine/perfetto_sql_engine_unittest.cc
+++ b/src/trace_processor/perfetto_sql/engine/perfetto_sql_engine_unittest.cc
@@ -109,6 +109,22 @@
ASSERT_TRUE(res.ok());
}
+TEST_F(PerfettoSqlEngineTest, CreatePerfettoViewSmoke) {
+ auto res = engine_.Execute(SqlSource::FromExecuteQuery(
+ "CREATE PERFETTO VIEW foo AS SELECT 42 AS bar"));
+ ASSERT_TRUE(res.ok());
+}
+
+TEST_F(PerfettoSqlEngineTest, CreatePerfettoViewWithSchemaSmoke) {
+ auto res = engine_.Execute(SqlSource::FromExecuteQuery(
+ "CREATE PERFETTO VIEW foo(bar INT) AS SELECT 42 AS bar"));
+ ASSERT_TRUE(res.ok());
+
+ res = engine_.Execute(SqlSource::FromExecuteQuery(
+ "CREATE PERFETTO VIEW foo2(bar INT) AS SELECT 42 AS bar; SELECT 1"));
+ ASSERT_TRUE(res.ok());
+}
+
TEST_F(PerfettoSqlEngineTest, CreateMacro) {
auto res_create = engine_.Execute(SqlSource::FromExecuteQuery(
"CREATE PERFETTO MACRO foo() RETURNS TableOrSubquery AS select 42 AS x"));
diff --git a/src/trace_processor/perfetto_sql/engine/perfetto_sql_parser.cc b/src/trace_processor/perfetto_sql/engine/perfetto_sql_parser.cc
index 33fc49b..fb6ddf8 100644
--- a/src/trace_processor/perfetto_sql/engine/perfetto_sql_parser.cc
+++ b/src/trace_processor/perfetto_sql/engine/perfetto_sql_parser.cc
@@ -85,21 +85,6 @@
std::not_fn(IsValidModuleWord)) == packages.end();
}
-std::string SerializeArgs(std::vector<std::pair<SqlSource, SqlSource>> args) {
- bool comma = false;
- std::string serialized;
- for (const auto& [name, type] : args) {
- if (comma) {
- serialized.append(", ");
- }
- comma = true;
- serialized.append(name.sql().c_str());
- serialized.push_back(' ');
- serialized.append(type.sql().c_str());
- }
- return serialized;
-}
-
} // namespace
PerfettoSqlParser::PerfettoSqlParser(
@@ -210,7 +195,12 @@
state == State::kCreateOrReplacePerfetto, *first_non_space_token);
}
if (TokenIsSqliteKeyword("table", token)) {
- return ParseCreatePerfettoTable(*first_non_space_token);
+ return ParseCreatePerfettoTableOrView(*first_non_space_token,
+ TableOrView::kTable);
+ }
+ if (TokenIsSqliteKeyword("view", token)) {
+ return ParseCreatePerfettoTableOrView(*first_non_space_token,
+ TableOrView::kView);
}
if (TokenIsCustomKeyword("macro", token)) {
return ParseCreatePerfettoMacro(state ==
@@ -244,7 +234,9 @@
return true;
}
-bool PerfettoSqlParser::ParseCreatePerfettoTable(Token first_non_space_token) {
+bool PerfettoSqlParser::ParseCreatePerfettoTableOrView(
+ Token first_non_space_token,
+ TableOrView table_or_view) {
Token table_name = tokenizer_.NextNonWhitespace();
if (table_name.token_type != SqliteTokenType::TK_ID) {
base::StackString<1024> err("Invalid table name %.*s",
@@ -253,8 +245,19 @@
return ErrorAtToken(table_name, err.c_str());
}
std::string name(table_name.str);
+ std::vector<sql_argument::ArgumentDefinition> schema;
auto token = tokenizer_.NextNonWhitespace();
+
+ // If the next token is a left parenthesis, then the table or view have a
+ // schema.
+ if (token.token_type == SqliteTokenType::TK_LP) {
+ if (!ParseArguments(schema)) {
+ return false;
+ }
+ token = tokenizer_.NextNonWhitespace();
+ }
+
if (!TokenIsSqliteKeyword("as", token)) {
base::StackString<1024> err(
"Expected 'AS' after table_name, received "
@@ -265,7 +268,23 @@
Token first = tokenizer_.NextNonWhitespace();
Token terminal = tokenizer_.NextTerminal();
- statement_ = CreateTable{std::move(name), tokenizer_.Substr(first, terminal)};
+ switch (table_or_view) {
+ case TableOrView::kTable:
+ statement_ = CreateTable{std::move(name),
+ tokenizer_.Substr(first, terminal), schema};
+ break;
+ case TableOrView::kView:
+ SqlSource original_statement =
+ tokenizer_.Substr(first_non_space_token, terminal);
+ SqlSource header = SqlSource::FromTraceProcessorImplementation(
+ "CREATE VIEW " + name + " AS ");
+ SqlSource::Rewriter rewriter(original_statement);
+ tokenizer_.Rewrite(rewriter, first_non_space_token, first, header,
+ SqliteTokenizer::EndToken::kExclusive);
+ statement_ =
+ CreateView{std::move(name), std::move(rewriter).Build(), schema};
+ break;
+ }
statement_sql_ = tokenizer_.Substr(first_non_space_token, terminal);
return true;
}
@@ -273,7 +292,6 @@
bool PerfettoSqlParser::ParseCreatePerfettoFunction(
bool replace,
Token first_non_space_token) {
- std::string prototype;
Token function_name = tokenizer_.NextNonWhitespace();
if (function_name.token_type != SqliteTokenType::TK_ID) {
// TODO(lalitm): add a link to create function documentation.
@@ -282,7 +300,6 @@
function_name.str.data());
return ErrorAtToken(function_name, err.c_str());
}
- prototype.append(function_name.str);
// TK_LP == '(' (i.e. left parenthesis).
if (Token lp = tokenizer_.NextNonWhitespace();
@@ -291,15 +308,11 @@
return ErrorAtToken(lp, "Malformed function prototype: '(' expected");
}
- std::vector<Argument> args;
- if (!ParseArgumentDefinitions(args)) {
+ std::vector<sql_argument::ArgumentDefinition> args;
+ if (!ParseArguments(args)) {
return false;
}
- prototype.push_back('(');
- prototype.append(SerializeArgs(args));
- prototype.push_back(')');
-
if (Token returns = tokenizer_.NextNonWhitespace();
!TokenIsCustomKeyword("returns", returns)) {
// TODO(lalitm): add a link to create function documentation.
@@ -316,11 +329,11 @@
return ErrorAtToken(lp, "Malformed table return: '(' expected");
}
// Table function return.
- std::vector<Argument> ret_args;
- if (!ParseArgumentDefinitions(ret_args)) {
+ std::vector<sql_argument::ArgumentDefinition> ret_args;
+ if (!ParseArguments(ret_args)) {
return false;
}
- ret = SerializeArgs(ret_args);
+ ret = sql_argument::SerializeArguments(ret_args);
} else if (ret_token.token_type != SqliteTokenType::TK_ID) {
// TODO(lalitm): add a link to create function documentation.
return ErrorAtToken(ret_token, "Invalid return type");
@@ -337,8 +350,10 @@
Token first = tokenizer_.NextNonWhitespace();
Token terminal = tokenizer_.NextTerminal();
- statement_ = CreateFunction{replace, std::move(prototype), std::move(ret),
- tokenizer_.Substr(first, terminal), table_return};
+ statement_ = CreateFunction{
+ replace,
+ FunctionPrototype{std::string(function_name.str), std::move(args)},
+ std::move(ret), tokenizer_.Substr(first, terminal), table_return};
statement_sql_ = tokenizer_.Substr(first_non_space_token, terminal);
return true;
}
@@ -360,10 +375,15 @@
return ErrorAtToken(lp, "Malformed macro prototype: '(' expected");
}
- std::vector<Argument> args;
- if (!ParseArgumentDefinitions(args)) {
+ std::vector<RawArgument> raw_args;
+ std::vector<std::pair<SqlSource, SqlSource>> args;
+ if (!ParseRawArguments(raw_args)) {
return false;
}
+ for (const auto& arg : raw_args) {
+ args.emplace_back(tokenizer_.SubstrToken(arg.name),
+ tokenizer_.SubstrToken(arg.type));
+ }
if (Token returns = tokenizer_.NextNonWhitespace();
!TokenIsCustomKeyword("returns", returns)) {
@@ -391,7 +411,7 @@
return true;
}
-bool PerfettoSqlParser::ParseArgumentDefinitions(std::vector<Argument>& res) {
+bool PerfettoSqlParser::ParseRawArguments(std::vector<RawArgument>& args) {
enum TokenType {
kIdOrRp,
kId,
@@ -432,8 +452,7 @@
return ErrorAtToken(tok, err.c_str());
}
PERFETTO_CHECK(id);
- res.push_back(std::make_pair(tokenizer_.SubstrToken(*id),
- tokenizer_.SubstrToken(tok)));
+ args.push_back({*id, tok});
id = std::nullopt;
expected = kCommaOrRp;
continue;
@@ -457,8 +476,46 @@
}
}
+bool PerfettoSqlParser::ParseArguments(
+ std::vector<sql_argument::ArgumentDefinition>& args) {
+ std::vector<RawArgument> raw_args;
+ if (!ParseRawArguments(raw_args)) {
+ return false;
+ }
+ for (const auto& raw_arg : raw_args) {
+ std::optional<sql_argument::ArgumentDefinition> arg =
+ ResolveRawArgument(raw_arg);
+ if (!arg) {
+ return false;
+ }
+ args.emplace_back(std::move(*arg));
+ }
+ return true;
+}
+
+std::optional<sql_argument::ArgumentDefinition>
+PerfettoSqlParser::ResolveRawArgument(RawArgument arg) {
+ std::string arg_name = tokenizer_.SubstrToken(arg.name).sql();
+ std::string arg_type = tokenizer_.SubstrToken(arg.type).sql();
+ if (!sql_argument::IsValidName(base::StringView(arg_name))) {
+ base::StackString<1024> err("Name %s is not alphanumeric",
+ arg_name.c_str());
+ ErrorAtToken(arg.name, err.c_str());
+ return std::nullopt;
+ }
+ std::optional<sql_argument::Type> parsed_arg_type =
+ sql_argument::ParseType(base::StringView(arg_type));
+ if (!parsed_arg_type) {
+ base::StackString<1024> err("Invalid type %s", arg_type.c_str());
+ ErrorAtToken(arg.name, err.c_str());
+ return std::nullopt;
+ }
+ return sql_argument::ArgumentDefinition("$" + arg_name, *parsed_arg_type);
+}
+
bool PerfettoSqlParser::ErrorAtToken(const SqliteTokenizer::Token& token,
- const char* error) {
+ const char* error,
+ ...) {
std::string traceback = tokenizer_.AsTraceback(token);
status_ = base::ErrStatus("%s%s", traceback.c_str(), error);
return false;
diff --git a/src/trace_processor/perfetto_sql/engine/perfetto_sql_parser.h b/src/trace_processor/perfetto_sql/engine/perfetto_sql_parser.h
index 1c38d43..b8120fb 100644
--- a/src/trace_processor/perfetto_sql/engine/perfetto_sql_parser.h
+++ b/src/trace_processor/perfetto_sql/engine/perfetto_sql_parser.h
@@ -24,6 +24,7 @@
#include <variant>
#include <vector>
+#include "function_util.h"
#include "perfetto/ext/base/flat_hash_map.h"
#include "perfetto/ext/base/status_or.h"
#include "src/trace_processor/perfetto_sql/engine/perfetto_sql_preprocessor.h"
@@ -52,7 +53,7 @@
// with the following parameters.
struct CreateFunction {
bool replace;
- std::string prototype;
+ FunctionPrototype prototype;
std::string returns;
SqlSource sql;
bool is_table;
@@ -61,7 +62,18 @@
// with the following parameters.
struct CreateTable {
std::string name;
+ // SQL source for the select statement.
SqlSource sql;
+ std::vector<sql_argument::ArgumentDefinition> schema;
+ };
+ // Indicates that the specified SQL was a CREATE PERFETTO VIEW statement
+ // with the following parameters.
+ struct CreateView {
+ std::string name;
+ // SQL source corresponding to the rewritten statement creating the
+ // underlying view.
+ SqlSource sql;
+ std::vector<sql_argument::ArgumentDefinition> schema;
};
// Indicates that the specified SQL was a INCLUDE PERFETTO MODULE statement
// with the following parameter.
@@ -77,8 +89,12 @@
SqlSource returns;
SqlSource sql;
};
- using Statement = std::
- variant<SqliteSql, CreateFunction, CreateTable, Include, CreateMacro>;
+ using Statement = std::variant<SqliteSql,
+ CreateFunction,
+ CreateTable,
+ CreateView,
+ Include,
+ CreateMacro>;
// Creates a new SQL parser with the a block of PerfettoSQL statements.
// Concretely, the passed string can contain >1 statement.
@@ -114,27 +130,46 @@
const base::Status& status() const { return status_; }
private:
- using Argument =
- std::pair<SqlSource /* name token */, SqlSource /* type token */>;
-
// This cannot be moved because we keep pointers into |sql_| in
// |preprocessor_|.
PerfettoSqlParser(PerfettoSqlParser&&) = delete;
PerfettoSqlParser& operator=(PerfettoSqlParser&&) = delete;
+ // Most of the code needs sql_argument::ArgumentDefinition, but we explcitly
+ // track raw arguments separately, as macro implementations need access to
+ // the underlying tokens.
+ struct RawArgument {
+ SqliteTokenizer::Token name;
+ SqliteTokenizer::Token type;
+ };
+
bool ParseCreatePerfettoFunction(
bool replace,
SqliteTokenizer::Token first_non_space_token);
- bool ParseCreatePerfettoTable(SqliteTokenizer::Token first_non_space_token);
+ enum class TableOrView {
+ kTable,
+ kView,
+ };
+ bool ParseCreatePerfettoTableOrView(
+ SqliteTokenizer::Token first_non_space_token,
+ TableOrView table_or_view);
bool ParseIncludePerfettoModule(SqliteTokenizer::Token first_non_space_token);
bool ParseCreatePerfettoMacro(bool replace);
- bool ParseArgumentDefinitions(std::vector<Argument>&);
+ // Convert a "raw" argument (i.e. one that points to specific tokens) to the
+ // argument definition consumed by the rest of the SQL code.
+ // Guarantees to call ErrorAtToken if std::nullopt is returned.
+ std::optional<sql_argument::ArgumentDefinition> ResolveRawArgument(
+ RawArgument arg);
+ // Parse the arguments in their raw token form.
+ bool ParseRawArguments(std::vector<RawArgument>&);
+ // Same as above, but also convert the raw tokens into argument definitions.
+ bool ParseArguments(std::vector<sql_argument::ArgumentDefinition>&);
- bool ErrorAtToken(const SqliteTokenizer::Token&, const char* error);
+ bool ErrorAtToken(const SqliteTokenizer::Token&, const char* error, ...);
PerfettoSqlPreprocessor preprocessor_;
SqliteTokenizer tokenizer_;
diff --git a/src/trace_processor/perfetto_sql/engine/perfetto_sql_parser_unittest.cc b/src/trace_processor/perfetto_sql/engine/perfetto_sql_parser_unittest.cc
index d2391c3..7856964 100644
--- a/src/trace_processor/perfetto_sql/engine/perfetto_sql_parser_unittest.cc
+++ b/src/trace_processor/perfetto_sql/engine/perfetto_sql_parser_unittest.cc
@@ -34,6 +34,7 @@
using SqliteSql = PerfettoSqlParser::SqliteSql;
using CreateFn = PerfettoSqlParser::CreateFunction;
using CreateTable = PerfettoSqlParser::CreateTable;
+using CreateView = PerfettoSqlParser::CreateView;
using Include = PerfettoSqlParser::Include;
using CreateMacro = PerfettoSqlParser::CreateMacro;
@@ -95,23 +96,39 @@
TEST_F(PerfettoSqlParserTest, CreatePerfettoFunctionScalar) {
auto res = SqlSource::FromExecuteQuery(
"create perfetto function foo() returns INT as select 1");
- ASSERT_THAT(*Parse(res),
- testing::ElementsAre(CreateFn{
- false, "foo()", "INT", FindSubstr(res, "select 1"), false}));
+ ASSERT_THAT(*Parse(res), testing::ElementsAre(CreateFn{
+ false, FunctionPrototype{"foo", {}}, "INT",
+ FindSubstr(res, "select 1"), false}));
res = SqlSource::FromExecuteQuery(
"create perfetto function bar(x INT, y LONG) returns STRING as "
"select 'foo'");
- ASSERT_THAT(*Parse(res), testing::ElementsAre(CreateFn{
- false, "bar(x INT, y LONG)", "STRING",
- FindSubstr(res, "select 'foo'"), false}));
+ ASSERT_THAT(*Parse(res),
+ testing::ElementsAre(
+ CreateFn{false,
+ FunctionPrototype{
+ "bar",
+ {
+ {"$x", sql_argument::Type::kInt},
+ {"$y", sql_argument::Type::kLong},
+ },
+ },
+ "STRING", FindSubstr(res, "select 'foo'"), false}));
res = SqlSource::FromExecuteQuery(
"CREATE perfetto FuNcTiOn bar(x INT, y LONG) returnS STRING As "
"select 'foo'");
- ASSERT_THAT(*Parse(res), testing::ElementsAre(CreateFn{
- false, "bar(x INT, y LONG)", "STRING",
- FindSubstr(res, "select 'foo'"), false}));
+ ASSERT_THAT(*Parse(res),
+ testing::ElementsAre(
+ CreateFn{false,
+ FunctionPrototype{
+ "bar",
+ {
+ {"$x", sql_argument::Type::kInt},
+ {"$y", sql_argument::Type::kLong},
+ },
+ },
+ "STRING", FindSubstr(res, "select 'foo'"), false}));
}
TEST_F(PerfettoSqlParserTest, CreatePerfettoFunctionScalarError) {
@@ -133,7 +150,8 @@
"create perfetto function foo() returns INT as select 1; select foo()");
PerfettoSqlParser parser(res, macros_);
ASSERT_TRUE(parser.Next());
- CreateFn fn{false, "foo()", "INT", FindSubstr(res, "select 1"), false};
+ CreateFn fn{false, FunctionPrototype{"foo", {}}, "INT",
+ FindSubstr(res, "select 1"), false};
ASSERT_EQ(parser.statement(), Statement{fn});
ASSERT_EQ(
parser.statement_sql().sql(),
@@ -203,6 +221,90 @@
ASSERT_FALSE(parser.Next());
}
+TEST_F(PerfettoSqlParserTest, CreatePerfettoTable) {
+ auto res = SqlSource::FromExecuteQuery(
+ "CREATE PERFETTO TABLE foo AS SELECT 42 AS bar");
+ PerfettoSqlParser parser(res, macros_);
+ ASSERT_TRUE(parser.Next());
+ ASSERT_EQ(
+ parser.statement(),
+ Statement(CreateTable{"foo", FindSubstr(res, "SELECT 42 AS bar"), {}}));
+ ASSERT_FALSE(parser.Next());
+}
+
+TEST_F(PerfettoSqlParserTest, CreatePerfettoTableWithSchema) {
+ auto res = SqlSource::FromExecuteQuery(
+ "CREATE PERFETTO TABLE foo(bar INT) AS SELECT 42 AS bar");
+ PerfettoSqlParser parser(res, macros_);
+ ASSERT_TRUE(parser.Next());
+ ASSERT_EQ(parser.statement(), Statement(CreateTable{
+ "foo",
+ FindSubstr(res, "SELECT 42 AS bar"),
+ {{"$bar", sql_argument::Type::kInt}},
+ }));
+ ASSERT_FALSE(parser.Next());
+}
+
+TEST_F(PerfettoSqlParserTest, CreatePerfettoTableAndOther) {
+ auto res = SqlSource::FromExecuteQuery(
+ "CREATE PERFETTO TABLE foo AS SELECT 42 AS bar; select 1");
+ PerfettoSqlParser parser(res, macros_);
+ ASSERT_TRUE(parser.Next());
+ ASSERT_EQ(
+ parser.statement(),
+ Statement(CreateTable{"foo", FindSubstr(res, "SELECT 42 AS bar"), {}}));
+ ASSERT_TRUE(parser.Next());
+ ASSERT_EQ(parser.statement(), Statement(SqliteSql{}));
+ ASSERT_EQ(parser.statement_sql(), FindSubstr(res, "select 1"));
+ ASSERT_FALSE(parser.Next());
+}
+
+TEST_F(PerfettoSqlParserTest, CreatePerfettoView) {
+ auto res = SqlSource::FromExecuteQuery(
+ "CREATE PERFETTO VIEW foo AS SELECT 42 AS bar");
+ PerfettoSqlParser parser(res, macros_);
+ ASSERT_TRUE(parser.Next());
+ ASSERT_EQ(parser.statement(),
+ Statement(CreateView{"foo",
+ SqlSource::FromExecuteQuery(
+ "CREATE VIEW foo AS SELECT 42 AS bar"),
+ {}}));
+ ASSERT_FALSE(parser.Next());
+}
+
+TEST_F(PerfettoSqlParserTest, CreatePerfettoViewAndOther) {
+ auto res = SqlSource::FromExecuteQuery(
+ "CREATE PERFETTO VIEW foo AS SELECT 42 AS bar; select 1");
+ PerfettoSqlParser parser(res, macros_);
+ ASSERT_TRUE(parser.Next());
+ ASSERT_EQ(parser.statement(),
+ Statement(CreateView{"foo",
+ SqlSource::FromExecuteQuery(
+ "CREATE VIEW foo AS SELECT 42 AS bar"),
+ {}}));
+ ASSERT_TRUE(parser.Next());
+ ASSERT_EQ(parser.statement(), Statement(SqliteSql{}));
+ ASSERT_EQ(parser.statement_sql(), FindSubstr(res, "select 1"));
+ ASSERT_FALSE(parser.Next());
+}
+
+TEST_F(PerfettoSqlParserTest, CreatePerfettoViewWithSchema) {
+ auto res = SqlSource::FromExecuteQuery(
+ "CREATE PERFETTO VIEW foo(foo STRING, bar INT) AS SELECT 'a' as foo, 42 "
+ "AS bar");
+ PerfettoSqlParser parser(res, macros_);
+ ASSERT_TRUE(parser.Next());
+ ASSERT_EQ(parser.statement(),
+ Statement(CreateView{
+ "foo",
+ SqlSource::FromExecuteQuery(
+ "CREATE VIEW foo AS SELECT 'a' as foo, 42 AS bar"),
+ {{"$foo", sql_argument::Type::kString},
+ {"$bar", sql_argument::Type::kInt}},
+ }));
+ ASSERT_FALSE(parser.Next());
+}
+
} // namespace
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/trace_processor/perfetto_sql/engine/perfetto_sql_test_utils.h b/src/trace_processor/perfetto_sql/engine/perfetto_sql_test_utils.h
index caca711..8382fe6 100644
--- a/src/trace_processor/perfetto_sql/engine/perfetto_sql_test_utils.h
+++ b/src/trace_processor/perfetto_sql/engine/perfetto_sql_test_utils.h
@@ -44,6 +44,11 @@
return std::tie(a.name, a.sql) == std::tie(b.name, b.sql);
}
+inline bool operator==(const PerfettoSqlParser::CreateView& a,
+ const PerfettoSqlParser::CreateView& b) {
+ return std::tie(a.name, a.sql) == std::tie(b.name, b.sql);
+}
+
inline bool operator==(const PerfettoSqlParser::Include& a,
const PerfettoSqlParser::Include& b) {
return std::tie(a.key) == std::tie(b.key);
@@ -75,6 +80,10 @@
return stream << "CreateTable(name=" << testing::PrintToString(tab->name)
<< ", sql=" << testing::PrintToString(tab->sql) << ")";
}
+ if (auto* tab = std::get_if<PerfettoSqlParser::CreateView>(&line)) {
+ return stream << "CreateView(name=" << testing::PrintToString(tab->name)
+ << ", sql=" << testing::PrintToString(tab->sql) << ")";
+ }
if (auto* macro = std::get_if<PerfettoSqlParser::CreateMacro>(&line)) {
return stream << "CreateTable(name=" << testing::PrintToString(macro->name)
<< ", args=" << testing::PrintToString(macro->args)
diff --git a/src/trace_processor/perfetto_sql/engine/runtime_table_function.h b/src/trace_processor/perfetto_sql/engine/runtime_table_function.h
index 9fe8c6e..7c92fcc 100644
--- a/src/trace_processor/perfetto_sql/engine/runtime_table_function.h
+++ b/src/trace_processor/perfetto_sql/engine/runtime_table_function.h
@@ -36,10 +36,9 @@
// because |RuntimeTableFunction| is owned by Sqlite while |State| is owned by
// PerfettoSqlEngine.
struct State {
- std::string prototype_str;
SqlSource sql_defn_str;
- Prototype prototype;
+ FunctionPrototype prototype;
std::vector<sql_argument::ArgumentDefinition> return_values;
std::optional<SqliteEngine::PreparedStatement> reusable_stmt;
diff --git a/src/trace_processor/perfetto_sql/intrinsics/functions/create_function.cc b/src/trace_processor/perfetto_sql/intrinsics/functions/create_function.cc
index ac6bfd0..2bada91 100644
--- a/src/trace_processor/perfetto_sql/intrinsics/functions/create_function.cc
+++ b/src/trace_processor/perfetto_sql/intrinsics/functions/create_function.cc
@@ -72,8 +72,12 @@
std::string prototype_str = extract_string(prototype_value).ToStdString();
std::string return_type_str = extract_string(return_type_value).ToStdString();
std::string sql_defn_str = extract_string(sql_defn_value).ToStdString();
+
+ FunctionPrototype prototype;
+ RETURN_IF_ERROR(ParsePrototype(base::StringView(prototype_str), prototype));
+
return engine->RegisterSqlFunction(
- false, prototype_str, return_type_str,
+ false, prototype, return_type_str,
SqlSource::FromTraceProcessorImplementation(std::move(sql_defn_str)));
}
diff --git a/src/trace_processor/perfetto_sql/intrinsics/operators/span_join_operator.cc b/src/trace_processor/perfetto_sql/intrinsics/operators/span_join_operator.cc
index 15b1f45..a279829 100644
--- a/src/trace_processor/perfetto_sql/intrinsics/operators/span_join_operator.cc
+++ b/src/trace_processor/perfetto_sql/intrinsics/operators/span_join_operator.cc
@@ -802,6 +802,7 @@
void SpanJoinOperatorTable::Query::ReportSqliteResult(sqlite3_context* context,
size_t index) {
+ const auto kSqliteTransient = reinterpret_cast<sqlite3_destructor_type>(-1);
if (state_ != State::kReal) {
sqlite3_result_null(context);
return;
@@ -820,12 +821,15 @@
// TODO(lalitm): note for future optimizations: if we knew the addresses
// of the string intern pool, we could check if the string returned here
// comes from the pool, and pass it as non-transient.
- const auto kSqliteTransient =
- reinterpret_cast<sqlite3_destructor_type>(-1);
auto ptr = reinterpret_cast<const char*>(sqlite3_column_text(stmt, idx));
sqlite3_result_text(context, ptr, -1, kSqliteTransient);
break;
}
+ case SQLITE_BLOB: {
+ sqlite3_result_blob(context, sqlite3_column_blob(stmt, idx),
+ sqlite3_column_bytes(stmt, idx), kSqliteTransient);
+ break;
+ }
}
}
diff --git a/src/trace_processor/perfetto_sql/stdlib/chrome/BUILD.gn b/src/trace_processor/perfetto_sql/stdlib/chrome/BUILD.gn
index cac258f..04a1571 100644
--- a/src/trace_processor/perfetto_sql/stdlib/chrome/BUILD.gn
+++ b/src/trace_processor/perfetto_sql/stdlib/chrome/BUILD.gn
@@ -20,7 +20,9 @@
"chrome_scrolls.sql",
"cpu_powerups.sql",
"histograms.sql",
+ "interactions.sql",
"metadata.sql",
+ "page_loads.sql",
"speedometer.sql",
"tasks.sql",
"vsync_intervals.sql",
diff --git a/src/trace_processor/perfetto_sql/stdlib/chrome/interactions.sql b/src/trace_processor/perfetto_sql/stdlib/chrome/interactions.sql
new file mode 100644
index 0000000..49ce0c8
--- /dev/null
+++ b/src/trace_processor/perfetto_sql/stdlib/chrome/interactions.sql
@@ -0,0 +1,46 @@
+-- Copyright 2023 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+-- This file specifies common metrics/tables for critical user interactions. It
+-- is expected to be in flux as metrics are added across different CUI types.
+-- Currently we only track Chrome page loads and their associated metrics.
+
+INCLUDE PERFETTO MODULE chrome.page_loads;
+
+-- All critical user interaction events, including type and table with
+-- associated metrics.
+--
+-- @column scoped_id Identifier of the interaction; this is not
+-- guaranteed to be unique to the table -
+-- rather, it is unique within an individual
+-- interaction type. Combine with type to get
+-- a unique identifier in this table.
+-- @column type Type of this interaction, which together
+-- with scoped_id uniquely identifies this
+-- interaction. Also corresponds to a SQL
+-- table name containing more details specific
+-- to this type of interaction.
+-- @column name Interaction name - e.g. 'PageLoad', 'Tap',
+-- etc. Interactions will have unique metrics
+-- stored in other tables.
+-- @column ts Timestamp of the CUI event.
+-- @column dur Duration of the CUI event.
+CREATE PERFETTO TABLE chrome_interactions AS
+SELECT
+ navigation_id AS scoped_id,
+ 'chrome_page_loads' AS type,
+ 'PageLoad' AS name,
+ navigation_start_ts AS ts,
+ IFNULL(lcp, fcp) AS dur
+FROM chrome_page_loads;
diff --git a/src/trace_processor/perfetto_sql/stdlib/chrome/page_loads.sql b/src/trace_processor/perfetto_sql/stdlib/chrome/page_loads.sql
new file mode 100644
index 0000000..fcc5874
--- /dev/null
+++ b/src/trace_processor/perfetto_sql/stdlib/chrome/page_loads.sql
@@ -0,0 +1,73 @@
+-- Copyright 2023 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+-- TODO(b/306300843): The recorded navigation ids are not guaranteed to be
+-- unique within a trace; they are only guaranteed to be unique within a single
+-- chrome instance. Chrome instance id needs to be recorded, and used here in
+-- combination with navigation id to uniquely identify page load metrics.
+
+INCLUDE PERFETTO MODULE common.slices;
+
+-- Chrome page loads, including associated high-level metrics and properties.
+--
+-- @column navigation_id ID of the navigation associated with the
+-- page load (i.e. the cross-document
+-- navigation in primary main frame which
+-- created this page's main document). Also
+-- note that navigation_id is specific to a
+-- given Chrome browser process, and not
+-- globally unique.
+-- @column navigation_start_ts Timestamp of the start of navigation.
+-- @column fcp Duration between the navigation start and
+-- the first contentful paint event
+-- (web.dev/fcp).
+-- @column fcp_ts Timestamp of the first contentful paint.
+-- @column lcp Duration between the navigation start and
+-- the largest contentful paint event
+-- (web.dev/lcp).
+-- @column lcp_ts Timestamp of the largest contentful paint.
+-- @column url URL at the page load event.
+-- @column browser_upid The unique process id (upid) of the browser
+-- process where the page load occurred.
+CREATE PERFETTO TABLE chrome_page_loads AS
+WITH fcp AS (
+ SELECT
+ ts,
+ dur,
+ EXTRACT_ARG(arg_set_id, 'page_load.navigation_id') AS navigation_id,
+ EXTRACT_ARG(arg_set_id, 'page_load.url') AS url,
+ upid AS browser_upid
+ FROM process_slice
+ WHERE name = 'PageLoadMetrics.NavigationToFirstContentfulPaint'
+),
+lcp AS (
+ SELECT
+ ts,
+ dur,
+ EXTRACT_ARG(arg_set_id, 'page_load.navigation_id')
+ AS navigation_id
+ FROM slice
+ WHERE name = 'PageLoadMetrics.NavigationToLargestContentfulPaint'
+)
+SELECT
+ fcp.navigation_id,
+ fcp.ts AS navigation_start_ts,
+ fcp.dur AS fcp,
+ fcp.ts + fcp.dur AS fcp_ts,
+ lcp.dur AS lcp,
+ IFNULL(lcp.dur, 0) + IFNULL(lcp.ts, 0) AS lcp_ts,
+ fcp.url,
+ fcp.browser_upid
+FROM fcp
+LEFT JOIN lcp USING (navigation_id);
diff --git a/src/trace_processor/perfetto_sql/stdlib/chrome/scroll_jank/scroll_jank_v3.sql b/src/trace_processor/perfetto_sql/stdlib/chrome/scroll_jank/scroll_jank_v3.sql
index c6b505a..3ba33c5 100644
--- a/src/trace_processor/perfetto_sql/stdlib/chrome/scroll_jank/scroll_jank_v3.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/chrome/scroll_jank/scroll_jank_v3.sql
@@ -330,7 +330,7 @@
CREATE VIEW chrome_janky_frames_no_subcause AS
SELECT
*,
- get_v3_jank_cause_id(event_latency_id, prev_event_latency_id) AS cause_id
+ chrome_get_v3_jank_cause_id(event_latency_id, prev_event_latency_id) AS cause_id
FROM chrome_janky_frames_no_cause;
-- Finds all causes of jank for all janky frames, and a cause of sub jank
@@ -352,7 +352,7 @@
slice_name_from_id(cause_id) AS cause_of_jank,
slice_name_from_id(
-- Getting sub-cause
- get_v3_jank_cause_id(
+ chrome_get_v3_jank_cause_id(
-- Here the cause itself is the parent.
cause_id,
-- Get the previous cause id as a child to the previous |EventLatency|.
diff --git a/src/trace_processor/perfetto_sql/stdlib/chrome/scroll_jank/scroll_jank_v3_cause.sql b/src/trace_processor/perfetto_sql/stdlib/chrome/scroll_jank/scroll_jank_v3_cause.sql
index 164ba7a..60bfca8 100644
--- a/src/trace_processor/perfetto_sql/stdlib/chrome/scroll_jank/scroll_jank_v3_cause.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/chrome/scroll_jank/scroll_jank_v3_cause.sql
@@ -29,9 +29,9 @@
-- cause among it's children.
-- @arg prev_slice_id LONG The slice id of the parent slice that's the reference
-- in comparison to |janky_slice_id|.
--- @ret breakdown_id LONG The slice id of the breakdown that has the maximum
+-- @ret LONG The slice id of the breakdown that has the maximum
-- duration delta.
-CREATE PERFETTO FUNCTION get_v3_jank_cause_id(
+CREATE PERFETTO FUNCTION chrome_get_v3_jank_cause_id(
janky_slice_id LONG,
prev_slice_id LONG
)
diff --git a/src/trace_processor/perfetto_sql/stdlib/chrome/scroll_jank/utils.sql b/src/trace_processor/perfetto_sql/stdlib/chrome/scroll_jank/utils.sql
index 44e6e1e..6d89427 100644
--- a/src/trace_processor/perfetto_sql/stdlib/chrome/scroll_jank/utils.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/chrome/scroll_jank/utils.sql
@@ -28,7 +28,7 @@
-- Function : function takes scroll ids of frames to verify it's from
-- the same scroll, and makes sure the frame ts occured within the scroll
-- timestamp of the neighbour and computes whether the frame was janky or not.
-CREATE PERFETTO FUNCTION is_janky_frame(cur_gesture_id LONG,
+CREATE PERFETTO FUNCTION internal_is_janky_frame(cur_gesture_id LONG,
neighbour_gesture_id LONG,
neighbour_ts LONG,
cur_gesture_begin_ts LONG,
@@ -56,7 +56,7 @@
--
-- Returns the jank budget in percentage (i.e. 0.75) of vsync interval
-- percentage.
-CREATE PERFETTO FUNCTION jank_budget(
+CREATE PERFETTO FUNCTION internal_jank_budget(
cur_frame_exact FLOAT,
prev_frame_exact FLOAT,
next_frame_exact FLOAT
diff --git a/src/trace_processor/perfetto_sql/stdlib/common/BUILD.gn b/src/trace_processor/perfetto_sql/stdlib/common/BUILD.gn
index 93ffc3d..bb4d758 100644
--- a/src/trace_processor/perfetto_sql/stdlib/common/BUILD.gn
+++ b/src/trace_processor/perfetto_sql/stdlib/common/BUILD.gn
@@ -22,6 +22,7 @@
"metadata.sql",
"percentiles.sql",
"slices.sql",
+ "thread_states.sql",
"timestamps.sql",
]
}
diff --git a/src/trace_processor/perfetto_sql/stdlib/common/thread_states.sql b/src/trace_processor/perfetto_sql/stdlib/common/thread_states.sql
new file mode 100644
index 0000000..2e9dce1
--- /dev/null
+++ b/src/trace_processor/perfetto_sql/stdlib/common/thread_states.sql
@@ -0,0 +1,111 @@
+--
+-- Copyright 2022 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+INCLUDE PERFETTO MODULE common.timestamps;
+INCLUDE PERFETTO MODULE common.cpus;
+
+-- TODO(altimin): this doesn't handle some corner cases which thread_state.ts
+-- handles (as complex strings manipulations in SQL are pretty painful),
+-- but they are pretty niche.
+-- Translates the thread state name from a single-letter shorthard to
+-- a human-readable name.
+CREATE PERFETTO FUNCTION internal_translate_thread_state_name(name STRING)
+RETURNS STRING AS
+SELECT CASE $name
+WHEN 'Running' THEN 'Running'
+WHEN 'R' THEN 'Runnable'
+WHEN 'R+' THEN 'Runnable (Preempted)'
+WHEN 'S' THEN 'Sleeping'
+WHEN 'D' THEN 'Uninterruptible Sleep'
+WHEN 'T' THEN 'Stopped'
+WHEN 't' THEN 'Traced'
+WHEN 'X' THEN 'Exit (Dead)'
+WHEN 'Z' THEN 'Exit (Zombie)'
+WHEN 'x' THEN 'Task Dead'
+WHEN 'I' THEN 'Idle'
+WHEN 'K' THEN 'Wakekill'
+WHEN 'W' THEN 'Waking'
+WHEN 'P' THEN 'Parked'
+WHEN 'N' THEN 'No Load'
+ELSE $name
+END;
+
+-- Returns a human-readable name for a thread state.
+-- @arg id INT Thread state id.
+-- @ret STRING Human-readable name for the thread state.
+CREATE PERFETTO FUNCTION human_readable_thread_state_name(id INT)
+RETURNS STRING AS
+WITH data AS (
+ SELECT
+ internal_translate_thread_state_name(state) AS state,
+ (CASE io_wait
+ WHEN 1 THEN ' (IO)'
+ WHEN 0 THEN ' (non-IO)'
+ ELSE ''
+ END) AS io_wait
+ FROM thread_state
+ WHERE id = $id
+)
+SELECT
+ printf('%s%s', state, io_wait)
+FROM data;
+
+-- Returns an aggregation of thread states (by state and cpu) for a given
+-- interval of time for a given thread.
+-- @arg ts INT The start of the interval.
+-- @arg dur INT The duration of the interval.
+-- @arg utid INT The utid of the thread.
+-- @column state Human-readable thread state name.
+-- @column raw_state Raw thread state name, alias of `thread_state.state`.
+-- @column cpu_type The type of CPU if available (e.g. "big" / "mid" / "little").
+-- @column cpu The CPU index.
+-- @column blocked_function The name of the kernel function execution is blocked in.
+-- @column dur The total duration.
+CREATE PERFETTO FUNCTION thread_state_summary_for_interval(
+ ts INT, dur INT, utid INT)
+RETURNS TABLE(
+ state STRING, raw_state STRING, cpu_type STRING, cpu INT, blocked_function STRING, dur INT)
+AS
+WITH
+states_starting_inside AS (
+ SELECT id
+ FROM thread_state
+ WHERE $ts <= ts
+ AND ts <= $ts + $dur
+ AND utid = $utid
+),
+first_state_starting_before AS (
+ SELECT id
+ FROM thread_state
+ WHERE ts < $ts AND utid = $utid
+ ORDER BY ts DESC
+ LIMIT 1
+),
+relevant_states AS (
+ SELECT * FROM states_starting_inside
+ UNION ALL
+ SELECT * FROM first_state_starting_before
+)
+SELECT
+ human_readable_thread_state_name(id) as state,
+ state as raw_state,
+ guess_cpu_size(cpu) as cpu_type,
+ cpu,
+ blocked_function,
+ sum(spans_overlapping_dur($ts, $dur, ts, dur)) as dur
+FROM thread_state
+JOIN relevant_states USING (id)
+GROUP BY state, raw_state, cpu_type, cpu, blocked_function
+ORDER BY dur desc;
\ No newline at end of file
diff --git a/src/trace_processor/perfetto_sql/stdlib/experimental/thread_executing_span.sql b/src/trace_processor/perfetto_sql/stdlib/experimental/thread_executing_span.sql
index b0f9310..34531c8 100644
--- a/src/trace_processor/perfetto_sql/stdlib/experimental/thread_executing_span.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/experimental/thread_executing_span.sql
@@ -406,7 +406,7 @@
-- Limited thread_state view that will later be span joined with the |experimental_thread_executing_span_graph|.
CREATE VIEW internal_span_thread_state_view
-AS SELECT id AS thread_state_id, ts, dur, utid, state, blocked_function as function, cpu FROM thread_state;
+AS SELECT id AS thread_state_id, ts, dur, utid, state, blocked_function as function, io_wait, cpu FROM thread_state;
-- |experimental_thread_executing_span_graph| span joined with thread_state information.
CREATE VIRTUAL TABLE internal_span_graph_thread_state_sp
@@ -431,7 +431,7 @@
-- Limited |experimental_thread_executing_span_graph| + thread_state view.
CREATE VIEW internal_span_graph_thread_state
AS
-SELECT ts, dur, id, thread_state_id, state, function, cpu
+SELECT ts, dur, id, thread_state_id, state, function, io_wait, cpu
FROM internal_span_graph_thread_state_sp;
-- Limited |experimental_thread_executing_span_graph| + slice view.
@@ -460,7 +460,8 @@
thread_state.ts + thread_state.dur AS thread_state_end_ts,
thread_state.state,
thread_state.function,
- thread_state.cpu
+ thread_state.cpu,
+ thread_state.io_wait
FROM span
JOIN internal_span_graph_thread_state_sp thread_state USING(id)
)
@@ -473,6 +474,7 @@
state,
function,
cpu,
+ io_wait,
critical_path_id,
critical_path_blocked_dur,
critical_path_blocked_state,
@@ -506,6 +508,7 @@
state AS self_state,
blocked_function AS self_function,
cpu AS self_cpu,
+ io_wait AS self_io_wait,
name AS self_slice_name,
depth AS self_slice_depth
FROM internal_self_sp;
@@ -552,8 +555,12 @@
self_slice_id,
self_slice_name,
self_slice_depth,
+ self_function,
+ self_io_wait,
thread_state_id,
state,
+ function,
+ io_wait,
slice_id,
slice_name,
slice_depth,
@@ -561,8 +568,7 @@
utid,
MAX(ts, $ts) AS ts,
MIN(ts + dur, $ts + $dur) AS end_ts,
- critical_path_utid,
- critical_path_blocked_function
+ critical_path_utid
FROM internal_self_and_critical_path_sp
WHERE dur > 0 AND critical_path_utid = $critical_path_utid
),
@@ -578,8 +584,12 @@
self_slice_id,
self_slice_name,
self_slice_depth,
+ self_function,
+ self_io_wait,
thread_state_id,
state,
+ function,
+ io_wait,
slice_id,
slice_name,
slice_depth,
@@ -588,8 +598,7 @@
ts,
end_ts - ts AS dur,
critical_path_utid,
- utid,
- critical_path_blocked_function
+ utid
FROM relevant_spans_starts
WHERE dur > 0
),
@@ -614,7 +623,19 @@
dur,
utid,
1 AS stack_depth,
- IIF(self_state GLOB 'R*', NULL, 'kernel function: ' || critical_path_blocked_function) AS name,
+ IIF(self_state GLOB 'R*', NULL, 'kernel function: ' || self_function) AS name,
+ 'thread_state' AS table_name,
+ critical_path_utid
+ FROM relevant_spans
+ UNION ALL
+ -- Builds the self kernel io_wait
+ SELECT
+ self_thread_state_id AS id,
+ ts,
+ dur,
+ utid,
+ 2 AS stack_depth,
+ IIF(self_state GLOB 'R*', NULL, 'io_wait: ' || self_io_wait) AS name,
'thread_state' AS table_name,
critical_path_utid
FROM relevant_spans
@@ -625,7 +646,7 @@
ts,
dur,
thread.utid,
- 2 AS stack_depth,
+ 3 AS stack_depth,
IIF($enable_process_name, 'process_name: ' || process.name, NULL) AS name,
'thread_state' AS table_name,
critical_path_utid
@@ -641,7 +662,7 @@
ts,
dur,
thread.utid,
- 3 AS stack_depth,
+ 4 AS stack_depth,
IIF($enable_thread_name, 'thread_name: ' || thread.name, NULL) AS name,
'thread_state' AS table_name,
critical_path_utid
@@ -657,7 +678,7 @@
slice.ts,
slice.dur,
slice.utid,
- anc.depth + 4 AS stack_depth,
+ anc.depth + 5 AS stack_depth,
IIF($enable_self_slice, anc.name, NULL) AS name,
'slice' AS table_name,
critical_path_utid
@@ -670,7 +691,7 @@
ts,
dur,
utid,
- self_slice_depth + 4 AS stack_depth,
+ self_slice_depth + 5 AS stack_depth,
IIF($enable_self_slice, self_slice_name, NULL) AS name,
'slice' AS table_name,
critical_path_utid
@@ -693,6 +714,8 @@
SELECT
thread_state_id,
state,
+ function,
+ io_wait,
slice_id,
slice_name,
slice_depth,
@@ -733,10 +756,8 @@
'thread_state' AS table_name,
critical_path_utid
FROM critical_path_span
- LEFT JOIN thread
- USING (utid)
- LEFT JOIN process
- USING (upid)
+ JOIN thread USING (utid)
+ LEFT JOIN process USING (upid)
UNION ALL
-- Builds the critical_path thread_name
SELECT
@@ -749,10 +770,33 @@
'thread_state' AS table_name,
critical_path_utid
FROM critical_path_span
- JOIN thread
- USING (utid)
- JOIN process
- USING (upid)
+ JOIN thread USING (utid)
+ UNION ALL
+ -- Builds the critical_path kernel blocked_function
+ SELECT
+ thread_state_id AS id,
+ ts,
+ dur,
+ thread.utid,
+ start_depth + 3 AS stack_depth,
+ 'blocking kernel_function: ' || function,
+ 'thread_state' AS table_name,
+ critical_path_utid
+ FROM critical_path_span
+ JOIN thread USING (utid)
+ UNION ALL
+ -- Builds the critical_path kernel io_wait
+ SELECT
+ thread_state_id AS id,
+ ts,
+ dur,
+ thread.utid,
+ start_depth + 4 AS stack_depth,
+ 'blocking io_wait: ' || io_wait,
+ 'thread_state' AS table_name,
+ critical_path_utid
+ FROM critical_path_span
+ JOIN thread USING (utid)
UNION ALL
-- Builds the critical_path 'ancestor' slice stack
SELECT
@@ -760,7 +804,7 @@
slice.ts,
slice.dur,
slice.utid,
- anc.depth + start_depth + 3 AS stack_depth,
+ anc.depth + start_depth + 5 AS stack_depth,
IIF($enable_critical_path_slice, anc.name, NULL) AS name,
'slice' AS table_name,
critical_path_utid
@@ -773,7 +817,7 @@
ts,
dur,
utid,
- slice_depth + start_depth + 3 AS stack_depth,
+ slice_depth + start_depth + 5 AS stack_depth,
IIF($enable_critical_path_slice, slice_name, NULL) AS name,
'slice' AS table_name,
critical_path_utid
diff --git a/src/trace_processor/rpc/BUILD.gn b/src/trace_processor/rpc/BUILD.gn
index 8604153..26b7528 100644
--- a/src/trace_processor/rpc/BUILD.gn
+++ b/src/trace_processor/rpc/BUILD.gn
@@ -23,9 +23,9 @@
# interface) and by the :httpd module for the HTTP interface.
source_set("rpc") {
sources = [
+ "query_result_serializer.cc",
"rpc.cc",
"rpc.h",
- "query_result_serializer.cc",
]
deps = [
"..:lib",
@@ -44,8 +44,10 @@
}
# Static library target for RPC code. Needed for BigTrace in Google3.
-static_library("trace_processor_rpc") {
- public_deps = [ ":rpc" ]
+if (is_perfetto_build_generator) {
+ static_library("trace_processor_rpc") {
+ public_deps = [ ":rpc" ]
+ }
}
perfetto_unittest_source_set("unittests") {
diff --git a/src/trace_processor/rpc/rpc.cc b/src/trace_processor/rpc/rpc.cc
index 031e3c8..68e0732 100644
--- a/src/trace_processor/rpc/rpc.cc
+++ b/src/trace_processor/rpc/rpc.cc
@@ -131,23 +131,29 @@
using ProtoEnum = protos::pbzero::MetatraceCategories;
TraceProcessor::MetatraceCategories MetatraceCategoriesToPublicEnum(
ProtoEnum categories) {
- switch (categories) {
- case ProtoEnum::QUERY_TIMELINE:
- return TraceProcessor::MetatraceCategories::QUERY_TIMELINE;
- case ProtoEnum::QUERY_DETAILED:
- return TraceProcessor::MetatraceCategories::QUERY_DETAILED;
- case ProtoEnum::FUNCTION_CALL:
- return TraceProcessor::MetatraceCategories::FUNCTION_CALL;
- case ProtoEnum::DB:
- return TraceProcessor::MetatraceCategories::DB;
- case ProtoEnum::API_TIMELINE:
- return TraceProcessor::MetatraceCategories::API_TIMELINE;
- case ProtoEnum::ALL:
- return TraceProcessor::MetatraceCategories::ALL;
- case ProtoEnum::NONE:
- return TraceProcessor::MetatraceCategories::NONE;
+ TraceProcessor::MetatraceCategories result =
+ TraceProcessor::MetatraceCategories::NONE;
+ if (categories & ProtoEnum::QUERY_TIMELINE) {
+ result = static_cast<TraceProcessor::MetatraceCategories>(
+ result | TraceProcessor::MetatraceCategories::QUERY_TIMELINE);
}
- return TraceProcessor::MetatraceCategories::NONE;
+ if (categories & ProtoEnum::QUERY_DETAILED) {
+ result = static_cast<TraceProcessor::MetatraceCategories>(
+ result | TraceProcessor::MetatraceCategories::QUERY_DETAILED);
+ }
+ if (categories & ProtoEnum::FUNCTION_CALL) {
+ result = static_cast<TraceProcessor::MetatraceCategories>(
+ result | TraceProcessor::MetatraceCategories::FUNCTION_CALL);
+ }
+ if (categories & ProtoEnum::DB) {
+ result = static_cast<TraceProcessor::MetatraceCategories>(
+ result | TraceProcessor::MetatraceCategories::DB);
+ }
+ if (categories & ProtoEnum::API_TIMELINE) {
+ result = static_cast<TraceProcessor::MetatraceCategories>(
+ result | TraceProcessor::MetatraceCategories::API_TIMELINE);
+ }
+ return result;
}
} // namespace
diff --git a/src/trace_processor/sorter/trace_sorter.cc b/src/trace_processor/sorter/trace_sorter.cc
index f72c892..708def9 100644
--- a/src/trace_processor/sorter/trace_sorter.cc
+++ b/src/trace_processor/sorter/trace_sorter.cc
@@ -177,6 +177,10 @@
void TraceSorter::ParseTracePacket(const TimestampedEvent& event) {
TraceTokenBuffer::Id id = GetTokenBufferId(event);
switch (static_cast<TimestampedEvent::Type>(event.event_type)) {
+ case TimestampedEvent::Type::kTraceBlobView:
+ parser_->ParseTraceBlobView(event.ts,
+ token_buffer_.Extract<TraceBlobView>(id));
+ return;
case TimestampedEvent::Type::kTracePacket:
parser_->ParseTracePacket(event.ts,
token_buffer_.Extract<TracePacketData>(id));
@@ -224,6 +228,7 @@
case TimestampedEvent::Type::kTrackEvent:
case TimestampedEvent::Type::kSystraceLine:
case TimestampedEvent::Type::kTracePacket:
+ case TimestampedEvent::Type::kTraceBlobView:
case TimestampedEvent::Type::kJsonValue:
case TimestampedEvent::Type::kFuchsiaRecord:
PERFETTO_FATAL("Invalid event type");
@@ -235,6 +240,9 @@
const TimestampedEvent& event) {
TraceTokenBuffer::Id id = GetTokenBufferId(event);
switch (static_cast<TimestampedEvent::Type>(event.event_type)) {
+ case TimestampedEvent::Type::kTraceBlobView:
+ base::ignore_result(token_buffer_.Extract<TraceBlobView>(id));
+ return;
case TimestampedEvent::Type::kTracePacket:
base::ignore_result(token_buffer_.Extract<TracePacketData>(id));
return;
diff --git a/src/trace_processor/sorter/trace_sorter.h b/src/trace_processor/sorter/trace_sorter.h
index 1e0f25a..9c26007 100644
--- a/src/trace_processor/sorter/trace_sorter.h
+++ b/src/trace_processor/sorter/trace_sorter.h
@@ -95,6 +95,11 @@
SortingMode);
~TraceSorter();
+ inline void PushTraceBlobView(int64_t timestamp, TraceBlobView tbv) {
+ TraceTokenBuffer::Id id = token_buffer_.Append(std::move(tbv));
+ AppendNonFtraceEvent(timestamp, TimestampedEvent::Type::kTraceBlobView, id);
+ }
+
inline void PushTracePacket(int64_t timestamp,
RefPtr<PacketSequenceStateGeneration> state,
TraceBlobView tbv) {
@@ -196,6 +201,7 @@
struct TimestampedEvent {
enum class Type : uint8_t {
kFtraceEvent,
+ kTraceBlobView,
kTracePacket,
kInlineSchedSwitch,
kInlineSchedWaking,
diff --git a/src/trace_processor/sqlite/sql_source.cc b/src/trace_processor/sqlite/sql_source.cc
index 570e87e..ee86e8c 100644
--- a/src/trace_processor/sqlite/sql_source.cc
+++ b/src/trace_processor/sqlite/sql_source.cc
@@ -313,7 +313,7 @@
void SqlSource::Rewriter::Rewrite(uint32_t rewritten_start,
uint32_t rewritten_end,
SqlSource source) {
- PERFETTO_CHECK(rewritten_start < rewritten_end);
+ PERFETTO_CHECK(rewritten_start <= rewritten_end);
PERFETTO_CHECK(rewritten_end <= orig_.rewritten_sql.size());
uint32_t original_start =
diff --git a/src/trace_processor/sqlite/sqlite_utils.cc b/src/trace_processor/sqlite/sqlite_utils.cc
index 3afb3ea..4165f2d 100644
--- a/src/trace_processor/sqlite/sqlite_utils.cc
+++ b/src/trace_processor/sqlite/sqlite_utils.cc
@@ -18,6 +18,8 @@
#include <bitset>
#include <sstream>
#include "perfetto/base/status.h"
+#include "perfetto/ext/base/string_utils.h"
+#include "perfetto/trace_processor/basic_types.h"
namespace perfetto {
namespace trace_processor {
@@ -136,6 +138,8 @@
base::CaseInsensitiveEqual(raw_type, "BOOLEAN") ||
base::CaseInsensitiveEqual(raw_type, "INTEGER")) {
type = SqlValue::Type::kLong;
+ } else if (base::CaseInsensitiveEqual(raw_type, "BLOB")) {
+ type = SqlValue::Type::kBytes;
} else if (!*raw_type) {
PERFETTO_DLOG("Unknown column type for %s %s", raw_table_name.c_str(),
name);
diff --git a/src/trace_processor/storage/metadata.h b/src/trace_processor/storage/metadata.h
index 88eac06..1fa85ae 100644
--- a/src/trace_processor/storage/metadata.h
+++ b/src/trace_processor/storage/metadata.h
@@ -29,6 +29,7 @@
// Compile time list of metadata items.
// clang-format off
#define PERFETTO_TP_METADATA(F) \
+ F(all_data_source_flushed_ns, KeyType::kMulti, Variadic::kInt), \
F(all_data_source_started_ns, KeyType::kSingle, Variadic::kInt), \
F(android_build_fingerprint, KeyType::kSingle, Variadic::kString), \
F(android_sdk_version, KeyType::kSingle, Variadic::kInt), \
@@ -48,6 +49,7 @@
F(system_name, KeyType::kSingle, Variadic::kString), \
F(system_release, KeyType::kSingle, Variadic::kString), \
F(system_version, KeyType::kSingle, Variadic::kString), \
+ F(timezone_off_mins, KeyType::kSingle, Variadic::kInt), \
F(trace_config_pbtxt, KeyType::kSingle, Variadic::kString), \
F(trace_size_bytes, KeyType::kSingle, Variadic::kInt), \
F(trace_time_clock_id, KeyType::kSingle, Variadic::kInt), \
diff --git a/src/trace_processor/util/descriptors.cc b/src/trace_processor/util/descriptors.cc
index bd365f8..96833ed 100644
--- a/src/trace_processor/util/descriptors.cc
+++ b/src/trace_processor/util/descriptors.cc
@@ -239,7 +239,8 @@
const std::string file_name = file.name().ToStdString();
if (base::StartsWithAny(file_name, skip_prefixes))
continue;
- if (processed_files_.find(file_name) != processed_files_.end()) {
+ if (!merge_existing_messages &&
+ processed_files_.find(file_name) != processed_files_.end()) {
// This file has been loaded once already. Skip.
continue;
}
diff --git a/src/trace_processor/util/sql_argument.cc b/src/trace_processor/util/sql_argument.cc
index 11cd010..f9ac83c 100644
--- a/src/trace_processor/util/sql_argument.cc
+++ b/src/trace_processor/util/sql_argument.cc
@@ -23,6 +23,9 @@
namespace sql_argument {
bool IsValidName(base::StringView str) {
+ if (str.empty()) {
+ return false;
+ }
auto pred = [](char c) { return !(isalnum(c) || c == '_'); };
return std::find_if(str.begin(), str.end(), pred) == str.end();
}
@@ -30,21 +33,29 @@
std::optional<Type> ParseType(base::StringView str) {
if (str == "BOOL") {
return Type::kBool;
- } else if (str == "INT") {
+ }
+ if (str == "INT") {
return Type::kInt;
- } else if (str == "UINT") {
+ }
+ if (str == "UINT") {
return Type::kUint;
- } else if (str == "LONG") {
+ }
+ if (str == "LONG") {
return Type::kLong;
- } else if (str == "FLOAT") {
+ }
+ if (str == "FLOAT") {
return Type::kFloat;
- } else if (str == "DOUBLE") {
+ }
+ if (str == "DOUBLE") {
return Type::kDouble;
- } else if (str == "STRING") {
+ }
+ if (str == "STRING") {
return Type::kString;
- } else if (str == "PROTO") {
+ }
+ if (str == "PROTO") {
return Type::kProto;
- } else if (str == "BYTES") {
+ }
+ if (str == "BYTES") {
return Type::kBytes;
}
return std::nullopt;
@@ -123,6 +134,21 @@
return base::OkStatus();
}
+std::string SerializeArguments(const std::vector<ArgumentDefinition>& args) {
+ bool comma = false;
+ std::string serialized;
+ for (const auto& arg : args) {
+ if (comma) {
+ serialized.append(", ");
+ }
+ comma = true;
+ serialized.append(arg.name().c_str());
+ serialized.push_back(' ');
+ serialized.append(TypeToHumanFriendlyString(arg.type()));
+ }
+ return serialized;
+}
+
} // namespace sql_argument
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/trace_processor/util/sql_argument.h b/src/trace_processor/util/sql_argument.h
index 8876bed..3856523 100644
--- a/src/trace_processor/util/sql_argument.h
+++ b/src/trace_processor/util/sql_argument.h
@@ -101,6 +101,9 @@
base::Status ParseArgumentDefinitions(const std::string& args,
std::vector<ArgumentDefinition>& out);
+// Serialises the given argument list into a string.
+std::string SerializeArguments(const std::vector<ArgumentDefinition>& args);
+
} // namespace sql_argument
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/traced/probes/sys_stats/sys_stats_data_source.cc b/src/traced/probes/sys_stats/sys_stats_data_source.cc
index e5c02a9..32cd67f 100644
--- a/src/traced/probes/sys_stats/sys_stats_data_source.cc
+++ b/src/traced/probes/sys_stats/sys_stats_data_source.cc
@@ -438,7 +438,7 @@
auto* cpu_stat = sys_stats->add_cpu_stat();
cpu_stat->set_cpu_id(static_cast<uint32_t>(cpu_id));
cpu_stat->set_user_ns(cpu_times[0] * ns_per_user_hz_);
- cpu_stat->set_user_ice_ns(cpu_times[1] * ns_per_user_hz_);
+ cpu_stat->set_user_nice_ns(cpu_times[1] * ns_per_user_hz_);
cpu_stat->set_system_mode_ns(cpu_times[2] * ns_per_user_hz_);
cpu_stat->set_idle_ns(cpu_times[3] * ns_per_user_hz_);
cpu_stat->set_io_wait_ns(cpu_times[4] * ns_per_user_hz_);
diff --git a/src/traced_relay/BUILD.gn b/src/traced_relay/BUILD.gn
index d4e27cc..6b49f94 100644
--- a/src/traced_relay/BUILD.gn
+++ b/src/traced_relay/BUILD.gn
@@ -14,6 +14,7 @@
import("../../gn/perfetto.gni")
import("../../gn/perfetto_component.gni")
+import("../../gn/test.gni")
executable("traced_relay") {
deps = [
@@ -45,3 +46,33 @@
"//src/ipc:perfetto_ipc",
]
}
+
+perfetto_unittest_source_set("unittests") {
+ testonly = true
+ deps = [
+ ":lib",
+ "../../gn:default_deps",
+ "../../gn:gtest_and_gmock",
+ "../base",
+ "../base:test_support",
+ "../base/threading",
+ "//src/ipc:perfetto_ipc",
+ ]
+ sources = [
+ "relay_service_unittest.cc",
+ "socket_relay_handler_unittest.cc",
+ ]
+}
+
+source_set("integrationtests") {
+ testonly = true
+ deps = [
+ ":lib",
+ "../../gn:default_deps",
+ "../../gn:gtest_and_gmock",
+ "../../test:test_helper",
+ "../base",
+ "../base:test_support",
+ ]
+ sources = [ "relay_service_integrationtest.cc" ]
+}
diff --git a/src/traced_relay/relay_service.cc b/src/traced_relay/relay_service.cc
index 4b1dc6b..1ef5855 100644
--- a/src/traced_relay/relay_service.cc
+++ b/src/traced_relay/relay_service.cc
@@ -70,7 +70,10 @@
IPCFrame ipc_frame;
ipc_frame.set_request_id(0);
auto* set_peer_identity = ipc_frame.mutable_set_peer_identity();
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+ PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
set_peer_identity->set_pid(server_conn->peer_pid_linux());
+#endif
set_peer_identity->set_uid(
static_cast<int32_t>(server_conn->peer_uid_posix()));
diff --git a/src/traced_relay/relay_service_integrationtest.cc b/src/traced_relay/relay_service_integrationtest.cc
new file mode 100644
index 0000000..7e29041
--- /dev/null
+++ b/src/traced_relay/relay_service_integrationtest.cc
@@ -0,0 +1,109 @@
+/*
+ * 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.
+ */
+
+#include <memory>
+#include "src/traced_relay/relay_service.h"
+
+#include "src/base/test/test_task_runner.h"
+#include "test/gtest_and_gmock.h"
+#include "test/test_helper.h"
+
+#include "protos/perfetto/config/test_config.gen.h"
+#include "protos/perfetto/config/trace_config.gen.h"
+#include "protos/perfetto/trace/test_event.gen.h"
+
+namespace perfetto {
+namespace {
+
+TEST(TracedRelayIntegrationTest, BasicCase) {
+ base::TestTaskRunner task_runner;
+
+ std::string sock_name;
+ {
+ // Set up a server UnixSocket to find an unused TCP port.
+ base::UnixSocket::EventListener event_listener;
+ auto srv = base::UnixSocket::Listen("127.0.0.1:0", &event_listener,
+ &task_runner, base::SockFamily::kInet,
+ base::SockType::kStream);
+ ASSERT_TRUE(srv->is_listening());
+ sock_name = srv->GetSockAddr();
+ // Shut down |srv| here to free the port. It's unlikely that the port will
+ // be taken by another process so quickly before we reach the code below.
+ }
+
+ TestHelper helper(&task_runner, TestHelper::Mode::kStartDaemons,
+ sock_name.c_str());
+ ASSERT_EQ(helper.num_producers(), 1u);
+ helper.StartServiceIfRequired();
+
+ auto relay_service = std::make_unique<RelayService>(&task_runner);
+
+ relay_service->Start("@traced_relay", sock_name.c_str());
+
+ auto producer_connected =
+ task_runner.CreateCheckpoint("perfetto.FakeProducer.connected");
+ auto noop = []() {};
+ auto connected = [&]() { task_runner.PostTask(producer_connected); };
+
+ // We won't use the built-in fake producer and will start our own.
+ auto producer_thread = std::make_unique<FakeProducerThread>(
+ "@traced_relay", connected, noop, noop, "perfetto.FakeProducer");
+ producer_thread->Connect();
+ task_runner.RunUntilCheckpoint("perfetto.FakeProducer.connected");
+
+ helper.ConnectConsumer();
+ helper.WaitForConsumerConnect();
+
+ TraceConfig trace_config;
+ trace_config.add_buffers()->set_size_kb(1024);
+ trace_config.set_duration_ms(200);
+
+ static constexpr uint32_t kMsgSize = 1024;
+ static constexpr uint32_t kRandomSeed = 42;
+ // Enable the producer.
+ auto* ds_config = trace_config.add_data_sources()->mutable_config();
+ ds_config->set_name("perfetto.FakeProducer");
+ ds_config->set_target_buffer(0);
+ ds_config->mutable_for_testing()->set_seed(kRandomSeed);
+ ds_config->mutable_for_testing()->set_message_count(12);
+ ds_config->mutable_for_testing()->set_message_size(kMsgSize);
+ ds_config->mutable_for_testing()->set_send_batch_on_register(true);
+
+ helper.StartTracing(trace_config);
+ helper.WaitForTracingDisabled();
+
+ helper.ReadData();
+ helper.WaitForReadData();
+
+ const auto& packets = helper.trace();
+ ASSERT_EQ(packets.size(), 12u);
+
+ // The producer is connected from this process. The relay service will inject
+ // the SetPeerIdentity message using the pid and euid of the current process.
+ auto pid = static_cast<int32_t>(getpid());
+ auto uid = static_cast<int32_t>(geteuid());
+
+ std::minstd_rand0 rnd_engine(kRandomSeed);
+ for (const auto& packet : packets) {
+ ASSERT_TRUE(packet.has_for_testing());
+ ASSERT_EQ(packet.trusted_pid(), pid);
+ ASSERT_EQ(packet.trusted_uid(), uid);
+ ASSERT_EQ(packet.for_testing().seq_value(), rnd_engine());
+ }
+}
+
+} // namespace
+} // namespace perfetto
diff --git a/src/traced_relay/relay_service_unittest.cc b/src/traced_relay/relay_service_unittest.cc
new file mode 100644
index 0000000..649f552
--- /dev/null
+++ b/src/traced_relay/relay_service_unittest.cc
@@ -0,0 +1,130 @@
+/*
+ * 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.
+ */
+
+#include "src/traced_relay/relay_service.h"
+
+#include <memory>
+
+#include "perfetto/ext/base/unix_socket.h"
+#include "protos/perfetto/ipc/wire_protocol.gen.h"
+#include "src/base/test/test_task_runner.h"
+#include "src/ipc/buffered_frame_deserializer.h"
+#include "test/gtest_and_gmock.h"
+
+namespace perfetto {
+namespace {
+
+using ::testing::_;
+using ::testing::Invoke;
+
+class TestEventListener : public base::UnixSocket::EventListener {
+ public:
+ MOCK_METHOD(void, OnDataAvailable, (base::UnixSocket*), (override));
+ MOCK_METHOD(void, OnConnect, (base::UnixSocket*, bool), (override));
+ MOCK_METHOD(void, OnNewIncomingConnection, (base::UnixSocket*));
+
+ void OnNewIncomingConnection(
+ base::UnixSocket*,
+ std::unique_ptr<base::UnixSocket> new_connection) override {
+ // Need to keep |new_connection| alive.
+ client_connection_ = std::move(new_connection);
+ OnNewIncomingConnection(client_connection_.get());
+ }
+
+ private:
+ std::unique_ptr<base::UnixSocket> client_connection_;
+};
+
+// Exercises the relay service and also validates that the relay service injects
+// a SetPeerIdentity message:
+//
+// producer (client UnixSocket) <- @producer.sock -> relay service
+// <- 127.0.0.1.* -> tcp_server (listening UnixSocet).
+TEST(RelayServiceTest, SetPeerIdentity) {
+ base::TestTaskRunner task_runner;
+ auto relay_service = std::make_unique<RelayService>(&task_runner);
+
+ // Set up a server UnixSocket to find an unused TCP port.
+ // The TCP connection emulates the socket to the host traced.
+ TestEventListener tcp_listener;
+ auto tcp_server = base::UnixSocket::Listen(
+ "127.0.0.1:0", &tcp_listener, &task_runner, base::SockFamily::kInet,
+ base::SockType::kStream);
+ ASSERT_TRUE(tcp_server->is_listening());
+ auto tcp_sock_name = tcp_server->GetSockAddr();
+ auto* unix_sock_name =
+ "@producer.sock"; // Use abstract unix socket for server socket.
+
+ // Start the relay service.
+ relay_service->Start(unix_sock_name, tcp_sock_name.c_str());
+
+ // Emulates the producer connection.
+ TestEventListener producer_listener;
+ auto producer = base::UnixSocket::Connect(
+ unix_sock_name, &producer_listener, &task_runner, base::SockFamily::kUnix,
+ base::SockType::kStream);
+ auto producer_connected = task_runner.CreateCheckpoint("producer_connected");
+ EXPECT_CALL(producer_listener, OnConnect(_, _))
+ .WillOnce(Invoke([&](base::UnixSocket* s, bool conn) {
+ EXPECT_TRUE(conn);
+ EXPECT_EQ(s, producer.get());
+ producer_connected();
+ }));
+ task_runner.RunUntilCheckpoint("producer_connected");
+
+ // Add some producer data.
+ ipc::Frame test_frame;
+ test_frame.add_data_for_testing("test_data");
+ auto test_data = ipc::BufferedFrameDeserializer::Serialize(test_frame);
+ producer->SendStr(test_data);
+
+ base::UnixSocket* tcp_client_connection = nullptr;
+ auto tcp_client_connected =
+ task_runner.CreateCheckpoint("tcp_client_connected");
+ EXPECT_CALL(tcp_listener, OnNewIncomingConnection(_))
+ .WillOnce(Invoke([&](base::UnixSocket* client) {
+ tcp_client_connection = client;
+ tcp_client_connected();
+ }));
+ task_runner.RunUntilCheckpoint("tcp_client_connected");
+
+ // Asserts that we can receive the SetPeerIdentity message.
+ auto peer_identity_recv = task_runner.CreateCheckpoint("peer_identity_recv");
+ ipc::BufferedFrameDeserializer deserializer;
+ EXPECT_CALL(tcp_listener, OnDataAvailable(_))
+ .WillRepeatedly(Invoke([&](base::UnixSocket* tcp_conn) {
+ auto buf = deserializer.BeginReceive();
+ auto rsize = tcp_conn->Receive(buf.data, buf.size);
+ EXPECT_TRUE(deserializer.EndReceive(rsize));
+
+ auto frame = deserializer.PopNextFrame();
+ EXPECT_TRUE(frame->has_set_peer_identity());
+
+ const auto& set_peer_identity = frame->set_peer_identity();
+ EXPECT_EQ(set_peer_identity.pid(), getpid());
+ EXPECT_EQ(set_peer_identity.uid(), static_cast<int32_t>(geteuid()));
+
+ frame = deserializer.PopNextFrame();
+ EXPECT_EQ(1u, frame->data_for_testing().size());
+ EXPECT_EQ(std::string("test_data"), frame->data_for_testing()[0]);
+
+ peer_identity_recv();
+ }));
+ task_runner.RunUntilCheckpoint("peer_identity_recv");
+}
+
+} // namespace
+} // namespace perfetto
diff --git a/src/traced_relay/socket_relay_handler.cc b/src/traced_relay/socket_relay_handler.cc
index 2930c86..e8aa556 100644
--- a/src/traced_relay/socket_relay_handler.cc
+++ b/src/traced_relay/socket_relay_handler.cc
@@ -29,7 +29,6 @@
#include "perfetto/ext/base/thread_checker.h"
#include "perfetto/ext/base/utils.h"
#include "perfetto/ext/base/watchdog.h"
-#include "perfetto/ext/base/watchdog_posix.h"
namespace perfetto {
namespace {
@@ -52,8 +51,8 @@
void FdPoller::Poll() {
PERFETTO_DCHECK_THREAD(thread_checker_);
- int num_fds =
- PERFETTO_EINTR(poll(&poll_fds_[0], poll_fds_.size(), kPollTimeoutMs));
+ int num_fds = PERFETTO_EINTR(poll(
+ &poll_fds_[0], static_cast<nfds_t>(poll_fds_.size()), kPollTimeoutMs));
if (num_fds == -1 && base::IsAgain(errno))
return; // Poll again.
PERFETTO_DCHECK(num_fds <= static_cast<int>(poll_fds_.size()));
diff --git a/src/traced_relay/socket_relay_handler_unittest.cc b/src/traced_relay/socket_relay_handler_unittest.cc
new file mode 100644
index 0000000..a96308a
--- /dev/null
+++ b/src/traced_relay/socket_relay_handler_unittest.cc
@@ -0,0 +1,204 @@
+/*
+ * 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.
+ */
+
+#include "src/traced_relay/socket_relay_handler.h"
+
+#include <chrono>
+#include <cstring>
+#include <memory>
+#include <random>
+#include <string>
+#include <thread>
+#include <utility>
+
+#include "perfetto/ext/base/threading/thread_pool.h"
+#include "perfetto/ext/base/unix_socket.h"
+
+#include "test/gtest_and_gmock.h"
+
+using testing::Values;
+
+namespace perfetto {
+namespace {
+
+using RawSocketPair = std::pair<base::UnixSocketRaw, base::UnixSocketRaw>;
+using RngValueType = std::minstd_rand0::result_type;
+
+struct TestClient {
+ RawSocketPair endpoint_sockets;
+ std::minstd_rand0 data_prng;
+ std::thread client_thread;
+};
+
+class SocketRelayHandlerTest : public ::testing::TestWithParam<uint32_t> {
+ protected:
+ void SetUp() override {
+ socket_relay_handler_ = std::make_unique<SocketRelayHandler>();
+
+ for (uint32_t i = 0; i < GetParam(); i++) {
+ TestClient client{SetUpEndToEndSockets(), std::minstd_rand0(i), {}};
+ test_clients_.push_back(std::move(client));
+ }
+ }
+ void TearDown() override { socket_relay_handler_ = nullptr; }
+
+ RawSocketPair SetUpEndToEndSockets() {
+ // Creates 2 SocketPairs:
+ // sock1 <-> sock2 <-> SocketRelayHandler <-> sock3 <-> sock4.
+ // sock2 and sock3 are transferred to the SocketRelayHandler.
+ // We test by reading and writing bidirectionally using sock1 and sock4.
+ auto [sock1, sock2] = base::UnixSocketRaw::CreatePairPosix(
+ base::SockFamily::kUnix, base::SockType::kStream);
+ sock2.SetBlocking(false);
+
+ auto [sock3, sock4] = base::UnixSocketRaw::CreatePairPosix(
+ base::SockFamily::kUnix, base::SockType::kStream);
+ sock3.SetBlocking(false);
+
+ auto socket_pair = std::make_unique<SocketPair>();
+ socket_pair->first.sock = std::move(sock2);
+ socket_pair->second.sock = std::move(sock3);
+
+ socket_relay_handler_->AddSocketPair(std::move(socket_pair));
+
+ RawSocketPair endpoint_sockets;
+ endpoint_sockets.first = std::move(sock1);
+ endpoint_sockets.second = std::move(sock4);
+
+ return endpoint_sockets;
+ }
+
+ std::unique_ptr<SocketRelayHandler> socket_relay_handler_;
+ std::vector<TestClient> test_clients_;
+ // Use fewer receiver threads than sender threads.
+ base::ThreadPool receiver_thread_pool_{1 + GetParam() / 10};
+};
+
+TEST(SocketWithBufferTest, EnqueueDequeue) {
+ SocketWithBuffer socket_with_buffer;
+ // No data initially.
+ EXPECT_EQ(0u, socket_with_buffer.data_size());
+
+ // Has room for writing some bytes into.
+ std::string data = "12345678901234567890";
+ EXPECT_GT(socket_with_buffer.available_bytes(), data.size());
+
+ memcpy(socket_with_buffer.buffer(), data.data(), data.size());
+ socket_with_buffer.EnqueueData(data.size());
+ EXPECT_EQ(data.size(), socket_with_buffer.data_size());
+
+ // Dequeue some bytes.
+ socket_with_buffer.DequeueData(5);
+ EXPECT_EQ(socket_with_buffer.data_size(), data.size() - 5);
+ std::string buffered_data(reinterpret_cast<char*>(socket_with_buffer.data()),
+ socket_with_buffer.data_size());
+ EXPECT_EQ(buffered_data, "678901234567890");
+}
+
+// Test the SocketRelayHander with randomized request and response data.
+TEST_P(SocketRelayHandlerTest, RandomizedRequestResponse) {
+ // The max message size in the number of RNG calls.
+ constexpr size_t kMaxMsgSizeRng = 1 << 20;
+
+ // Create the threads for sending and receiving data through the
+ // SocketRelayHandler.
+ for (auto& client : test_clients_) {
+ auto* thread_pool = &receiver_thread_pool_;
+
+ auto thread_func = [&client, thread_pool]() {
+ auto& rng = client.data_prng;
+
+ // The max number of requests.
+ const size_t num_requests = rng() % 50;
+
+ for (size_t j = 0; j < num_requests; j++) {
+ auto& send_endpoint = client.endpoint_sockets.first;
+ auto& receive_endpoint = client.endpoint_sockets.second;
+
+ auto req_size = rng() % kMaxMsgSizeRng;
+
+ // Generate the random request.
+ std::vector<RngValueType> request;
+ request.reserve(req_size);
+ for (size_t r = 0; r < req_size; r++) {
+ request.emplace_back(rng());
+ }
+
+ // Create a buffer for receiving the request.
+ std::vector<RngValueType> received_request(request.size());
+
+ std::mutex mutex;
+ std::condition_variable cv;
+ std::unique_lock<std::mutex> lock(mutex);
+ bool done = false;
+
+ // Blocking receive on the thread pool.
+ thread_pool->PostTask([&]() {
+ const size_t bytes_to_receive =
+ received_request.size() * sizeof(RngValueType);
+ uint8_t* receive_buffer =
+ reinterpret_cast<uint8_t*>(received_request.data());
+ size_t bytes_received = 0;
+
+ // Perform a blocking read until we received the expected bytes.
+ while (bytes_received < bytes_to_receive) {
+ ssize_t rsize = PERFETTO_EINTR(
+ receive_endpoint.Receive(receive_buffer + bytes_received,
+ bytes_to_receive - bytes_received));
+ if (rsize <= 0)
+ break;
+ bytes_received += static_cast<size_t>(rsize);
+
+ std::this_thread::yield(); // Adds some scheduling randomness.
+ }
+
+ std::lock_guard<std::mutex> inner_lock(mutex);
+ done = true;
+ cv.notify_one();
+ });
+
+ // Perform a blocking send of the request data.
+ PERFETTO_EINTR(send_endpoint.Send(
+ request.data(), request.size() * sizeof(RngValueType)));
+
+ // Wait until the request is fully received.
+ cv.wait(lock, [&done] { return done; });
+
+ // Check data integrity.
+ EXPECT_EQ(request, received_request);
+
+ // Add some randomness to timing.
+ std::this_thread::sleep_for(std::chrono::microseconds(rng() % 1000));
+
+ // Emulate the response by reversing the data flow direction.
+ std::swap(send_endpoint, receive_endpoint);
+ }
+ };
+
+ client.client_thread = std::thread(std::move(thread_func));
+ }
+
+ for (auto& client : test_clients_) {
+ client.client_thread.join();
+ }
+}
+
+INSTANTIATE_TEST_SUITE_P(ByConnections,
+ SocketRelayHandlerTest,
+ Values(1, 5, 50));
+
+} // namespace
+} // namespace perfetto
diff --git a/src/tracing/BUILD.gn b/src/tracing/BUILD.gn
index 19b3205..f0a04eb 100644
--- a/src/tracing/BUILD.gn
+++ b/src/tracing/BUILD.gn
@@ -92,7 +92,7 @@
"../../include/perfetto/tracing/core",
"../../protos/perfetto/common:zero",
"../../protos/perfetto/config:cpp",
- "../../protos/perfetto/config/interceptors:zero",
+ "../../protos/perfetto/config/interceptors:cpp",
"../../protos/perfetto/config/track_event:cpp",
"../base",
"core",
diff --git a/src/tracing/console_interceptor.cc b/src/tracing/console_interceptor.cc
index 2c3221f..a594409 100644
--- a/src/tracing/console_interceptor.cc
+++ b/src/tracing/console_interceptor.cc
@@ -33,7 +33,7 @@
#include "protos/perfetto/common/interceptor_descriptor.gen.h"
#include "protos/perfetto/config/data_source_config.gen.h"
#include "protos/perfetto/config/interceptor_config.gen.h"
-#include "protos/perfetto/config/interceptors/console_config.pbzero.h"
+#include "protos/perfetto/config/interceptors/console_config.gen.h"
#include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
#include "protos/perfetto/trace/trace_packet.pbzero.h"
#include "protos/perfetto/trace/trace_packet_defaults.pbzero.h"
@@ -275,13 +275,13 @@
#else
bool use_colors = false;
#endif
- protos::pbzero::ConsoleConfig::Decoder config(
- args.config.interceptor_config().console_config_raw());
+ const protos::gen::ConsoleConfig& config =
+ args.config.interceptor_config().console_config();
if (config.has_enable_colors())
use_colors = config.enable_colors();
- if (config.output() == protos::pbzero::ConsoleConfig::OUTPUT_STDOUT) {
+ if (config.output() == protos::gen::ConsoleConfig::OUTPUT_STDOUT) {
fd = STDOUT_FILENO;
- } else if (config.output() == protos::pbzero::ConsoleConfig::OUTPUT_STDERR) {
+ } else if (config.output() == protos::gen::ConsoleConfig::OUTPUT_STDERR) {
fd = STDERR_FILENO;
}
fd_ = fd;
diff --git a/src/tracing/core/trace_buffer.cc b/src/tracing/core/trace_buffer.cc
index f0e9d31..bd5e4a5 100644
--- a/src/tracing/core/trace_buffer.cc
+++ b/src/tracing/core/trace_buffer.cc
@@ -75,6 +75,7 @@
return false;
}
size_ = size;
+ used_size_ = 0;
stats_.set_buffer_size(size);
max_chunk_size_ = std::min(size, ChunkRecord::kMaxSize);
wptr_ = begin();
@@ -134,7 +135,7 @@
record.chunk_id = chunk_id;
record.writer_id = writer_id;
record.num_fragments = num_fragments;
- record.flags = chunk_flags;
+ record.flags = chunk_flags & ChunkRecord::kFlagsBitMask;
ChunkMeta::Key key(record);
// Check whether we have already copied the same chunk previously. This may
@@ -451,7 +452,7 @@
stats_.set_patches_succeeded(stats_.patches_succeeded() + patches_size);
if (!other_patches_pending) {
chunk_meta.flags &= ~kChunkNeedsPatching;
- chunk_record->flags = chunk_meta.flags;
+ chunk_record->flags = chunk_meta.flags & ChunkRecord::kFlagsBitMask;
}
return true;
}
@@ -915,8 +916,8 @@
// The assignments below must be done after Initialize().
- data_.EnsureCommitted(data_.size());
- memcpy(data_.Get(), src.data_.Get(), src.data_.size());
+ EnsureCommitted(src.used_size_);
+ memcpy(data_.Get(), src.data_.Get(), src.used_size_);
last_chunk_id_written_ = src.last_chunk_id_written_;
stats_ = src.stats_;
diff --git a/src/tracing/core/trace_buffer.h b/src/tracing/core/trace_buffer.h
index 9dea557..3ca3161 100644
--- a/src/tracing/core/trace_buffer.h
+++ b/src/tracing/core/trace_buffer.h
@@ -286,6 +286,7 @@
const WriterStatsMap& writer_stats() const { return writer_stats_; }
const TraceStats::BufferStats& stats() const { return stats_; }
size_t size() const { return size_; }
+ size_t used_size() const { return used_size_; }
OverwritePolicy overwrite_policy() const { return overwrite_policy_; }
bool has_data() const { return has_data_; }
@@ -338,6 +339,8 @@
uint16_t size;
uint8_t flags : 6; // See SharedMemoryABI::ChunkHeader::flags.
+ static constexpr size_t kFlagsBitMask = (1 << 6) - 1;
+
uint8_t is_padding : 1;
uint8_t unused_flag : 1;
@@ -613,11 +616,16 @@
ChunkRecord* GetChunkRecordAt(uint8_t* ptr) {
DcheckIsAlignedAndWithinBounds(ptr);
// We may be accessing a new (empty) record.
- data_.EnsureCommitted(
- static_cast<size_t>(ptr + sizeof(ChunkRecord) - begin()));
+ EnsureCommitted(static_cast<size_t>(ptr + sizeof(ChunkRecord) - begin()));
return reinterpret_cast<ChunkRecord*>(ptr);
}
+ void EnsureCommitted(size_t size) {
+ PERFETTO_DCHECK(size <= size_);
+ data_.EnsureCommitted(size);
+ used_size_ = std::max(used_size_, size);
+ }
+
void DiscardWrite();
// |src| can be nullptr (in which case |size| must be ==
@@ -639,7 +647,7 @@
DcheckIsAlignedAndWithinBounds(wptr);
// We may be writing to this area for the first time.
- data_.EnsureCommitted(static_cast<size_t>(wptr + record.size - begin()));
+ EnsureCommitted(static_cast<size_t>(wptr + record.size - begin()));
// Deliberately not a *D*CHECK.
PERFETTO_CHECK(wptr + sizeof(record) + size <= end());
@@ -676,6 +684,12 @@
base::PagedMemory data_;
size_t size_ = 0; // Size in bytes of |data_|.
+
+ // High watermark. The number of bytes (<= |size_|) written into the buffer
+ // before the first wraparound. This increases as data is written into the
+ // buffer and then saturates at |size_|. Used for CloneReadOnly().
+ size_t used_size_ = 0;
+
size_t max_chunk_size_ = 0; // Max size in bytes allowed for a chunk.
uint8_t* wptr_ = nullptr; // Write pointer.
diff --git a/src/tracing/core/trace_buffer_unittest.cc b/src/tracing/core/trace_buffer_unittest.cc
index 38d343d..44847dd 100644
--- a/src/tracing/core/trace_buffer_unittest.cc
+++ b/src/tracing/core/trace_buffer_unittest.cc
@@ -26,6 +26,7 @@
#include "perfetto/ext/tracing/core/shared_memory_abi.h"
#include "perfetto/ext/tracing/core/trace_packet.h"
#include "perfetto/protozero/proto_utils.h"
+#include "src/base/test/vm_test_utils.h"
#include "src/tracing/core/trace_buffer.h"
#include "src/tracing/test/fake_packet.h"
#include "test/gtest_and_gmock.h"
@@ -49,6 +50,22 @@
static constexpr uint8_t kChunkNeedsPatching =
SharedMemoryABI::ChunkHeader::kChunkNeedsPatching;
+ void TearDown() override {
+ // Test that the used_size() logic works and that all the data after that
+ // is zero-filled.
+ if (trace_buffer_) {
+ const size_t used_size = trace_buffer_->used_size();
+ ASSERT_LE(used_size, trace_buffer_->size());
+ trace_buffer_->EnsureCommitted(trace_buffer_->size());
+ bool zero_padded = true;
+ for (size_t i = used_size; i < trace_buffer_->size(); ++i) {
+ bool is_zero = static_cast<char*>(trace_buffer_->data_.Get())[i] == 0;
+ zero_padded = zero_padded && is_zero;
+ }
+ ASSERT_TRUE(zero_padded);
+ }
+ }
+
FakeChunk CreateChunk(ProducerID p, WriterID w, ChunkID c) {
return FakeChunk(trace_buffer_.get(), p, w, c);
}
@@ -144,6 +161,7 @@
return keys;
}
+ uint8_t* GetBufData(const TraceBuffer& buf) { return buf.begin(); }
TraceBuffer* trace_buffer() { return trace_buffer_.get(); }
size_t size_to_end() { return trace_buffer_->size_to_end(); }
@@ -1854,6 +1872,8 @@
.CopyIntoTraceBuffer());
}
+ ASSERT_EQ(trace_buffer()->used_size(), 32u * kNumWriters);
+
// Make some reads *before* cloning. This is to check that the behaviour of
// CloneReadOnly() is not affected by reads made before cloning.
// On every round (|num_pre_reads|), read a different number of packets.
@@ -1866,6 +1886,7 @@
// Now create a snapshot and make sure we always read all the packets.
std::unique_ptr<TraceBuffer> snap = trace_buffer()->CloneReadOnly();
+ ASSERT_EQ(snap->used_size(), 32u * kNumWriters);
snap->BeginRead();
for (char i = 'A'; i < 'A' + kNumWriters; i++) {
auto frags = ReadPacket(snap);
@@ -1929,4 +1950,69 @@
ASSERT_THAT(ReadPacket(snap), IsEmpty());
}
+TEST_F(TraceBufferTest, Clone_Wrapping) {
+ ResetBuffer(4096);
+ const size_t kFrgSize = 1024 - 16; // For perfect wrapping every 4 fragments.
+ for (WriterID i = 0; i < 6; i++) {
+ CreateChunk(ProducerID(1), WriterID(i), ChunkID(0))
+ .AddPacket(kFrgSize, static_cast<char>('a' + i))
+ .CopyIntoTraceBuffer();
+ }
+ std::unique_ptr<TraceBuffer> snap = trace_buffer()->CloneReadOnly();
+ ASSERT_EQ(snap->used_size(), snap->size());
+ snap->BeginRead();
+ ASSERT_THAT(ReadPacket(snap), ElementsAre(FakePacketFragment(kFrgSize, 'c')));
+ ASSERT_THAT(ReadPacket(snap), ElementsAre(FakePacketFragment(kFrgSize, 'd')));
+ ASSERT_THAT(ReadPacket(snap), ElementsAre(FakePacketFragment(kFrgSize, 'e')));
+ ASSERT_THAT(ReadPacket(snap), ElementsAre(FakePacketFragment(kFrgSize, 'f')));
+ ASSERT_THAT(ReadPacket(snap), IsEmpty());
+}
+
+TEST_F(TraceBufferTest, Clone_WrappingWithPadding) {
+ ResetBuffer(4096);
+ // First create one 2KB chunk, so the contents are [aaaaaaaa00000000].
+ CreateChunk(ProducerID(1), WriterID(0), ChunkID(0))
+ .AddPacket(2048, static_cast<char>('a'))
+ .CopyIntoTraceBuffer();
+
+ // Then write a 3KB chunk that fits in the buffer, but requires zero padding
+ // and restarting from the beginning, so the contents are [bbbbbbbbbbbb0000].
+ CreateChunk(ProducerID(1), WriterID(1), ChunkID(0))
+ .AddPacket(3192, static_cast<char>('b'))
+ .CopyIntoTraceBuffer();
+
+ ASSERT_EQ(trace_buffer()->used_size(), trace_buffer()->size());
+ std::unique_ptr<TraceBuffer> snap = trace_buffer()->CloneReadOnly();
+ ASSERT_EQ(snap->used_size(), snap->size());
+ snap->BeginRead();
+ ASSERT_THAT(ReadPacket(snap), ElementsAre(FakePacketFragment(3192, 'b')));
+ ASSERT_THAT(ReadPacket(snap), IsEmpty());
+}
+
+TEST_F(TraceBufferTest, Clone_CommitOnlyUsedSize) {
+ const size_t kPages = 32;
+ const size_t kPageSize = base::GetSysPageSize();
+ ResetBuffer(kPageSize * kPages);
+ CreateChunk(ProducerID(1), WriterID(0), ChunkID(0))
+ .AddPacket(1024, static_cast<char>('a'))
+ .CopyIntoTraceBuffer();
+
+ using base::vm_test_utils::IsMapped;
+ auto is_only_first_page_mapped = [&](const TraceBuffer& buf) {
+ bool first_mapped = IsMapped(GetBufData(buf), kPageSize);
+ bool rest_mapped = IsMapped(GetBufData(buf) + kPageSize, kPages - 1);
+ return first_mapped && !rest_mapped;
+ };
+
+ // If the test doesn't work as expected until here, there is no point checking
+ // that the same assumptions hold true on the cloned buffer. Various platforms
+ // can legitimately pre-fetch memory even if we don't page fault (also asan).
+ if (!is_only_first_page_mapped(*trace_buffer()))
+ GTEST_SKIP() << "VM commit detection not supported";
+
+ std::unique_ptr<TraceBuffer> snap = trace_buffer()->CloneReadOnly();
+ ASSERT_EQ(snap->used_size(), trace_buffer()->used_size());
+ ASSERT_TRUE(is_only_first_page_mapped(*snap));
+}
+
} // namespace perfetto
diff --git a/src/tracing/core/tracing_service_impl.cc b/src/tracing/core/tracing_service_impl.cc
index 9040ded..45ce1eb 100644
--- a/src/tracing/core/tracing_service_impl.cc
+++ b/src/tracing/core/tracing_service_impl.cc
@@ -3470,6 +3470,11 @@
protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
auto* info = packet->set_system_info();
info->set_tracing_service_version(base::GetVersionString());
+
+ std::optional<int32_t> tzoff = base::GetTimezoneOffsetMins();
+ if (tzoff.has_value())
+ info->set_timezone_off_mins(*tzoff);
+
#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
!PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
struct utsname uname_info;
diff --git a/src/tracing/internal/track_event_internal.cc b/src/tracing/internal/track_event_internal.cc
index 5d67ad8..c594adb 100644
--- a/src/tracing/internal/track_event_internal.cc
+++ b/src/tracing/internal/track_event_internal.cc
@@ -53,6 +53,7 @@
static constexpr const char kLegacySlowPrefix[] = "disabled-by-default-";
static constexpr const char kSlowTag[] = "slow";
static constexpr const char kDebugTag[] = "debug";
+static constexpr const char kFilteredEventName[] = "FILTERED";
constexpr auto kClockIdIncremental =
TrackEventIncrementalState::kClockIdIncremental;
@@ -515,7 +516,10 @@
void TrackEventInternal::WriteEventName(perfetto::DynamicString event_name,
perfetto::EventContext& event_ctx,
const TrackEventTlsState& tls_state) {
- if (PERFETTO_LIKELY(!tls_state.filter_dynamic_event_names)) {
+ if (PERFETTO_UNLIKELY(tls_state.filter_dynamic_event_names)) {
+ event_ctx.event()->set_name(kFilteredEventName,
+ sizeof(kFilteredEventName) - 1);
+ } else {
event_ctx.event()->set_name(event_name.value, event_name.length);
}
}
diff --git a/src/tracing/test/api_integrationtest.cc b/src/tracing/test/api_integrationtest.cc
index 0660ada..707e775 100644
--- a/src/tracing/test/api_integrationtest.cc
+++ b/src/tracing/test/api_integrationtest.cc
@@ -3560,7 +3560,8 @@
auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
ASSERT_EQ(3u, slices.size());
EXPECT_EQ("B:test.Event1", slices[0]);
- EXPECT_EQ(filter_dynamic_names ? "B:test" : "B:test.Event2", slices[1]);
+ EXPECT_EQ(filter_dynamic_names ? "B:test.FILTERED" : "B:test.Event2",
+ slices[1]);
EXPECT_EQ("B:test.Event3", slices[2]);
}
}
diff --git a/test/data/chrome_fcp_lcp_navigations.pftrace.sha256 b/test/data/chrome_fcp_lcp_navigations.pftrace.sha256
new file mode 100644
index 0000000..e4274e2
--- /dev/null
+++ b/test/data/chrome_fcp_lcp_navigations.pftrace.sha256
@@ -0,0 +1 @@
+ae01d849fbd75a98be1b7ddd5a8873217c377b393a1d5bbd788ed3364f7fefc3
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-chrome_rendering_desktop_select_slice_with_flows.png.sha256 b/test/data/ui-screenshots/ui-chrome_rendering_desktop_select_slice_with_flows.png.sha256
index 60017fd..3af03af 100644
--- a/test/data/ui-screenshots/ui-chrome_rendering_desktop_select_slice_with_flows.png.sha256
+++ b/test/data/ui-screenshots/ui-chrome_rendering_desktop_select_slice_with_flows.png.sha256
@@ -1 +1 @@
-d4047dbc06457be945fc612e629fca6a8ffaf15332fe76c653b1dd7a9a58d06b
\ No newline at end of file
+b51988f52a96b6576e714111c96018b8f13541a5ccd44b8bf9b1989185edd515
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-modal_dialog_show_dialog_1.png.sha256 b/test/data/ui-screenshots/ui-modal_dialog_show_dialog_1.png.sha256
index 655b0f9..e268e28 100644
--- a/test/data/ui-screenshots/ui-modal_dialog_show_dialog_1.png.sha256
+++ b/test/data/ui-screenshots/ui-modal_dialog_show_dialog_1.png.sha256
@@ -1 +1 @@
-fff7ed44c6100f75f93e21bdb9dbd093a8e67274d5eee255bf96e7d26a5614ca
\ No newline at end of file
+c753a17a466814841035cd006716128187d838c6c00fb7c600f810b6b36a7be9
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-modal_dialog_show_dialog_2.png.sha256 b/test/data/ui-screenshots/ui-modal_dialog_show_dialog_2.png.sha256
index 8febff4..a26ddd5 100644
--- a/test/data/ui-screenshots/ui-modal_dialog_show_dialog_2.png.sha256
+++ b/test/data/ui-screenshots/ui-modal_dialog_show_dialog_2.png.sha256
@@ -1 +1 @@
-31029a524c31322ce5c72f246de163b28047b839275a30b07061153a963a386b
\ No newline at end of file
+784304442fea618ab4ba75c16ccbc3d08fcfbe3ba19d7f7b1a470aa520d801a1
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_open_invalid_trace_from_blank_page.png.sha256 b/test/data/ui-screenshots/ui-routing_open_invalid_trace_from_blank_page.png.sha256
index 7a976a8..36fadce 100644
--- a/test/data/ui-screenshots/ui-routing_open_invalid_trace_from_blank_page.png.sha256
+++ b/test/data/ui-screenshots/ui-routing_open_invalid_trace_from_blank_page.png.sha256
@@ -1 +1 @@
-4486b3cba3f423541c1efd3f8dba5ee157e8215263c3250e8cefac6382905691
\ No newline at end of file
+ac4b7c10fb3ca19724f2f66b3b4b013cec90bac60d06d09b2bf96e30944750d8
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_invalid_trace.png.sha256 b/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_invalid_trace.png.sha256
index 99e5f07..4afc696 100644
--- a/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_invalid_trace.png.sha256
+++ b/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_invalid_trace.png.sha256
@@ -1 +1 @@
-4b96c2f13ce655e31532c21eac0652244803043ae6c56b5dcaec0e3158552256
\ No newline at end of file
+3b624767a7b2118e71fb4efa948ffe2021f1e59e30ddfadf0a07fa22203fbb67
\ No newline at end of file
diff --git a/test/trace_processor/diff_tests/chrome/chrome_dropped_frames_metric_test.sql b/test/trace_processor/diff_tests/chrome/chrome_dropped_frames_metric_test.sql
deleted file mode 100644
index 550a34f..0000000
--- a/test/trace_processor/diff_tests/chrome/chrome_dropped_frames_metric_test.sql
+++ /dev/null
@@ -1,18 +0,0 @@
---
--- Copyright 2021 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
-
-SELECT RUN_METRIC('experimental/chrome_dropped_frames.sql');
-
-SELECT * FROM dropped_frames_with_process_info;
diff --git a/test/trace_processor/diff_tests/chrome/chrome_speedometer_test.sql b/test/trace_processor/diff_tests/chrome/chrome_speedometer_test.sql
deleted file mode 100644
index 9b40054..0000000
--- a/test/trace_processor/diff_tests/chrome/chrome_speedometer_test.sql
+++ /dev/null
@@ -1,20 +0,0 @@
-INCLUDE PERFETTO MODULE chrome.speedometer;
-
-SELECT
- iteration,
- ts,
- dur,
- total,
- format('%.1f', mean) AS mean,
- format('%.1f', geomean) AS geomean,
- format('%.1f', score) AS score,
- num_measurements
-FROM
- chrome_speedometer_iteration,
- (
- SELECT iteration, COUNT(*) AS num_measurements
- FROM chrome_speedometer_measure
- GROUP BY iteration
- )
-USING (iteration)
-ORDER BY iteration;
diff --git a/test/trace_processor/diff_tests/chrome/tests.py b/test/trace_processor/diff_tests/chrome/tests.py
deleted file mode 100644
index b72a098..0000000
--- a/test/trace_processor/diff_tests/chrome/tests.py
+++ /dev/null
@@ -1,572 +0,0 @@
-#!/usr/bin/env python3
-# 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 a
-#
-# 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, Json, TextProto
-from python.generators.diff_tests.testing import DiffTestBlueprint
-from python.generators.diff_tests.testing import TestSuite
-
-
-class Chrome(TestSuite):
- # Tests related to Chrome's use of Perfetto. Chrome histogram hashes
- def test_chrome_histogram_hashes(self):
- return DiffTestBlueprint(
- trace=TextProto(r"""
- packet {
- trusted_packet_sequence_id: 1
- timestamp: 0
- incremental_state_cleared: true
- track_event {
- categories: "cat1"
- type: 3
- name_iid: 1
- chrome_histogram_sample {
- name_hash: 10
- sample: 100
- }
- }
- }
- packet {
- trusted_packet_sequence_id: 1
- timestamp: 0
- incremental_state_cleared: true
- track_event {
- categories: "cat2"
- type: 3
- name_iid: 2
- chrome_histogram_sample {
- name_hash: 20
- }
- }
- }
- """),
- query=Metric('chrome_histogram_hashes'),
- out=TextProto(r"""
- [perfetto.protos.chrome_histogram_hashes]: {
- hash: 10
- hash: 20
- }
- """))
-
- # Chrome user events
- def test_chrome_user_event_hashes(self):
- return DiffTestBlueprint(
- trace=TextProto(r"""
- packet {
- trusted_packet_sequence_id: 1
- timestamp: 0
- incremental_state_cleared: true
- track_event {
- categories: "cat1"
- type: 3
- name_iid: 1
- chrome_user_event {
- action_hash: 10
- }
- }
- }
- packet {
- trusted_packet_sequence_id: 1
- timestamp: 0
- incremental_state_cleared: true
- track_event {
- categories: "cat2"
- type: 3
- name_iid: 2
- chrome_user_event {
- action_hash: 20
- }
- }
- }
- """),
- query=Metric('chrome_user_event_hashes'),
- out=TextProto(r"""
- [perfetto.protos.chrome_user_event_hashes]: {
- action_hash: 10
- action_hash: 20
- }
- """))
-
- # Chrome performance mark
- def test_chrome_performance_mark_hashes(self):
- return DiffTestBlueprint(
- trace=TextProto(r"""
- packet {
- trusted_packet_sequence_id: 1
- timestamp: 0
- incremental_state_cleared: true
- track_event {
- categories: "cat1"
- type: 3
- name: "name1"
- [perfetto.protos.ChromeTrackEvent.chrome_hashed_performance_mark] {
- site_hash: 10
- mark_hash: 100
- }
- }
- }
- packet {
- trusted_packet_sequence_id: 1
- timestamp: 0
- incremental_state_cleared: true
- track_event {
- categories: "cat2"
- type: 3
- name: "name2"
- [perfetto.protos.ChromeTrackEvent.chrome_hashed_performance_mark] {
- site_hash: 20
- mark_hash: 200
- }
- }
- }
- """),
- query=Metric('chrome_performance_mark_hashes'),
- out=TextProto(r"""
- [perfetto.protos.chrome_performance_mark_hashes]: {
- site_hash: 10
- site_hash: 20
- mark_hash: 100
- mark_hash: 200
- }
- """))
-
- # Chrome reliable range
- def test_chrome_reliable_range(self):
- return DiffTestBlueprint(
- trace=Path('chrome_reliable_range.textproto'),
- query=Path('chrome_reliable_range_test.sql'),
- out=Csv("""
- "start","reason","debug_limiting_upid","debug_limiting_utid"
- 12,"First slice for utid=2","[NULL]",2
- """))
-
- def test_chrome_reliable_range_cropping(self):
- return DiffTestBlueprint(
- trace=Path('chrome_reliable_range_cropping.textproto'),
- query=Path('chrome_reliable_range_test.sql'),
- out=Csv("""
- "start","reason","debug_limiting_upid","debug_limiting_utid"
- 10000,"Range of interest packet","[NULL]",2
- """))
-
- def test_chrome_reliable_range_missing_processes(self):
- return DiffTestBlueprint(
- trace=Path('chrome_reliable_range_missing_processes.textproto'),
- query=Path('chrome_reliable_range_test.sql'),
- out=Csv("""
- "start","reason","debug_limiting_upid","debug_limiting_utid"
- 1011,"Missing process data for upid=2",2,1
- """))
-
- def test_chrome_reliable_range_missing_browser_main(self):
- return DiffTestBlueprint(
- trace=Path('chrome_reliable_range_missing_browser_main.textproto'),
- query=Path('chrome_reliable_range_test.sql'),
- out=Csv("""
- "start","reason","debug_limiting_upid","debug_limiting_utid"
- 1011,"Missing main thread for upid=1",1,1
- """))
-
- def test_chrome_reliable_range_missing_gpu_main(self):
- return DiffTestBlueprint(
- trace=Path('chrome_reliable_range_missing_gpu_main.textproto'),
- query=Path('chrome_reliable_range_test.sql'),
- out=Csv("""
- "start","reason","debug_limiting_upid","debug_limiting_utid"
- 1011,"Missing main thread for upid=1",1,1
- """))
-
- def test_chrome_reliable_range_missing_renderer_main(self):
- return DiffTestBlueprint(
- trace=Path('chrome_reliable_range_missing_renderer_main.textproto'),
- query=Path('chrome_reliable_range_test.sql'),
- out=Csv("""
- "start","reason","debug_limiting_upid","debug_limiting_utid"
- 1011,"Missing main thread for upid=1",1,1
- """))
-
- def test_chrome_reliable_range_non_chrome_process(self):
- return DiffTestBlueprint(
- # We need a trace with a large number of non-chrome slices, so that the
- # reliable range is affected by their filtering.
- trace=DataPath('example_android_trace_30s.pb'),
- query=Path('chrome_reliable_range_test.sql'),
- out=Csv("""
- "start","reason","debug_limiting_upid","debug_limiting_utid"
- 0,"[NULL]","[NULL]","[NULL]"
- """))
-
- # Chrome slices
- def test_chrome_slice_names(self):
- return DiffTestBlueprint(
- trace=TextProto(r"""
- packet {
- trusted_packet_sequence_id: 1
- timestamp: 1000
- track_event {
- categories: "cat"
- name: "Looper.Dispatch: class1"
- type: 3
- }
- }
- packet {
- trusted_packet_sequence_id: 1
- timestamp: 2000
- track_event {
- categories: "cat"
- name: "name2"
- type: 3
- }
- }
- packet {
- chrome_metadata {
- chrome_version_code: 123
- }
- }
- """),
- query=Metric('chrome_slice_names'),
- out=TextProto(r"""
- [perfetto.protos.chrome_slice_names]: {
- chrome_version_code: 123
- slice_name: "Looper.Dispatch: class1"
- slice_name: "name2"
- }
- """))
-
- # Chrome tasks.
- def test_chrome_tasks(self):
- return DiffTestBlueprint(
- trace=DataPath(
- 'chrome_page_load_all_categories_not_extended.pftrace.gz'),
- query="""
- INCLUDE PERFETTO MODULE chrome.tasks;
-
- SELECT full_name as name, task_type, count() AS count
- FROM chrome_tasks
- GROUP BY full_name, task_type
- HAVING count >= 5
- ORDER BY count DESC, name;
- """,
- out=Path('chrome_tasks.out'))
-
- def test_top_level_java_choreographer_slices_top_level_java_chrome_tasks(
- self):
- return DiffTestBlueprint(
- trace=DataPath('top_level_java_choreographer_slices'),
- query="""
- INCLUDE PERFETTO MODULE chrome.tasks;
-
- SELECT
- full_name,
- task_type
- FROM chrome_tasks
- WHERE category = "toplevel,Java"
- AND ts < 263904000000000
- GROUP BY full_name, task_type;
- """,
- out=Path(
- 'top_level_java_choreographer_slices_top_level_java_chrome_tasks_test.out'
- ))
-
- # Chrome stack samples.
- def test_chrome_stack_samples_for_task(self):
- return DiffTestBlueprint(
- trace=DataPath('chrome_stack_traces_symbolized_trace.pftrace'),
- query="""
- SELECT RUN_METRIC('chrome/chrome_stack_samples_for_task.sql',
- 'target_duration_ms', '0.000001',
- 'thread_name', '"CrBrowserMain"',
- 'task_name', '"sendTouchEvent"');
-
- SELECT
- sample.description,
- sample.ts,
- sample.depth
- FROM chrome_stack_samples_for_task sample
- JOIN (
- SELECT
- ts,
- dur
- FROM slice
- WHERE ts = 696373965001470
- ) test_slice
- ON sample.ts >= test_slice.ts
- AND sample.ts <= test_slice.ts + test_slice.dur
- ORDER BY sample.ts, sample.depth;
- """,
- out=Path('chrome_stack_samples_for_task_test.out'))
-
- # Log messages.
- def test_chrome_log_message(self):
- return DiffTestBlueprint(
- trace=TextProto(r"""
- packet {
- timestamp: 0
- incremental_state_cleared: true
- trusted_packet_sequence_id: 1
- track_descriptor {
- uuid: 12345
- thread {
- pid: 123
- tid: 345
- }
- parent_uuid: 0
- chrome_thread {
- thread_type: THREAD_POOL_FG_WORKER
- }
- }
- }
-
- packet {
- trusted_packet_sequence_id: 1
- timestamp: 10
- track_event {
- track_uuid: 12345
- categories: "cat1"
- type: TYPE_INSTANT
- name: "slice1"
- log_message {
- body_iid: 1
- source_location_iid: 3
- }
- }
- interned_data {
- log_message_body {
- iid: 1
- body: "log message"
- }
- source_locations {
- iid: 3
- function_name: "func"
- file_name: "foo.cc"
- line_number: 123
- }
- }
- }
- """),
- query="""
- SELECT utid, tag, msg, prio FROM android_logs;
- """,
- # If the log_message_body doesn't have any priority, a default 4 (i.e.
- # INFO) is assumed (otherwise the UI will not show the message).
- out=Csv("""
- "utid","tag","msg","prio"
- 1,"foo.cc:123","log message",4
- """))
-
- def test_chrome_log_message_priority(self):
- return DiffTestBlueprint(
- trace=TextProto(r"""
- packet {
- timestamp: 0
- incremental_state_cleared: true
- trusted_packet_sequence_id: 1
- track_descriptor {
- uuid: 12345
- thread {
- pid: 123
- tid: 345
- }
- parent_uuid: 0
- chrome_thread {
- thread_type: THREAD_POOL_FG_WORKER
- }
- }
- }
-
- packet {
- trusted_packet_sequence_id: 1
- timestamp: 10
- track_event {
- track_uuid: 12345
- categories: "cat1"
- type: TYPE_INSTANT
- name: "slice1"
- log_message {
- body_iid: 1
- source_location_iid: 3
- prio: PRIO_WARN
- }
- }
- interned_data {
- log_message_body {
- iid: 1
- body: "log message"
- }
- source_locations {
- iid: 3
- function_name: "func"
- file_name: "foo.cc"
- line_number: 123
- }
- }
- }
- """),
- query="""
- SELECT utid, tag, msg, prio FROM android_logs;
- """,
- out=Csv("""
- "utid","tag","msg","prio"
- 1,"foo.cc:123","log message",5
- """))
-
- def test_chrome_log_message_args(self):
- return DiffTestBlueprint(
- trace=TextProto(r"""
- packet {
- timestamp: 0
- incremental_state_cleared: true
- trusted_packet_sequence_id: 1
- track_descriptor {
- uuid: 12345
- thread {
- pid: 123
- tid: 345
- }
- parent_uuid: 0
- chrome_thread {
- thread_type: THREAD_POOL_FG_WORKER
- }
- }
- }
-
- packet {
- trusted_packet_sequence_id: 1
- timestamp: 10
- track_event {
- track_uuid: 12345
- categories: "cat1"
- type: TYPE_INSTANT
- name: "slice1"
- log_message {
- body_iid: 1
- source_location_iid: 3
- }
- }
- interned_data {
- log_message_body {
- iid: 1
- body: "log message"
- }
- source_locations {
- iid: 3
- function_name: "func"
- file_name: "foo.cc"
- line_number: 123
- }
- }
- }
- """),
- query=Path('chrome_log_message_args_test.sql'),
- out=Csv("""
- "log_message","function_name","file_name","line_number"
- "log message","func","foo.cc",123
- """))
-
- # Chrome custom navigation event names
- def test_chrome_custom_navigation_tasks(self):
- return DiffTestBlueprint(
- trace=DataPath('chrome_custom_navigation_trace.gz'),
- query="""
- INCLUDE PERFETTO MODULE chrome.tasks;
-
- SELECT full_name, task_type, count() AS count
- FROM chrome_tasks
- WHERE full_name GLOB 'FrameHost::BeginNavigation*'
- OR full_name GLOB 'FrameHost::DidCommitProvisionalLoad*'
- OR full_name GLOB 'FrameHost::DidCommitSameDocumentNavigation*'
- OR full_name GLOB 'FrameHost::DidStopLoading*'
- GROUP BY full_name, task_type
- ORDER BY count DESC
- LIMIT 50;
- """,
- out=Csv("""
- "full_name","task_type","count"
- "FrameHost::BeginNavigation (SUBFRAME)","navigation_task",5
- "FrameHost::DidStopLoading (SUBFRAME)","navigation_task",3
- "FrameHost::BeginNavigation (PRIMARY_MAIN_FRAME)","navigation_task",1
- "FrameHost::DidCommitProvisionalLoad (SUBFRAME)","navigation_task",1
- """))
-
- # Chrome custom navigation event names
- def test_chrome_histograms(self):
- return DiffTestBlueprint(
- trace=DataPath('chrome_5672_histograms.pftrace.gz'),
- query="""
- INCLUDE PERFETTO MODULE chrome.histograms;
-
- SELECT
- name,
- count() as count
- FROM chrome_histograms
- GROUP BY name
- ORDER BY count DESC, name
- LIMIT 20;
- """,
- out=Csv("""
- "name","count"
- "Net.QuicSession.AsyncRead",19207
- "Net.QuicSession.NumQueuedPacketsBeforeWrite",19193
- "RendererScheduler.QueueingDuration.NormalPriority",9110
- "Net.OnTransferSizeUpdated.Experimental.OverridenBy",8525
- "Compositing.Renderer.AnimationUpdateOnMissingPropertyNode",3489
- "Net.QuicConnection.WritePacketStatus",3099
- "Net.QuicSession.PacketWriteTime.Synchronous",3082
- "Net.QuicSession.SendPacketSize.ForwardSecure",3012
- "Net.URLLoaderThrottleExecutionTime.WillStartRequest",1789
- "Net.URLLoaderThrottleExecutionTime.BeforeWillProcessResponse",1773
- "Net.URLLoaderThrottleExecutionTime.WillProcessResponse",1773
- "UMA.StackProfiler.SampleInOrder",1534
- "GPU.SharedImage.ContentConsumed",1037
- "Gpu.Rasterization.Raster.MSAASampleCountLog2",825
- "Scheduling.Renderer.DeadlineMode",637
- "Blink.CullRect.UpdateTime",622
- "Scheduling.Renderer.BeginImplFrameLatency2",591
- "Net.QuicSession.CoalesceStreamFrameStatus",551
- "API.StorageAccess.AllowedRequests2",541
- "Net.HttpResponseCode",541
- """))
-
- # Trace proto content
- def test_proto_content(self):
- return DiffTestBlueprint(
- trace=DataPath('chrome_scroll_without_vsync.pftrace'),
- query=Path('proto_content_test.sql'),
- out=Path('proto_content.out'))
-
- def test_speedometer(self):
- return DiffTestBlueprint(
- trace=DataPath('speedometer.perfetto_trace.gz'),
- query=Path('chrome_speedometer_test.sql'),
- out=Path('chrome_speedometer.out'))
-
- # TODO(mayzner): Uncomment when it works
- # def test_proto_content_path(self):
- # return DiffTestBlueprint(
- # trace=DataPath('chrome_scroll_without_vsync.pftrace'),
- # query=Path('proto_content_path_test.sql'),
- # out=Csv("""
- # "total_size","field_type","field_name","parent_id","event_category","event_name"
- # 137426,"TracePacket","[NULL]","[NULL]","[NULL]","[NULL]"
- # 59475,"TrackEvent","#track_event",415,"[NULL]","[NULL]"
- # 37903,"TrackEvent","#track_event",17,"[NULL]","[NULL]"
- # 35904,"int32","#trusted_uid",17,"[NULL]","[NULL]"
- # 35705,"TracePacket","[NULL]","[NULL]","input,benchmark","LatencyInfo.Flow"
- # 29403,"TracePacket","[NULL]","[NULL]","cc,input","[NULL]"
- # 24703,"ChromeLatencyInfo","#chrome_latency_info",18,"[NULL]","[NULL]"
- # 22620,"uint64","#time_us",26,"[NULL]","[NULL]"
- # 18711,"TrackEvent","#track_event",1467,"[NULL]","[NULL]"
- # 15606,"uint64","#timestamp",17,"[NULL]","[NULL]"
- # """))
diff --git a/test/trace_processor/diff_tests/graphics/composition_layer.py b/test/trace_processor/diff_tests/graphics/composition_layer.py
deleted file mode 100644
index b69bab2..0000000
--- a/test/trace_processor/diff_tests/graphics/composition_layer.py
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/usr/bin/env python3
-# Copyright (C) 2021 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.
-
-# This synthetic trace tests handling of the mm_id field in the rss_stat
-# event when mm_structs are reused on process death.
-
-from os import sys, path
-
-import synth_common
-
-trace = synth_common.create_trace()
-
-trace.add_packet(ts=1)
-trace.add_process(10, 1, "parent_process")
-trace.add_process(11, 10, "child_process")
-
-trace.add_ftrace_packet(1)
-
-trace.add_print(ts=99, tid=11, buf='C|10|HWComposer: Total Layer for PrimaryDisplay(0)|7')
-trace.add_print(ts=100, tid=11, buf='C|10|HWComposer: Total Layer for PrimaryDisplay(0)|5')
-trace.add_print(ts=101, tid=11, buf='C|10|HWComposer: Total Layer for PrimaryDisplay(0)|6')
-trace.add_print(ts=102, tid=11, buf='C|10|HWComposer: Total Layer for PrimaryDisplay(0)|0')
-trace.add_print(ts=103, tid=11, buf='C|10|HWComposer: Total Layer for PrimaryDisplay(0)|4')
-trace.add_print(ts=104, tid=11, buf='C|10|HWComposer: Total Layer for PrimaryDisplay(0)|6')
-trace.add_print(ts=105, tid=11, buf='C|10|HWComposer: Total Layer for PrimaryDisplay(0)|0')
-trace.add_print(ts=106, tid=11, buf='C|10|HWComposer: Total Layer for PrimaryDisplay(0)|4')
-trace.add_print(ts=107, tid=11, buf='C|10|HWComposer: Total Layer for PrimaryDisplay(0)|5')
-trace.add_print(ts=108, tid=11, buf='C|10|HWComposer: Total Layer for PrimaryDisplay(0)|0')
-trace.add_print(ts=108, tid=11, buf='C|10|HWComposer: Total Layer for PrimaryDisplay(0)|3')
-trace.add_print(ts=108, tid=11, buf='C|10|HWComposer: Total Layer for PrimaryDisplay(0)|0')
-
-trace.add_print(ts=109, tid=11, buf='C|10|HWComposer: Total Layer for SecondaryDisplay(1)|5')
-
-sys.stdout.buffer.write(trace.trace.SerializeToString())
diff --git a/test/trace_processor/diff_tests/graphics/tests.py b/test/trace_processor/diff_tests/graphics/tests.py
deleted file mode 100644
index 04a86bd..0000000
--- a/test/trace_processor/diff_tests/graphics/tests.py
+++ /dev/null
@@ -1,496 +0,0 @@
-#!/usr/bin/env python3
-# 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 a
-#
-# 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, Json, TextProto
-from python.generators.diff_tests.testing import DiffTestBlueprint
-from python.generators.diff_tests.testing import TestSuite
-
-
-class Graphics(TestSuite):
- # Contains tests for graphics related events and tables. Graphics frame
- # trace tests.
- def test_graphics_frame_events(self):
- return DiffTestBlueprint(
- trace=Path('graphics_frame_events.py'),
- query="""
- SELECT ts, gpu_track.name AS track_name, dur, frame_slice.name AS slice_name,
- frame_number, layer_name
- FROM gpu_track
- LEFT JOIN frame_slice ON gpu_track.id = frame_slice.track_id
- WHERE scope = 'graphics_frame_event'
- ORDER BY ts;
- """,
- out=Path('graphics_frame_events.out'))
-
- # GPU Memory ftrace packets
- def test_gpu_mem_total(self):
- return DiffTestBlueprint(
- trace=Path('gpu_mem_total.py'),
- query=Path('gpu_mem_total_test.sql'),
- out=Csv("""
- "name","unit","description","ts","pid","value"
- "GPU Memory","7","Total GPU memory used by the entire system",0,"[NULL]",123
- "GPU Memory","7","Total GPU memory used by this process",0,1,100
- "GPU Memory","7","Total GPU memory used by the entire system",5,"[NULL]",256
- "GPU Memory","7","Total GPU memory used by this process",5,1,233
- "GPU Memory","7","Total GPU memory used by the entire system",10,"[NULL]",123
- "GPU Memory","7","Total GPU memory used by this process",10,1,0
- """))
-
- def test_gpu_mem_total_after_free_gpu_mem_total(self):
- return DiffTestBlueprint(
- trace=Path('gpu_mem_total_after_free.py'),
- query=Path('gpu_mem_total_test.sql'),
- out=Csv("""
- "name","unit","description","ts","pid","value"
- "GPU Memory","7","Total GPU memory used by this process",0,1,100
- "GPU Memory","7","Total GPU memory used by this process",5,1,233
- "GPU Memory","7","Total GPU memory used by this process",10,1,50
- """))
-
- # Clock sync
- def test_clock_sync(self):
- return DiffTestBlueprint(
- trace=Path('clock_sync.py'),
- query="""
- SELECT ts, cast(value AS integer) AS int_value
- FROM counters
- WHERE name GLOB 'gpu_counter*';
- """,
- out=Csv("""
- "ts","int_value"
- 1,3
- 102,5
- 1003,7
- 1005,9
- 2006,11
- 2010,12
- 2013,13
- 3007,14
- 3010,15
- """))
-
- # Android SurfaceFlinger metrics
- def test_frame_missed_event_frame_missed(self):
- return DiffTestBlueprint(
- trace=Path('frame_missed.py'),
- query="""
- SELECT RUN_METRIC('android/android_surfaceflinger.sql');
-
- SELECT ts, dur
- FROM android_surfaceflinger_event;
- """,
- out=Csv("""
- "ts","dur"
- 100,1
- 102,1
- 103,1
- """))
-
- def test_frame_missed_metrics(self):
- return DiffTestBlueprint(
- trace=Path('frame_missed.py'),
- query=Metric('android_surfaceflinger'),
- out=TextProto(r"""
- android_surfaceflinger {
- missed_frames: 3
- missed_hwc_frames: 0
- missed_gpu_frames: 0
- missed_frame_rate: 0.42857142857142855 # = 3/7
- gpu_invocations: 0
- metrics_per_display: {
- display_id: "101"
- missed_frames: 2
- missed_hwc_frames: 0
- missed_gpu_frames: 0
- missed_frame_rate: 0.5
- }
- metrics_per_display: {
- display_id: "102"
- missed_frames: 1
- missed_hwc_frames: 0
- missed_gpu_frames: 0
- missed_frame_rate: 0.33333333333333333
- }
- }
- """))
-
- def test_surfaceflinger_gpu_invocation(self):
- return DiffTestBlueprint(
- trace=Path('surfaceflinger_gpu_invocation.py'),
- query=Metric('android_surfaceflinger'),
- out=TextProto(r"""
- android_surfaceflinger {
- missed_frames: 0
- missed_hwc_frames: 0
- missed_gpu_frames: 0
- gpu_invocations: 4
- avg_gpu_waiting_dur_ms: 4
- total_non_empty_gpu_waiting_dur_ms: 11
- }
- """))
-
- # GPU metrics
- def test_gpu_metric(self):
- return DiffTestBlueprint(
- trace=Path('gpu_metric.py'),
- query=Metric('android_gpu'),
- out=TextProto(r"""
- android_gpu {
- processes {
- name: "app_1"
- mem_max: 8
- mem_min: 2
- mem_avg: 3
- }
- processes {
- name: "app_2"
- mem_max: 10
- mem_min: 6
- mem_avg: 8
- }
- mem_max: 4
- mem_min: 1
- mem_avg: 2
- }
- """))
-
- def test_gpu_frequency_metric(self):
- return DiffTestBlueprint(
- trace=Path('gpu_frequency_metric.textproto'),
- query=Metric('android_gpu'),
- out=Path('gpu_frequency_metric.out'))
-
- # Android Jank CUJ metric
- def test_android_jank_cuj(self):
- return DiffTestBlueprint(
- trace=Path('android_jank_cuj.py'),
- query=Metric('android_jank_cuj'),
- out=Path('android_jank_cuj.out'))
-
- def test_android_jank_cuj_query(self):
- return DiffTestBlueprint(
- trace=Path('android_jank_cuj.py'),
- query=Path('android_jank_cuj_query_test.sql'),
- out=Path('android_jank_cuj_query.out'))
-
- # Frame Timeline event trace tests
- def test_expected_frame_timeline_events(self):
- return DiffTestBlueprint(
- trace=Path('frame_timeline_events.py'),
- query=Path('expected_frame_timeline_events_test.sql'),
- out=Csv("""
- "ts","dur","pid","display_frame_token","surface_frame_token","layer_name"
- 20,6,666,2,0,"[NULL]"
- 21,15,1000,4,1,"Layer1"
- 40,6,666,4,0,"[NULL]"
- 41,15,1000,6,5,"Layer1"
- 80,6,666,6,0,"[NULL]"
- 90,16,1000,8,7,"Layer1"
- 120,6,666,8,0,"[NULL]"
- 140,6,666,12,0,"[NULL]"
- 150,20,1000,15,14,"Layer1"
- 170,6,666,15,0,"[NULL]"
- 200,6,666,17,0,"[NULL]"
- 220,10,666,18,0,"[NULL]"
- """))
-
- def test_actual_frame_timeline_events(self):
- return DiffTestBlueprint(
- trace=Path('frame_timeline_events.py'),
- query=Path('actual_frame_timeline_events_test.sql'),
- out=Path('actual_frame_timeline_events.out'))
-
- # Composition layer
- def test_composition_layer_count(self):
- return DiffTestBlueprint(
- trace=Path('composition_layer.py'),
- query="""
- SELECT RUN_METRIC('android/android_hwcomposer.sql');
-
- SELECT display_id, AVG(value)
- FROM total_layers
- GROUP BY display_id;
- """,
- out=Csv("""
- "display_id","AVG(value)"
- "0",3.000000
- "1",5.000000
- """))
-
- # G2D metrics TODO(rsavitski): find a real trace and double-check that the
- # is realistic. One kernel's source I checked had tgid=0 for all counter
- # Initial support was added/discussed in b/171296908.
- def test_g2d_metrics(self):
- return DiffTestBlueprint(
- trace=Path('g2d_metrics.textproto'),
- query=Metric('g2d'),
- out=Path('g2d_metrics.out'))
-
- # Composer execution
- def test_composer_execution(self):
- return DiffTestBlueprint(
- trace=Path('composer_execution.py'),
- query="""
- SELECT RUN_METRIC('android/composer_execution.sql',
- 'output', 'hwc_execution_spans');
-
- SELECT
- validation_type,
- display_id,
- COUNT(*) AS count,
- SUM(execution_time_ns) AS total
- FROM hwc_execution_spans
- GROUP BY validation_type, display_id
- ORDER BY validation_type, display_id;
- """,
- out=Csv("""
- "validation_type","display_id","count","total"
- "separated_validation","1",1,200
- "skipped_validation","0",2,200
- "skipped_validation","1",1,100
- "unknown","1",1,0
- "unskipped_validation","0",1,200
- """))
-
- # Display metrics
- def test_display_metrics(self):
- return DiffTestBlueprint(
- trace=Path('display_metrics.py'),
- query=Metric('display_metrics'),
- out=TextProto(r"""
- display_metrics {
- total_duplicate_frames: 0
- duplicate_frames_logged: 0
- total_dpu_underrun_count: 0
- refresh_rate_switches: 5
- refresh_rate_stats {
- refresh_rate_fps: 60
- count: 2
- total_dur_ms: 2
- avg_dur_ms: 1
- }
- refresh_rate_stats {
- refresh_rate_fps: 90
- count: 2
- total_dur_ms: 2
- avg_dur_ms: 1
- }
- refresh_rate_stats {
- refresh_rate_fps: 120
- count: 1
- total_dur_ms: 2
- avg_dur_ms: 2
- }
- update_power_state {
- avg_runtime_micro_secs: 4000
- }
- }
- """))
-
- # DPU vote clock and bandwidth
- def test_dpu_vote_clock_bw(self):
- return DiffTestBlueprint(
- trace=Path('dpu_vote_clock_bw.textproto'),
- query=Metric('android_hwcomposer'),
- out=TextProto(r"""
- android_hwcomposer {
- skipped_validation_count: 0
- unskipped_validation_count: 0
- separated_validation_count: 0
- unknown_validation_count: 0
- dpu_vote_metrics {
- tid: 237
- avg_dpu_vote_clock: 206250
- avg_dpu_vote_avg_bw: 210000
- avg_dpu_vote_peak_bw: 205000
- avg_dpu_vote_rt_bw: 271000
- }
- dpu_vote_metrics {
- tid: 299
- avg_dpu_vote_clock: 250000
- }
- }
- """))
-
- # Video 4 Linux 2 related tests
- def test_v4l2_vidioc_slice(self):
- return DiffTestBlueprint(
- trace=Path('v4l2_vidioc.textproto'),
- query="""
- SELECT ts, dur, name
- FROM slice
- WHERE category = 'Video 4 Linux 2';
- """,
- out=Csv("""
- "ts","dur","name"
- 593268475912,0,"VIDIOC_QBUF minor=0 seq=0 type=9 index=19"
- 593268603800,0,"VIDIOC_QBUF minor=0 seq=0 type=9 index=20"
- 593528238295,0,"VIDIOC_DQBUF minor=0 seq=0 type=9 index=19"
- 593544028229,0,"VIDIOC_DQBUF minor=0 seq=0 type=9 index=20"
- """))
-
- def test_v4l2_vidioc_flow(self):
- return DiffTestBlueprint(
- trace=Path('v4l2_vidioc.textproto'),
- query="""
- SELECT qbuf.ts, qbuf.dur, qbuf.name, dqbuf.ts, dqbuf.dur, dqbuf.name
- FROM flow
- JOIN slice qbuf ON flow.slice_out = qbuf.id
- JOIN slice dqbuf ON flow.slice_in = dqbuf.id;
- """,
- out=Path('v4l2_vidioc_flow.out'))
-
- def test_virtio_video_slice(self):
- return DiffTestBlueprint(
- trace=Path('virtio_video.textproto'),
- query="""
- SELECT slice.ts, slice.dur, slice.name, track.name
- FROM slice
- JOIN track ON slice.track_id = track.id;
- """,
- out=Csv("""
- "ts","dur","name","name"
- 593125003271,84500592,"Resource #102","virtio_video stream #4 OUTPUT"
- 593125003785,100000,"RESOURCE_QUEUE","virtio_video stream #4 Requests"
- 593125084611,709696,"Resource #62","virtio_video stream #3 OUTPUT"
- 593125084935,100000,"RESOURCE_QUEUE","virtio_video stream #3 Requests"
- 593125794194,100000,"RESOURCE_QUEUE","virtio_video stream #3 Responses"
- 593209502603,100000,"RESOURCE_QUEUE","virtio_video stream #4 Responses"
- """))
-
- # virtgpu (drm/virtio) related tests
- def test_virtio_gpu(self):
- return DiffTestBlueprint(
- trace=Path('virtio_gpu.textproto'),
- query="""
- SELECT
- ts,
- dur,
- name
- FROM
- slice
- ORDER BY ts;
- """,
- out=Csv("""
- "ts","dur","name"
- 1345090723759,1180312,"SUBMIT_3D"
- 1345090746311,1167135,"CTX_DETACH_RESOURCE"
- """))
-
- # TODO(b/294866695): Reenable
- # mali GPU events
- #def test_mali(self):
- # return DiffTestBlueprint(
- # trace=TextProto(r"""
- # packet {
- # ftrace_events {
- # cpu: 2
- # event {
- # timestamp: 751796307210
- # pid: 2857
- # mali_mali_KCPU_CQS_WAIT_START {
- # info_val1: 1
- # info_val2: 0
- # kctx_tgid: 2201
- # kctx_id: 10
- # id: 0
- # }
- # }
- # event {
- # timestamp: 751800621175
- # pid: 2857
- # mali_mali_KCPU_CQS_WAIT_END {
- # info_val1: 412313493488
- # info_val2: 0
- # kctx_tgid: 2201
- # kctx_id: 10
- # id: 0
- # }
- # }
- # event {
- # timestamp: 751800638997
- # pid: 2857
- # mali_mali_KCPU_CQS_SET {
- # info_val1: 412313493480
- # info_val2: 0
- # kctx_tgid: 2201
- # kctx_id: 10
- # id: 0
- # }
- # }
- # }
- # }
- # """),
- # query="""
- # SELECT ts, dur, name FROM slice WHERE name GLOB "mali_KCPU_CQS*";
- # """,
- # out=Csv("""
- # "ts","dur","name"
- # 751796307210,4313965,"mali_KCPU_CQS_WAIT"
- # 751800638997,0,"mali_KCPU_CQS_SET"
- # """))
-
- #def test_mali_fence(self):
- # return DiffTestBlueprint(
- # trace=TextProto(r"""
- # packet {
- # ftrace_events {
- # cpu: 2
- # event {
- # timestamp: 751796307210
- # pid: 2857
- # mali_mali_KCPU_FENCE_WAIT_START {
- # info_val1: 1
- # info_val2: 0
- # kctx_tgid: 2201
- # kctx_id: 10
- # id: 0
- # }
- # }
- # event {
- # timestamp: 751800621175
- # pid: 2857
- # mali_mali_KCPU_FENCE_WAIT_END {
- # info_val1: 412313493488
- # info_val2: 0
- # kctx_tgid: 2201
- # kctx_id: 10
- # id: 0
- # }
- # }
- # event {
- # timestamp: 751800638997
- # pid: 2857
- # mali_mali_KCPU_FENCE_SIGNAL {
- # info_val1: 412313493480
- # info_val2: 0
- # kctx_tgid: 2201
- # kctx_id: 10
- # id: 0
- # }
- # }
- # }
- # }
- # """),
- # query="""
- # SELECT ts, dur, name FROM slice WHERE name GLOB "mali_KCPU_FENCE*";
- # """,
- # out=Csv("""
- # "ts","dur","name"
- # 751796307210,4313965,"mali_KCPU_FENCE_WAIT"
- # 751800638997,0,"mali_KCPU_FENCE_SIGNAL"
- # """))
diff --git a/test/trace_processor/diff_tests/include_index.py b/test/trace_processor/diff_tests/include_index.py
index b131e43..7430548 100644
--- a/test/trace_processor/diff_tests/include_index.py
+++ b/test/trace_processor/diff_tests/include_index.py
@@ -25,164 +25,213 @@
os.path.dirname(os.path.abspath(__file__)))
sys.path.append(TRACE_PROCESSOR_TEST_DIR)
-from diff_tests.android.tests import Android
-from diff_tests.android.tests_bugreport import AndroidBugreport
-from diff_tests.android.tests_games import AndroidGames
-from diff_tests.android.tests_surfaceflinger_layers import SurfaceFlingerLayers
-from diff_tests.android.tests_surfaceflinger_transactions import SurfaceFlingerTransactions
-from diff_tests.atrace.tests import Atrace
-from diff_tests.atrace.tests_error_handling import AtraceErrorHandling
-from diff_tests.camera.tests import Camera
-from diff_tests.chrome.tests import Chrome
-from diff_tests.chrome.tests_args import ChromeArgs
-from diff_tests.chrome.tests_memory_snapshots import ChromeMemorySnapshots
-from diff_tests.chrome.tests_processes import ChromeProcesses
-from diff_tests.chrome.tests_rail_modes import ChromeRailModes
-from diff_tests.chrome.tests_scroll_jank import ChromeScrollJank
-from diff_tests.chrome.tests_touch_gesture import ChromeTouchGesture
-from diff_tests.codecs.tests import Codecs
-from diff_tests.cros.tests import Cros
-from diff_tests.dynamic.tests import Dynamic
-from diff_tests.fs.tests import Fs
-from diff_tests.fuchsia.tests import Fuchsia
-from diff_tests.functions.tests import Functions
-from diff_tests.graphics.tests import Graphics
-from diff_tests.graphics.tests_drm_related_ftrace_events import \
- GraphicsDrmRelatedFtraceEvents
-from diff_tests.graphics.tests_gpu_trace import GraphicsGpuTrace
-from diff_tests.memory.tests import Memory
-from diff_tests.memory.tests_metrics import MemoryMetrics
-from diff_tests.network.tests import Network
-from diff_tests.parsing.tests import Parsing
-from diff_tests.parsing.tests_debug_annotation import ParsingDebugAnnotation
-from diff_tests.parsing.tests_memory_counters import ParsingMemoryCounters
-from diff_tests.parsing.tests_rss_stats import ParsingRssStats
-from diff_tests.perfetto_sql.tests import PerfettoSql
-from diff_tests.performance.tests import Performance
-from diff_tests.pkvm.tests import Pkvm
-from diff_tests.power.tests import Power
-from diff_tests.power.tests_energy_breakdown import PowerEnergyBreakdown
-from diff_tests.power.tests_entity_state_residency import EntityStateResidency
-from diff_tests.power.tests_linux_sysfs_power import LinuxSysfsPower
-from diff_tests.power.tests_power_rails import PowerPowerRails
-from diff_tests.power.tests_voltage_and_scaling import PowerVoltageAndScaling
-from diff_tests.process_tracking.tests import ProcessTracking
-from diff_tests.profiling.tests import Profiling
-from diff_tests.profiling.tests_heap_graph import ProfilingHeapGraph
-from diff_tests.profiling.tests_heap_profiling import ProfilingHeapProfiling
-from diff_tests.profiling.tests_llvm_symbolizer import ProfilingLlvmSymbolizer
-from diff_tests.profiling.tests_metrics import ProfilingMetrics
-from diff_tests.scheduler.tests import Scheduler
-from diff_tests.slices.tests import Slices
-from diff_tests.smoke.tests import Smoke
-from diff_tests.smoke.tests_compute_metrics import SmokeComputeMetrics
-from diff_tests.smoke.tests_json import SmokeJson
-from diff_tests.smoke.tests_sched_events import SmokeSchedEvents
-from diff_tests.span_join.tests_left_join import SpanJoinLeftJoin
-from diff_tests.span_join.tests_outer_join import SpanJoinOuterJoin
-from diff_tests.span_join.tests_regression import SpanJoinRegression
-from diff_tests.span_join.tests_smoke import SpanJoinSmoke
-from diff_tests.startup.tests import Startup
-from diff_tests.startup.tests_broadcasts import StartupBroadcasts
-from diff_tests.startup.tests_lock_contention import StartupLockContention
-from diff_tests.startup.tests_metrics import StartupMetrics
+from diff_tests.metrics.android.tests import AndroidMetrics
+from diff_tests.metrics.camera.tests import Camera
+from diff_tests.metrics.chrome.tests import ChromeMetrics
+from diff_tests.metrics.chrome.tests_args import ChromeArgs
+from diff_tests.metrics.chrome.tests_processes import ChromeProcesses
+from diff_tests.metrics.chrome.tests_rail_modes import ChromeRailModes
+from diff_tests.metrics.chrome.tests_scroll_jank import ChromeScrollJankMetrics
+from diff_tests.metrics.chrome.tests_touch_gesture import ChromeTouchGesture
+from diff_tests.metrics.codecs.tests import Codecs
+from diff_tests.metrics.frame_timeline.tests import FrameTimeline
+from diff_tests.metrics.graphics.tests import GraphicsMetrics
+from diff_tests.metrics.irq.tests import IRQ
+from diff_tests.metrics.memory.tests import MemoryMetrics
+from diff_tests.metrics.network.tests import NetworkMetrics
+from diff_tests.metrics.power.tests import Power
+from diff_tests.metrics.profiling.tests import ProfilingMetrics
+from diff_tests.metrics.startup.tests import Startup
+from diff_tests.metrics.startup.tests_broadcasts import StartupBroadcasts
+from diff_tests.metrics.startup.tests_lock_contention import StartupLockContention
+from diff_tests.metrics.startup.tests_metrics import StartupMetrics
+from diff_tests.metrics.webview.tests import WebView
+from diff_tests.parser.android.tests import AndroidParser
+from diff_tests.parser.android.tests_bugreport import AndroidBugreport
+from diff_tests.parser.android.tests_games import AndroidGames
+from diff_tests.parser.android.tests_surfaceflinger_layers import SurfaceFlingerLayers
+from diff_tests.parser.android.tests_surfaceflinger_transactions import SurfaceFlingerTransactions
+from diff_tests.parser.android_fs.tests import AndroidFs
+from diff_tests.parser.atrace.tests import Atrace
+from diff_tests.parser.atrace.tests_error_handling import AtraceErrorHandling
+from diff_tests.parser.chrome.tests import ChromeParser
+from diff_tests.parser.chrome.tests_memory_snapshots import ChromeMemorySnapshots
+from diff_tests.parser.cros.tests import Cros
+from diff_tests.parser.fs.tests import Fs
+from diff_tests.parser.fuchsia.tests import Fuchsia
+from diff_tests.parser.graphics.tests import GraphicsParser
+from diff_tests.parser.graphics.tests_drm_related_ftrace_events import GraphicsDrmRelatedFtraceEvents
+from diff_tests.parser.graphics.tests_gpu_trace import GraphicsGpuTrace
+from diff_tests.parser.memory.tests import MemoryParser
+from diff_tests.parser.network.tests import NetworkParser
+from diff_tests.parser.parsing.tests import Parsing
+from diff_tests.parser.parsing.tests_debug_annotation import ParsingDebugAnnotation
+from diff_tests.parser.parsing.tests_memory_counters import ParsingMemoryCounters
+from diff_tests.parser.parsing.tests_rss_stats import ParsingRssStats
+from diff_tests.parser.power.tests_energy_breakdown import PowerEnergyBreakdown
+from diff_tests.parser.power.tests_entity_state_residency import EntityStateResidency
+from diff_tests.parser.power.tests_linux_sysfs_power import LinuxSysfsPower
+from diff_tests.parser.power.tests_power_rails import PowerPowerRails
+from diff_tests.parser.power.tests_voltage_and_scaling import PowerVoltageAndScaling
+from diff_tests.parser.process_tracking.tests import ProcessTracking
+from diff_tests.parser.profiling.tests import Profiling
+from diff_tests.parser.profiling.tests_heap_graph import ProfilingHeapGraph
+from diff_tests.parser.profiling.tests_heap_profiling import ProfilingHeapProfiling
+from diff_tests.parser.profiling.tests_llvm_symbolizer import ProfilingLlvmSymbolizer
+from diff_tests.parser.sched.tests import SchedParser
+from diff_tests.parser.smoke.tests import Smoke
+from diff_tests.parser.smoke.tests_compute_metrics import SmokeComputeMetrics
+from diff_tests.parser.smoke.tests_json import SmokeJson
+from diff_tests.parser.smoke.tests_sched_events import SmokeSchedEvents
+from diff_tests.parser.track_event.tests import TrackEvent
+from diff_tests.parser.translated_args.tests import TranslatedArgs
+from diff_tests.parser.ufs.tests import Ufs
+from diff_tests.stdlib.android.tests import AndroidStdlib
+from diff_tests.stdlib.common.tests import StdlibCommon
+from diff_tests.stdlib.chrome.tests import ChromeStdlib
+from diff_tests.stdlib.chrome.tests_chrome_interactions import ChromeInteractions
+from diff_tests.stdlib.chrome.tests_scroll_jank import ChromeScrollJankStdlib
+from diff_tests.stdlib.dynamic_tables.tests import DynamicTables
+from diff_tests.stdlib.pkvm.tests import Pkvm
+from diff_tests.stdlib.slices.tests import Slices
+from diff_tests.stdlib.span_join.tests_left_join import SpanJoinLeftJoin
+from diff_tests.stdlib.span_join.tests_outer_join import SpanJoinOuterJoin
+from diff_tests.stdlib.span_join.tests_regression import SpanJoinRegression
+from diff_tests.stdlib.span_join.tests_smoke import SpanJoinSmoke
+from diff_tests.stdlib.timestamps.tests import Timestamps
+from diff_tests.syntax.functions.tests import Functions
+from diff_tests.syntax.perfetto_sql.tests import PerfettoSql
from diff_tests.tables.tests import Tables
from diff_tests.tables.tests_counters import TablesCounters
from diff_tests.tables.tests_sched import TablesSched
-from diff_tests.time.tests import Time
-from diff_tests.track_event.tests import TrackEvent
-from diff_tests.translation.tests import Translation
-from diff_tests.ufs.tests import Ufs
-from diff_tests.webview.tests import WebView
-from diff_tests.android_fs.tests import AndroidFs
sys.path.pop()
def fetch_all_diff_tests(index_path: str) -> List['testing.TestCase']:
- return [
- *Android(index_path, 'android', 'Android').fetch(),
- *AndroidBugreport(index_path, 'android', 'AndroidBugreport').fetch(),
- *AndroidFs(index_path, 'android_fs', 'AndroidFs').fetch(),
- *AndroidGames(index_path, 'android', 'AndroidGames').fetch(),
- *Atrace(index_path, 'atrace', 'Atrace').fetch(),
- *AtraceErrorHandling(index_path, 'atrace', 'AtraceErrorHandling').fetch(),
- *Camera(index_path, 'camera', 'Camera').fetch(),
- *ChromeScrollJank(index_path, 'chrome', 'ChromeScrollJank').fetch(),
- *ChromeTouchGesture(index_path, 'chrome', 'ChromeTouchGesture').fetch(),
- *ChromeMemorySnapshots(index_path, 'chrome',
+ parser_tests = [
+ *AndroidBugreport(index_path, 'parser/android',
+ 'AndroidBugreport').fetch(),
+ *AndroidFs(index_path, 'parser/android_fs', 'AndroidFs').fetch(),
+ *AndroidGames(index_path, 'parser/android', 'AndroidGames').fetch(),
+ *AndroidParser(index_path, 'parser/android', 'AndroidParser').fetch(),
+ *Atrace(index_path, 'parser/atrace', 'Atrace').fetch(),
+ *AtraceErrorHandling(index_path, 'parser/atrace',
+ 'AtraceErrorHandling').fetch(),
+ *ChromeMemorySnapshots(index_path, 'parser/chrome',
'ChromeMemorySnapshots').fetch(),
- *ChromeRailModes(index_path, 'chrome', 'ChromeRailModes').fetch(),
- *ChromeProcesses(index_path, 'chrome', 'ChromeProcesses').fetch(),
- *ChromeArgs(index_path, 'chrome', 'ChromeArgs').fetch(),
- *Chrome(index_path, 'chrome', 'Chrome').fetch(),
- *Codecs(index_path, 'codecs', 'Codecs').fetch(),
- *Cros(index_path, 'cros', 'Cros').fetch(),
- *Dynamic(index_path, 'dynamic', 'Dynamic').fetch(),
- *EntityStateResidency(index_path, 'power',
- 'EntityStateResidency').fetch(),
- *Fs(index_path, 'fs', 'Fs').fetch(),
- *Fuchsia(index_path, 'fuchsia', 'Fuchsia').fetch(),
- *Functions(index_path, 'functions', 'Functions').fetch(),
- *Graphics(index_path, 'graphics', 'Graphics').fetch(),
- *GraphicsGpuTrace(index_path, 'graphics', 'GraphicsGpuTrace').fetch(),
- *GraphicsDrmRelatedFtraceEvents(index_path, 'graphics',
+ *ChromeParser(index_path, 'parser/chrome', 'ChromeParser').fetch(),
+ *Cros(index_path, 'parser/cros', 'Cros').fetch(),
+ *Fs(index_path, 'parser/fs', 'Fs').fetch(),
+ *Fuchsia(index_path, 'parser/fuchsia', 'Fuchsia').fetch(),
+ *GraphicsDrmRelatedFtraceEvents(index_path, 'parser/graphics',
'GraphicsDrmRelatedFtraceEvents').fetch(),
- *Ufs(index_path, 'ufs', 'Ufs').fetch(),
- *LinuxSysfsPower(index_path, 'power', 'LinuxSysfsPower').fetch(),
- *Memory(index_path, 'memory', 'Memory').fetch(),
- *MemoryMetrics(index_path, 'memory', 'MemoryMetrics').fetch(),
- *Network(index_path, 'network', 'Network').fetch(),
- *Parsing(index_path, 'parsing', 'Parsing').fetch(),
- *ParsingDebugAnnotation(index_path, 'parsing',
- 'ParsingDebugAnnotation').fetch(),
- *ParsingRssStats(index_path, 'parsing', 'ParsingRssStats').fetch(),
- *ParsingMemoryCounters(index_path, 'parsing',
- 'ParsingMemoryCounters').fetch(),
- *PerfettoSql(index_path, 'perfetto_sql', 'PerfettoSql').fetch(),
- *Performance(index_path, 'performance', 'Performance').fetch(),
- *Pkvm(index_path, 'pkvm', 'Pkvm').fetch(),
- *Power(index_path, 'power', 'Power').fetch(),
- *PowerPowerRails(index_path, 'power', 'PowerPowerRails').fetch(),
- *PowerVoltageAndScaling(index_path, 'power',
- 'PowerVoltageAndScaling').fetch(),
- *PowerEnergyBreakdown(index_path, 'power',
+ *GraphicsGpuTrace(index_path, 'parser/graphics',
+ 'GraphicsGpuTrace').fetch(),
+ *GraphicsParser(index_path, 'parser/graphics', 'GraphicsParser').fetch(),
+ *MemoryParser(index_path, 'parser/memory', 'MemoryParser').fetch(),
+ *NetworkParser(index_path, 'parser/network', 'NetworkParser').fetch(),
+ *PowerEnergyBreakdown(index_path, 'parser/power',
'PowerEnergyBreakdown').fetch(),
- *ProcessTracking(index_path, 'process_tracking',
+ *PowerPowerRails(index_path, 'parser/power', 'PowerPowerRails').fetch(),
+ *PowerVoltageAndScaling(index_path, 'parser/power',
+ 'PowerVoltageAndScaling').fetch(),
+ *EntityStateResidency(index_path, 'parser/power',
+ 'EntityStateResidency').fetch(),
+ *LinuxSysfsPower(index_path, 'parser/power', 'LinuxSysfsPower').fetch(),
+ *ProcessTracking(index_path, 'parser/process_tracking',
'ProcessTracking').fetch(),
- *Profiling(index_path, 'profiling', 'Profiling').fetch(),
- *ProfilingHeapProfiling(index_path, 'profiling',
- 'ProfilingHeapProfiling').fetch(),
- *ProfilingHeapGraph(index_path, 'profiling',
+ *Profiling(index_path, 'parser/profiling', 'Profiling').fetch(),
+ *ProfilingHeapGraph(index_path, 'parser/profiling',
'ProfilingHeapGraph').fetch(),
- *ProfilingMetrics(index_path, 'profiling', 'ProfilingMetrics').fetch(),
- *ProfilingLlvmSymbolizer(index_path, 'profiling',
+ *ProfilingHeapProfiling(index_path, 'parser/profiling',
+ 'ProfilingHeapProfiling').fetch(),
+ *ProfilingLlvmSymbolizer(index_path, 'parser/profiling',
'ProfilingLlvmSymbolizer').fetch(),
- *Scheduler(index_path, 'scheduler', 'Scheduler').fetch(),
- *Slices(index_path, 'slices', 'Slices').fetch(),
- *Smoke(index_path, 'smoke', 'Smoke').fetch(),
- *SmokeComputeMetrics(index_path, 'smoke', 'SmokeComputeMetrics').fetch(),
- *SmokeJson(index_path, 'smoke', 'SmokeJson').fetch(),
- *SmokeSchedEvents(index_path, 'smoke', 'SmokeSchedEvents').fetch(),
- *SpanJoinLeftJoin(index_path, 'span_join', 'SpanJoinLeftJoin').fetch(),
- *SpanJoinOuterJoin(index_path, 'span_join', 'SpanJoinOuterJoin').fetch(),
- *SpanJoinSmoke(index_path, 'span_join', 'SpanJoinSmoke').fetch(),
- *SpanJoinRegression(index_path, 'span_join',
- 'SpanJoinRegression').fetch(),
- *Startup(index_path, 'startup', 'Startup').fetch(),
- *StartupBroadcasts(index_path, 'startup', 'StartupBroadcasts').fetch(),
- *StartupMetrics(index_path, 'startup', 'StartupMetrics').fetch(),
- *StartupLockContention(index_path, 'startup',
- 'StartupLockContention').fetch(),
- *SurfaceFlingerLayers(index_path, 'android',
+ *SchedParser(index_path, 'parser/sched', 'SchedParser').fetch(),
+ *Smoke(index_path, 'parser/smoke', 'Smoke').fetch(),
+ *SmokeComputeMetrics(index_path, 'parser/smoke',
+ 'SmokeComputeMetrics').fetch(),
+ *SmokeJson(index_path, 'parser/smoke', 'SmokeJson').fetch(),
+ *SmokeSchedEvents(index_path, 'parser/smoke', 'SmokeSchedEvents').fetch(),
+ *SurfaceFlingerLayers(index_path, 'parser/android',
'SurfaceFlingerLayers').fetch(),
- *SurfaceFlingerTransactions(index_path, 'android',
+ *SurfaceFlingerTransactions(index_path, 'parser/android',
'SurfaceFlingerTransactions').fetch(),
+ *TrackEvent(index_path, 'parser/track_event', 'TrackEvent').fetch(),
+ *TranslatedArgs(index_path, 'parser/translated_args',
+ 'TranslatedArgs').fetch(),
+ *Ufs(index_path, 'parser/ufs', 'Ufs').fetch(),
+ # TODO(altimin, lalitm): "parsing" should be split into more specific
+ # directories.
+ *Parsing(index_path, 'parser/parsing', 'Parsing').fetch(),
+ *ParsingDebugAnnotation(index_path, 'parser/parsing',
+ 'ParsingDebugAnnotation').fetch(),
+ *ParsingRssStats(index_path, 'parser/parsing', 'ParsingRssStats').fetch(),
+ *ParsingMemoryCounters(index_path, 'parser/parsing',
+ 'ParsingMemoryCounters').fetch(),
+ ]
+
+ metrics_tests = [
+ *AndroidMetrics(index_path, 'metrics/android', 'AndroidMetrics').fetch(),
+ *Camera(index_path, 'metrics/camera', 'Camera').fetch(),
+ *ChromeArgs(index_path, 'metrics/chrome', 'ChromeArgs').fetch(),
+ *ChromeMetrics(index_path, 'metrics/chrome', 'ChromeMetrics').fetch(),
+ *ChromeProcesses(index_path, 'metrics/chrome', 'ChromeProcesses').fetch(),
+ *ChromeRailModes(index_path, 'metrics/chrome', 'ChromeRailModes').fetch(),
+ *ChromeScrollJankMetrics(index_path, 'metrics/chrome',
+ 'ChromeScrollJankMetrics').fetch(),
+ *ChromeTouchGesture(index_path, 'metrics/chrome',
+ 'ChromeTouchGesture').fetch(),
+ *Codecs(index_path, 'metrics/codecs', 'Codecs').fetch(),
+ *FrameTimeline(index_path, 'metrics/frame_timeline',
+ 'FrameTimeline').fetch(),
+ *GraphicsMetrics(index_path, 'metrics/graphics',
+ 'GraphicsMetrics').fetch(),
+ *IRQ(index_path, 'metrics/irq', 'IRQ').fetch(),
+ *MemoryMetrics(index_path, 'metrics/memory', 'MemoryMetrics').fetch(),
+ *NetworkMetrics(index_path, 'metrics/network', 'NetworkMetrics').fetch(),
+ *Power(index_path, 'metrics/power', 'Power').fetch(),
+ *ProfilingMetrics(index_path, 'metrics/profiling',
+ 'ProfilingMetrics').fetch(),
+ *Startup(index_path, 'metrics/startup', 'Startup').fetch(),
+ *StartupBroadcasts(index_path, 'metrics/startup',
+ 'StartupBroadcasts').fetch(),
+ *StartupLockContention(index_path, 'metrics/startup',
+ 'StartupLockContention').fetch(),
+ *StartupMetrics(index_path, 'metrics/startup', 'StartupMetrics').fetch(),
+ *WebView(index_path, 'metrics/webview', 'WebView').fetch(),
+ ]
+
+ stdlib_tests = [
+ *AndroidStdlib(index_path, 'stdlib/android', 'AndroidStdlib').fetch(),
+ *ChromeInteractions(index_path, 'stdlib/chrome',
+ 'ChromeInteractions').fetch(),
+ *ChromeScrollJankStdlib(index_path, 'stdlib/chrome',
+ 'ChromeScrollJankStdlib').fetch(),
+ *ChromeStdlib(index_path, 'stdlib/chrome', 'ChromeStdlib').fetch(),
+ *DynamicTables(index_path, 'stdlib/dynamic_tables',
+ 'DynamicTables').fetch(),
+ *Pkvm(index_path, 'stdlib/pkvm', 'Pkvm').fetch(),
+ *StdlibCommon(index_path, 'stdlib/common', 'StdlibCommon').fetch(),
+ *Slices(index_path, 'stdlib/slices', 'Slices').fetch(),
+ *SpanJoinLeftJoin(index_path, 'stdlib/span_join',
+ 'SpanJoinLeftJoin').fetch(),
+ *SpanJoinOuterJoin(index_path, 'stdlib/span_join',
+ 'SpanJoinOuterJoin').fetch(),
+ *SpanJoinRegression(index_path, 'stdlib/span_join',
+ 'SpanJoinRegression').fetch(),
+ *SpanJoinSmoke(index_path, 'stdlib/span_join', 'SpanJoinSmoke').fetch(),
+ *Timestamps(index_path, 'stdlib/timestamps', 'Timestamps').fetch(),
+ ]
+
+ syntax_tests = [
+ *Functions(index_path, 'syntax/functions', 'Functions').fetch(),
+ *PerfettoSql(index_path, 'syntax/perfetto_sql', 'PerfettoSql').fetch(),
+ ]
+
+ return parser_tests + metrics_tests + stdlib_tests + syntax_tests + [
*Tables(index_path, 'tables', 'Tables').fetch(),
*TablesCounters(index_path, 'tables', 'TablesCounters').fetch(),
*TablesSched(index_path, 'tables', 'TablesSched').fetch(),
- *Time(index_path, 'time', 'Time').fetch(),
- *TrackEvent(index_path, 'track_event', 'TrackEvent').fetch(),
- *Translation(index_path, 'translation', 'Translation').fetch(),
- *WebView(index_path, 'webview', 'WebView').fetch(),
]
diff --git a/test/trace_processor/diff_tests/memory/tests_metrics.py b/test/trace_processor/diff_tests/memory/tests_metrics.py
deleted file mode 100644
index 8a45185..0000000
--- a/test/trace_processor/diff_tests/memory/tests_metrics.py
+++ /dev/null
@@ -1,112 +0,0 @@
-#!/usr/bin/env python3
-# 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 a
-#
-# 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, Json, TextProto
-from python.generators.diff_tests.testing import DiffTestBlueprint
-from python.generators.diff_tests.testing import TestSuite
-
-
-class MemoryMetrics(TestSuite):
-
- def test_android_mem_counters(self):
- return DiffTestBlueprint(
- trace=DataPath('memory_counters.pb'),
- query=Metric('android_mem'),
- out=Path('android_mem_counters.out'))
-
- def test_trace_metadata(self):
- return DiffTestBlueprint(
- trace=DataPath('memory_counters.pb'),
- query=Metric('trace_metadata'),
- out=Path('trace_metadata.out'))
-
- def test_android_mem_by_priority(self):
- return DiffTestBlueprint(
- trace=Path('android_mem_by_priority.py'),
- query=Metric('android_mem'),
- out=Path('android_mem_by_priority.out'))
-
- def test_android_mem_lmk(self):
- return DiffTestBlueprint(
- trace=Path('android_systrace_lmk.py'),
- query=Metric('android_lmk'),
- out=TextProto(r"""
- android_lmk {
- total_count: 1
- by_oom_score {
- oom_score_adj: 900
- count: 1
- }
- oom_victim_count: 0
- }
- """))
-
- def test_android_lmk_oom(self):
- return DiffTestBlueprint(
- trace=TextProto(r"""
- packet {
- process_tree {
- processes {
- pid: 1000
- ppid: 1
- cmdline: "com.google.android.gm"
- }
- threads {
- tid: 1001
- tgid: 1000
- }
- }
- }
- packet {
- ftrace_events {
- cpu: 4
- event {
- timestamp: 1234
- pid: 4321
- mark_victim {
- pid: 1001
- }
- }
- }
- }
- """),
- query=Metric('android_lmk'),
- out=TextProto(r"""
- android_lmk {
- total_count: 0
- oom_victim_count: 1
- }
- """))
-
- def test_android_mem_delta(self):
- return DiffTestBlueprint(
- trace=Path('android_mem_delta.py'),
- query=Metric('android_mem'),
- out=TextProto(r"""
- android_mem {
- process_metrics {
- process_name: "com.my.pkg"
- total_counters {
- file_rss {
- min: 2000.0
- max: 10000.0
- avg: 6666.666666666667
- delta: 7000.0
- }
- }
- }
- }
- """))
diff --git a/test/trace_processor/diff_tests/metrics/android/ad_services_metric.py b/test/trace_processor/diff_tests/metrics/android/ad_services_metric.py
new file mode 100644
index 0000000..d4b9cf6
--- /dev/null
+++ b/test/trace_processor/diff_tests/metrics/android/ad_services_metric.py
@@ -0,0 +1,41 @@
+#!/usr/bin/env python3
+# 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.
+
+from os import sys, path
+
+import synth_common
+
+UI_NOTIFICATION_TRIGGER_EVENT = "NotificationTriggerEvent"
+AD_ID_CACHE_EVENT = "AdIdCacheEvent"
+APP_SET_ID_EVENT = "AppSetIdEvent"
+
+trace = synth_common.create_trace()
+
+trace.add_ftrace_packet(cpu=0)
+
+trace.add_sys_enter(ts=100, tid=42, id=64)
+trace.add_sys_exit(ts=200, tid=42, id=64, ret=0)
+
+trace.add_atrace_begin(
+ ts=350, tid=42, pid=42, buf=UI_NOTIFICATION_TRIGGER_EVENT)
+trace.add_atrace_end(ts=650, tid=42, pid=42)
+
+trace.add_atrace_begin(ts=750, tid=42, pid=42, buf=AD_ID_CACHE_EVENT)
+trace.add_atrace_end(ts=850, tid=42, pid=42)
+
+trace.add_atrace_begin(ts=900, tid=42, pid=42, buf=APP_SET_ID_EVENT)
+trace.add_atrace_end(ts=1200, tid=42, pid=42)
+
+sys.stdout.buffer.write(trace.trace.SerializeToString())
diff --git a/test/trace_processor/diff_tests/android/android_anr_metric.out b/test/trace_processor/diff_tests/metrics/android/android_anr_metric.out
similarity index 100%
rename from test/trace_processor/diff_tests/android/android_anr_metric.out
rename to test/trace_processor/diff_tests/metrics/android/android_anr_metric.out
diff --git a/test/trace_processor/diff_tests/android/android_anr_metric.py b/test/trace_processor/diff_tests/metrics/android/android_anr_metric.py
similarity index 100%
rename from test/trace_processor/diff_tests/android/android_anr_metric.py
rename to test/trace_processor/diff_tests/metrics/android/android_anr_metric.py
diff --git a/test/trace_processor/diff_tests/android/android_binder_metric.out b/test/trace_processor/diff_tests/metrics/android/android_binder_metric.out
similarity index 100%
rename from test/trace_processor/diff_tests/android/android_binder_metric.out
rename to test/trace_processor/diff_tests/metrics/android/android_binder_metric.out
diff --git a/test/trace_processor/diff_tests/android/android_blocking_calls_cuj_metric.out b/test/trace_processor/diff_tests/metrics/android/android_blocking_calls_cuj_metric.out
similarity index 100%
rename from test/trace_processor/diff_tests/android/android_blocking_calls_cuj_metric.out
rename to test/trace_processor/diff_tests/metrics/android/android_blocking_calls_cuj_metric.out
diff --git a/test/trace_processor/diff_tests/android/android_blocking_calls_cuj_metric.py b/test/trace_processor/diff_tests/metrics/android/android_blocking_calls_cuj_metric.py
similarity index 90%
rename from test/trace_processor/diff_tests/android/android_blocking_calls_cuj_metric.py
rename to test/trace_processor/diff_tests/metrics/android/android_blocking_calls_cuj_metric.py
index 7ec8cb9..f4eb10f 100755
--- a/test/trace_processor/diff_tests/android/android_blocking_calls_cuj_metric.py
+++ b/test/trace_processor/diff_tests/metrics/android/android_blocking_calls_cuj_metric.py
@@ -60,6 +60,7 @@
reply_tid=rx_pid,
reply_pid=rx_pid)
+
# Adds a set of predefined blocking calls in places near the cuj boundaries to
# verify that only the portion inside the cuj is counted in the metric.
def add_cuj_with_blocking_calls(trace, cuj_name, pid):
@@ -140,6 +141,7 @@
pid=pid)
blocking_call_ts += blocking_call_dur
+
# Creates 2 overlapping cuj, and a blocking call that lasts for both of them.
def add_overlapping_cujs_with_blocking_calls(trace, start_ts, pid):
add_async_trace(
@@ -190,20 +192,25 @@
def add_process(trace, package_name, uid, pid):
trace.add_package_list(ts=0, name=package_name, uid=uid, version_code=1)
- trace.add_process(
- pid=pid, ppid=0, cmdline=package_name, uid=uid)
+ trace.add_process(pid=pid, ppid=0, cmdline=package_name, uid=uid)
trace.add_thread(tid=pid, tgid=pid, cmdline="MainThread", name="MainThread")
def setup_trace():
trace = synth_common.create_trace()
trace.add_packet()
- add_process(trace, package_name="com.android.systemui", uid=10001,
- pid=SYSUI_PID)
- add_process(trace, package_name="com.google.android.apps.nexuslauncher",
- uid=10002, pid=LAUNCHER_PID)
- add_process(trace, package_name="com.google.android.third.process",
- uid=10003, pid=THIRD_PROCESS_PID)
+ add_process(
+ trace, package_name="com.android.systemui", uid=10001, pid=SYSUI_PID)
+ add_process(
+ trace,
+ package_name="com.google.android.apps.nexuslauncher",
+ uid=10002,
+ pid=LAUNCHER_PID)
+ add_process(
+ trace,
+ package_name="com.google.android.third.process",
+ uid=10003,
+ pid=THIRD_PROCESS_PID)
trace.add_ftrace_packet(cpu=0)
add_async_trace(trace, ts=0, ts_end=5, buf="J<IGNORED>", pid=SYSUI_PID)
return trace
@@ -212,13 +219,13 @@
trace = setup_trace()
add_cuj_with_blocking_calls(trace, "L<TEST_SYSUI_LATENCY_EVENT>", pid=SYSUI_PID)
-add_cuj_with_blocking_calls(trace, "L<TEST_LAUNCHER_LATENCY_EVENT>",
- pid=LAUNCHER_PID)
+add_cuj_with_blocking_calls(
+ trace, "L<TEST_LAUNCHER_LATENCY_EVENT>", pid=LAUNCHER_PID)
add_all_blocking_calls_in_cuj(trace, pid=THIRD_PROCESS_PID)
-add_overlapping_cujs_with_blocking_calls(trace, pid=SYSUI_PID,
- start_ts=20_000_000)
+add_overlapping_cujs_with_blocking_calls(
+ trace, pid=SYSUI_PID, start_ts=20_000_000)
add_cuj_with_named_binder_transaction(pid=SYSUI_PID, rx_pid=LAUNCHER_PID)
diff --git a/test/trace_processor/diff_tests/android/android_blocking_calls_on_jank_cuj_metric.out b/test/trace_processor/diff_tests/metrics/android/android_blocking_calls_on_jank_cuj_metric.out
similarity index 100%
rename from test/trace_processor/diff_tests/android/android_blocking_calls_on_jank_cuj_metric.out
rename to test/trace_processor/diff_tests/metrics/android/android_blocking_calls_on_jank_cuj_metric.out
diff --git a/test/trace_processor/diff_tests/android/android_monitor_contention.out b/test/trace_processor/diff_tests/metrics/android/android_monitor_contention.out
similarity index 100%
rename from test/trace_processor/diff_tests/android/android_monitor_contention.out
rename to test/trace_processor/diff_tests/metrics/android/android_monitor_contention.out
diff --git a/test/trace_processor/diff_tests/android/android_network_activity.out b/test/trace_processor/diff_tests/metrics/android/android_network_activity.out
similarity index 100%
rename from test/trace_processor/diff_tests/android/android_network_activity.out
rename to test/trace_processor/diff_tests/metrics/android/android_network_activity.out
diff --git a/test/trace_processor/diff_tests/android/android_sysui_notifications_blocking_calls_metric.out b/test/trace_processor/diff_tests/metrics/android/android_sysui_notifications_blocking_calls_metric.out
similarity index 100%
rename from test/trace_processor/diff_tests/android/android_sysui_notifications_blocking_calls_metric.out
rename to test/trace_processor/diff_tests/metrics/android/android_sysui_notifications_blocking_calls_metric.out
diff --git a/test/trace_processor/diff_tests/android/android_sysui_notifications_blocking_calls_metric.py b/test/trace_processor/diff_tests/metrics/android/android_sysui_notifications_blocking_calls_metric.py
similarity index 86%
rename from test/trace_processor/diff_tests/android/android_sysui_notifications_blocking_calls_metric.py
rename to test/trace_processor/diff_tests/metrics/android/android_sysui_notifications_blocking_calls_metric.py
index cab8c8f..43d15cc 100644
--- a/test/trace_processor/diff_tests/android/android_sysui_notifications_blocking_calls_metric.py
+++ b/test/trace_processor/diff_tests/metrics/android/android_sysui_notifications_blocking_calls_metric.py
@@ -23,9 +23,9 @@
# List of blocking calls
blocking_call_names = [
- 'NotificationStackScrollLayout#onMeasure', 'ExpNotRow#onMeasure(MessagingStyle)',
- 'ExpNotRow#onMeasure(BigTextStyle)', 'NotificationShadeWindowView#onMeasure',
- 'ImageFloatingTextView#onMeasure',
+ 'NotificationStackScrollLayout#onMeasure',
+ 'ExpNotRow#onMeasure(MessagingStyle)', 'ExpNotRow#onMeasure(BigTextStyle)',
+ 'NotificationShadeWindowView#onMeasure', 'ImageFloatingTextView#onMeasure',
'Should not be in the metric'
]
@@ -39,6 +39,7 @@
trace.add_atrace_async_begin(ts=ts, tid=pid, pid=pid, buf=buf)
trace.add_atrace_async_end(ts=ts_end, tid=pid, pid=pid, buf=buf)
+
# Creates a trace that contains one of each blocking call.
def add_all_sysui_notifications_blocking_calls(trace, pid):
blocking_call_dur = 10_000_000
@@ -64,23 +65,21 @@
def add_process(trace, package_name, uid, pid):
trace.add_package_list(ts=0, name=package_name, uid=uid, version_code=1)
- trace.add_process(
- pid=pid, ppid=0, cmdline=package_name, uid=uid)
+ trace.add_process(pid=pid, ppid=0, cmdline=package_name, uid=uid)
trace.add_thread(tid=pid, tgid=pid, cmdline="MainThread", name="MainThread")
def setup_trace():
trace = synth_common.create_trace()
trace.add_packet()
- add_process(trace, package_name="com.android.systemui", uid=10001,
- pid=SYSUI_PID)
+ add_process(
+ trace, package_name="com.android.systemui", uid=10001, pid=SYSUI_PID)
trace.add_ftrace_packet(cpu=0)
return trace
trace = setup_trace()
-
add_all_sysui_notifications_blocking_calls(trace, pid=SYSUI_PID)
# See test_android_sysui_notifications_blocking_calls.
diff --git a/test/trace_processor/diff_tests/metrics/android/tests.py b/test/trace_processor/diff_tests/metrics/android/tests.py
new file mode 100644
index 0000000..f5ffcf7
--- /dev/null
+++ b/test/trace_processor/diff_tests/metrics/android/tests.py
@@ -0,0 +1,206 @@
+#!/usr/bin/env python3
+# 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 a
+#
+# 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, Systrace
+from python.generators.diff_tests.testing import Csv, Json, TextProto, BinaryProto
+from python.generators.diff_tests.testing import DiffTestBlueprint
+from python.generators.diff_tests.testing import TestSuite
+from python.generators.diff_tests.testing import PrintProfileProto
+
+
+class AndroidMetrics(TestSuite):
+
+ def test_android_network_activity(self):
+ # The following should have three activity regions:
+ # * uid=123 from 1000 to 2010 (note: end is max(ts)+idle_ns)
+ # * uid=456 from 1005 to 3115 (note: doesn't group with above due to name)
+ # * Also tests that groups form based on (ts+dur), not just start ts.
+ # * uid=123 from 3000 to 5500 (note: gap between 1010 to 3000 > idle_ns)
+ # Note: packet_timestamps are delta encoded from the base timestamp.
+ return DiffTestBlueprint(
+ trace=TextProto(r"""
+ packet {
+ timestamp: 0
+ network_packet_bundle {
+ ctx {
+ direction: DIR_EGRESS
+ interface: "wlan"
+ uid: 123
+ }
+ packet_timestamps: [
+ 1000, 1010,
+ 3000, 3050, 4000, 4500
+ ],
+ packet_lengths: [
+ 50, 50,
+ 50, 50, 50, 50
+ ],
+ }
+ }
+ packet {
+ timestamp: 1005
+ network_packet_bundle {
+ ctx {
+ direction: DIR_EGRESS
+ interface: "wlan"
+ uid: 456
+ }
+ total_duration: 100
+ total_packets: 2
+ total_length: 300
+ }
+ }
+ packet {
+ timestamp: 2015
+ network_packet_bundle {
+ ctx {
+ direction: DIR_EGRESS
+ interface: "wlan"
+ uid: 456
+ }
+ total_duration: 100
+ total_packets: 1
+ total_length: 50
+ }
+ }
+ packet {
+ timestamp: 0
+ network_packet_bundle {
+ ctx {
+ direction: DIR_INGRESS
+ interface: "loopback"
+ uid: 123
+ }
+ packet_timestamps: [6000]
+ packet_lengths: [100]
+ }
+ }
+ """),
+ query="""
+ SELECT RUN_METRIC(
+ 'android/network_activity_template.sql',
+ 'view_name', 'android_network_activity',
+ 'group_by', 'package_name',
+ 'filter', 'iface = "wlan"',
+ 'idle_ns', '1000',
+ 'quant_ns', '100'
+ );
+
+ SELECT * FROM android_network_activity
+ ORDER BY package_name, ts;
+ """,
+ out=Path('android_network_activity.out'))
+
+ def test_anr_metric(self):
+ return DiffTestBlueprint(
+ trace=Path('android_anr_metric.py'),
+ query=Metric('android_anr'),
+ out=Path('android_anr_metric.out'))
+
+ def test_binder_metric(self):
+ return DiffTestBlueprint(
+ trace=DataPath('android_binder_metric_trace.atr'),
+ query=Metric('android_binder'),
+ out=Path('android_binder_metric.out'))
+
+ def test_android_blocking_calls_cuj(self):
+ return DiffTestBlueprint(
+ trace=Path('android_blocking_calls_cuj_metric.py'),
+ query=Metric('android_blocking_calls_cuj_metric'),
+ out=Path('android_blocking_calls_cuj_metric.out'))
+
+ def test_android_blocking_calls_on_jank_cujs(self):
+ return DiffTestBlueprint(
+ trace=Path('../graphics/android_jank_cuj.py'),
+ query=Metric('android_blocking_calls_cuj_metric'),
+ out=Path('android_blocking_calls_on_jank_cuj_metric.out'))
+
+ def test_android_sysui_notifications_blocking_calls(self):
+ return DiffTestBlueprint(
+ trace=Path('android_sysui_notifications_blocking_calls_metric.py'),
+ query=Metric('android_sysui_notifications_blocking_calls_metric'),
+ out=Path('android_sysui_notifications_blocking_calls_metric.out'))
+
+ def test_monitor_contention_metric(self):
+ return DiffTestBlueprint(
+ trace=DataPath('android_monitor_contention_trace.atr'),
+ query=Metric('android_monitor_contention'),
+ out=Path('android_monitor_contention.out'))
+
+ def test_monitor_contention_agg_metric(self):
+ return DiffTestBlueprint(
+ trace=DataPath('android_monitor_contention_trace.atr'),
+ query=Metric('android_monitor_contention_agg'),
+ out=TextProto(r"""
+ android_monitor_contention_agg {
+ process_aggregation {
+ name: "android.process.media"
+ total_contention_count: 12
+ total_contention_dur: 12893198
+ main_thread_contention_count: 12
+ main_thread_contention_dur: 12893198
+ }
+ process_aggregation {
+ name: "com.android.providers.media.module"
+ total_contention_count: 7
+ total_contention_dur: 169793
+ }
+ process_aggregation {
+ name: "com.android.systemui"
+ total_contention_count: 8
+ total_contention_dur: 9445959
+ main_thread_contention_count: 5
+ main_thread_contention_dur: 9228582
+ }
+ process_aggregation {
+ name: "system_server"
+ total_contention_count: 354
+ total_contention_dur: 358898613
+ main_thread_contention_count: 27
+ main_thread_contention_dur: 36904702
+ }
+ }
+ """))
+
+ def test_android_boot(self):
+ return DiffTestBlueprint(
+ trace=DataPath('android_boot.pftrace'),
+ query=Metric('android_boot'),
+ out=TextProto(r"""
+ android_boot {
+ system_server_durations {
+ total_dur: 267193980530
+ uninterruptible_sleep_dur: 3843119529
+ }
+ }
+ """))
+
+ def test_ad_services_metric(self):
+ return DiffTestBlueprint(
+ trace=Path('ad_services_metric.py'),
+ query=Metric('ad_services_metric'),
+ out=TextProto(r"""
+ ad_services_metric {
+ ui_metric {
+ latency: 0.0003
+ }
+ app_set_id_metric {
+ latency: 0.0001
+ }
+ ad_id_metric {
+ latency:0.0003
+ }
+ }
+ """))
diff --git a/test/trace_processor/diff_tests/camera/camera-ion-mem-trace_android_camera_unagg.out b/test/trace_processor/diff_tests/metrics/camera/camera-ion-mem-trace_android_camera_unagg.out
similarity index 100%
rename from test/trace_processor/diff_tests/camera/camera-ion-mem-trace_android_camera_unagg.out
rename to test/trace_processor/diff_tests/metrics/camera/camera-ion-mem-trace_android_camera_unagg.out
diff --git a/test/trace_processor/diff_tests/camera/tests.py b/test/trace_processor/diff_tests/metrics/camera/tests.py
similarity index 100%
rename from test/trace_processor/diff_tests/camera/tests.py
rename to test/trace_processor/diff_tests/metrics/camera/tests.py
diff --git a/test/trace_processor/diff_tests/chrome/actual_power_by_combined_rail_mode.py b/test/trace_processor/diff_tests/metrics/chrome/actual_power_by_combined_rail_mode.py
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/actual_power_by_combined_rail_mode.py
rename to test/trace_processor/diff_tests/metrics/chrome/actual_power_by_combined_rail_mode.py
diff --git a/test/trace_processor/diff_tests/chrome/chrome_input_to_browser_intervals.out b/test/trace_processor/diff_tests/metrics/chrome/chrome_input_to_browser_intervals.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/chrome_input_to_browser_intervals.out
rename to test/trace_processor/diff_tests/metrics/chrome/chrome_input_to_browser_intervals.out
diff --git a/test/trace_processor/diff_tests/chrome/chrome_long_tasks_delaying_input_processing_compare_default_test.sql b/test/trace_processor/diff_tests/metrics/chrome/chrome_long_tasks_delaying_input_processing_compare_default_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/chrome_long_tasks_delaying_input_processing_compare_default_test.sql
rename to test/trace_processor/diff_tests/metrics/chrome/chrome_long_tasks_delaying_input_processing_compare_default_test.sql
diff --git a/test/trace_processor/diff_tests/chrome/chrome_processes_android_systrace.out b/test/trace_processor/diff_tests/metrics/chrome/chrome_processes_android_systrace.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/chrome_processes_android_systrace.out
rename to test/trace_processor/diff_tests/metrics/chrome/chrome_processes_android_systrace.out
diff --git a/test/trace_processor/diff_tests/chrome/chrome_processes_type_android_systrace.out b/test/trace_processor/diff_tests/metrics/chrome/chrome_processes_type_android_systrace.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/chrome_processes_type_android_systrace.out
rename to test/trace_processor/diff_tests/metrics/chrome/chrome_processes_type_android_systrace.out
diff --git a/test/trace_processor/diff_tests/chrome/chrome_reliable_range.textproto b/test/trace_processor/diff_tests/metrics/chrome/chrome_reliable_range.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/chrome_reliable_range.textproto
rename to test/trace_processor/diff_tests/metrics/chrome/chrome_reliable_range.textproto
diff --git a/test/trace_processor/diff_tests/chrome/chrome_reliable_range_cropping.textproto b/test/trace_processor/diff_tests/metrics/chrome/chrome_reliable_range_cropping.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/chrome_reliable_range_cropping.textproto
rename to test/trace_processor/diff_tests/metrics/chrome/chrome_reliable_range_cropping.textproto
diff --git a/test/trace_processor/diff_tests/chrome/chrome_reliable_range_missing_browser_main.out b/test/trace_processor/diff_tests/metrics/chrome/chrome_reliable_range_missing_browser_main.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/chrome_reliable_range_missing_browser_main.out
rename to test/trace_processor/diff_tests/metrics/chrome/chrome_reliable_range_missing_browser_main.out
diff --git a/test/trace_processor/diff_tests/chrome/chrome_reliable_range_missing_browser_main.textproto b/test/trace_processor/diff_tests/metrics/chrome/chrome_reliable_range_missing_browser_main.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/chrome_reliable_range_missing_browser_main.textproto
rename to test/trace_processor/diff_tests/metrics/chrome/chrome_reliable_range_missing_browser_main.textproto
diff --git a/test/trace_processor/diff_tests/chrome/chrome_reliable_range_missing_gpu_main.textproto b/test/trace_processor/diff_tests/metrics/chrome/chrome_reliable_range_missing_gpu_main.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/chrome_reliable_range_missing_gpu_main.textproto
rename to test/trace_processor/diff_tests/metrics/chrome/chrome_reliable_range_missing_gpu_main.textproto
diff --git a/test/trace_processor/diff_tests/chrome/chrome_reliable_range_missing_processes.textproto b/test/trace_processor/diff_tests/metrics/chrome/chrome_reliable_range_missing_processes.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/chrome_reliable_range_missing_processes.textproto
rename to test/trace_processor/diff_tests/metrics/chrome/chrome_reliable_range_missing_processes.textproto
diff --git a/test/trace_processor/diff_tests/chrome/chrome_reliable_range_missing_renderer_main.out b/test/trace_processor/diff_tests/metrics/chrome/chrome_reliable_range_missing_renderer_main.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/chrome_reliable_range_missing_renderer_main.out
rename to test/trace_processor/diff_tests/metrics/chrome/chrome_reliable_range_missing_renderer_main.out
diff --git a/test/trace_processor/diff_tests/chrome/chrome_reliable_range_missing_renderer_main.textproto b/test/trace_processor/diff_tests/metrics/chrome/chrome_reliable_range_missing_renderer_main.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/chrome_reliable_range_missing_renderer_main.textproto
rename to test/trace_processor/diff_tests/metrics/chrome/chrome_reliable_range_missing_renderer_main.textproto
diff --git a/test/trace_processor/diff_tests/chrome/chrome_reliable_range_non_chrome_process.out b/test/trace_processor/diff_tests/metrics/chrome/chrome_reliable_range_non_chrome_process.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/chrome_reliable_range_non_chrome_process.out
rename to test/trace_processor/diff_tests/metrics/chrome/chrome_reliable_range_non_chrome_process.out
diff --git a/test/trace_processor/diff_tests/chrome/chrome_reliable_range_test.sql b/test/trace_processor/diff_tests/metrics/chrome/chrome_reliable_range_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/chrome_reliable_range_test.sql
rename to test/trace_processor/diff_tests/metrics/chrome/chrome_reliable_range_test.sql
diff --git a/test/trace_processor/diff_tests/chrome/chrome_scroll_helper.py b/test/trace_processor/diff_tests/metrics/chrome/chrome_scroll_helper.py
similarity index 99%
rename from test/trace_processor/diff_tests/chrome/chrome_scroll_helper.py
rename to test/trace_processor/diff_tests/metrics/chrome/chrome_scroll_helper.py
index 7b7cee1..77b6e05 100644
--- a/test/trace_processor/diff_tests/chrome/chrome_scroll_helper.py
+++ b/test/trace_processor/diff_tests/metrics/chrome/chrome_scroll_helper.py
@@ -20,6 +20,7 @@
import synth_common
from synth_common import ms_to_ns
+
trace = synth_common.create_trace()
diff --git a/test/trace_processor/diff_tests/chrome/chrome_scroll_jank_caused_by_scheduling_test.out b/test/trace_processor/diff_tests/metrics/chrome/chrome_scroll_jank_caused_by_scheduling_test.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/chrome_scroll_jank_caused_by_scheduling_test.out
rename to test/trace_processor/diff_tests/metrics/chrome/chrome_scroll_jank_caused_by_scheduling_test.out
diff --git a/test/trace_processor/diff_tests/chrome/chrome_stack_samples_for_task_test.out b/test/trace_processor/diff_tests/metrics/chrome/chrome_stack_samples_for_task_test.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/chrome_stack_samples_for_task_test.out
rename to test/trace_processor/diff_tests/metrics/chrome/chrome_stack_samples_for_task_test.out
diff --git a/test/trace_processor/diff_tests/chrome/chrome_tasks_delaying_input_processing_test.out b/test/trace_processor/diff_tests/metrics/chrome/chrome_tasks_delaying_input_processing_test.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/chrome_tasks_delaying_input_processing_test.out
rename to test/trace_processor/diff_tests/metrics/chrome/chrome_tasks_delaying_input_processing_test.out
diff --git a/test/trace_processor/diff_tests/chrome/chrome_threads.out b/test/trace_processor/diff_tests/metrics/chrome/chrome_threads.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/chrome_threads.out
rename to test/trace_processor/diff_tests/metrics/chrome/chrome_threads.out
diff --git a/test/trace_processor/diff_tests/chrome/chrome_threads_android_systrace.out b/test/trace_processor/diff_tests/metrics/chrome/chrome_threads_android_systrace.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/chrome_threads_android_systrace.out
rename to test/trace_processor/diff_tests/metrics/chrome/chrome_threads_android_systrace.out
diff --git a/test/trace_processor/diff_tests/chrome/combined_rail_modes.py b/test/trace_processor/diff_tests/metrics/chrome/combined_rail_modes.py
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/combined_rail_modes.py
rename to test/trace_processor/diff_tests/metrics/chrome/combined_rail_modes.py
diff --git a/test/trace_processor/diff_tests/chrome/cpu_time_by_combined_rail_mode.py b/test/trace_processor/diff_tests/metrics/chrome/cpu_time_by_combined_rail_mode.py
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/cpu_time_by_combined_rail_mode.py
rename to test/trace_processor/diff_tests/metrics/chrome/cpu_time_by_combined_rail_mode.py
diff --git a/test/trace_processor/diff_tests/chrome/estimated_power_by_combined_rail_mode.py b/test/trace_processor/diff_tests/metrics/chrome/estimated_power_by_combined_rail_mode.py
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/estimated_power_by_combined_rail_mode.py
rename to test/trace_processor/diff_tests/metrics/chrome/estimated_power_by_combined_rail_mode.py
diff --git a/test/trace_processor/diff_tests/chrome/experimental_reliable_chrome_tasks_delaying_input_processing_test.out b/test/trace_processor/diff_tests/metrics/chrome/experimental_reliable_chrome_tasks_delaying_input_processing_test.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/experimental_reliable_chrome_tasks_delaying_input_processing_test.out
rename to test/trace_processor/diff_tests/metrics/chrome/experimental_reliable_chrome_tasks_delaying_input_processing_test.out
diff --git a/test/trace_processor/diff_tests/chrome/frame_times_metric.out b/test/trace_processor/diff_tests/metrics/chrome/frame_times_metric.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/frame_times_metric.out
rename to test/trace_processor/diff_tests/metrics/chrome/frame_times_metric.out
diff --git a/test/trace_processor/diff_tests/chrome/frame_times_metric_test.sql b/test/trace_processor/diff_tests/metrics/chrome/frame_times_metric_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/frame_times_metric_test.sql
rename to test/trace_processor/diff_tests/metrics/chrome/frame_times_metric_test.sql
diff --git a/test/trace_processor/diff_tests/chrome/long_event_latency.textproto b/test/trace_processor/diff_tests/metrics/chrome/long_event_latency.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/long_event_latency.textproto
rename to test/trace_processor/diff_tests/metrics/chrome/long_event_latency.textproto
diff --git a/test/trace_processor/diff_tests/chrome/long_task_tracking_trace_chrome_long_tasks_delaying_input_processing_compare_default_test.out b/test/trace_processor/diff_tests/metrics/chrome/long_task_tracking_trace_chrome_long_tasks_delaying_input_processing_compare_default_test.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/long_task_tracking_trace_chrome_long_tasks_delaying_input_processing_compare_default_test.out
rename to test/trace_processor/diff_tests/metrics/chrome/long_task_tracking_trace_chrome_long_tasks_delaying_input_processing_compare_default_test.out
diff --git a/test/trace_processor/diff_tests/chrome/long_task_tracking_trace_chrome_long_tasks_delaying_input_processing_test.out b/test/trace_processor/diff_tests/metrics/chrome/long_task_tracking_trace_chrome_long_tasks_delaying_input_processing_test.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/long_task_tracking_trace_chrome_long_tasks_delaying_input_processing_test.out
rename to test/trace_processor/diff_tests/metrics/chrome/long_task_tracking_trace_chrome_long_tasks_delaying_input_processing_test.out
diff --git a/test/trace_processor/diff_tests/chrome/modified_rail_modes.py b/test/trace_processor/diff_tests/metrics/chrome/modified_rail_modes.py
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/modified_rail_modes.py
rename to test/trace_processor/diff_tests/metrics/chrome/modified_rail_modes.py
diff --git a/test/trace_processor/diff_tests/chrome/modified_rail_modes_extra_long.py b/test/trace_processor/diff_tests/metrics/chrome/modified_rail_modes_extra_long.py
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/modified_rail_modes_extra_long.py
rename to test/trace_processor/diff_tests/metrics/chrome/modified_rail_modes_extra_long.py
diff --git a/test/trace_processor/diff_tests/chrome/modified_rail_modes_long.py b/test/trace_processor/diff_tests/metrics/chrome/modified_rail_modes_long.py
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/modified_rail_modes_long.py
rename to test/trace_processor/diff_tests/metrics/chrome/modified_rail_modes_long.py
diff --git a/test/trace_processor/diff_tests/chrome/modified_rail_modes_no_vsyncs.py b/test/trace_processor/diff_tests/metrics/chrome/modified_rail_modes_no_vsyncs.py
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/modified_rail_modes_no_vsyncs.py
rename to test/trace_processor/diff_tests/metrics/chrome/modified_rail_modes_no_vsyncs.py
diff --git a/test/trace_processor/diff_tests/chrome/modified_rail_modes_with_input.py b/test/trace_processor/diff_tests/metrics/chrome/modified_rail_modes_with_input.py
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/modified_rail_modes_with_input.py
rename to test/trace_processor/diff_tests/metrics/chrome/modified_rail_modes_with_input.py
diff --git a/test/trace_processor/diff_tests/chrome/proto_content.out b/test/trace_processor/diff_tests/metrics/chrome/proto_content.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/proto_content.out
rename to test/trace_processor/diff_tests/metrics/chrome/proto_content.out
diff --git a/test/trace_processor/diff_tests/chrome/proto_content_path_test.sql b/test/trace_processor/diff_tests/metrics/chrome/proto_content_path_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/proto_content_path_test.sql
rename to test/trace_processor/diff_tests/metrics/chrome/proto_content_path_test.sql
diff --git a/test/trace_processor/diff_tests/chrome/proto_content_test.sql b/test/trace_processor/diff_tests/metrics/chrome/proto_content_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/proto_content_test.sql
rename to test/trace_processor/diff_tests/metrics/chrome/proto_content_test.sql
diff --git a/test/trace_processor/diff_tests/chrome/scroll_flow_event.out b/test/trace_processor/diff_tests/metrics/chrome/scroll_flow_event.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/scroll_flow_event.out
rename to test/trace_processor/diff_tests/metrics/chrome/scroll_flow_event.out
diff --git a/test/trace_processor/diff_tests/chrome/scroll_flow_event_general_validation.out b/test/trace_processor/diff_tests/metrics/chrome/scroll_flow_event_general_validation.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/scroll_flow_event_general_validation.out
rename to test/trace_processor/diff_tests/metrics/chrome/scroll_flow_event_general_validation.out
diff --git a/test/trace_processor/diff_tests/chrome/scroll_flow_event_queuing_delay.out b/test/trace_processor/diff_tests/metrics/chrome/scroll_flow_event_queuing_delay.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/scroll_flow_event_queuing_delay.out
rename to test/trace_processor/diff_tests/metrics/chrome/scroll_flow_event_queuing_delay.out
diff --git a/test/trace_processor/diff_tests/chrome/scroll_flow_event_queuing_delay_general_validation_test.sql b/test/trace_processor/diff_tests/metrics/chrome/scroll_flow_event_queuing_delay_general_validation_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/scroll_flow_event_queuing_delay_general_validation_test.sql
rename to test/trace_processor/diff_tests/metrics/chrome/scroll_flow_event_queuing_delay_general_validation_test.sql
diff --git a/test/trace_processor/diff_tests/chrome/scroll_jank.out b/test/trace_processor/diff_tests/metrics/chrome/scroll_jank.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/scroll_jank.out
rename to test/trace_processor/diff_tests/metrics/chrome/scroll_jank.out
diff --git a/test/trace_processor/diff_tests/chrome/scroll_jank_cause_queuing_delay.out b/test/trace_processor/diff_tests/metrics/chrome/scroll_jank_cause_queuing_delay.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/scroll_jank_cause_queuing_delay.out
rename to test/trace_processor/diff_tests/metrics/chrome/scroll_jank_cause_queuing_delay.out
diff --git a/test/trace_processor/diff_tests/chrome/scroll_jank_cause_queuing_delay_general_validation.out b/test/trace_processor/diff_tests/metrics/chrome/scroll_jank_cause_queuing_delay_general_validation.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/scroll_jank_cause_queuing_delay_general_validation.out
rename to test/trace_processor/diff_tests/metrics/chrome/scroll_jank_cause_queuing_delay_general_validation.out
diff --git a/test/trace_processor/diff_tests/chrome/scroll_jank_cause_queuing_delay_restricted.out b/test/trace_processor/diff_tests/metrics/chrome/scroll_jank_cause_queuing_delay_restricted.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/scroll_jank_cause_queuing_delay_restricted.out
rename to test/trace_processor/diff_tests/metrics/chrome/scroll_jank_cause_queuing_delay_restricted.out
diff --git a/test/trace_processor/diff_tests/chrome/scroll_jank_general_validation.out b/test/trace_processor/diff_tests/metrics/chrome/scroll_jank_general_validation.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/scroll_jank_general_validation.out
rename to test/trace_processor/diff_tests/metrics/chrome/scroll_jank_general_validation.out
diff --git a/test/trace_processor/diff_tests/chrome/scroll_jank_general_validation_test.sql b/test/trace_processor/diff_tests/metrics/chrome/scroll_jank_general_validation_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/scroll_jank_general_validation_test.sql
rename to test/trace_processor/diff_tests/metrics/chrome/scroll_jank_general_validation_test.sql
diff --git a/test/trace_processor/diff_tests/chrome/scroll_jank_gpu_check.py b/test/trace_processor/diff_tests/metrics/chrome/scroll_jank_gpu_check.py
similarity index 99%
rename from test/trace_processor/diff_tests/chrome/scroll_jank_gpu_check.py
rename to test/trace_processor/diff_tests/metrics/chrome/scroll_jank_gpu_check.py
index c9ba45c..3de4221 100644
--- a/test/trace_processor/diff_tests/chrome/scroll_jank_gpu_check.py
+++ b/test/trace_processor/diff_tests/metrics/chrome/scroll_jank_gpu_check.py
@@ -22,6 +22,7 @@
import synth_common
from synth_common import ms_to_ns
+
trace = synth_common.create_trace()
from chrome_scroll_helper import ChromeScrollHelper
diff --git a/test/trace_processor/diff_tests/chrome/scroll_jank_mojo_simple_watcher.out b/test/trace_processor/diff_tests/metrics/chrome/scroll_jank_mojo_simple_watcher.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/scroll_jank_mojo_simple_watcher.out
rename to test/trace_processor/diff_tests/metrics/chrome/scroll_jank_mojo_simple_watcher.out
diff --git a/test/trace_processor/diff_tests/chrome/scroll_jank_mojo_simple_watcher.py b/test/trace_processor/diff_tests/metrics/chrome/scroll_jank_mojo_simple_watcher.py
similarity index 99%
rename from test/trace_processor/diff_tests/chrome/scroll_jank_mojo_simple_watcher.py
rename to test/trace_processor/diff_tests/metrics/chrome/scroll_jank_mojo_simple_watcher.py
index 72dfa7d..e8839a7 100644
--- a/test/trace_processor/diff_tests/chrome/scroll_jank_mojo_simple_watcher.py
+++ b/test/trace_processor/diff_tests/metrics/chrome/scroll_jank_mojo_simple_watcher.py
@@ -22,6 +22,7 @@
import synth_common
from synth_common import ms_to_ns
+
trace = synth_common.create_trace()
process_track1 = 1234
diff --git a/test/trace_processor/diff_tests/metrics/chrome/tests.py b/test/trace_processor/diff_tests/metrics/chrome/tests.py
new file mode 100644
index 0000000..f005556
--- /dev/null
+++ b/test/trace_processor/diff_tests/metrics/chrome/tests.py
@@ -0,0 +1,300 @@
+#!/usr/bin/env python3
+# 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 a
+#
+# 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, Json, TextProto
+from python.generators.diff_tests.testing import DiffTestBlueprint
+from python.generators.diff_tests.testing import TestSuite
+
+
+class ChromeMetrics(TestSuite):
+ # Tests related to Chrome's use of Perfetto. Chrome histogram hashes
+ def test_chrome_histogram_hashes(self):
+ return DiffTestBlueprint(
+ trace=TextProto(r"""
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ incremental_state_cleared: true
+ track_event {
+ categories: "cat1"
+ type: 3
+ name_iid: 1
+ chrome_histogram_sample {
+ name_hash: 10
+ sample: 100
+ }
+ }
+ }
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ incremental_state_cleared: true
+ track_event {
+ categories: "cat2"
+ type: 3
+ name_iid: 2
+ chrome_histogram_sample {
+ name_hash: 20
+ }
+ }
+ }
+ """),
+ query=Metric('chrome_histogram_hashes'),
+ out=TextProto(r"""
+ [perfetto.protos.chrome_histogram_hashes]: {
+ hash: 10
+ hash: 20
+ }
+ """))
+
+ # Chrome user events
+ def test_chrome_user_event_hashes(self):
+ return DiffTestBlueprint(
+ trace=TextProto(r"""
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ incremental_state_cleared: true
+ track_event {
+ categories: "cat1"
+ type: 3
+ name_iid: 1
+ chrome_user_event {
+ action_hash: 10
+ }
+ }
+ }
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ incremental_state_cleared: true
+ track_event {
+ categories: "cat2"
+ type: 3
+ name_iid: 2
+ chrome_user_event {
+ action_hash: 20
+ }
+ }
+ }
+ """),
+ query=Metric('chrome_user_event_hashes'),
+ out=TextProto(r"""
+ [perfetto.protos.chrome_user_event_hashes]: {
+ action_hash: 10
+ action_hash: 20
+ }
+ """))
+
+ # Chrome performance mark
+ def test_chrome_performance_mark_hashes(self):
+ return DiffTestBlueprint(
+ trace=TextProto(r"""
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ incremental_state_cleared: true
+ track_event {
+ categories: "cat1"
+ type: 3
+ name: "name1"
+ [perfetto.protos.ChromeTrackEvent.chrome_hashed_performance_mark] {
+ site_hash: 10
+ mark_hash: 100
+ }
+ }
+ }
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ incremental_state_cleared: true
+ track_event {
+ categories: "cat2"
+ type: 3
+ name: "name2"
+ [perfetto.protos.ChromeTrackEvent.chrome_hashed_performance_mark] {
+ site_hash: 20
+ mark_hash: 200
+ }
+ }
+ }
+ """),
+ query=Metric('chrome_performance_mark_hashes'),
+ out=TextProto(r"""
+ [perfetto.protos.chrome_performance_mark_hashes]: {
+ site_hash: 10
+ site_hash: 20
+ mark_hash: 100
+ mark_hash: 200
+ }
+ """))
+
+ # Chrome reliable range
+ def test_chrome_reliable_range(self):
+ return DiffTestBlueprint(
+ trace=Path('chrome_reliable_range.textproto'),
+ query=Path('chrome_reliable_range_test.sql'),
+ out=Csv("""
+ "start","reason","debug_limiting_upid","debug_limiting_utid"
+ 12,"First slice for utid=2","[NULL]",2
+ """))
+
+ def test_chrome_reliable_range_cropping(self):
+ return DiffTestBlueprint(
+ trace=Path('chrome_reliable_range_cropping.textproto'),
+ query=Path('chrome_reliable_range_test.sql'),
+ out=Csv("""
+ "start","reason","debug_limiting_upid","debug_limiting_utid"
+ 10000,"Range of interest packet","[NULL]",2
+ """))
+
+ def test_chrome_reliable_range_missing_processes(self):
+ return DiffTestBlueprint(
+ trace=Path('chrome_reliable_range_missing_processes.textproto'),
+ query=Path('chrome_reliable_range_test.sql'),
+ out=Csv("""
+ "start","reason","debug_limiting_upid","debug_limiting_utid"
+ 1011,"Missing process data for upid=2",2,1
+ """))
+
+ def test_chrome_reliable_range_missing_browser_main(self):
+ return DiffTestBlueprint(
+ trace=Path('chrome_reliable_range_missing_browser_main.textproto'),
+ query=Path('chrome_reliable_range_test.sql'),
+ out=Csv("""
+ "start","reason","debug_limiting_upid","debug_limiting_utid"
+ 1011,"Missing main thread for upid=1",1,1
+ """))
+
+ def test_chrome_reliable_range_missing_gpu_main(self):
+ return DiffTestBlueprint(
+ trace=Path('chrome_reliable_range_missing_gpu_main.textproto'),
+ query=Path('chrome_reliable_range_test.sql'),
+ out=Csv("""
+ "start","reason","debug_limiting_upid","debug_limiting_utid"
+ 1011,"Missing main thread for upid=1",1,1
+ """))
+
+ def test_chrome_reliable_range_missing_renderer_main(self):
+ return DiffTestBlueprint(
+ trace=Path('chrome_reliable_range_missing_renderer_main.textproto'),
+ query=Path('chrome_reliable_range_test.sql'),
+ out=Csv("""
+ "start","reason","debug_limiting_upid","debug_limiting_utid"
+ 1011,"Missing main thread for upid=1",1,1
+ """))
+
+ def test_chrome_reliable_range_non_chrome_process(self):
+ return DiffTestBlueprint(
+ # We need a trace with a large number of non-chrome slices, so that the
+ # reliable range is affected by their filtering.
+ trace=DataPath('example_android_trace_30s.pb'),
+ query=Path('chrome_reliable_range_test.sql'),
+ out=Csv("""
+ "start","reason","debug_limiting_upid","debug_limiting_utid"
+ 0,"[NULL]","[NULL]","[NULL]"
+ """))
+
+ # Chrome slices
+ def test_chrome_slice_names(self):
+ return DiffTestBlueprint(
+ trace=TextProto(r"""
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 1000
+ track_event {
+ categories: "cat"
+ name: "Looper.Dispatch: class1"
+ type: 3
+ }
+ }
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 2000
+ track_event {
+ categories: "cat"
+ name: "name2"
+ type: 3
+ }
+ }
+ packet {
+ chrome_metadata {
+ chrome_version_code: 123
+ }
+ }
+ """),
+ query=Metric('chrome_slice_names'),
+ out=TextProto(r"""
+ [perfetto.protos.chrome_slice_names]: {
+ chrome_version_code: 123
+ slice_name: "Looper.Dispatch: class1"
+ slice_name: "name2"
+ }
+ """))
+
+ # Chrome stack samples.
+ def test_chrome_stack_samples_for_task(self):
+ return DiffTestBlueprint(
+ trace=DataPath('chrome_stack_traces_symbolized_trace.pftrace'),
+ query="""
+ SELECT RUN_METRIC('chrome/chrome_stack_samples_for_task.sql',
+ 'target_duration_ms', '0.000001',
+ 'thread_name', '"CrBrowserMain"',
+ 'task_name', '"sendTouchEvent"');
+
+ SELECT
+ sample.description,
+ sample.ts,
+ sample.depth
+ FROM chrome_stack_samples_for_task sample
+ JOIN (
+ SELECT
+ ts,
+ dur
+ FROM slice
+ WHERE ts = 696373965001470
+ ) test_slice
+ ON sample.ts >= test_slice.ts
+ AND sample.ts <= test_slice.ts + test_slice.dur
+ ORDER BY sample.ts, sample.depth;
+ """,
+ out=Path('chrome_stack_samples_for_task_test.out'))
+
+ # Trace proto content
+ def test_proto_content(self):
+ return DiffTestBlueprint(
+ trace=DataPath('chrome_scroll_without_vsync.pftrace'),
+ query=Path('proto_content_test.sql'),
+ out=Path('proto_content.out'))
+
+ # TODO(mayzner): Uncomment when it works
+ # def test_proto_content_path(self):
+ # return DiffTestBlueprint(
+ # trace=DataPath('chrome_scroll_without_vsync.pftrace'),
+ # query=Path('proto_content_path_test.sql'),
+ # out=Csv("""
+ # "total_size","field_type","field_name","parent_id","event_category","event_name"
+ # 137426,"TracePacket","[NULL]","[NULL]","[NULL]","[NULL]"
+ # 59475,"TrackEvent","#track_event",415,"[NULL]","[NULL]"
+ # 37903,"TrackEvent","#track_event",17,"[NULL]","[NULL]"
+ # 35904,"int32","#trusted_uid",17,"[NULL]","[NULL]"
+ # 35705,"TracePacket","[NULL]","[NULL]","input,benchmark","LatencyInfo.Flow"
+ # 29403,"TracePacket","[NULL]","[NULL]","cc,input","[NULL]"
+ # 24703,"ChromeLatencyInfo","#chrome_latency_info",18,"[NULL]","[NULL]"
+ # 22620,"uint64","#time_us",26,"[NULL]","[NULL]"
+ # 18711,"TrackEvent","#track_event",1467,"[NULL]","[NULL]"
+ # 15606,"uint64","#timestamp",17,"[NULL]","[NULL]"
+ # """))
diff --git a/test/trace_processor/diff_tests/chrome/tests_args.py b/test/trace_processor/diff_tests/metrics/chrome/tests_args.py
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/tests_args.py
rename to test/trace_processor/diff_tests/metrics/chrome/tests_args.py
diff --git a/test/trace_processor/diff_tests/chrome/tests_processes.py b/test/trace_processor/diff_tests/metrics/chrome/tests_processes.py
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/tests_processes.py
rename to test/trace_processor/diff_tests/metrics/chrome/tests_processes.py
diff --git a/test/trace_processor/diff_tests/chrome/tests_rail_modes.py b/test/trace_processor/diff_tests/metrics/chrome/tests_rail_modes.py
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/tests_rail_modes.py
rename to test/trace_processor/diff_tests/metrics/chrome/tests_rail_modes.py
diff --git a/test/trace_processor/diff_tests/chrome/tests_scroll_jank.py b/test/trace_processor/diff_tests/metrics/chrome/tests_scroll_jank.py
similarity index 81%
rename from test/trace_processor/diff_tests/chrome/tests_scroll_jank.py
rename to test/trace_processor/diff_tests/metrics/chrome/tests_scroll_jank.py
index ef8ec6a..c2336ce 100644
--- a/test/trace_processor/diff_tests/chrome/tests_scroll_jank.py
+++ b/test/trace_processor/diff_tests/metrics/chrome/tests_scroll_jank.py
@@ -19,7 +19,7 @@
from python.generators.diff_tests.testing import TestSuite
-class ChromeScrollJank(TestSuite):
+class ChromeScrollJankMetrics(TestSuite):
# Scroll jank metrics
def test_scroll_jank_general_validation(self):
return DiffTestBlueprint(
@@ -44,33 +44,6 @@
""",
out=Path('scroll_jank.out'))
- def test_chrome_frames_with_missed_vsyncs(self):
- return DiffTestBlueprint(
- trace=DataPath('chrome_input_with_frame_view.pftrace'),
- query="""
- INCLUDE PERFETTO MODULE chrome.scroll_jank.scroll_jank_v3;
-
- SELECT
- cause_of_jank,
- sub_cause_of_jank,
- delay_since_last_frame,
- vsync_interval
- FROM chrome_janky_frames;
- """,
- out=Path('scroll_jank_v3.out'))
-
- def test_chrome_frames_with_missed_vsyncs_percentage(self):
- return DiffTestBlueprint(
- trace=DataPath('chrome_input_with_frame_view.pftrace'),
- query="""
- INCLUDE PERFETTO MODULE chrome.scroll_jank.scroll_jank_v3;
-
- SELECT
- delayed_frame_percentage
- FROM chrome_janky_frames_percentage;
- """,
- out=Path('scroll_jank_v3_percentage.out'))
-
def test_scroll_flow_event(self):
return DiffTestBlueprint(
trace=DataPath('chrome_scroll_without_vsync.pftrace'),
@@ -355,7 +328,7 @@
def test_chrome_thread_slice_repeated(self):
return DiffTestBlueprint(
- trace=Path('../track_event/track_event_counters.textproto'),
+ trace=Path('../../parser/track_event/track_event_counters.textproto'),
query="""
SELECT RUN_METRIC('chrome/chrome_thread_slice.sql');
@@ -450,49 +423,6 @@
115000000,0
"""))
- def test_chrome_scrolls(self):
- return DiffTestBlueprint(
- trace=Path('chrome_scroll_check.py'),
- query="""
- INCLUDE PERFETTO MODULE chrome.chrome_scrolls;
-
- SELECT
- id,
- ts,
- dur,
- gesture_scroll_begin_ts,
- gesture_scroll_end_ts
- FROM chrome_scrolls
- ORDER by id;
- """,
- out=Csv("""
- "id","ts","dur","gesture_scroll_begin_ts","gesture_scroll_end_ts"
- 5678,0,55000000,0,45000000
- 5679,60000000,40000000,60000000,90000000
- 5680,80000000,30000000,80000000,100000000
- 5681,120000000,70000000,120000000,"[NULL]"
- """))
-
- def test_chrome_scroll_intervals(self):
- return DiffTestBlueprint(
- trace=Path('chrome_scroll_check.py'),
- query="""
- INCLUDE PERFETTO MODULE chrome.chrome_scrolls;
-
- SELECT
- id,
- ts,
- dur
- FROM chrome_scrolling_intervals
- ORDER by id;
- """,
- out=Csv("""
- "id","ts","dur"
- 1,0,55000000
- 2,60000000,50000000
- 3,120000000,70000000
- """))
-
def test_chrome_scroll_jank_v3(self):
return DiffTestBlueprint(
trace=DataPath('chrome_input_with_frame_view.pftrace'),
@@ -528,52 +458,4 @@
}
}
}
- """))
-
- def test_chrome_scroll_input_offsets(self):
- return DiffTestBlueprint(
- trace=DataPath('scroll_offsets.pftrace'),
- query="""
- SELECT IMPORT('chrome.scroll_jank.scroll_offsets');
-
- SELECT
- scroll_update_id,
- ts,
- delta_y,
- offset_y
- FROM chrome_scroll_input_offsets
- ORDER by ts
- LIMIT 5;
- """,
- out=Csv("""
- "scroll_update_id","ts","delta_y","offset_y"
- 1983,4687296612739,-36.999939,-36.999939
- 1983,4687307175845,-39.000092,-76.000031
- 1987,4687313206739,-35.999969,-112.000000
- 1987,4687323152462,-35.000000,-147.000000
- 1991,4687329240739,-28.999969,-175.999969
- """))
-
- def test_chrome_presented_scroll_offsets(self):
- return DiffTestBlueprint(
- trace=DataPath('scroll_offsets.pftrace'),
- query="""
- SELECT IMPORT('chrome.scroll_jank.scroll_offsets');
-
- SELECT
- scroll_update_id,
- ts,
- delta_y,
- offset_y
- FROM chrome_presented_scroll_offsets
- ORDER by ts
- LIMIT 5;
- """,
- out=Csv("""
- "scroll_update_id","ts","delta_y","offset_y"
- 1983,4687296612739,"[NULL]",0
- 1987,4687313206739,-50,-50
- 1991,4687329240739,-50,-100
- 1993,4687336155739,-81,-181
- 1996,4687346164739,-66,-247
- """))
+ """))
\ No newline at end of file
diff --git a/test/trace_processor/diff_tests/chrome/tests_touch_gesture.py b/test/trace_processor/diff_tests/metrics/chrome/tests_touch_gesture.py
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/tests_touch_gesture.py
rename to test/trace_processor/diff_tests/metrics/chrome/tests_touch_gesture.py
diff --git a/test/trace_processor/diff_tests/chrome/touch_flow_event.out b/test/trace_processor/diff_tests/metrics/chrome/touch_flow_event.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/touch_flow_event.out
rename to test/trace_processor/diff_tests/metrics/chrome/touch_flow_event.out
diff --git a/test/trace_processor/diff_tests/chrome/touch_flow_event_queuing_delay.out b/test/trace_processor/diff_tests/metrics/chrome/touch_flow_event_queuing_delay.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/touch_flow_event_queuing_delay.out
rename to test/trace_processor/diff_tests/metrics/chrome/touch_flow_event_queuing_delay.out
diff --git a/test/trace_processor/diff_tests/chrome/touch_flow_event_queuing_delay_synth.out b/test/trace_processor/diff_tests/metrics/chrome/touch_flow_event_queuing_delay_synth.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/touch_flow_event_queuing_delay_synth.out
rename to test/trace_processor/diff_tests/metrics/chrome/touch_flow_event_queuing_delay_synth.out
diff --git a/test/trace_processor/diff_tests/chrome/touch_flow_event_synth.out b/test/trace_processor/diff_tests/metrics/chrome/touch_flow_event_synth.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/touch_flow_event_synth.out
rename to test/trace_processor/diff_tests/metrics/chrome/touch_flow_event_synth.out
diff --git a/test/trace_processor/diff_tests/chrome/touch_jank.out b/test/trace_processor/diff_tests/metrics/chrome/touch_jank.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/touch_jank.out
rename to test/trace_processor/diff_tests/metrics/chrome/touch_jank.out
diff --git a/test/trace_processor/diff_tests/chrome/touch_jank.py b/test/trace_processor/diff_tests/metrics/chrome/touch_jank.py
similarity index 99%
rename from test/trace_processor/diff_tests/chrome/touch_jank.py
rename to test/trace_processor/diff_tests/metrics/chrome/touch_jank.py
index 0dd0e8d..8262bc7 100644
--- a/test/trace_processor/diff_tests/chrome/touch_jank.py
+++ b/test/trace_processor/diff_tests/metrics/chrome/touch_jank.py
@@ -22,6 +22,7 @@
import synth_common
from synth_common import ms_to_ns
+
trace = synth_common.create_trace()
process_track1 = 1234
diff --git a/test/trace_processor/diff_tests/chrome/unsymbolized_args.textproto b/test/trace_processor/diff_tests/metrics/chrome/unsymbolized_args.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/unsymbolized_args.textproto
rename to test/trace_processor/diff_tests/metrics/chrome/unsymbolized_args.textproto
diff --git a/test/trace_processor/diff_tests/codecs/codec-framedecoder-trace.out b/test/trace_processor/diff_tests/metrics/codecs/codec-framedecoder-trace.out
similarity index 100%
rename from test/trace_processor/diff_tests/codecs/codec-framedecoder-trace.out
rename to test/trace_processor/diff_tests/metrics/codecs/codec-framedecoder-trace.out
diff --git a/test/trace_processor/diff_tests/codecs/tests.py b/test/trace_processor/diff_tests/metrics/codecs/tests.py
similarity index 100%
rename from test/trace_processor/diff_tests/codecs/tests.py
rename to test/trace_processor/diff_tests/metrics/codecs/tests.py
diff --git a/test/trace_processor/diff_tests/performance/frame_timeline_metric.out b/test/trace_processor/diff_tests/metrics/frame_timeline/frame_timeline_metric.out
similarity index 100%
rename from test/trace_processor/diff_tests/performance/frame_timeline_metric.out
rename to test/trace_processor/diff_tests/metrics/frame_timeline/frame_timeline_metric.out
diff --git a/test/trace_processor/diff_tests/performance/frame_timeline_metric.py b/test/trace_processor/diff_tests/metrics/frame_timeline/frame_timeline_metric.py
similarity index 99%
rename from test/trace_processor/diff_tests/performance/frame_timeline_metric.py
rename to test/trace_processor/diff_tests/metrics/frame_timeline/frame_timeline_metric.py
index 05cfee3..c7c1885 100755
--- a/test/trace_processor/diff_tests/performance/frame_timeline_metric.py
+++ b/test/trace_processor/diff_tests/metrics/frame_timeline/frame_timeline_metric.py
@@ -181,7 +181,6 @@
prediction_type=PredictionType.PREDICTION_VALID)
trace.add_frame_end_event(ts=14000000, cookie=25)
-
trace.add_actual_surface_frame_start_event(
ts=14500000,
cookie=30,
@@ -196,7 +195,6 @@
prediction_type=PredictionType.PREDICTION_VALID)
trace.add_frame_end_event(ts=15000000, cookie=30)
-
trace.add_actual_surface_frame_start_event(
ts=15500000,
cookie=35,
@@ -211,7 +209,6 @@
prediction_type=PredictionType.PREDICTION_VALID)
trace.add_frame_end_event(ts=16000000, cookie=35)
-
trace.add_actual_surface_frame_start_event(
ts=16500000,
cookie=40,
diff --git a/test/trace_processor/diff_tests/metrics/frame_timeline/tests.py b/test/trace_processor/diff_tests/metrics/frame_timeline/tests.py
new file mode 100644
index 0000000..24ef27a
--- /dev/null
+++ b/test/trace_processor/diff_tests/metrics/frame_timeline/tests.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python3
+# 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 a
+#
+# 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, Json, TextProto
+from python.generators.diff_tests.testing import DiffTestBlueprint
+from python.generators.diff_tests.testing import TestSuite
+
+
+class FrameTimeline(TestSuite):
+ # frame_timeline_metric collects App_Deadline_Missed metrics
+ def test_frame_timeline_metric(self):
+ return DiffTestBlueprint(
+ trace=Path('frame_timeline_metric.py'),
+ query=Metric('android_frame_timeline_metric'),
+ out=Path('frame_timeline_metric.out'))
diff --git a/test/trace_processor/diff_tests/graphics/android_jank_cuj.out b/test/trace_processor/diff_tests/metrics/graphics/android_jank_cuj.out
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/android_jank_cuj.out
rename to test/trace_processor/diff_tests/metrics/graphics/android_jank_cuj.out
diff --git a/test/trace_processor/diff_tests/graphics/android_jank_cuj.py b/test/trace_processor/diff_tests/metrics/graphics/android_jank_cuj.py
similarity index 92%
rename from test/trace_processor/diff_tests/graphics/android_jank_cuj.py
rename to test/trace_processor/diff_tests/metrics/graphics/android_jank_cuj.py
index beb39f7..4909eba 100644
--- a/test/trace_processor/diff_tests/graphics/android_jank_cuj.py
+++ b/test/trace_processor/diff_tests/metrics/graphics/android_jank_cuj.py
@@ -36,6 +36,7 @@
SHADE_CUJ_TRACK = 654
CANCELED_CUJ_TRACK = 987
+
def add_instant_for_track(trace, ts, track, name):
trace.add_track_event_slice(ts=ts, dur=0, track=track, name=name)
@@ -98,9 +99,9 @@
add_main_thread_atrace(trace, ts_do_frame, ts_end_do_frame,
"Choreographer#doFrame %d" % vsync)
if resync:
- add_main_thread_atrace(trace, ts_do_frame, ts_end_do_frame,
- "Choreographer#doFrame - resynced to %d in 0.0s"
- % (vsync+1))
+ add_main_thread_atrace(
+ trace, ts_do_frame, ts_end_do_frame,
+ "Choreographer#doFrame - resynced to %d in 0.0s" % (vsync + 1))
gpu_idx = 1000 + vsync * 10 + 1
if ts_gpu is None:
gpu_fence_message = "GPU completion fence %d has signaled"
@@ -117,13 +118,13 @@
def add_sf_frame(trace,
- vsync,
- ts_commit,
- ts_end_commit,
- ts_composite,
- ts_end_composite,
- ts_compose_surfaces=None,
- ts_end_compose_surfaces=None):
+ vsync,
+ ts_commit,
+ ts_end_commit,
+ ts_composite,
+ ts_end_composite,
+ ts_compose_surfaces=None,
+ ts_end_compose_surfaces=None):
add_sf_main_thread_atrace(trace, ts_commit, ts_end_commit,
"commit %d" % vsync)
add_sf_main_thread_atrace_begin(trace, ts_composite, "composite %d" % vsync)
@@ -168,13 +169,13 @@
def add_actual_surface_frame_events(ts,
- dur,
- token,
- cookie=None,
- jank=None,
- on_time_finish_override=None,
- display_frame_token_override=None,
- layer_name=LAYER):
+ dur,
+ token,
+ cookie=None,
+ jank=None,
+ on_time_finish_override=None,
+ display_frame_token_override=None,
+ layer_name=LAYER):
if cookie is None:
cookie = token + 1
jank_type = jank if jank is not None else 1
@@ -220,11 +221,11 @@
trace.add_track_descriptor(FIRST_CUJ_TRACK, parent=PROCESS_TRACK)
trace.add_track_descriptor(SHADE_CUJ_TRACK, parent=PROCESS_TRACK)
trace.add_track_descriptor(CANCELED_CUJ_TRACK, parent=PROCESS_TRACK)
-trace.add_track_event_slice_begin(ts=5, track=FIRST_CUJ_TRACK,
- name="J<FIRST_CUJ>")
+trace.add_track_event_slice_begin(
+ ts=5, track=FIRST_CUJ_TRACK, name="J<FIRST_CUJ>")
trace.add_track_event_slice_end(ts=100_000_000, track=FIRST_CUJ_TRACK)
-trace.add_track_event_slice_begin(ts=10, track=SHADE_CUJ_TRACK,
- name="J<SHADE_ROW_EXPAND>")
+trace.add_track_event_slice_begin(
+ ts=10, track=SHADE_CUJ_TRACK, name="J<SHADE_ROW_EXPAND>")
trace.add_track_event_slice_end(ts=901_000_010, track=SHADE_CUJ_TRACK)
add_instant_for_track(trace, ts=11, track=SHADE_CUJ_TRACK, name="FT#layerId#0")
add_instant_for_track(
@@ -244,29 +245,13 @@
trace.add_ftrace_packet(cpu=0)
trace.add_atrace_counter(
- ts=150_000_000,
- tid=PID,
- pid=PID,
- buf="J<FIRST_CUJ>#totalFrames",
- cnt=6)
+ ts=150_000_000, tid=PID, pid=PID, buf="J<FIRST_CUJ>#totalFrames", cnt=6)
trace.add_atrace_counter(
- ts=150_100_000,
- tid=PID,
- pid=PID,
- buf="J<FIRST_CUJ>#missedFrames",
- cnt=5)
+ ts=150_100_000, tid=PID, pid=PID, buf="J<FIRST_CUJ>#missedFrames", cnt=5)
trace.add_atrace_counter(
- ts=150_200_000,
- tid=PID,
- pid=PID,
- buf="J<FIRST_CUJ>#missedAppFrames",
- cnt=5)
+ ts=150_200_000, tid=PID, pid=PID, buf="J<FIRST_CUJ>#missedAppFrames", cnt=5)
trace.add_atrace_counter(
- ts=150_300_000,
- tid=PID,
- pid=PID,
- buf="J<FIRST_CUJ>#missedSfFrames",
- cnt=1)
+ ts=150_300_000, tid=PID, pid=PID, buf="J<FIRST_CUJ>#missedSfFrames", cnt=1)
trace.add_atrace_counter(
ts=150_400_000,
tid=PID,
@@ -644,8 +629,8 @@
ts_gpu=1_400_000_000,
ts_end_gpu=1_500_000_000)
-add_instant_for_track(trace, ts=990_000_000, track=CANCELED_CUJ_TRACK,
- name="FT#cancel#0")
+add_instant_for_track(
+ trace, ts=990_000_000, track=CANCELED_CUJ_TRACK, name="FT#cancel#0")
add_expected_display_frame_events(ts=1_000_000_000, dur=16_000_000, token=10)
add_actual_display_frame_events(ts=1_000_000_000, dur=16_000_000, token=10)
@@ -704,11 +689,15 @@
ts=200_000_000, dur=22_000_000, token=100, jank=34)
add_expected_surface_frame_events(ts=300_000_000, dur=20_000_000, token=110)
-add_actual_surface_frame_events(ts=300_000_000, cookie=112, dur=61_000_000,
- token=110)
-add_actual_surface_frame_events(ts=300_000_000, cookie=114, dur=80_000_000,
- token=110, jank=64,
- layer_name="TX - JankyLayer#1")
+add_actual_surface_frame_events(
+ ts=300_000_000, cookie=112, dur=61_000_000, token=110)
+add_actual_surface_frame_events(
+ ts=300_000_000,
+ cookie=114,
+ dur=80_000_000,
+ token=110,
+ jank=64,
+ layer_name="TX - JankyLayer#1")
add_expected_surface_frame_events(ts=400_000_000, dur=20_000_000, token=120)
add_actual_surface_frame_events(
@@ -732,10 +721,7 @@
# Surface flinger stuffing frame not classified as missed
add_expected_surface_frame_events(ts=650_000_000, dur=20_000_000, token=145)
add_actual_surface_frame_events(
- ts=650_000_000,
- dur=20_000_000,
- token=145,
- jank=512)
+ ts=650_000_000, dur=20_000_000, token=145, jank=512)
add_expected_surface_frame_events(ts=700_000_000, dur=20_000_000, token=150)
add_actual_surface_frame_events(ts=700_500_000, dur=14_500_000, token=150)
diff --git a/test/trace_processor/diff_tests/graphics/android_jank_cuj_query.out b/test/trace_processor/diff_tests/metrics/graphics/android_jank_cuj_query.out
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/android_jank_cuj_query.out
rename to test/trace_processor/diff_tests/metrics/graphics/android_jank_cuj_query.out
diff --git a/test/trace_processor/diff_tests/graphics/android_jank_cuj_query_test.sql b/test/trace_processor/diff_tests/metrics/graphics/android_jank_cuj_query_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/android_jank_cuj_query_test.sql
rename to test/trace_processor/diff_tests/metrics/graphics/android_jank_cuj_query_test.sql
diff --git a/test/trace_processor/diff_tests/graphics/composer_execution.py b/test/trace_processor/diff_tests/metrics/graphics/composer_execution.py
similarity index 94%
rename from test/trace_processor/diff_tests/graphics/composer_execution.py
rename to test/trace_processor/diff_tests/metrics/graphics/composer_execution.py
index b93044d..35e1184 100644
--- a/test/trace_processor/diff_tests/graphics/composer_execution.py
+++ b/test/trace_processor/diff_tests/metrics/graphics/composer_execution.py
@@ -48,10 +48,12 @@
# separated validation where HwcValidateDisplay is executed from worker thread
trace.add_atrace_begin(ts=2_100, tid=10335, pid=10335, buf="composite 3")
trace.add_atrace_begin(ts=2_200, tid=15000, pid=10335, buf="otherFunction")
-trace.add_atrace_begin(ts=2_300, tid=15000, pid=10335, buf="HwcValidateDisplay 1")
+trace.add_atrace_begin(
+ ts=2_300, tid=15000, pid=10335, buf="HwcValidateDisplay 1")
trace.add_atrace_end(ts=2_400, tid=15000, pid=10335)
trace.add_atrace_end(ts=2_500, tid=15000, pid=10335)
-trace.add_atrace_begin(ts=2_600, tid=10335, pid=10335, buf="HwcPresentDisplay 1")
+trace.add_atrace_begin(
+ ts=2_600, tid=10335, pid=10335, buf="HwcPresentDisplay 1")
trace.add_atrace_end(ts=2_700, tid=10335, pid=10335)
trace.add_atrace_end(ts=2_800, tid=10335, pid=10335)
@@ -73,4 +75,4 @@
ts=4_200, tid=10335, pid=10335, buf="HwcValidateDisplay 1")
trace.add_atrace_end(ts=4_300, tid=10335, pid=10335)
-sys.stdout.buffer.write(trace.trace.SerializeToString())
\ No newline at end of file
+sys.stdout.buffer.write(trace.trace.SerializeToString())
diff --git a/test/trace_processor/diff_tests/metrics/graphics/composition_layer.py b/test/trace_processor/diff_tests/metrics/graphics/composition_layer.py
new file mode 100644
index 0000000..7788c06
--- /dev/null
+++ b/test/trace_processor/diff_tests/metrics/graphics/composition_layer.py
@@ -0,0 +1,61 @@
+#!/usr/bin/env python3
+# Copyright (C) 2021 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.
+
+# This synthetic trace tests handling of the mm_id field in the rss_stat
+# event when mm_structs are reused on process death.
+
+from os import sys, path
+
+import synth_common
+
+trace = synth_common.create_trace()
+
+trace.add_packet(ts=1)
+trace.add_process(10, 1, "parent_process")
+trace.add_process(11, 10, "child_process")
+
+trace.add_ftrace_packet(1)
+
+trace.add_print(
+ ts=99, tid=11, buf='C|10|HWComposer: Total Layer for PrimaryDisplay(0)|7')
+trace.add_print(
+ ts=100, tid=11, buf='C|10|HWComposer: Total Layer for PrimaryDisplay(0)|5')
+trace.add_print(
+ ts=101, tid=11, buf='C|10|HWComposer: Total Layer for PrimaryDisplay(0)|6')
+trace.add_print(
+ ts=102, tid=11, buf='C|10|HWComposer: Total Layer for PrimaryDisplay(0)|0')
+trace.add_print(
+ ts=103, tid=11, buf='C|10|HWComposer: Total Layer for PrimaryDisplay(0)|4')
+trace.add_print(
+ ts=104, tid=11, buf='C|10|HWComposer: Total Layer for PrimaryDisplay(0)|6')
+trace.add_print(
+ ts=105, tid=11, buf='C|10|HWComposer: Total Layer for PrimaryDisplay(0)|0')
+trace.add_print(
+ ts=106, tid=11, buf='C|10|HWComposer: Total Layer for PrimaryDisplay(0)|4')
+trace.add_print(
+ ts=107, tid=11, buf='C|10|HWComposer: Total Layer for PrimaryDisplay(0)|5')
+trace.add_print(
+ ts=108, tid=11, buf='C|10|HWComposer: Total Layer for PrimaryDisplay(0)|0')
+trace.add_print(
+ ts=108, tid=11, buf='C|10|HWComposer: Total Layer for PrimaryDisplay(0)|3')
+trace.add_print(
+ ts=108, tid=11, buf='C|10|HWComposer: Total Layer for PrimaryDisplay(0)|0')
+
+trace.add_print(
+ ts=109,
+ tid=11,
+ buf='C|10|HWComposer: Total Layer for SecondaryDisplay(1)|5')
+
+sys.stdout.buffer.write(trace.trace.SerializeToString())
diff --git a/test/trace_processor/diff_tests/graphics/display_metrics.py b/test/trace_processor/diff_tests/metrics/graphics/display_metrics.py
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/display_metrics.py
rename to test/trace_processor/diff_tests/metrics/graphics/display_metrics.py
diff --git a/test/trace_processor/diff_tests/graphics/dpu_vote_clock_bw.textproto b/test/trace_processor/diff_tests/metrics/graphics/dpu_vote_clock_bw.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/dpu_vote_clock_bw.textproto
rename to test/trace_processor/diff_tests/metrics/graphics/dpu_vote_clock_bw.textproto
diff --git a/test/trace_processor/diff_tests/graphics/frame_missed.py b/test/trace_processor/diff_tests/metrics/graphics/frame_missed.py
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/frame_missed.py
rename to test/trace_processor/diff_tests/metrics/graphics/frame_missed.py
diff --git a/test/trace_processor/diff_tests/graphics/g2d_metrics.out b/test/trace_processor/diff_tests/metrics/graphics/g2d_metrics.out
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/g2d_metrics.out
rename to test/trace_processor/diff_tests/metrics/graphics/g2d_metrics.out
diff --git a/test/trace_processor/diff_tests/graphics/g2d_metrics.textproto b/test/trace_processor/diff_tests/metrics/graphics/g2d_metrics.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/g2d_metrics.textproto
rename to test/trace_processor/diff_tests/metrics/graphics/g2d_metrics.textproto
diff --git a/test/trace_processor/diff_tests/graphics/gpu_frequency_metric.out b/test/trace_processor/diff_tests/metrics/graphics/gpu_frequency_metric.out
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/gpu_frequency_metric.out
rename to test/trace_processor/diff_tests/metrics/graphics/gpu_frequency_metric.out
diff --git a/test/trace_processor/diff_tests/graphics/gpu_frequency_metric.textproto b/test/trace_processor/diff_tests/metrics/graphics/gpu_frequency_metric.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/gpu_frequency_metric.textproto
rename to test/trace_processor/diff_tests/metrics/graphics/gpu_frequency_metric.textproto
diff --git a/test/trace_processor/diff_tests/graphics/gpu_metric.py b/test/trace_processor/diff_tests/metrics/graphics/gpu_metric.py
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/gpu_metric.py
rename to test/trace_processor/diff_tests/metrics/graphics/gpu_metric.py
diff --git a/test/trace_processor/diff_tests/graphics/surfaceflinger_gpu_invocation.py b/test/trace_processor/diff_tests/metrics/graphics/surfaceflinger_gpu_invocation.py
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/surfaceflinger_gpu_invocation.py
rename to test/trace_processor/diff_tests/metrics/graphics/surfaceflinger_gpu_invocation.py
diff --git a/test/trace_processor/diff_tests/metrics/graphics/tests.py b/test/trace_processor/diff_tests/metrics/graphics/tests.py
new file mode 100644
index 0000000..f5bb896
--- /dev/null
+++ b/test/trace_processor/diff_tests/metrics/graphics/tests.py
@@ -0,0 +1,237 @@
+#!/usr/bin/env python3
+# 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 a
+#
+# 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, Json, TextProto
+from python.generators.diff_tests.testing import DiffTestBlueprint
+from python.generators.diff_tests.testing import TestSuite
+
+
+class GraphicsMetrics(TestSuite):
+ # Android SurfaceFlinger metrics
+ def test_frame_missed_event_frame_missed(self):
+ return DiffTestBlueprint(
+ trace=Path('frame_missed.py'),
+ query="""
+ SELECT RUN_METRIC('android/android_surfaceflinger.sql');
+
+ SELECT ts, dur
+ FROM android_surfaceflinger_event;
+ """,
+ out=Csv("""
+ "ts","dur"
+ 100,1
+ 102,1
+ 103,1
+ """))
+
+ def test_frame_missed_metrics(self):
+ return DiffTestBlueprint(
+ trace=Path('frame_missed.py'),
+ query=Metric('android_surfaceflinger'),
+ out=TextProto(r"""
+ android_surfaceflinger {
+ missed_frames: 3
+ missed_hwc_frames: 0
+ missed_gpu_frames: 0
+ missed_frame_rate: 0.42857142857142855 # = 3/7
+ gpu_invocations: 0
+ metrics_per_display: {
+ display_id: "101"
+ missed_frames: 2
+ missed_hwc_frames: 0
+ missed_gpu_frames: 0
+ missed_frame_rate: 0.5
+ }
+ metrics_per_display: {
+ display_id: "102"
+ missed_frames: 1
+ missed_hwc_frames: 0
+ missed_gpu_frames: 0
+ missed_frame_rate: 0.33333333333333333
+ }
+ }
+ """))
+
+ def test_surfaceflinger_gpu_invocation(self):
+ return DiffTestBlueprint(
+ trace=Path('surfaceflinger_gpu_invocation.py'),
+ query=Metric('android_surfaceflinger'),
+ out=TextProto(r"""
+ android_surfaceflinger {
+ missed_frames: 0
+ missed_hwc_frames: 0
+ missed_gpu_frames: 0
+ gpu_invocations: 4
+ avg_gpu_waiting_dur_ms: 4
+ total_non_empty_gpu_waiting_dur_ms: 11
+ }
+ """))
+
+ # GPU metrics
+ def test_gpu_metric(self):
+ return DiffTestBlueprint(
+ trace=Path('gpu_metric.py'),
+ query=Metric('android_gpu'),
+ out=TextProto(r"""
+ android_gpu {
+ processes {
+ name: "app_1"
+ mem_max: 8
+ mem_min: 2
+ mem_avg: 3
+ }
+ processes {
+ name: "app_2"
+ mem_max: 10
+ mem_min: 6
+ mem_avg: 8
+ }
+ mem_max: 4
+ mem_min: 1
+ mem_avg: 2
+ }
+ """))
+
+ def test_gpu_frequency_metric(self):
+ return DiffTestBlueprint(
+ trace=Path('gpu_frequency_metric.textproto'),
+ query=Metric('android_gpu'),
+ out=Path('gpu_frequency_metric.out'))
+
+ # Android Jank CUJ metric
+ def test_android_jank_cuj(self):
+ return DiffTestBlueprint(
+ trace=Path('android_jank_cuj.py'),
+ query=Metric('android_jank_cuj'),
+ out=Path('android_jank_cuj.out'))
+
+ def test_android_jank_cuj_query(self):
+ return DiffTestBlueprint(
+ trace=Path('android_jank_cuj.py'),
+ query=Path('android_jank_cuj_query_test.sql'),
+ out=Path('android_jank_cuj_query.out'))
+
+ # Composition layer
+ def test_composition_layer_count(self):
+ return DiffTestBlueprint(
+ trace=Path('composition_layer.py'),
+ query="""
+ SELECT RUN_METRIC('android/android_hwcomposer.sql');
+
+ SELECT display_id, AVG(value)
+ FROM total_layers
+ GROUP BY display_id;
+ """,
+ out=Csv("""
+ "display_id","AVG(value)"
+ "0",3.000000
+ "1",5.000000
+ """))
+
+ # G2D metrics TODO(rsavitski): find a real trace and double-check that the
+ # is realistic. One kernel's source I checked had tgid=0 for all counter
+ # Initial support was added/discussed in b/171296908.
+ def test_g2d_metrics(self):
+ return DiffTestBlueprint(
+ trace=Path('g2d_metrics.textproto'),
+ query=Metric('g2d'),
+ out=Path('g2d_metrics.out'))
+
+ # Composer execution
+ def test_composer_execution(self):
+ return DiffTestBlueprint(
+ trace=Path('composer_execution.py'),
+ query="""
+ SELECT RUN_METRIC('android/composer_execution.sql',
+ 'output', 'hwc_execution_spans');
+
+ SELECT
+ validation_type,
+ display_id,
+ COUNT(*) AS count,
+ SUM(execution_time_ns) AS total
+ FROM hwc_execution_spans
+ GROUP BY validation_type, display_id
+ ORDER BY validation_type, display_id;
+ """,
+ out=Csv("""
+ "validation_type","display_id","count","total"
+ "separated_validation","1",1,200
+ "skipped_validation","0",2,200
+ "skipped_validation","1",1,100
+ "unknown","1",1,0
+ "unskipped_validation","0",1,200
+ """))
+
+ # Display metrics
+ def test_display_metrics(self):
+ return DiffTestBlueprint(
+ trace=Path('display_metrics.py'),
+ query=Metric('display_metrics'),
+ out=TextProto(r"""
+ display_metrics {
+ total_duplicate_frames: 0
+ duplicate_frames_logged: 0
+ total_dpu_underrun_count: 0
+ refresh_rate_switches: 5
+ refresh_rate_stats {
+ refresh_rate_fps: 60
+ count: 2
+ total_dur_ms: 2
+ avg_dur_ms: 1
+ }
+ refresh_rate_stats {
+ refresh_rate_fps: 90
+ count: 2
+ total_dur_ms: 2
+ avg_dur_ms: 1
+ }
+ refresh_rate_stats {
+ refresh_rate_fps: 120
+ count: 1
+ total_dur_ms: 2
+ avg_dur_ms: 2
+ }
+ update_power_state {
+ avg_runtime_micro_secs: 4000
+ }
+ }
+ """))
+
+ # DPU vote clock and bandwidth
+ def test_dpu_vote_clock_bw(self):
+ return DiffTestBlueprint(
+ trace=Path('dpu_vote_clock_bw.textproto'),
+ query=Metric('android_hwcomposer'),
+ out=TextProto(r"""
+ android_hwcomposer {
+ skipped_validation_count: 0
+ unskipped_validation_count: 0
+ separated_validation_count: 0
+ unknown_validation_count: 0
+ dpu_vote_metrics {
+ tid: 237
+ avg_dpu_vote_clock: 206250
+ avg_dpu_vote_avg_bw: 210000
+ avg_dpu_vote_peak_bw: 205000
+ avg_dpu_vote_rt_bw: 271000
+ }
+ dpu_vote_metrics {
+ tid: 299
+ avg_dpu_vote_clock: 250000
+ }
+ }
+ """))
\ No newline at end of file
diff --git a/test/trace_processor/diff_tests/performance/irq_runtime_metric.out b/test/trace_processor/diff_tests/metrics/irq/irq_runtime_metric.out
similarity index 100%
rename from test/trace_processor/diff_tests/performance/irq_runtime_metric.out
rename to test/trace_processor/diff_tests/metrics/irq/irq_runtime_metric.out
diff --git a/test/trace_processor/diff_tests/performance/irq_runtime_metric.textproto b/test/trace_processor/diff_tests/metrics/irq/irq_runtime_metric.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/performance/irq_runtime_metric.textproto
rename to test/trace_processor/diff_tests/metrics/irq/irq_runtime_metric.textproto
diff --git a/test/trace_processor/diff_tests/metrics/irq/tests.py b/test/trace_processor/diff_tests/metrics/irq/tests.py
new file mode 100644
index 0000000..f7b11fd
--- /dev/null
+++ b/test/trace_processor/diff_tests/metrics/irq/tests.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python3
+# 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 a
+#
+# 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, Json, TextProto
+from python.generators.diff_tests.testing import DiffTestBlueprint
+from python.generators.diff_tests.testing import TestSuite
+
+
+class IRQ(TestSuite):
+ # IRQ max runtime and count over 1ms
+ def test_irq_runtime_metric(self):
+ return DiffTestBlueprint(
+ trace=Path('irq_runtime_metric.textproto'),
+ query=Metric('android_irq_runtime'),
+ out=Path('irq_runtime_metric.out'))
\ No newline at end of file
diff --git a/test/trace_processor/diff_tests/memory/android_ion.py b/test/trace_processor/diff_tests/metrics/memory/android_ion.py
similarity index 100%
rename from test/trace_processor/diff_tests/memory/android_ion.py
rename to test/trace_processor/diff_tests/metrics/memory/android_ion.py
diff --git a/test/trace_processor/diff_tests/memory/android_lmk_reason.out b/test/trace_processor/diff_tests/metrics/memory/android_lmk_reason.out
similarity index 100%
rename from test/trace_processor/diff_tests/memory/android_lmk_reason.out
rename to test/trace_processor/diff_tests/metrics/memory/android_lmk_reason.out
diff --git a/test/trace_processor/diff_tests/memory/android_mem_by_priority.out b/test/trace_processor/diff_tests/metrics/memory/android_mem_by_priority.out
similarity index 100%
rename from test/trace_processor/diff_tests/memory/android_mem_by_priority.out
rename to test/trace_processor/diff_tests/metrics/memory/android_mem_by_priority.out
diff --git a/test/trace_processor/diff_tests/memory/android_mem_by_priority.py b/test/trace_processor/diff_tests/metrics/memory/android_mem_by_priority.py
similarity index 100%
rename from test/trace_processor/diff_tests/memory/android_mem_by_priority.py
rename to test/trace_processor/diff_tests/metrics/memory/android_mem_by_priority.py
diff --git a/test/trace_processor/diff_tests/memory/android_mem_counters.out b/test/trace_processor/diff_tests/metrics/memory/android_mem_counters.out
similarity index 100%
rename from test/trace_processor/diff_tests/memory/android_mem_counters.out
rename to test/trace_processor/diff_tests/metrics/memory/android_mem_counters.out
diff --git a/test/trace_processor/diff_tests/memory/android_mem_delta.py b/test/trace_processor/diff_tests/metrics/memory/android_mem_delta.py
similarity index 100%
rename from test/trace_processor/diff_tests/memory/android_mem_delta.py
rename to test/trace_processor/diff_tests/metrics/memory/android_mem_delta.py
diff --git a/test/trace_processor/diff_tests/memory/android_systrace_lmk.py b/test/trace_processor/diff_tests/metrics/memory/android_systrace_lmk.py
similarity index 100%
rename from test/trace_processor/diff_tests/memory/android_systrace_lmk.py
rename to test/trace_processor/diff_tests/metrics/memory/android_systrace_lmk.py
diff --git a/test/trace_processor/diff_tests/memory/tests.py b/test/trace_processor/diff_tests/metrics/memory/tests.py
similarity index 78%
rename from test/trace_processor/diff_tests/memory/tests.py
rename to test/trace_processor/diff_tests/metrics/memory/tests.py
index aca4edf..7ea5fda 100644
--- a/test/trace_processor/diff_tests/memory/tests.py
+++ b/test/trace_processor/diff_tests/metrics/memory/tests.py
@@ -19,7 +19,7 @@
from python.generators.diff_tests.testing import TestSuite
-class Memory(TestSuite):
+class MemoryMetrics(TestSuite):
# Contains test for Android memory metrics. ION metric
def test_android_ion(self):
return DiffTestBlueprint(
@@ -132,48 +132,6 @@
}
"""))
- def test_android_dma_buffer_tracks(self):
- return DiffTestBlueprint(
- trace=TextProto(r"""
- packet {
- ftrace_events {
- cpu: 0
- event {
- timestamp: 100
- pid: 1
- dma_heap_stat {
- inode: 123
- len: 1024
- total_allocated: 2048
- }
- }
- }
- }
- packet {
- ftrace_events {
- cpu: 0
- event {
- timestamp: 200
- pid: 1
- dma_heap_stat {
- inode: 123
- len: -1024
- total_allocated: 1024
- }
- }
- }
- }
- """),
- query="""
- SELECT track.name, slice.ts, slice.dur, slice.name
- FROM slice JOIN track ON slice.track_id = track.id
- WHERE track.name = 'mem.dma_buffer';
- """,
- out=Csv("""
- "name","ts","dur","name"
- "mem.dma_buffer",100,100,"1 kB"
- """))
-
# fastrpc metric
def test_android_fastrpc_dma_stat(self):
return DiffTestBlueprint(
@@ -220,55 +178,94 @@
}
"""))
- # shrink slab
- def test_shrink_slab(self):
+ def test_android_mem_counters(self):
+ return DiffTestBlueprint(
+ trace=DataPath('memory_counters.pb'),
+ query=Metric('android_mem'),
+ out=Path('android_mem_counters.out'))
+
+ def test_trace_metadata(self):
+ return DiffTestBlueprint(
+ trace=DataPath('memory_counters.pb'),
+ query=Metric('trace_metadata'),
+ out=Path('trace_metadata.out'))
+
+ def test_android_mem_by_priority(self):
+ return DiffTestBlueprint(
+ trace=Path('android_mem_by_priority.py'),
+ query=Metric('android_mem'),
+ out=Path('android_mem_by_priority.out'))
+
+ def test_android_mem_lmk(self):
+ return DiffTestBlueprint(
+ trace=Path('android_systrace_lmk.py'),
+ query=Metric('android_lmk'),
+ out=TextProto(r"""
+ android_lmk {
+ total_count: 1
+ by_oom_score {
+ oom_score_adj: 900
+ count: 1
+ }
+ oom_victim_count: 0
+ }
+ """))
+
+ def test_android_lmk_oom(self):
return DiffTestBlueprint(
trace=TextProto(r"""
packet {
- ftrace_events {
- cpu: 7
- event {
- timestamp: 36448185787847
- pid: 156
- mm_shrink_slab_start {
- cache_items: 1
- delta: 0
- gfp_flags: 3264
- nr_objects_to_shrink: 0
- shr: 18446743882920355600
- shrink: 90
- total_scan: 0
- nid: 0
- priority: 12
- }
+ process_tree {
+ processes {
+ pid: 1000
+ ppid: 1
+ cmdline: "com.google.android.gm"
+ }
+ threads {
+ tid: 1001
+ tgid: 1000
}
}
}
packet {
ftrace_events {
- cpu: 7
+ cpu: 4
event {
- timestamp: 36448185788539
- pid: 156
- mm_shrink_slab_end {
- new_scan: 0
- retval: 0
- shr: 18446743882920355600
- shrink: 90
- total_scan: 0
- unused_scan: 0
- nid: 0
+ timestamp: 1234
+ pid: 4321
+ mark_victim {
+ pid: 1001
}
}
}
}
"""),
- query="""
- SELECT ts, dur, name FROM slice WHERE name = 'mm_vmscan_shrink_slab';
- """,
- out=Csv("""
- "ts","dur","name"
- 36448185787847,692,"mm_vmscan_shrink_slab"
+ query=Metric('android_lmk'),
+ out=TextProto(r"""
+ android_lmk {
+ total_count: 0
+ oom_victim_count: 1
+ }
+ """))
+
+ def test_android_mem_delta(self):
+ return DiffTestBlueprint(
+ trace=Path('android_mem_delta.py'),
+ query=Metric('android_mem'),
+ out=TextProto(r"""
+ android_mem {
+ process_metrics {
+ process_name: "com.my.pkg"
+ total_counters {
+ file_rss {
+ min: 2000.0
+ max: 10000.0
+ avg: 6666.666666666667
+ delta: 7000.0
+ }
+ }
+ }
+ }
"""))
# cma alloc
@@ -321,3 +318,45 @@
"ts","dur","name"
74288080958099,110151652,"mm_cma_alloc"
"""))
+
+ def test_android_dma_buffer_tracks(self):
+ return DiffTestBlueprint(
+ trace=TextProto(r"""
+ packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 100
+ pid: 1
+ dma_heap_stat {
+ inode: 123
+ len: 1024
+ total_allocated: 2048
+ }
+ }
+ }
+ }
+ packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 200
+ pid: 1
+ dma_heap_stat {
+ inode: 123
+ len: -1024
+ total_allocated: 1024
+ }
+ }
+ }
+ }
+ """),
+ query="""
+ SELECT track.name, slice.ts, slice.dur, slice.name
+ FROM slice JOIN track ON slice.track_id = track.id
+ WHERE track.name = 'mem.dma_buffer';
+ """,
+ out=Csv("""
+ "name","ts","dur","name"
+ "mem.dma_buffer",100,100,"1 kB"
+ """))
diff --git a/test/trace_processor/diff_tests/memory/trace_metadata.out b/test/trace_processor/diff_tests/metrics/memory/trace_metadata.out
similarity index 100%
rename from test/trace_processor/diff_tests/memory/trace_metadata.out
rename to test/trace_processor/diff_tests/metrics/memory/trace_metadata.out
diff --git a/test/trace_processor/diff_tests/network/netperf_metric.out b/test/trace_processor/diff_tests/metrics/network/netperf_metric.out
similarity index 100%
rename from test/trace_processor/diff_tests/network/netperf_metric.out
rename to test/trace_processor/diff_tests/metrics/network/netperf_metric.out
diff --git a/test/trace_processor/diff_tests/network/netperf_metric.textproto b/test/trace_processor/diff_tests/metrics/network/netperf_metric.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/network/netperf_metric.textproto
rename to test/trace_processor/diff_tests/metrics/network/netperf_metric.textproto
diff --git a/test/trace_processor/diff_tests/metrics/network/tests.py b/test/trace_processor/diff_tests/metrics/network/tests.py
new file mode 100644
index 0000000..d59879f
--- /dev/null
+++ b/test/trace_processor/diff_tests/metrics/network/tests.py
@@ -0,0 +1,27 @@
+#!/usr/bin/env python3
+# 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 a
+#
+# 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, Metric
+from python.generators.diff_tests.testing import DiffTestBlueprint
+from python.generators.diff_tests.testing import TestSuite
+
+
+class NetworkMetrics(TestSuite):
+
+ def test_netperf_metric(self):
+ return DiffTestBlueprint(
+ trace=Path('netperf_metric.textproto'),
+ query=Metric('android_netperf'),
+ out=Path('netperf_metric.out'))
diff --git a/test/trace_processor/diff_tests/power/cpu_counters_p_state_test.out b/test/trace_processor/diff_tests/metrics/power/cpu_counters_p_state_test.out
similarity index 100%
rename from test/trace_processor/diff_tests/power/cpu_counters_p_state_test.out
rename to test/trace_processor/diff_tests/metrics/power/cpu_counters_p_state_test.out
diff --git a/test/trace_processor/diff_tests/power/tests.py b/test/trace_processor/diff_tests/metrics/power/tests.py
similarity index 75%
rename from test/trace_processor/diff_tests/power/tests.py
rename to test/trace_processor/diff_tests/metrics/power/tests.py
index b776eda..a1b7cdd 100644
--- a/test/trace_processor/diff_tests/power/tests.py
+++ b/test/trace_processor/diff_tests/metrics/power/tests.py
@@ -29,19 +29,4 @@
SELECT * FROM P_STATE_OVER_INTERVAL(2579596465618, 2579606465618);
""",
- out=Path('cpu_counters_p_state_test.out'))
-
- # CPU power ups
- def test_cpu_powerups(self):
- return DiffTestBlueprint(
- trace=DataPath('cpu_powerups_1.pb'),
- query="""
- INCLUDE PERFETTO MODULE chrome.cpu_powerups;
- SELECT * FROM chrome_cpu_power_first_toplevel_slice_after_powerup;
- """,
- out=Csv("""
- "slice_id","previous_power_state"
- 424,2
- 703,2
- 708,2
- """))
+ out=Path('cpu_counters_p_state_test.out'))
\ No newline at end of file
diff --git a/test/trace_processor/diff_tests/profiling/heap_graph.textproto b/test/trace_processor/diff_tests/metrics/profiling/heap_graph.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/heap_graph.textproto
rename to test/trace_processor/diff_tests/metrics/profiling/heap_graph.textproto
diff --git a/test/trace_processor/diff_tests/profiling/heap_graph_closest_proc.textproto b/test/trace_processor/diff_tests/metrics/profiling/heap_graph_closest_proc.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/heap_graph_closest_proc.textproto
rename to test/trace_processor/diff_tests/metrics/profiling/heap_graph_closest_proc.textproto
diff --git a/test/trace_processor/diff_tests/profiling/heap_profile_no_symbols.textproto b/test/trace_processor/diff_tests/metrics/profiling/heap_profile_no_symbols.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/heap_profile_no_symbols.textproto
rename to test/trace_processor/diff_tests/metrics/profiling/heap_profile_no_symbols.textproto
diff --git a/test/trace_processor/diff_tests/profiling/heap_stats_closest_proc.out b/test/trace_processor/diff_tests/metrics/profiling/heap_stats_closest_proc.out
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/heap_stats_closest_proc.out
rename to test/trace_processor/diff_tests/metrics/profiling/heap_stats_closest_proc.out
diff --git a/test/trace_processor/diff_tests/profiling/java_heap_histogram.out b/test/trace_processor/diff_tests/metrics/profiling/java_heap_histogram.out
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/java_heap_histogram.out
rename to test/trace_processor/diff_tests/metrics/profiling/java_heap_histogram.out
diff --git a/test/trace_processor/diff_tests/profiling/simpleperf_event.out b/test/trace_processor/diff_tests/metrics/profiling/simpleperf_event.out
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/simpleperf_event.out
rename to test/trace_processor/diff_tests/metrics/profiling/simpleperf_event.out
diff --git a/test/trace_processor/diff_tests/profiling/simpleperf_event.py b/test/trace_processor/diff_tests/metrics/profiling/simpleperf_event.py
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/simpleperf_event.py
rename to test/trace_processor/diff_tests/metrics/profiling/simpleperf_event.py
diff --git a/test/trace_processor/diff_tests/profiling/tests_metrics.py b/test/trace_processor/diff_tests/metrics/profiling/tests.py
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/tests_metrics.py
rename to test/trace_processor/diff_tests/metrics/profiling/tests.py
diff --git a/test/trace_processor/diff_tests/startup/android_startup.out b/test/trace_processor/diff_tests/metrics/startup/android_startup.out
similarity index 100%
rename from test/trace_processor/diff_tests/startup/android_startup.out
rename to test/trace_processor/diff_tests/metrics/startup/android_startup.out
diff --git a/test/trace_processor/diff_tests/startup/android_startup.py b/test/trace_processor/diff_tests/metrics/startup/android_startup.py
similarity index 100%
rename from test/trace_processor/diff_tests/startup/android_startup.py
rename to test/trace_processor/diff_tests/metrics/startup/android_startup.py
diff --git a/test/trace_processor/diff_tests/startup/android_startup_attribution.out b/test/trace_processor/diff_tests/metrics/startup/android_startup_attribution.out
similarity index 100%
rename from test/trace_processor/diff_tests/startup/android_startup_attribution.out
rename to test/trace_processor/diff_tests/metrics/startup/android_startup_attribution.out
diff --git a/test/trace_processor/diff_tests/startup/android_startup_attribution.py b/test/trace_processor/diff_tests/metrics/startup/android_startup_attribution.py
similarity index 98%
rename from test/trace_processor/diff_tests/startup/android_startup_attribution.py
rename to test/trace_processor/diff_tests/metrics/startup/android_startup_attribution.py
index 59301e0..a48edcc 100644
--- a/test/trace_processor/diff_tests/startup/android_startup_attribution.py
+++ b/test/trace_processor/diff_tests/metrics/startup/android_startup_attribution.py
@@ -78,7 +78,7 @@
trace.add_atrace_begin(
ts=170, pid=APP_PID, tid=APP_TID, buf='OpenDexFilesFromOat(something else)')
-trace.add_atrace_end(ts=5*10**8, pid=APP_PID, tid=APP_TID)
+trace.add_atrace_end(ts=5 * 10**8, pid=APP_PID, tid=APP_TID)
# OpenDex slice outside the startup.
trace.add_atrace_begin(
diff --git a/test/trace_processor/diff_tests/startup/android_startup_attribution_slow.out b/test/trace_processor/diff_tests/metrics/startup/android_startup_attribution_slow.out
similarity index 100%
rename from test/trace_processor/diff_tests/startup/android_startup_attribution_slow.out
rename to test/trace_processor/diff_tests/metrics/startup/android_startup_attribution_slow.out
diff --git a/test/trace_processor/diff_tests/startup/android_startup_attribution_slow.py b/test/trace_processor/diff_tests/metrics/startup/android_startup_attribution_slow.py
similarity index 100%
rename from test/trace_processor/diff_tests/startup/android_startup_attribution_slow.py
rename to test/trace_processor/diff_tests/metrics/startup/android_startup_attribution_slow.py
diff --git a/test/trace_processor/diff_tests/startup/android_startup_battery.py b/test/trace_processor/diff_tests/metrics/startup/android_startup_battery.py
similarity index 100%
rename from test/trace_processor/diff_tests/startup/android_startup_battery.py
rename to test/trace_processor/diff_tests/metrics/startup/android_startup_battery.py
diff --git a/test/trace_processor/diff_tests/startup/android_startup_breakdown.out b/test/trace_processor/diff_tests/metrics/startup/android_startup_breakdown.out
similarity index 100%
rename from test/trace_processor/diff_tests/startup/android_startup_breakdown.out
rename to test/trace_processor/diff_tests/metrics/startup/android_startup_breakdown.out
diff --git a/test/trace_processor/diff_tests/startup/android_startup_breakdown.py b/test/trace_processor/diff_tests/metrics/startup/android_startup_breakdown.py
similarity index 100%
rename from test/trace_processor/diff_tests/startup/android_startup_breakdown.py
rename to test/trace_processor/diff_tests/metrics/startup/android_startup_breakdown.py
diff --git a/test/trace_processor/diff_tests/startup/android_startup_breakdown_slow.out b/test/trace_processor/diff_tests/metrics/startup/android_startup_breakdown_slow.out
similarity index 100%
rename from test/trace_processor/diff_tests/startup/android_startup_breakdown_slow.out
rename to test/trace_processor/diff_tests/metrics/startup/android_startup_breakdown_slow.out
diff --git a/test/trace_processor/diff_tests/startup/android_startup_breakdown_slow.py b/test/trace_processor/diff_tests/metrics/startup/android_startup_breakdown_slow.py
similarity index 97%
rename from test/trace_processor/diff_tests/startup/android_startup_breakdown_slow.py
rename to test/trace_processor/diff_tests/metrics/startup/android_startup_breakdown_slow.py
index f4ea962..b8f473f 100644
--- a/test/trace_processor/diff_tests/startup/android_startup_breakdown_slow.py
+++ b/test/trace_processor/diff_tests/metrics/startup/android_startup_breakdown_slow.py
@@ -29,7 +29,10 @@
trace.add_process(3, 1, 'com.google.android.calendar', uid=10001)
trace.add_package_list(
- ts=to_s(100), name='com.google.android.calendar', uid=10001, version_code=123)
+ ts=to_s(100),
+ name='com.google.android.calendar',
+ uid=10001,
+ version_code=123)
trace.add_ftrace_packet(cpu=0)
diff --git a/test/trace_processor/diff_tests/startup/android_startup_broadcast.out b/test/trace_processor/diff_tests/metrics/startup/android_startup_broadcast.out
similarity index 100%
rename from test/trace_processor/diff_tests/startup/android_startup_broadcast.out
rename to test/trace_processor/diff_tests/metrics/startup/android_startup_broadcast.out
diff --git a/test/trace_processor/diff_tests/startup/android_startup_broadcast.py b/test/trace_processor/diff_tests/metrics/startup/android_startup_broadcast.py
similarity index 100%
rename from test/trace_processor/diff_tests/startup/android_startup_broadcast.py
rename to test/trace_processor/diff_tests/metrics/startup/android_startup_broadcast.py
diff --git a/test/trace_processor/diff_tests/startup/android_startup_broadcast_multiple.out b/test/trace_processor/diff_tests/metrics/startup/android_startup_broadcast_multiple.out
similarity index 100%
rename from test/trace_processor/diff_tests/startup/android_startup_broadcast_multiple.out
rename to test/trace_processor/diff_tests/metrics/startup/android_startup_broadcast_multiple.out
diff --git a/test/trace_processor/diff_tests/startup/android_startup_broadcast_multiple.py b/test/trace_processor/diff_tests/metrics/startup/android_startup_broadcast_multiple.py
similarity index 100%
rename from test/trace_processor/diff_tests/startup/android_startup_broadcast_multiple.py
rename to test/trace_processor/diff_tests/metrics/startup/android_startup_broadcast_multiple.py
diff --git a/test/trace_processor/diff_tests/startup/android_startup_cpu.out b/test/trace_processor/diff_tests/metrics/startup/android_startup_cpu.out
similarity index 100%
rename from test/trace_processor/diff_tests/startup/android_startup_cpu.out
rename to test/trace_processor/diff_tests/metrics/startup/android_startup_cpu.out
diff --git a/test/trace_processor/diff_tests/startup/android_startup_cpu.py b/test/trace_processor/diff_tests/metrics/startup/android_startup_cpu.py
similarity index 100%
rename from test/trace_processor/diff_tests/startup/android_startup_cpu.py
rename to test/trace_processor/diff_tests/metrics/startup/android_startup_cpu.py
diff --git a/test/trace_processor/diff_tests/startup/android_startup_installd_dex2oat.out b/test/trace_processor/diff_tests/metrics/startup/android_startup_installd_dex2oat.out
similarity index 100%
rename from test/trace_processor/diff_tests/startup/android_startup_installd_dex2oat.out
rename to test/trace_processor/diff_tests/metrics/startup/android_startup_installd_dex2oat.out
diff --git a/test/trace_processor/diff_tests/startup/android_startup_installd_dex2oat.py b/test/trace_processor/diff_tests/metrics/startup/android_startup_installd_dex2oat.py
similarity index 100%
rename from test/trace_processor/diff_tests/startup/android_startup_installd_dex2oat.py
rename to test/trace_processor/diff_tests/metrics/startup/android_startup_installd_dex2oat.py
diff --git a/test/trace_processor/diff_tests/startup/android_startup_installd_dex2oat_slow.out b/test/trace_processor/diff_tests/metrics/startup/android_startup_installd_dex2oat_slow.out
similarity index 100%
rename from test/trace_processor/diff_tests/startup/android_startup_installd_dex2oat_slow.out
rename to test/trace_processor/diff_tests/metrics/startup/android_startup_installd_dex2oat_slow.out
diff --git a/test/trace_processor/diff_tests/startup/android_startup_installd_dex2oat_slow.py b/test/trace_processor/diff_tests/metrics/startup/android_startup_installd_dex2oat_slow.py
similarity index 100%
rename from test/trace_processor/diff_tests/startup/android_startup_installd_dex2oat_slow.py
rename to test/trace_processor/diff_tests/metrics/startup/android_startup_installd_dex2oat_slow.py
diff --git a/test/trace_processor/diff_tests/startup/android_startup_lock_contention.out b/test/trace_processor/diff_tests/metrics/startup/android_startup_lock_contention.out
similarity index 100%
rename from test/trace_processor/diff_tests/startup/android_startup_lock_contention.out
rename to test/trace_processor/diff_tests/metrics/startup/android_startup_lock_contention.out
diff --git a/test/trace_processor/diff_tests/startup/android_startup_lock_contention.py b/test/trace_processor/diff_tests/metrics/startup/android_startup_lock_contention.py
similarity index 100%
rename from test/trace_processor/diff_tests/startup/android_startup_lock_contention.py
rename to test/trace_processor/diff_tests/metrics/startup/android_startup_lock_contention.py
diff --git a/test/trace_processor/diff_tests/startup/android_startup_lock_contention_slow.out b/test/trace_processor/diff_tests/metrics/startup/android_startup_lock_contention_slow.out
similarity index 100%
rename from test/trace_processor/diff_tests/startup/android_startup_lock_contention_slow.out
rename to test/trace_processor/diff_tests/metrics/startup/android_startup_lock_contention_slow.out
diff --git a/test/trace_processor/diff_tests/startup/android_startup_lock_contention_slow.py b/test/trace_processor/diff_tests/metrics/startup/android_startup_lock_contention_slow.py
similarity index 100%
rename from test/trace_processor/diff_tests/startup/android_startup_lock_contention_slow.py
rename to test/trace_processor/diff_tests/metrics/startup/android_startup_lock_contention_slow.py
diff --git a/test/trace_processor/diff_tests/startup/android_startup_minsdk33.out b/test/trace_processor/diff_tests/metrics/startup/android_startup_minsdk33.out
similarity index 100%
rename from test/trace_processor/diff_tests/startup/android_startup_minsdk33.out
rename to test/trace_processor/diff_tests/metrics/startup/android_startup_minsdk33.out
diff --git a/test/trace_processor/diff_tests/startup/android_startup_minsdk33.py b/test/trace_processor/diff_tests/metrics/startup/android_startup_minsdk33.py
similarity index 100%
rename from test/trace_processor/diff_tests/startup/android_startup_minsdk33.py
rename to test/trace_processor/diff_tests/metrics/startup/android_startup_minsdk33.py
diff --git a/test/trace_processor/diff_tests/startup/android_startup_powrails.out b/test/trace_processor/diff_tests/metrics/startup/android_startup_powrails.out
similarity index 100%
rename from test/trace_processor/diff_tests/startup/android_startup_powrails.out
rename to test/trace_processor/diff_tests/metrics/startup/android_startup_powrails.out
diff --git a/test/trace_processor/diff_tests/startup/android_startup_powrails.py b/test/trace_processor/diff_tests/metrics/startup/android_startup_powrails.py
similarity index 100%
rename from test/trace_processor/diff_tests/startup/android_startup_powrails.py
rename to test/trace_processor/diff_tests/metrics/startup/android_startup_powrails.py
diff --git a/test/trace_processor/diff_tests/startup/android_startup_process_track.out b/test/trace_processor/diff_tests/metrics/startup/android_startup_process_track.out
similarity index 100%
rename from test/trace_processor/diff_tests/startup/android_startup_process_track.out
rename to test/trace_processor/diff_tests/metrics/startup/android_startup_process_track.out
diff --git a/test/trace_processor/diff_tests/startup/android_startup_process_track.py b/test/trace_processor/diff_tests/metrics/startup/android_startup_process_track.py
similarity index 100%
rename from test/trace_processor/diff_tests/startup/android_startup_process_track.py
rename to test/trace_processor/diff_tests/metrics/startup/android_startup_process_track.py
diff --git a/test/trace_processor/diff_tests/startup/android_startup_slow.out b/test/trace_processor/diff_tests/metrics/startup/android_startup_slow.out
similarity index 100%
rename from test/trace_processor/diff_tests/startup/android_startup_slow.out
rename to test/trace_processor/diff_tests/metrics/startup/android_startup_slow.out
diff --git a/test/trace_processor/diff_tests/startup/android_startup_slow.py b/test/trace_processor/diff_tests/metrics/startup/android_startup_slow.py
similarity index 100%
rename from test/trace_processor/diff_tests/startup/android_startup_slow.py
rename to test/trace_processor/diff_tests/metrics/startup/android_startup_slow.py
diff --git a/test/trace_processor/diff_tests/startup/android_startup_unlock.out b/test/trace_processor/diff_tests/metrics/startup/android_startup_unlock.out
similarity index 100%
rename from test/trace_processor/diff_tests/startup/android_startup_unlock.out
rename to test/trace_processor/diff_tests/metrics/startup/android_startup_unlock.out
diff --git a/test/trace_processor/diff_tests/startup/android_startup_unlock.py b/test/trace_processor/diff_tests/metrics/startup/android_startup_unlock.py
similarity index 100%
rename from test/trace_processor/diff_tests/startup/android_startup_unlock.py
rename to test/trace_processor/diff_tests/metrics/startup/android_startup_unlock.py
diff --git a/test/trace_processor/diff_tests/startup/tests.py b/test/trace_processor/diff_tests/metrics/startup/tests.py
similarity index 100%
rename from test/trace_processor/diff_tests/startup/tests.py
rename to test/trace_processor/diff_tests/metrics/startup/tests.py
diff --git a/test/trace_processor/diff_tests/startup/tests_broadcasts.py b/test/trace_processor/diff_tests/metrics/startup/tests_broadcasts.py
similarity index 100%
rename from test/trace_processor/diff_tests/startup/tests_broadcasts.py
rename to test/trace_processor/diff_tests/metrics/startup/tests_broadcasts.py
diff --git a/test/trace_processor/diff_tests/startup/tests_lock_contention.py b/test/trace_processor/diff_tests/metrics/startup/tests_lock_contention.py
similarity index 100%
rename from test/trace_processor/diff_tests/startup/tests_lock_contention.py
rename to test/trace_processor/diff_tests/metrics/startup/tests_lock_contention.py
diff --git a/test/trace_processor/diff_tests/startup/tests_metrics.py b/test/trace_processor/diff_tests/metrics/startup/tests_metrics.py
similarity index 100%
rename from test/trace_processor/diff_tests/startup/tests_metrics.py
rename to test/trace_processor/diff_tests/metrics/startup/tests_metrics.py
diff --git a/test/trace_processor/diff_tests/webview/tests.py b/test/trace_processor/diff_tests/metrics/webview/tests.py
similarity index 100%
rename from test/trace_processor/diff_tests/webview/tests.py
rename to test/trace_processor/diff_tests/metrics/webview/tests.py
diff --git a/test/trace_processor/diff_tests/android/android_bugreport_dumpstate_test.out b/test/trace_processor/diff_tests/parser/android/android_bugreport_dumpstate_test.out
similarity index 100%
rename from test/trace_processor/diff_tests/android/android_bugreport_dumpstate_test.out
rename to test/trace_processor/diff_tests/parser/android/android_bugreport_dumpstate_test.out
diff --git a/test/trace_processor/diff_tests/android/android_bugreport_dumpsys_test.out b/test/trace_processor/diff_tests/parser/android/android_bugreport_dumpsys_test.out
similarity index 100%
rename from test/trace_processor/diff_tests/android/android_bugreport_dumpsys_test.out
rename to test/trace_processor/diff_tests/parser/android/android_bugreport_dumpsys_test.out
diff --git a/test/trace_processor/diff_tests/android/android_bugreport_logs_test.out b/test/trace_processor/diff_tests/parser/android/android_bugreport_logs_test.out
similarity index 100%
rename from test/trace_processor/diff_tests/android/android_bugreport_logs_test.out
rename to test/trace_processor/diff_tests/parser/android/android_bugreport_logs_test.out
diff --git a/test/trace_processor/diff_tests/android/android_system_property_slice.out b/test/trace_processor/diff_tests/parser/android/android_system_property_slice.out
similarity index 100%
rename from test/trace_processor/diff_tests/android/android_system_property_slice.out
rename to test/trace_processor/diff_tests/parser/android/android_system_property_slice.out
diff --git a/test/trace_processor/diff_tests/android/game_intervention_list_test.out b/test/trace_processor/diff_tests/parser/android/game_intervention_list_test.out
similarity index 100%
rename from test/trace_processor/diff_tests/android/game_intervention_list_test.out
rename to test/trace_processor/diff_tests/parser/android/game_intervention_list_test.out
diff --git a/test/trace_processor/diff_tests/android/surfaceflinger_layers.textproto b/test/trace_processor/diff_tests/parser/android/surfaceflinger_layers.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/android/surfaceflinger_layers.textproto
rename to test/trace_processor/diff_tests/parser/android/surfaceflinger_layers.textproto
diff --git a/test/trace_processor/diff_tests/android/surfaceflinger_transactions.textproto b/test/trace_processor/diff_tests/parser/android/surfaceflinger_transactions.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/android/surfaceflinger_transactions.textproto
rename to test/trace_processor/diff_tests/parser/android/surfaceflinger_transactions.textproto
diff --git a/test/trace_processor/diff_tests/parser/android/tests.py b/test/trace_processor/diff_tests/parser/android/tests.py
new file mode 100644
index 0000000..9fca28e
--- /dev/null
+++ b/test/trace_processor/diff_tests/parser/android/tests.py
@@ -0,0 +1,205 @@
+#!/usr/bin/env python3
+# 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 a
+#
+# 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, Systrace
+from python.generators.diff_tests.testing import Csv, Json, TextProto, BinaryProto
+from python.generators.diff_tests.testing import DiffTestBlueprint
+from python.generators.diff_tests.testing import TestSuite
+from python.generators.diff_tests.testing import PrintProfileProto
+
+
+class AndroidParser(TestSuite):
+
+ def test_android_system_property_counter(self):
+ return DiffTestBlueprint(
+ trace=TextProto(r"""
+ packet {
+ timestamp: 1000
+ android_system_property {
+ values {
+ name: "debug.tracing.screen_state"
+ value: "2"
+ }
+ values {
+ name: "debug.tracing.device_state"
+ value: "some_state_from_sysprops"
+ }
+ }
+ }
+ packet {
+ ftrace_events {
+ cpu: 1
+ event {
+ timestamp: 2000
+ pid: 1
+ print {
+ buf: "C|1000|ScreenState|1\n"
+ }
+ }
+ event {
+ timestamp: 3000
+ pid: 1
+ print {
+ buf: "N|1000|DeviceStateChanged|some_state_from_atrace\n"
+ }
+ }
+ }
+ }
+ """),
+ query="""
+ SELECT t.type, t.name, c.id, c.ts, c.type, c.value
+ FROM counter_track t JOIN counter c ON t.id = c.track_id
+ WHERE name = 'ScreenState';
+ """,
+ out=Csv("""
+ "type","name","id","ts","type","value"
+ "counter_track","ScreenState",0,1000,"counter",2.000000
+ "counter_track","ScreenState",1,2000,"counter",1.000000
+ """))
+
+ def test_android_system_property_slice(self):
+ return DiffTestBlueprint(
+ trace=TextProto(r"""
+ packet {
+ timestamp: 1000
+ android_system_property {
+ values {
+ name: "debug.tracing.screen_state"
+ value: "2"
+ }
+ values {
+ name: "debug.tracing.device_state"
+ value: "some_state_from_sysprops"
+ }
+ }
+ }
+ packet {
+ ftrace_events {
+ cpu: 1
+ event {
+ timestamp: 2000
+ pid: 1
+ print {
+ buf: "C|1000|ScreenState|1\n"
+ }
+ }
+ event {
+ timestamp: 3000
+ pid: 1
+ print {
+ buf: "N|1000|DeviceStateChanged|some_state_from_atrace\n"
+ }
+ }
+ }
+ }
+ """),
+ query="""
+ SELECT t.type, t.name, s.id, s.ts, s.dur, s.type, s.name
+ FROM track t JOIN slice s ON s.track_id = t.id
+ WHERE t.name = 'DeviceStateChanged';
+ """,
+ out=Path('android_system_property_slice.out'))
+
+ def test_binder_txn_sync_good(self):
+ return DiffTestBlueprint(
+ trace=Systrace(
+ """ client-521390 [005] ..... 137012.464739: binder_command: cmd=0x40406300 BC_TRANSACTION
+ client-521390 [005] ..... 137012.464741: binder_transaction: transaction=5149 dest_node=5143 dest_proc=521383 dest_thread=0 reply=0 flags=0x0 code=0x3
+ server-521383 [004] ..... 137012.464771: binder_transaction_received: transaction=5149
+ server-521383 [004] ..... 137012.464772: binder_return: cmd=0x80407202 BR_TRANSACTION
+ server-521383 [004] ..... 137012.464815: binder_command: cmd=0x40086303 BC_FREE_BUFFER
+ server-521383 [004] ..... 137012.464823: binder_command: cmd=0x40406301 BC_REPLY
+ server-521383 [004] ..... 137012.464826: binder_transaction: transaction=5150 dest_node=0 dest_proc=521390 dest_thread=521390 reply=1 flags=0x20 code=0x3
+ server-521383 [004] ..... 137012.464837: binder_return: cmd=0x7206 BR_TRANSACTION_COMPLETE
+ client-521390 [005] ..... 137012.464847: binder_return: cmd=0x7206 BR_TRANSACTION_COMPLETE
+ client-521390 [005] ..... 137012.464848: binder_transaction_received: transaction=5150
+ client-521390 [005] ..... 137012.464849: binder_return: cmd=0x80407203 BR_REPLY
+ """),
+ query="""
+ SELECT
+ dur
+ FROM slice
+ ORDER BY dur;
+ """,
+ out=Csv("""
+ "dur"
+ 55000
+ 107000
+ """))
+
+ def test_binder_txn_sync_bad_request(self):
+ return DiffTestBlueprint(
+ trace=Systrace(
+ """ client-521349 [005] ..... 137004.281009: binder_command: cmd=0x40406300 BC_TRANSACTION
+ client-521349 [005] ..... 137004.281010: binder_transaction: transaction=5135 dest_node=5129 dest_proc=521347 dest_thread=0 reply=0 flags=0x0 code=0x3
+ client-521349 [005] ..... 137004.281410: binder_return: cmd=0x7211 BR_FAILED_REPLY
+ """),
+ query="""
+ SELECT
+ dur
+ FROM slice
+ ORDER BY dur;
+ """,
+ out=Csv("""
+ "dur"
+ 400000
+ """))
+
+ def test_binder_txn_sync_bad_reply(self):
+ return DiffTestBlueprint(
+ trace=Systrace(
+ """ client-521332 [007] ..... 136996.112660: binder_command: cmd=0x40406300 BC_TRANSACTION
+ client-521332 [007] ..... 136996.112662: binder_transaction: transaction=5120 dest_node=5114 dest_proc=521330 dest_thread=0 reply=0 flags=0x0 code=0x3
+ server-521330 [000] ..... 136996.112714: binder_transaction_received: transaction=5120
+ server-521330 [000] ..... 136996.112715: binder_return: cmd=0x80407202 BR_TRANSACTION
+ server-521330 [000] ..... 136996.112752: binder_command: cmd=0x40086303 BC_FREE_BUFFER
+ server-521330 [000] ..... 136996.112758: binder_command: cmd=0x40406301 BC_REPLY
+ server-521330 [000] ..... 136996.112760: binder_transaction: transaction=5121 dest_node=0 dest_proc=521332 dest_thread=521332 reply=1 flags=0x20 code=0x3
+ server-521330 [000] ..... 136996.113163: binder_return: cmd=0x7206 BR_TRANSACTION_COMPLETE
+ client-521332 [007] ..... 136996.113201: binder_return: cmd=0x7206 BR_TRANSACTION_COMPLETE
+ client-521332 [007] ..... 136996.113201: binder_return: cmd=0x7211 BR_FAILED_REPLY
+ """),
+ query="""
+ SELECT
+ dur
+ FROM slice
+ ORDER BY dur;
+ """,
+ out=Csv("""
+ "dur"
+ 46000
+ 539000
+ """))
+
+ def test_binder_txn_oneway_good(self):
+ return DiffTestBlueprint(
+ trace=Systrace(
+ """ client-521406 [003] ..... 137020.679833: binder_command: cmd=0x40406300 BC_TRANSACTION
+ client-521406 [003] ..... 137020.679834: binder_transaction: transaction=5161 dest_node=5155 dest_proc=521404 dest_thread=0 reply=0 flags=0x1 code=0x3
+ client-521406 [003] ..... 137020.679843: binder_return: cmd=0x7206 BR_TRANSACTION_COMPLETE
+ server-521404 [006] ..... 137020.679890: binder_transaction_received: transaction=5161
+ server-521404 [006] ..... 137020.679890: binder_return: cmd=0x80407202 BR_TRANSACTION
+ """),
+ query="""
+ SELECT
+ dur
+ FROM slice
+ ORDER BY dur;
+ """,
+ out=Csv("""
+ "dur"
+ 0
+ 0
+ """))
diff --git a/test/trace_processor/diff_tests/android/tests_bugreport.py b/test/trace_processor/diff_tests/parser/android/tests_bugreport.py
similarity index 100%
rename from test/trace_processor/diff_tests/android/tests_bugreport.py
rename to test/trace_processor/diff_tests/parser/android/tests_bugreport.py
diff --git a/test/trace_processor/diff_tests/android/tests_games.py b/test/trace_processor/diff_tests/parser/android/tests_games.py
similarity index 100%
rename from test/trace_processor/diff_tests/android/tests_games.py
rename to test/trace_processor/diff_tests/parser/android/tests_games.py
diff --git a/test/trace_processor/diff_tests/android/tests_surfaceflinger_layers.py b/test/trace_processor/diff_tests/parser/android/tests_surfaceflinger_layers.py
similarity index 99%
rename from test/trace_processor/diff_tests/android/tests_surfaceflinger_layers.py
rename to test/trace_processor/diff_tests/parser/android/tests_surfaceflinger_layers.py
index 1ccf102..ac1fcab 100644
--- a/test/trace_processor/diff_tests/android/tests_surfaceflinger_layers.py
+++ b/test/trace_processor/diff_tests/parser/android/tests_surfaceflinger_layers.py
@@ -20,6 +20,7 @@
class SurfaceFlingerLayers(TestSuite):
+
def test_snapshot_table(self):
return DiffTestBlueprint(
trace=Path('surfaceflinger_layers.textproto'),
@@ -80,4 +81,3 @@
2,1,"surfaceflinger_layer"
3,1,"surfaceflinger_layer"
"""))
-
diff --git a/test/trace_processor/diff_tests/android/tests_surfaceflinger_transactions.py b/test/trace_processor/diff_tests/parser/android/tests_surfaceflinger_transactions.py
similarity index 99%
rename from test/trace_processor/diff_tests/android/tests_surfaceflinger_transactions.py
rename to test/trace_processor/diff_tests/parser/android/tests_surfaceflinger_transactions.py
index 1c13e67..cf83ce4 100644
--- a/test/trace_processor/diff_tests/android/tests_surfaceflinger_transactions.py
+++ b/test/trace_processor/diff_tests/parser/android/tests_surfaceflinger_transactions.py
@@ -20,6 +20,7 @@
class SurfaceFlingerTransactions(TestSuite):
+
def test_has_expected_transactions_rows(self):
return DiffTestBlueprint(
trace=Path('surfaceflinger_transactions.textproto'),
diff --git a/test/trace_processor/diff_tests/android_fs/tests.py b/test/trace_processor/diff_tests/parser/android_fs/tests.py
similarity index 100%
rename from test/trace_processor/diff_tests/android_fs/tests.py
rename to test/trace_processor/diff_tests/parser/android_fs/tests.py
diff --git a/test/trace_processor/diff_tests/atrace/android_b2b_async_begin.textproto b/test/trace_processor/diff_tests/parser/atrace/android_b2b_async_begin.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/atrace/android_b2b_async_begin.textproto
rename to test/trace_processor/diff_tests/parser/atrace/android_b2b_async_begin.textproto
diff --git a/test/trace_processor/diff_tests/atrace/async_track_atrace.py b/test/trace_processor/diff_tests/parser/atrace/async_track_atrace.py
similarity index 100%
rename from test/trace_processor/diff_tests/atrace/async_track_atrace.py
rename to test/trace_processor/diff_tests/parser/atrace/async_track_atrace.py
diff --git a/test/trace_processor/diff_tests/atrace/bad_print.systrace b/test/trace_processor/diff_tests/parser/atrace/bad_print.systrace
similarity index 100%
rename from test/trace_processor/diff_tests/atrace/bad_print.systrace
rename to test/trace_processor/diff_tests/parser/atrace/bad_print.systrace
diff --git a/test/trace_processor/diff_tests/atrace/bad_print.textproto b/test/trace_processor/diff_tests/parser/atrace/bad_print.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/atrace/bad_print.textproto
rename to test/trace_processor/diff_tests/parser/atrace/bad_print.textproto
diff --git a/test/trace_processor/diff_tests/atrace/instant_async_atrace.py b/test/trace_processor/diff_tests/parser/atrace/instant_async_atrace.py
similarity index 100%
rename from test/trace_processor/diff_tests/atrace/instant_async_atrace.py
rename to test/trace_processor/diff_tests/parser/atrace/instant_async_atrace.py
diff --git a/test/trace_processor/diff_tests/atrace/instant_atrace.py b/test/trace_processor/diff_tests/parser/atrace/instant_atrace.py
similarity index 100%
rename from test/trace_processor/diff_tests/atrace/instant_atrace.py
rename to test/trace_processor/diff_tests/parser/atrace/instant_atrace.py
diff --git a/test/trace_processor/diff_tests/atrace/process_track_slices_android_async_slice.out b/test/trace_processor/diff_tests/parser/atrace/process_track_slices_android_async_slice.out
similarity index 100%
rename from test/trace_processor/diff_tests/atrace/process_track_slices_android_async_slice.out
rename to test/trace_processor/diff_tests/parser/atrace/process_track_slices_android_async_slice.out
diff --git a/test/trace_processor/diff_tests/atrace/sys_write_and_atrace.py b/test/trace_processor/diff_tests/parser/atrace/sys_write_and_atrace.py
similarity index 100%
rename from test/trace_processor/diff_tests/atrace/sys_write_and_atrace.py
rename to test/trace_processor/diff_tests/parser/atrace/sys_write_and_atrace.py
diff --git a/test/trace_processor/diff_tests/atrace/tests.py b/test/trace_processor/diff_tests/parser/atrace/tests.py
similarity index 100%
rename from test/trace_processor/diff_tests/atrace/tests.py
rename to test/trace_processor/diff_tests/parser/atrace/tests.py
diff --git a/test/trace_processor/diff_tests/atrace/tests_error_handling.py b/test/trace_processor/diff_tests/parser/atrace/tests_error_handling.py
similarity index 100%
rename from test/trace_processor/diff_tests/atrace/tests_error_handling.py
rename to test/trace_processor/diff_tests/parser/atrace/tests_error_handling.py
diff --git a/test/trace_processor/diff_tests/chrome/chrome_log_message_args_test.sql b/test/trace_processor/diff_tests/parser/chrome/chrome_log_message_args_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/chrome_log_message_args_test.sql
rename to test/trace_processor/diff_tests/parser/chrome/chrome_log_message_args_test.sql
diff --git a/test/trace_processor/diff_tests/chrome/memory_snapshot_chrome_dump_events.out b/test/trace_processor/diff_tests/parser/chrome/memory_snapshot_chrome_dump_events.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/memory_snapshot_chrome_dump_events.out
rename to test/trace_processor/diff_tests/parser/chrome/memory_snapshot_chrome_dump_events.out
diff --git a/test/trace_processor/diff_tests/chrome/memory_snapshot_edges.out b/test/trace_processor/diff_tests/parser/chrome/memory_snapshot_edges.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/memory_snapshot_edges.out
rename to test/trace_processor/diff_tests/parser/chrome/memory_snapshot_edges.out
diff --git a/test/trace_processor/diff_tests/chrome/memory_snapshot_general_validation.out b/test/trace_processor/diff_tests/parser/chrome/memory_snapshot_general_validation.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/memory_snapshot_general_validation.out
rename to test/trace_processor/diff_tests/parser/chrome/memory_snapshot_general_validation.out
diff --git a/test/trace_processor/diff_tests/chrome/memory_snapshot_node_args.out b/test/trace_processor/diff_tests/parser/chrome/memory_snapshot_node_args.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/memory_snapshot_node_args.out
rename to test/trace_processor/diff_tests/parser/chrome/memory_snapshot_node_args.out
diff --git a/test/trace_processor/diff_tests/chrome/memory_snapshot_nodes.out b/test/trace_processor/diff_tests/parser/chrome/memory_snapshot_nodes.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/memory_snapshot_nodes.out
rename to test/trace_processor/diff_tests/parser/chrome/memory_snapshot_nodes.out
diff --git a/test/trace_processor/diff_tests/chrome/memory_snapshot_os_dump_events.out b/test/trace_processor/diff_tests/parser/chrome/memory_snapshot_os_dump_events.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/memory_snapshot_os_dump_events.out
rename to test/trace_processor/diff_tests/parser/chrome/memory_snapshot_os_dump_events.out
diff --git a/test/trace_processor/diff_tests/chrome/memory_snapshot_os_dump_events_test.sql b/test/trace_processor/diff_tests/parser/chrome/memory_snapshot_os_dump_events_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/memory_snapshot_os_dump_events_test.sql
rename to test/trace_processor/diff_tests/parser/chrome/memory_snapshot_os_dump_events_test.sql
diff --git a/test/trace_processor/diff_tests/chrome/memory_snapshot_smaps.out b/test/trace_processor/diff_tests/parser/chrome/memory_snapshot_smaps.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/memory_snapshot_smaps.out
rename to test/trace_processor/diff_tests/parser/chrome/memory_snapshot_smaps.out
diff --git a/test/trace_processor/diff_tests/parser/chrome/tests.py b/test/trace_processor/diff_tests/parser/chrome/tests.py
new file mode 100644
index 0000000..6fe4547
--- /dev/null
+++ b/test/trace_processor/diff_tests/parser/chrome/tests.py
@@ -0,0 +1,188 @@
+#!/usr/bin/env python3
+# 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 a
+#
+# 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, Json, TextProto
+from python.generators.diff_tests.testing import DiffTestBlueprint
+from python.generators.diff_tests.testing import TestSuite
+
+
+class ChromeParser(TestSuite):
+ # Log messages.
+ def test_chrome_log_message(self):
+ return DiffTestBlueprint(
+ trace=TextProto(r"""
+ packet {
+ timestamp: 0
+ incremental_state_cleared: true
+ trusted_packet_sequence_id: 1
+ track_descriptor {
+ uuid: 12345
+ thread {
+ pid: 123
+ tid: 345
+ }
+ parent_uuid: 0
+ chrome_thread {
+ thread_type: THREAD_POOL_FG_WORKER
+ }
+ }
+ }
+
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 10
+ track_event {
+ track_uuid: 12345
+ categories: "cat1"
+ type: TYPE_INSTANT
+ name: "slice1"
+ log_message {
+ body_iid: 1
+ source_location_iid: 3
+ }
+ }
+ interned_data {
+ log_message_body {
+ iid: 1
+ body: "log message"
+ }
+ source_locations {
+ iid: 3
+ function_name: "func"
+ file_name: "foo.cc"
+ line_number: 123
+ }
+ }
+ }
+ """),
+ query="""
+ SELECT utid, tag, msg, prio FROM android_logs;
+ """,
+ # If the log_message_body doesn't have any priority, a default 4 (i.e.
+ # INFO) is assumed (otherwise the UI will not show the message).
+ out=Csv("""
+ "utid","tag","msg","prio"
+ 1,"foo.cc:123","log message",4
+ """))
+
+ def test_chrome_log_message_priority(self):
+ return DiffTestBlueprint(
+ trace=TextProto(r"""
+ packet {
+ timestamp: 0
+ incremental_state_cleared: true
+ trusted_packet_sequence_id: 1
+ track_descriptor {
+ uuid: 12345
+ thread {
+ pid: 123
+ tid: 345
+ }
+ parent_uuid: 0
+ chrome_thread {
+ thread_type: THREAD_POOL_FG_WORKER
+ }
+ }
+ }
+
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 10
+ track_event {
+ track_uuid: 12345
+ categories: "cat1"
+ type: TYPE_INSTANT
+ name: "slice1"
+ log_message {
+ body_iid: 1
+ source_location_iid: 3
+ prio: PRIO_WARN
+ }
+ }
+ interned_data {
+ log_message_body {
+ iid: 1
+ body: "log message"
+ }
+ source_locations {
+ iid: 3
+ function_name: "func"
+ file_name: "foo.cc"
+ line_number: 123
+ }
+ }
+ }
+ """),
+ query="""
+ SELECT utid, tag, msg, prio FROM android_logs;
+ """,
+ out=Csv("""
+ "utid","tag","msg","prio"
+ 1,"foo.cc:123","log message",5
+ """))
+
+ def test_chrome_log_message_args(self):
+ return DiffTestBlueprint(
+ trace=TextProto(r"""
+ packet {
+ timestamp: 0
+ incremental_state_cleared: true
+ trusted_packet_sequence_id: 1
+ track_descriptor {
+ uuid: 12345
+ thread {
+ pid: 123
+ tid: 345
+ }
+ parent_uuid: 0
+ chrome_thread {
+ thread_type: THREAD_POOL_FG_WORKER
+ }
+ }
+ }
+
+ packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 10
+ track_event {
+ track_uuid: 12345
+ categories: "cat1"
+ type: TYPE_INSTANT
+ name: "slice1"
+ log_message {
+ body_iid: 1
+ source_location_iid: 3
+ }
+ }
+ interned_data {
+ log_message_body {
+ iid: 1
+ body: "log message"
+ }
+ source_locations {
+ iid: 3
+ function_name: "func"
+ file_name: "foo.cc"
+ line_number: 123
+ }
+ }
+ }
+ """),
+ query=Path('chrome_log_message_args_test.sql'),
+ out=Csv("""
+ "log_message","function_name","file_name","line_number"
+ "log message","func","foo.cc",123
+ """))
\ No newline at end of file
diff --git a/test/trace_processor/diff_tests/chrome/tests_memory_snapshots.py b/test/trace_processor/diff_tests/parser/chrome/tests_memory_snapshots.py
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/tests_memory_snapshots.py
rename to test/trace_processor/diff_tests/parser/chrome/tests_memory_snapshots.py
diff --git a/test/trace_processor/diff_tests/cros/cros_ec_sensorhub_data.out b/test/trace_processor/diff_tests/parser/cros/cros_ec_sensorhub_data.out
similarity index 100%
rename from test/trace_processor/diff_tests/cros/cros_ec_sensorhub_data.out
rename to test/trace_processor/diff_tests/parser/cros/cros_ec_sensorhub_data.out
diff --git a/test/trace_processor/diff_tests/cros/tests.py b/test/trace_processor/diff_tests/parser/cros/tests.py
similarity index 100%
rename from test/trace_processor/diff_tests/cros/tests.py
rename to test/trace_processor/diff_tests/parser/cros/tests.py
diff --git a/test/trace_processor/diff_tests/fs/f2fs_iostat.out b/test/trace_processor/diff_tests/parser/fs/f2fs_iostat.out
similarity index 100%
rename from test/trace_processor/diff_tests/fs/f2fs_iostat.out
rename to test/trace_processor/diff_tests/parser/fs/f2fs_iostat.out
diff --git a/test/trace_processor/diff_tests/fs/f2fs_iostat.textproto b/test/trace_processor/diff_tests/parser/fs/f2fs_iostat.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/fs/f2fs_iostat.textproto
rename to test/trace_processor/diff_tests/parser/fs/f2fs_iostat.textproto
diff --git a/test/trace_processor/diff_tests/fs/f2fs_iostat_latency.out b/test/trace_processor/diff_tests/parser/fs/f2fs_iostat_latency.out
similarity index 100%
rename from test/trace_processor/diff_tests/fs/f2fs_iostat_latency.out
rename to test/trace_processor/diff_tests/parser/fs/f2fs_iostat_latency.out
diff --git a/test/trace_processor/diff_tests/fs/f2fs_iostat_latency.textproto b/test/trace_processor/diff_tests/parser/fs/f2fs_iostat_latency.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/fs/f2fs_iostat_latency.textproto
rename to test/trace_processor/diff_tests/parser/fs/f2fs_iostat_latency.textproto
diff --git a/test/trace_processor/diff_tests/fs/tests.py b/test/trace_processor/diff_tests/parser/fs/tests.py
similarity index 100%
rename from test/trace_processor/diff_tests/fs/tests.py
rename to test/trace_processor/diff_tests/parser/fs/tests.py
diff --git a/test/trace_processor/diff_tests/fuchsia/fuchsia_workstation_smoke_slices.out b/test/trace_processor/diff_tests/parser/fuchsia/fuchsia_workstation_smoke_slices.out
similarity index 100%
rename from test/trace_processor/diff_tests/fuchsia/fuchsia_workstation_smoke_slices.out
rename to test/trace_processor/diff_tests/parser/fuchsia/fuchsia_workstation_smoke_slices.out
diff --git a/test/trace_processor/diff_tests/fuchsia/tests.py b/test/trace_processor/diff_tests/parser/fuchsia/tests.py
similarity index 100%
rename from test/trace_processor/diff_tests/fuchsia/tests.py
rename to test/trace_processor/diff_tests/parser/fuchsia/tests.py
diff --git a/test/trace_processor/diff_tests/graphics/actual_frame_timeline_events.out b/test/trace_processor/diff_tests/parser/graphics/actual_frame_timeline_events.out
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/actual_frame_timeline_events.out
rename to test/trace_processor/diff_tests/parser/graphics/actual_frame_timeline_events.out
diff --git a/test/trace_processor/diff_tests/graphics/actual_frame_timeline_events_test.sql b/test/trace_processor/diff_tests/parser/graphics/actual_frame_timeline_events_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/actual_frame_timeline_events_test.sql
rename to test/trace_processor/diff_tests/parser/graphics/actual_frame_timeline_events_test.sql
diff --git a/test/trace_processor/diff_tests/graphics/clock_sync.py b/test/trace_processor/diff_tests/parser/graphics/clock_sync.py
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/clock_sync.py
rename to test/trace_processor/diff_tests/parser/graphics/clock_sync.py
diff --git a/test/trace_processor/diff_tests/graphics/drm_dma_fence.textproto b/test/trace_processor/diff_tests/parser/graphics/drm_dma_fence.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/drm_dma_fence.textproto
rename to test/trace_processor/diff_tests/parser/graphics/drm_dma_fence.textproto
diff --git a/test/trace_processor/diff_tests/graphics/drm_sched.textproto b/test/trace_processor/diff_tests/parser/graphics/drm_sched.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/drm_sched.textproto
rename to test/trace_processor/diff_tests/parser/graphics/drm_sched.textproto
diff --git a/test/trace_processor/diff_tests/graphics/expected_frame_timeline_events_test.sql b/test/trace_processor/diff_tests/parser/graphics/expected_frame_timeline_events_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/expected_frame_timeline_events_test.sql
rename to test/trace_processor/diff_tests/parser/graphics/expected_frame_timeline_events_test.sql
diff --git a/test/trace_processor/diff_tests/graphics/frame_timeline_events.py b/test/trace_processor/diff_tests/parser/graphics/frame_timeline_events.py
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/frame_timeline_events.py
rename to test/trace_processor/diff_tests/parser/graphics/frame_timeline_events.py
diff --git a/test/trace_processor/diff_tests/graphics/gpu_counter_specs.textproto b/test/trace_processor/diff_tests/parser/graphics/gpu_counter_specs.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/gpu_counter_specs.textproto
rename to test/trace_processor/diff_tests/parser/graphics/gpu_counter_specs.textproto
diff --git a/test/trace_processor/diff_tests/graphics/gpu_counters.py b/test/trace_processor/diff_tests/parser/graphics/gpu_counters.py
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/gpu_counters.py
rename to test/trace_processor/diff_tests/parser/graphics/gpu_counters.py
diff --git a/test/trace_processor/diff_tests/graphics/gpu_log.py b/test/trace_processor/diff_tests/parser/graphics/gpu_log.py
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/gpu_log.py
rename to test/trace_processor/diff_tests/parser/graphics/gpu_log.py
diff --git a/test/trace_processor/diff_tests/graphics/gpu_mem_total.py b/test/trace_processor/diff_tests/parser/graphics/gpu_mem_total.py
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/gpu_mem_total.py
rename to test/trace_processor/diff_tests/parser/graphics/gpu_mem_total.py
diff --git a/test/trace_processor/diff_tests/graphics/gpu_mem_total_after_free.py b/test/trace_processor/diff_tests/parser/graphics/gpu_mem_total_after_free.py
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/gpu_mem_total_after_free.py
rename to test/trace_processor/diff_tests/parser/graphics/gpu_mem_total_after_free.py
diff --git a/test/trace_processor/diff_tests/graphics/gpu_mem_total_test.sql b/test/trace_processor/diff_tests/parser/graphics/gpu_mem_total_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/gpu_mem_total_test.sql
rename to test/trace_processor/diff_tests/parser/graphics/gpu_mem_total_test.sql
diff --git a/test/trace_processor/diff_tests/graphics/gpu_render_stages.out b/test/trace_processor/diff_tests/parser/graphics/gpu_render_stages.out
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/gpu_render_stages.out
rename to test/trace_processor/diff_tests/parser/graphics/gpu_render_stages.out
diff --git a/test/trace_processor/diff_tests/graphics/gpu_render_stages.py b/test/trace_processor/diff_tests/parser/graphics/gpu_render_stages.py
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/gpu_render_stages.py
rename to test/trace_processor/diff_tests/parser/graphics/gpu_render_stages.py
diff --git a/test/trace_processor/diff_tests/graphics/gpu_render_stages_interned_spec.out b/test/trace_processor/diff_tests/parser/graphics/gpu_render_stages_interned_spec.out
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/gpu_render_stages_interned_spec.out
rename to test/trace_processor/diff_tests/parser/graphics/gpu_render_stages_interned_spec.out
diff --git a/test/trace_processor/diff_tests/graphics/gpu_render_stages_interned_spec.textproto b/test/trace_processor/diff_tests/parser/graphics/gpu_render_stages_interned_spec.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/gpu_render_stages_interned_spec.textproto
rename to test/trace_processor/diff_tests/parser/graphics/gpu_render_stages_interned_spec.textproto
diff --git a/test/trace_processor/diff_tests/graphics/gpu_render_stages_test.sql b/test/trace_processor/diff_tests/parser/graphics/gpu_render_stages_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/gpu_render_stages_test.sql
rename to test/trace_processor/diff_tests/parser/graphics/gpu_render_stages_test.sql
diff --git a/test/trace_processor/diff_tests/graphics/graphics_frame_events.out b/test/trace_processor/diff_tests/parser/graphics/graphics_frame_events.out
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/graphics_frame_events.out
rename to test/trace_processor/diff_tests/parser/graphics/graphics_frame_events.out
diff --git a/test/trace_processor/diff_tests/graphics/graphics_frame_events.py b/test/trace_processor/diff_tests/parser/graphics/graphics_frame_events.py
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/graphics_frame_events.py
rename to test/trace_processor/diff_tests/parser/graphics/graphics_frame_events.py
diff --git a/test/trace_processor/diff_tests/parser/graphics/tests.py b/test/trace_processor/diff_tests/parser/graphics/tests.py
new file mode 100644
index 0000000..563ddbe
--- /dev/null
+++ b/test/trace_processor/diff_tests/parser/graphics/tests.py
@@ -0,0 +1,280 @@
+#!/usr/bin/env python3
+# 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 a
+#
+# 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, Json, TextProto
+from python.generators.diff_tests.testing import DiffTestBlueprint
+from python.generators.diff_tests.testing import TestSuite
+
+
+class GraphicsParser(TestSuite):
+ # Contains tests for graphics related events and tables. Graphics frame
+ # trace tests.
+ def test_graphics_frame_events(self):
+ return DiffTestBlueprint(
+ trace=Path('graphics_frame_events.py'),
+ query="""
+ SELECT ts, gpu_track.name AS track_name, dur, frame_slice.name AS slice_name,
+ frame_number, layer_name
+ FROM gpu_track
+ LEFT JOIN frame_slice ON gpu_track.id = frame_slice.track_id
+ WHERE scope = 'graphics_frame_event'
+ ORDER BY ts;
+ """,
+ out=Path('graphics_frame_events.out'))
+
+ # GPU Memory ftrace packets
+ def test_gpu_mem_total(self):
+ return DiffTestBlueprint(
+ trace=Path('gpu_mem_total.py'),
+ query=Path('gpu_mem_total_test.sql'),
+ out=Csv("""
+ "name","unit","description","ts","pid","value"
+ "GPU Memory","7","Total GPU memory used by the entire system",0,"[NULL]",123
+ "GPU Memory","7","Total GPU memory used by this process",0,1,100
+ "GPU Memory","7","Total GPU memory used by the entire system",5,"[NULL]",256
+ "GPU Memory","7","Total GPU memory used by this process",5,1,233
+ "GPU Memory","7","Total GPU memory used by the entire system",10,"[NULL]",123
+ "GPU Memory","7","Total GPU memory used by this process",10,1,0
+ """))
+
+ def test_gpu_mem_total_after_free_gpu_mem_total(self):
+ return DiffTestBlueprint(
+ trace=Path('gpu_mem_total_after_free.py'),
+ query=Path('gpu_mem_total_test.sql'),
+ out=Csv("""
+ "name","unit","description","ts","pid","value"
+ "GPU Memory","7","Total GPU memory used by this process",0,1,100
+ "GPU Memory","7","Total GPU memory used by this process",5,1,233
+ "GPU Memory","7","Total GPU memory used by this process",10,1,50
+ """))
+
+ # Clock sync
+ def test_clock_sync(self):
+ return DiffTestBlueprint(
+ trace=Path('clock_sync.py'),
+ query="""
+ SELECT ts, cast(value AS integer) AS int_value
+ FROM counters
+ WHERE name GLOB 'gpu_counter*';
+ """,
+ out=Csv("""
+ "ts","int_value"
+ 1,3
+ 102,5
+ 1003,7
+ 1005,9
+ 2006,11
+ 2010,12
+ 2013,13
+ 3007,14
+ 3010,15
+ """))
+
+ # Frame Timeline event trace tests
+ def test_expected_frame_timeline_events(self):
+ return DiffTestBlueprint(
+ trace=Path('frame_timeline_events.py'),
+ query=Path('expected_frame_timeline_events_test.sql'),
+ out=Csv("""
+ "ts","dur","pid","display_frame_token","surface_frame_token","layer_name"
+ 20,6,666,2,0,"[NULL]"
+ 21,15,1000,4,1,"Layer1"
+ 40,6,666,4,0,"[NULL]"
+ 41,15,1000,6,5,"Layer1"
+ 80,6,666,6,0,"[NULL]"
+ 90,16,1000,8,7,"Layer1"
+ 120,6,666,8,0,"[NULL]"
+ 140,6,666,12,0,"[NULL]"
+ 150,20,1000,15,14,"Layer1"
+ 170,6,666,15,0,"[NULL]"
+ 200,6,666,17,0,"[NULL]"
+ 220,10,666,18,0,"[NULL]"
+ """))
+
+ def test_actual_frame_timeline_events(self):
+ return DiffTestBlueprint(
+ trace=Path('frame_timeline_events.py'),
+ query=Path('actual_frame_timeline_events_test.sql'),
+ out=Path('actual_frame_timeline_events.out'))
+
+ # Video 4 Linux 2 related tests
+ def test_v4l2_vidioc_slice(self):
+ return DiffTestBlueprint(
+ trace=Path('v4l2_vidioc.textproto'),
+ query="""
+ SELECT ts, dur, name
+ FROM slice
+ WHERE category = 'Video 4 Linux 2';
+ """,
+ out=Csv("""
+ "ts","dur","name"
+ 593268475912,0,"VIDIOC_QBUF minor=0 seq=0 type=9 index=19"
+ 593268603800,0,"VIDIOC_QBUF minor=0 seq=0 type=9 index=20"
+ 593528238295,0,"VIDIOC_DQBUF minor=0 seq=0 type=9 index=19"
+ 593544028229,0,"VIDIOC_DQBUF minor=0 seq=0 type=9 index=20"
+ """))
+
+ def test_v4l2_vidioc_flow(self):
+ return DiffTestBlueprint(
+ trace=Path('v4l2_vidioc.textproto'),
+ query="""
+ SELECT qbuf.ts, qbuf.dur, qbuf.name, dqbuf.ts, dqbuf.dur, dqbuf.name
+ FROM flow
+ JOIN slice qbuf ON flow.slice_out = qbuf.id
+ JOIN slice dqbuf ON flow.slice_in = dqbuf.id;
+ """,
+ out=Path('v4l2_vidioc_flow.out'))
+
+ def test_virtio_video_slice(self):
+ return DiffTestBlueprint(
+ trace=Path('virtio_video.textproto'),
+ query="""
+ SELECT slice.ts, slice.dur, slice.name, track.name
+ FROM slice
+ JOIN track ON slice.track_id = track.id;
+ """,
+ out=Csv("""
+ "ts","dur","name","name"
+ 593125003271,84500592,"Resource #102","virtio_video stream #4 OUTPUT"
+ 593125003785,100000,"RESOURCE_QUEUE","virtio_video stream #4 Requests"
+ 593125084611,709696,"Resource #62","virtio_video stream #3 OUTPUT"
+ 593125084935,100000,"RESOURCE_QUEUE","virtio_video stream #3 Requests"
+ 593125794194,100000,"RESOURCE_QUEUE","virtio_video stream #3 Responses"
+ 593209502603,100000,"RESOURCE_QUEUE","virtio_video stream #4 Responses"
+ """))
+
+ # virtgpu (drm/virtio) related tests
+ def test_virtio_gpu(self):
+ return DiffTestBlueprint(
+ trace=Path('virtio_gpu.textproto'),
+ query="""
+ SELECT
+ ts,
+ dur,
+ name
+ FROM
+ slice
+ ORDER BY ts;
+ """,
+ out=Csv("""
+ "ts","dur","name"
+ 1345090723759,1180312,"SUBMIT_3D"
+ 1345090746311,1167135,"CTX_DETACH_RESOURCE"
+ """))
+
+ # TODO(b/294866695): Reenable
+ # mali GPU events
+ #def test_mali(self):
+ # return DiffTestBlueprint(
+ # trace=TextProto(r"""
+ # packet {
+ # ftrace_events {
+ # cpu: 2
+ # event {
+ # timestamp: 751796307210
+ # pid: 2857
+ # mali_mali_KCPU_CQS_WAIT_START {
+ # info_val1: 1
+ # info_val2: 0
+ # kctx_tgid: 2201
+ # kctx_id: 10
+ # id: 0
+ # }
+ # }
+ # event {
+ # timestamp: 751800621175
+ # pid: 2857
+ # mali_mali_KCPU_CQS_WAIT_END {
+ # info_val1: 412313493488
+ # info_val2: 0
+ # kctx_tgid: 2201
+ # kctx_id: 10
+ # id: 0
+ # }
+ # }
+ # event {
+ # timestamp: 751800638997
+ # pid: 2857
+ # mali_mali_KCPU_CQS_SET {
+ # info_val1: 412313493480
+ # info_val2: 0
+ # kctx_tgid: 2201
+ # kctx_id: 10
+ # id: 0
+ # }
+ # }
+ # }
+ # }
+ # """),
+ # query="""
+ # SELECT ts, dur, name FROM slice WHERE name GLOB "mali_KCPU_CQS*";
+ # """,
+ # out=Csv("""
+ # "ts","dur","name"
+ # 751796307210,4313965,"mali_KCPU_CQS_WAIT"
+ # 751800638997,0,"mali_KCPU_CQS_SET"
+ # """))
+
+ #def test_mali_fence(self):
+ # return DiffTestBlueprint(
+ # trace=TextProto(r"""
+ # packet {
+ # ftrace_events {
+ # cpu: 2
+ # event {
+ # timestamp: 751796307210
+ # pid: 2857
+ # mali_mali_KCPU_FENCE_WAIT_START {
+ # info_val1: 1
+ # info_val2: 0
+ # kctx_tgid: 2201
+ # kctx_id: 10
+ # id: 0
+ # }
+ # }
+ # event {
+ # timestamp: 751800621175
+ # pid: 2857
+ # mali_mali_KCPU_FENCE_WAIT_END {
+ # info_val1: 412313493488
+ # info_val2: 0
+ # kctx_tgid: 2201
+ # kctx_id: 10
+ # id: 0
+ # }
+ # }
+ # event {
+ # timestamp: 751800638997
+ # pid: 2857
+ # mali_mali_KCPU_FENCE_SIGNAL {
+ # info_val1: 412313493480
+ # info_val2: 0
+ # kctx_tgid: 2201
+ # kctx_id: 10
+ # id: 0
+ # }
+ # }
+ # }
+ # }
+ # """),
+ # query="""
+ # SELECT ts, dur, name FROM slice WHERE name GLOB "mali_KCPU_FENCE*";
+ # """,
+ # out=Csv("""
+ # "ts","dur","name"
+ # 751796307210,4313965,"mali_KCPU_FENCE_WAIT"
+ # 751800638997,0,"mali_KCPU_FENCE_SIGNAL"
+ # """))
diff --git a/test/trace_processor/diff_tests/graphics/tests_drm_related_ftrace_events.py b/test/trace_processor/diff_tests/parser/graphics/tests_drm_related_ftrace_events.py
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/tests_drm_related_ftrace_events.py
rename to test/trace_processor/diff_tests/parser/graphics/tests_drm_related_ftrace_events.py
diff --git a/test/trace_processor/diff_tests/graphics/tests_gpu_trace.py b/test/trace_processor/diff_tests/parser/graphics/tests_gpu_trace.py
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/tests_gpu_trace.py
rename to test/trace_processor/diff_tests/parser/graphics/tests_gpu_trace.py
diff --git a/test/trace_processor/diff_tests/graphics/v4l2_vidioc.textproto b/test/trace_processor/diff_tests/parser/graphics/v4l2_vidioc.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/v4l2_vidioc.textproto
rename to test/trace_processor/diff_tests/parser/graphics/v4l2_vidioc.textproto
diff --git a/test/trace_processor/diff_tests/graphics/v4l2_vidioc_flow.out b/test/trace_processor/diff_tests/parser/graphics/v4l2_vidioc_flow.out
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/v4l2_vidioc_flow.out
rename to test/trace_processor/diff_tests/parser/graphics/v4l2_vidioc_flow.out
diff --git a/test/trace_processor/diff_tests/graphics/virtio_gpu.textproto b/test/trace_processor/diff_tests/parser/graphics/virtio_gpu.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/virtio_gpu.textproto
rename to test/trace_processor/diff_tests/parser/graphics/virtio_gpu.textproto
diff --git a/test/trace_processor/diff_tests/graphics/virtio_video.textproto b/test/trace_processor/diff_tests/parser/graphics/virtio_video.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/virtio_video.textproto
rename to test/trace_processor/diff_tests/parser/graphics/virtio_video.textproto
diff --git a/test/trace_processor/diff_tests/graphics/vulkan_api_events.out b/test/trace_processor/diff_tests/parser/graphics/vulkan_api_events.out
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/vulkan_api_events.out
rename to test/trace_processor/diff_tests/parser/graphics/vulkan_api_events.out
diff --git a/test/trace_processor/diff_tests/graphics/vulkan_api_events.py b/test/trace_processor/diff_tests/parser/graphics/vulkan_api_events.py
similarity index 100%
rename from test/trace_processor/diff_tests/graphics/vulkan_api_events.py
rename to test/trace_processor/diff_tests/parser/graphics/vulkan_api_events.py
diff --git a/test/trace_processor/diff_tests/parser/memory/tests.py b/test/trace_processor/diff_tests/parser/memory/tests.py
new file mode 100644
index 0000000..f7bdf1c
--- /dev/null
+++ b/test/trace_processor/diff_tests/parser/memory/tests.py
@@ -0,0 +1,113 @@
+#!/usr/bin/env python3
+# 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 a
+#
+# 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 Csv, TextProto
+from python.generators.diff_tests.testing import DiffTestBlueprint
+from python.generators.diff_tests.testing import TestSuite
+
+
+class MemoryParser(TestSuite):
+ # cma alloc
+ def test_cma(self):
+ return DiffTestBlueprint(
+ trace=TextProto(r"""
+ packet {
+ system_info {
+ utsname {
+ sysname: "Linux"
+ release: "5.10.0"
+ }
+ }
+ }
+ packet {
+ ftrace_events {
+ cpu: 4
+ event {
+ timestamp: 74288080958099
+ pid: 537
+ cma_alloc_start {
+ align: 4
+ count: 6592
+ name: "farawimg"
+ }
+ }
+ event {
+ timestamp: 74288191109751
+ pid: 537
+ cma_alloc_info {
+ align: 4
+ count: 6592
+ err_iso: 0
+ err_mig: 0
+ err_test: 0
+ name: "farawimg"
+ nr_mapped: 832596
+ nr_migrated: 6365
+ nr_reclaimed: 7
+ pfn: 10365824
+ }
+ }
+ }
+ }
+ """),
+ query="""
+ SELECT ts, dur, name FROM slice WHERE name = 'mm_cma_alloc';
+ """,
+ out=Csv("""
+ "ts","dur","name"
+ 74288080958099,110151652,"mm_cma_alloc"
+ """))
+
+ def test_android_dma_buffer_tracks(self):
+ return DiffTestBlueprint(
+ trace=TextProto(r"""
+ packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 100
+ pid: 1
+ dma_heap_stat {
+ inode: 123
+ len: 1024
+ total_allocated: 2048
+ }
+ }
+ }
+ }
+ packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 200
+ pid: 1
+ dma_heap_stat {
+ inode: 123
+ len: -1024
+ total_allocated: 1024
+ }
+ }
+ }
+ }
+ """),
+ query="""
+ SELECT track.name, slice.ts, slice.dur, slice.name
+ FROM slice JOIN track ON slice.track_id = track.id
+ WHERE track.name = 'mem.dma_buffer';
+ """,
+ out=Csv("""
+ "name","ts","dur","name"
+ "mem.dma_buffer",100,100,"1 kB"
+ """))
diff --git a/test/trace_processor/diff_tests/network/inet_sock_set_state.textproto b/test/trace_processor/diff_tests/parser/network/inet_sock_set_state.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/network/inet_sock_set_state.textproto
rename to test/trace_processor/diff_tests/parser/network/inet_sock_set_state.textproto
diff --git a/test/trace_processor/diff_tests/network/napi_gro_receive.textproto b/test/trace_processor/diff_tests/parser/network/napi_gro_receive.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/network/napi_gro_receive.textproto
rename to test/trace_processor/diff_tests/parser/network/napi_gro_receive.textproto
diff --git a/test/trace_processor/diff_tests/network/net_dev_xmit.textproto b/test/trace_processor/diff_tests/parser/network/net_dev_xmit.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/network/net_dev_xmit.textproto
rename to test/trace_processor/diff_tests/parser/network/net_dev_xmit.textproto
diff --git a/test/trace_processor/diff_tests/network/netif_receive_skb.textproto b/test/trace_processor/diff_tests/parser/network/netif_receive_skb.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/network/netif_receive_skb.textproto
rename to test/trace_processor/diff_tests/parser/network/netif_receive_skb.textproto
diff --git a/test/trace_processor/diff_tests/network/tests.py b/test/trace_processor/diff_tests/parser/network/tests.py
similarity index 94%
rename from test/trace_processor/diff_tests/network/tests.py
rename to test/trace_processor/diff_tests/parser/network/tests.py
index a8bdd72..76f2446 100644
--- a/test/trace_processor/diff_tests/network/tests.py
+++ b/test/trace_processor/diff_tests/parser/network/tests.py
@@ -13,13 +13,13 @@
# 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, Json, TextProto
+from python.generators.diff_tests.testing import Path, Metric
+from python.generators.diff_tests.testing import Csv, TextProto
from python.generators.diff_tests.testing import DiffTestBlueprint
from python.generators.diff_tests.testing import TestSuite
-class Network(TestSuite):
+class NetworkParser(TestSuite):
# Network performance
def test_netif_receive_skb(self):
return DiffTestBlueprint(
@@ -74,12 +74,6 @@
12000,"wlan0",4,1300
"""))
- def test_netperf_metric(self):
- return DiffTestBlueprint(
- trace=Path('netperf_metric.textproto'),
- query=Metric('android_netperf'),
- out=Path('netperf_metric.out'))
-
def test_inet_sock_set_state(self):
return DiffTestBlueprint(
trace=Path('inet_sock_set_state.textproto'),
diff --git a/test/trace_processor/diff_tests/parsing/all_atoms_test.sql b/test/trace_processor/diff_tests/parser/parsing/all_atoms_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/all_atoms_test.sql
rename to test/trace_processor/diff_tests/parser/parsing/all_atoms_test.sql
diff --git a/test/trace_processor/diff_tests/parsing/android_binder.py b/test/trace_processor/diff_tests/parser/parsing/android_binder.py
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/android_binder.py
rename to test/trace_processor/diff_tests/parser/parsing/android_binder.py
diff --git a/test/trace_processor/diff_tests/parsing/android_log_counts_test.sql b/test/trace_processor/diff_tests/parser/parsing/android_log_counts_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/android_log_counts_test.sql
rename to test/trace_processor/diff_tests/parser/parsing/android_log_counts_test.sql
diff --git a/test/trace_processor/diff_tests/parsing/android_log_msgs.out b/test/trace_processor/diff_tests/parser/parsing/android_log_msgs.out
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/android_log_msgs.out
rename to test/trace_processor/diff_tests/parser/parsing/android_log_msgs.out
diff --git a/test/trace_processor/diff_tests/parsing/android_log_msgs_test.sql b/test/trace_processor/diff_tests/parser/parsing/android_log_msgs_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/android_log_msgs_test.sql
rename to test/trace_processor/diff_tests/parser/parsing/android_log_msgs_test.sql
diff --git a/test/trace_processor/diff_tests/parsing/android_multiuser_switch.textproto b/test/trace_processor/diff_tests/parser/parsing/android_multiuser_switch.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/android_multiuser_switch.textproto
rename to test/trace_processor/diff_tests/parser/parsing/android_multiuser_switch.textproto
diff --git a/test/trace_processor/diff_tests/parsing/android_package_list.py b/test/trace_processor/diff_tests/parser/parsing/android_package_list.py
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/android_package_list.py
rename to test/trace_processor/diff_tests/parser/parsing/android_package_list.py
diff --git a/test/trace_processor/diff_tests/parsing/android_sched_and_ps_stats.out b/test/trace_processor/diff_tests/parser/parsing/android_sched_and_ps_stats.out
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/android_sched_and_ps_stats.out
rename to test/trace_processor/diff_tests/parser/parsing/android_sched_and_ps_stats.out
diff --git a/test/trace_processor/diff_tests/parsing/args_string_filter_null_test.sql b/test/trace_processor/diff_tests/parser/parsing/args_string_filter_null_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/args_string_filter_null_test.sql
rename to test/trace_processor/diff_tests/parser/parsing/args_string_filter_null_test.sql
diff --git a/test/trace_processor/diff_tests/parsing/b120487929_test.sql b/test/trace_processor/diff_tests/parser/parsing/b120487929_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/b120487929_test.sql
rename to test/trace_processor/diff_tests/parser/parsing/b120487929_test.sql
diff --git a/test/trace_processor/diff_tests/parsing/cgroup_attach_task_post_s_print_systrace.out b/test/trace_processor/diff_tests/parser/parsing/cgroup_attach_task_post_s_print_systrace.out
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/cgroup_attach_task_post_s_print_systrace.out
rename to test/trace_processor/diff_tests/parser/parsing/cgroup_attach_task_post_s_print_systrace.out
diff --git a/test/trace_processor/diff_tests/parsing/cgroup_attach_task_pre_s_print_systrace.out b/test/trace_processor/diff_tests/parser/parsing/cgroup_attach_task_pre_s_print_systrace.out
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/cgroup_attach_task_pre_s_print_systrace.out
rename to test/trace_processor/diff_tests/parser/parsing/cgroup_attach_task_pre_s_print_systrace.out
diff --git a/test/trace_processor/diff_tests/parsing/chrome_metadata.out b/test/trace_processor/diff_tests/parser/parsing/chrome_metadata.out
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/chrome_metadata.out
rename to test/trace_processor/diff_tests/parser/parsing/chrome_metadata.out
diff --git a/test/trace_processor/diff_tests/parsing/cpu_counters_b120487929.out b/test/trace_processor/diff_tests/parser/parsing/cpu_counters_b120487929.out
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/cpu_counters_b120487929.out
rename to test/trace_processor/diff_tests/parser/parsing/cpu_counters_b120487929.out
diff --git a/test/trace_processor/diff_tests/parsing/cpu_freq.out b/test/trace_processor/diff_tests/parser/parsing/cpu_freq.out
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/cpu_freq.out
rename to test/trace_processor/diff_tests/parser/parsing/cpu_freq.out
diff --git a/test/trace_processor/diff_tests/parsing/cpu_info.textproto b/test/trace_processor/diff_tests/parser/parsing/cpu_info.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/cpu_info.textproto
rename to test/trace_processor/diff_tests/parser/parsing/cpu_info.textproto
diff --git a/test/trace_processor/diff_tests/parsing/flow_events_json_v1.json b/test/trace_processor/diff_tests/parser/parsing/flow_events_json_v1.json
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/flow_events_json_v1.json
rename to test/trace_processor/diff_tests/parser/parsing/flow_events_json_v1.json
diff --git a/test/trace_processor/diff_tests/parsing/flow_events_json_v2.json b/test/trace_processor/diff_tests/parser/parsing/flow_events_json_v2.json
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/flow_events_json_v2.json
rename to test/trace_processor/diff_tests/parser/parsing/flow_events_json_v2.json
diff --git a/test/trace_processor/diff_tests/parsing/ftrace_with_tracing_start.py b/test/trace_processor/diff_tests/parser/parsing/ftrace_with_tracing_start.py
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/ftrace_with_tracing_start.py
rename to test/trace_processor/diff_tests/parser/parsing/ftrace_with_tracing_start.py
diff --git a/test/trace_processor/diff_tests/parsing/funcgraph_trace.textproto b/test/trace_processor/diff_tests/parser/parsing/funcgraph_trace.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/funcgraph_trace.textproto
rename to test/trace_processor/diff_tests/parser/parsing/funcgraph_trace.textproto
diff --git a/test/trace_processor/diff_tests/parsing/kernel_dpu_tmw_counter_thread_counter_and_track.out b/test/trace_processor/diff_tests/parser/parsing/kernel_dpu_tmw_counter_thread_counter_and_track.out
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/kernel_dpu_tmw_counter_thread_counter_and_track.out
rename to test/trace_processor/diff_tests/parser/parsing/kernel_dpu_tmw_counter_thread_counter_and_track.out
diff --git a/test/trace_processor/diff_tests/parsing/kernel_tmw_counter.textproto b/test/trace_processor/diff_tests/parser/parsing/kernel_tmw_counter.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/kernel_tmw_counter.textproto
rename to test/trace_processor/diff_tests/parser/parsing/kernel_tmw_counter.textproto
diff --git a/test/trace_processor/diff_tests/parsing/kernel_tmw_counter_thread_counter_and_track.out b/test/trace_processor/diff_tests/parser/parsing/kernel_tmw_counter_thread_counter_and_track.out
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/kernel_tmw_counter_thread_counter_and_track.out
rename to test/trace_processor/diff_tests/parser/parsing/kernel_tmw_counter_thread_counter_and_track.out
diff --git a/test/trace_processor/diff_tests/parsing/mm_event.out b/test/trace_processor/diff_tests/parser/parsing/mm_event.out
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/mm_event.out
rename to test/trace_processor/diff_tests/parser/parsing/mm_event.out
diff --git a/test/trace_processor/diff_tests/parsing/oom_query_test.sql b/test/trace_processor/diff_tests/parser/parsing/oom_query_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/oom_query_test.sql
rename to test/trace_processor/diff_tests/parser/parsing/oom_query_test.sql
diff --git a/test/trace_processor/diff_tests/parsing/otheruuids.textproto b/test/trace_processor/diff_tests/parser/parsing/otheruuids.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/otheruuids.textproto
rename to test/trace_processor/diff_tests/parser/parsing/otheruuids.textproto
diff --git a/test/trace_processor/diff_tests/parsing/print_systrace_lmk_userspace.out b/test/trace_processor/diff_tests/parser/parsing/print_systrace_lmk_userspace.out
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/print_systrace_lmk_userspace.out
rename to test/trace_processor/diff_tests/parser/parsing/print_systrace_lmk_userspace.out
diff --git a/test/trace_processor/diff_tests/parsing/print_systrace_unsigned.out b/test/trace_processor/diff_tests/parser/parsing/print_systrace_unsigned.out
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/print_systrace_unsigned.out
rename to test/trace_processor/diff_tests/parser/parsing/print_systrace_unsigned.out
diff --git a/test/trace_processor/diff_tests/parsing/print_systrace_unsigned.py b/test/trace_processor/diff_tests/parser/parsing/print_systrace_unsigned.py
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/print_systrace_unsigned.py
rename to test/trace_processor/diff_tests/parser/parsing/print_systrace_unsigned.py
diff --git a/test/trace_processor/diff_tests/parsing/process_stats_poll_oom_score.out b/test/trace_processor/diff_tests/parser/parsing/process_stats_poll_oom_score.out
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/process_stats_poll_oom_score.out
rename to test/trace_processor/diff_tests/parser/parsing/process_stats_poll_oom_score.out
diff --git a/test/trace_processor/diff_tests/parsing/rss_stat_after_free.py b/test/trace_processor/diff_tests/parser/parsing/rss_stat_after_free.py
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/rss_stat_after_free.py
rename to test/trace_processor/diff_tests/parser/parsing/rss_stat_after_free.py
diff --git a/test/trace_processor/diff_tests/parsing/rss_stat_legacy.py b/test/trace_processor/diff_tests/parser/parsing/rss_stat_legacy.py
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/rss_stat_legacy.py
rename to test/trace_processor/diff_tests/parser/parsing/rss_stat_legacy.py
diff --git a/test/trace_processor/diff_tests/parsing/rss_stat_mm_id.py b/test/trace_processor/diff_tests/parser/parsing/rss_stat_mm_id.py
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/rss_stat_mm_id.py
rename to test/trace_processor/diff_tests/parser/parsing/rss_stat_mm_id.py
diff --git a/test/trace_processor/diff_tests/parsing/rss_stat_mm_id_clone.py b/test/trace_processor/diff_tests/parser/parsing/rss_stat_mm_id_clone.py
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/rss_stat_mm_id_clone.py
rename to test/trace_processor/diff_tests/parser/parsing/rss_stat_mm_id_clone.py
diff --git a/test/trace_processor/diff_tests/parsing/rss_stat_mm_id_reuse.py b/test/trace_processor/diff_tests/parser/parsing/rss_stat_mm_id_reuse.py
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/rss_stat_mm_id_reuse.py
rename to test/trace_processor/diff_tests/parser/parsing/rss_stat_mm_id_reuse.py
diff --git a/test/trace_processor/diff_tests/parsing/sched_blocked_proto.py b/test/trace_processor/diff_tests/parser/parsing/sched_blocked_proto.py
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/sched_blocked_proto.py
rename to test/trace_processor/diff_tests/parser/parsing/sched_blocked_proto.py
diff --git a/test/trace_processor/diff_tests/parsing/sched_blocked_reason_symbolized.textproto b/test/trace_processor/diff_tests/parser/parsing/sched_blocked_reason_symbolized.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/sched_blocked_reason_symbolized.textproto
rename to test/trace_processor/diff_tests/parser/parsing/sched_blocked_reason_symbolized.textproto
diff --git a/test/trace_processor/diff_tests/parsing/sched_blocked_reason_symbolized_to_systrace.out b/test/trace_processor/diff_tests/parser/parsing/sched_blocked_reason_symbolized_to_systrace.out
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/sched_blocked_reason_symbolized_to_systrace.out
rename to test/trace_processor/diff_tests/parser/parsing/sched_blocked_reason_symbolized_to_systrace.out
diff --git a/test/trace_processor/diff_tests/parsing/sched_blocked_systrace.systrace b/test/trace_processor/diff_tests/parser/parsing/sched_blocked_systrace.systrace
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/sched_blocked_systrace.systrace
rename to test/trace_processor/diff_tests/parser/parsing/sched_blocked_systrace.systrace
diff --git a/test/trace_processor/diff_tests/parsing/sched_slices_sched_switch_compact.out b/test/trace_processor/diff_tests/parser/parsing/sched_slices_sched_switch_compact.out
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/sched_slices_sched_switch_compact.out
rename to test/trace_processor/diff_tests/parser/parsing/sched_slices_sched_switch_compact.out
diff --git a/test/trace_processor/diff_tests/parsing/sched_slices_sched_switch_original.out b/test/trace_processor/diff_tests/parser/parsing/sched_slices_sched_switch_original.out
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/sched_slices_sched_switch_original.out
rename to test/trace_processor/diff_tests/parser/parsing/sched_slices_sched_switch_original.out
diff --git a/test/trace_processor/diff_tests/parsing/sched_waking_instants_compact_sched.out b/test/trace_processor/diff_tests/parser/parsing/sched_waking_instants_compact_sched.out
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/sched_waking_instants_compact_sched.out
rename to test/trace_processor/diff_tests/parser/parsing/sched_waking_instants_compact_sched.out
diff --git a/test/trace_processor/diff_tests/parsing/sched_waking_raw_compact_sched.out b/test/trace_processor/diff_tests/parser/parsing/sched_waking_raw_compact_sched.out
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/sched_waking_raw_compact_sched.out
rename to test/trace_processor/diff_tests/parser/parsing/sched_waking_raw_compact_sched.out
diff --git a/test/trace_processor/diff_tests/parsing/sched_waking_raw_test.sql b/test/trace_processor/diff_tests/parser/parsing/sched_waking_raw_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/sched_waking_raw_test.sql
rename to test/trace_processor/diff_tests/parser/parsing/sched_waking_raw_test.sql
diff --git a/test/trace_processor/diff_tests/parsing/statsd_atoms_all_atoms.out b/test/trace_processor/diff_tests/parser/parsing/statsd_atoms_all_atoms.out
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/statsd_atoms_all_atoms.out
rename to test/trace_processor/diff_tests/parser/parsing/statsd_atoms_all_atoms.out
diff --git a/test/trace_processor/diff_tests/parsing/synth_oom.py b/test/trace_processor/diff_tests/parser/parsing/synth_oom.py
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/synth_oom.py
rename to test/trace_processor/diff_tests/parser/parsing/synth_oom.py
diff --git a/test/trace_processor/diff_tests/parsing/synth_oom_oom_query.out b/test/trace_processor/diff_tests/parser/parsing/synth_oom_oom_query.out
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/synth_oom_oom_query.out
rename to test/trace_processor/diff_tests/parser/parsing/synth_oom_oom_query.out
diff --git a/test/trace_processor/diff_tests/parsing/syscall.py b/test/trace_processor/diff_tests/parser/parsing/syscall.py
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/syscall.py
rename to test/trace_processor/diff_tests/parser/parsing/syscall.py
diff --git a/test/trace_processor/diff_tests/parsing/systrace_html.out b/test/trace_processor/diff_tests/parser/parsing/systrace_html.out
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/systrace_html.out
rename to test/trace_processor/diff_tests/parser/parsing/systrace_html.out
diff --git a/test/trace_processor/diff_tests/parsing/tests.py b/test/trace_processor/diff_tests/parser/parsing/tests.py
similarity index 97%
rename from test/trace_processor/diff_tests/parsing/tests.py
rename to test/trace_processor/diff_tests/parser/parsing/tests.py
index 83a986c..5261b09 100644
--- a/test/trace_processor/diff_tests/parsing/tests.py
+++ b/test/trace_processor/diff_tests/parser/parsing/tests.py
@@ -1213,3 +1213,27 @@
"name","dur","tid"
"test_event",100,584
"""))
+
+ def test_all_data_source_flushed_metadata(self):
+ return DiffTestBlueprint(
+ trace=TextProto(r"""
+ packet {
+ timestamp: 12344
+ service_event {
+ all_data_sources_flushed: true
+ }
+ }
+ packet {
+ timestamp: 12345
+ service_event {
+ all_data_sources_flushed: true
+ }
+ }
+ """),
+ query="""
+ SELECT name, int_value FROM metadata WHERE name = 'all_data_source_flushed_ns'""",
+ out=Csv("""
+ "name","int_value"
+ "all_data_source_flushed_ns",12344
+ "all_data_source_flushed_ns",12345
+ """))
diff --git a/test/trace_processor/diff_tests/parsing/tests_debug_annotation.py b/test/trace_processor/diff_tests/parser/parsing/tests_debug_annotation.py
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/tests_debug_annotation.py
rename to test/trace_processor/diff_tests/parser/parsing/tests_debug_annotation.py
diff --git a/test/trace_processor/diff_tests/parsing/tests_memory_counters.py b/test/trace_processor/diff_tests/parser/parsing/tests_memory_counters.py
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/tests_memory_counters.py
rename to test/trace_processor/diff_tests/parser/parsing/tests_memory_counters.py
diff --git a/test/trace_processor/diff_tests/parsing/tests_rss_stats.py b/test/trace_processor/diff_tests/parser/parsing/tests_rss_stats.py
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/tests_rss_stats.py
rename to test/trace_processor/diff_tests/parser/parsing/tests_rss_stats.py
diff --git a/test/trace_processor/diff_tests/parsing/thread_counter_and_track_test.sql b/test/trace_processor/diff_tests/parser/parsing/thread_counter_and_track_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/thread_counter_and_track_test.sql
rename to test/trace_processor/diff_tests/parser/parsing/thread_counter_and_track_test.sql
diff --git a/test/trace_processor/diff_tests/parsing/thread_time_in_state.out b/test/trace_processor/diff_tests/parser/parsing/thread_time_in_state.out
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/thread_time_in_state.out
rename to test/trace_processor/diff_tests/parser/parsing/thread_time_in_state.out
diff --git a/test/trace_processor/diff_tests/parsing/thread_time_in_state_event.out b/test/trace_processor/diff_tests/parser/parsing/thread_time_in_state_event.out
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/thread_time_in_state_event.out
rename to test/trace_processor/diff_tests/parser/parsing/thread_time_in_state_event.out
diff --git a/test/trace_processor/diff_tests/parsing/thread_time_in_state_event.py b/test/trace_processor/diff_tests/parser/parsing/thread_time_in_state_event.py
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/thread_time_in_state_event.py
rename to test/trace_processor/diff_tests/parser/parsing/thread_time_in_state_event.py
diff --git a/test/trace_processor/diff_tests/parsing/triggers_packets_test.sql b/test/trace_processor/diff_tests/parser/parsing/triggers_packets_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/triggers_packets_test.sql
rename to test/trace_processor/diff_tests/parser/parsing/triggers_packets_test.sql
diff --git a/test/trace_processor/diff_tests/parsing/very_long_sched.py b/test/trace_processor/diff_tests/parser/parsing/very_long_sched.py
similarity index 100%
rename from test/trace_processor/diff_tests/parsing/very_long_sched.py
rename to test/trace_processor/diff_tests/parser/parsing/very_long_sched.py
diff --git a/test/trace_processor/diff_tests/power/dvfs_metric.out b/test/trace_processor/diff_tests/parser/power/dvfs_metric.out
similarity index 100%
rename from test/trace_processor/diff_tests/power/dvfs_metric.out
rename to test/trace_processor/diff_tests/parser/power/dvfs_metric.out
diff --git a/test/trace_processor/diff_tests/power/dvfs_metric.textproto b/test/trace_processor/diff_tests/parser/power/dvfs_metric.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/power/dvfs_metric.textproto
rename to test/trace_processor/diff_tests/parser/power/dvfs_metric.textproto
diff --git a/test/trace_processor/diff_tests/power/energy_breakdown.textproto b/test/trace_processor/diff_tests/parser/power/energy_breakdown.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/power/energy_breakdown.textproto
rename to test/trace_processor/diff_tests/parser/power/energy_breakdown.textproto
diff --git a/test/trace_processor/diff_tests/power/energy_breakdown_uid.textproto b/test/trace_processor/diff_tests/parser/power/energy_breakdown_uid.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/power/energy_breakdown_uid.textproto
rename to test/trace_processor/diff_tests/parser/power/energy_breakdown_uid.textproto
diff --git a/test/trace_processor/diff_tests/power/entity_state_residency.textproto b/test/trace_processor/diff_tests/parser/power/entity_state_residency.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/power/entity_state_residency.textproto
rename to test/trace_processor/diff_tests/parser/power/entity_state_residency.textproto
diff --git a/test/trace_processor/diff_tests/power/power_rails.textproto b/test/trace_processor/diff_tests/parser/power/power_rails.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/power/power_rails.textproto
rename to test/trace_processor/diff_tests/parser/power/power_rails.textproto
diff --git a/test/trace_processor/diff_tests/power/power_rails_custom_clock.textproto b/test/trace_processor/diff_tests/parser/power/power_rails_custom_clock.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/power/power_rails_custom_clock.textproto
rename to test/trace_processor/diff_tests/parser/power/power_rails_custom_clock.textproto
diff --git a/test/trace_processor/diff_tests/power/suspend_period.textproto b/test/trace_processor/diff_tests/parser/power/suspend_period.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/power/suspend_period.textproto
rename to test/trace_processor/diff_tests/parser/power/suspend_period.textproto
diff --git a/test/trace_processor/diff_tests/power/suspend_resume.textproto b/test/trace_processor/diff_tests/parser/power/suspend_resume.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/power/suspend_resume.textproto
rename to test/trace_processor/diff_tests/parser/power/suspend_resume.textproto
diff --git a/test/trace_processor/diff_tests/power/tests_energy_breakdown.py b/test/trace_processor/diff_tests/parser/power/tests_energy_breakdown.py
similarity index 100%
rename from test/trace_processor/diff_tests/power/tests_energy_breakdown.py
rename to test/trace_processor/diff_tests/parser/power/tests_energy_breakdown.py
diff --git a/test/trace_processor/diff_tests/power/tests_entity_state_residency.py b/test/trace_processor/diff_tests/parser/power/tests_entity_state_residency.py
similarity index 100%
rename from test/trace_processor/diff_tests/power/tests_entity_state_residency.py
rename to test/trace_processor/diff_tests/parser/power/tests_entity_state_residency.py
diff --git a/test/trace_processor/diff_tests/power/tests_linux_sysfs_power.py b/test/trace_processor/diff_tests/parser/power/tests_linux_sysfs_power.py
similarity index 100%
rename from test/trace_processor/diff_tests/power/tests_linux_sysfs_power.py
rename to test/trace_processor/diff_tests/parser/power/tests_linux_sysfs_power.py
diff --git a/test/trace_processor/diff_tests/power/tests_power_rails.py b/test/trace_processor/diff_tests/parser/power/tests_power_rails.py
similarity index 100%
rename from test/trace_processor/diff_tests/power/tests_power_rails.py
rename to test/trace_processor/diff_tests/parser/power/tests_power_rails.py
diff --git a/test/trace_processor/diff_tests/power/tests_voltage_and_scaling.py b/test/trace_processor/diff_tests/parser/power/tests_voltage_and_scaling.py
similarity index 100%
rename from test/trace_processor/diff_tests/power/tests_voltage_and_scaling.py
rename to test/trace_processor/diff_tests/parser/power/tests_voltage_and_scaling.py
diff --git a/test/trace_processor/diff_tests/power/wakesource.textproto b/test/trace_processor/diff_tests/parser/power/wakesource.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/power/wakesource.textproto
rename to test/trace_processor/diff_tests/parser/power/wakesource.textproto
diff --git a/test/trace_processor/diff_tests/process_tracking/process_parent_pid_tracking_1.py b/test/trace_processor/diff_tests/parser/process_tracking/process_parent_pid_tracking_1.py
similarity index 100%
rename from test/trace_processor/diff_tests/process_tracking/process_parent_pid_tracking_1.py
rename to test/trace_processor/diff_tests/parser/process_tracking/process_parent_pid_tracking_1.py
diff --git a/test/trace_processor/diff_tests/process_tracking/process_parent_pid_tracking_2.py b/test/trace_processor/diff_tests/parser/process_tracking/process_parent_pid_tracking_2.py
similarity index 100%
rename from test/trace_processor/diff_tests/process_tracking/process_parent_pid_tracking_2.py
rename to test/trace_processor/diff_tests/parser/process_tracking/process_parent_pid_tracking_2.py
diff --git a/test/trace_processor/diff_tests/process_tracking/process_tracking_exec.py b/test/trace_processor/diff_tests/parser/process_tracking/process_tracking_exec.py
similarity index 100%
rename from test/trace_processor/diff_tests/process_tracking/process_tracking_exec.py
rename to test/trace_processor/diff_tests/parser/process_tracking/process_tracking_exec.py
diff --git a/test/trace_processor/diff_tests/process_tracking/process_tracking_short_lived_1.py b/test/trace_processor/diff_tests/parser/process_tracking/process_tracking_short_lived_1.py
similarity index 100%
rename from test/trace_processor/diff_tests/process_tracking/process_tracking_short_lived_1.py
rename to test/trace_processor/diff_tests/parser/process_tracking/process_tracking_short_lived_1.py
diff --git a/test/trace_processor/diff_tests/process_tracking/process_tracking_short_lived_2.py b/test/trace_processor/diff_tests/parser/process_tracking/process_tracking_short_lived_2.py
similarity index 100%
rename from test/trace_processor/diff_tests/process_tracking/process_tracking_short_lived_2.py
rename to test/trace_processor/diff_tests/parser/process_tracking/process_tracking_short_lived_2.py
diff --git a/test/trace_processor/diff_tests/process_tracking/reused_thread_print.py b/test/trace_processor/diff_tests/parser/process_tracking/reused_thread_print.py
similarity index 100%
rename from test/trace_processor/diff_tests/process_tracking/reused_thread_print.py
rename to test/trace_processor/diff_tests/parser/process_tracking/reused_thread_print.py
diff --git a/test/trace_processor/diff_tests/process_tracking/synth_process_tracking.py b/test/trace_processor/diff_tests/parser/process_tracking/synth_process_tracking.py
similarity index 100%
rename from test/trace_processor/diff_tests/process_tracking/synth_process_tracking.py
rename to test/trace_processor/diff_tests/parser/process_tracking/synth_process_tracking.py
diff --git a/test/trace_processor/diff_tests/process_tracking/tests.py b/test/trace_processor/diff_tests/parser/process_tracking/tests.py
similarity index 100%
rename from test/trace_processor/diff_tests/process_tracking/tests.py
rename to test/trace_processor/diff_tests/parser/process_tracking/tests.py
diff --git a/test/trace_processor/diff_tests/process_tracking/unknown_thread_name.systrace b/test/trace_processor/diff_tests/parser/process_tracking/unknown_thread_name.systrace
similarity index 100%
rename from test/trace_processor/diff_tests/process_tracking/unknown_thread_name.systrace
rename to test/trace_processor/diff_tests/parser/process_tracking/unknown_thread_name.systrace
diff --git a/test/trace_processor/diff_tests/profiling/callstack_sampling_flamegraph.out b/test/trace_processor/diff_tests/parser/profiling/callstack_sampling_flamegraph.out
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/callstack_sampling_flamegraph.out
rename to test/trace_processor/diff_tests/parser/profiling/callstack_sampling_flamegraph.out
diff --git a/test/trace_processor/diff_tests/profiling/heap_graph.textproto b/test/trace_processor/diff_tests/parser/profiling/heap_graph.textproto
similarity index 100%
copy from test/trace_processor/diff_tests/profiling/heap_graph.textproto
copy to test/trace_processor/diff_tests/parser/profiling/heap_graph.textproto
diff --git a/test/trace_processor/diff_tests/profiling/heap_graph_baseapk.textproto b/test/trace_processor/diff_tests/parser/profiling/heap_graph_baseapk.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/heap_graph_baseapk.textproto
rename to test/trace_processor/diff_tests/parser/profiling/heap_graph_baseapk.textproto
diff --git a/test/trace_processor/diff_tests/profiling/heap_graph_branching.textproto b/test/trace_processor/diff_tests/parser/profiling/heap_graph_branching.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/heap_graph_branching.textproto
rename to test/trace_processor/diff_tests/parser/profiling/heap_graph_branching.textproto
diff --git a/test/trace_processor/diff_tests/profiling/heap_graph_deobfuscate_pkg.textproto b/test/trace_processor/diff_tests/parser/profiling/heap_graph_deobfuscate_pkg.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/heap_graph_deobfuscate_pkg.textproto
rename to test/trace_processor/diff_tests/parser/profiling/heap_graph_deobfuscate_pkg.textproto
diff --git a/test/trace_processor/diff_tests/profiling/heap_graph_duplicate_flamegraph.out b/test/trace_processor/diff_tests/parser/profiling/heap_graph_duplicate_flamegraph.out
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/heap_graph_duplicate_flamegraph.out
rename to test/trace_processor/diff_tests/parser/profiling/heap_graph_duplicate_flamegraph.out
diff --git a/test/trace_processor/diff_tests/profiling/heap_graph_flamegraph.out b/test/trace_processor/diff_tests/parser/profiling/heap_graph_flamegraph.out
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/heap_graph_flamegraph.out
rename to test/trace_processor/diff_tests/parser/profiling/heap_graph_flamegraph.out
diff --git a/test/trace_processor/diff_tests/profiling/heap_graph_flamegraph_focused.out b/test/trace_processor/diff_tests/parser/profiling/heap_graph_flamegraph_focused.out
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/heap_graph_flamegraph_focused.out
rename to test/trace_processor/diff_tests/parser/profiling/heap_graph_flamegraph_focused.out
diff --git a/test/trace_processor/diff_tests/profiling/heap_graph_flamegraph_system-server-heap-graph.out b/test/trace_processor/diff_tests/parser/profiling/heap_graph_flamegraph_system-server-heap-graph.out
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/heap_graph_flamegraph_system-server-heap-graph.out
rename to test/trace_processor/diff_tests/parser/profiling/heap_graph_flamegraph_system-server-heap-graph.out
diff --git a/test/trace_processor/diff_tests/profiling/heap_graph_huge_size.textproto b/test/trace_processor/diff_tests/parser/profiling/heap_graph_huge_size.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/heap_graph_huge_size.textproto
rename to test/trace_processor/diff_tests/parser/profiling/heap_graph_huge_size.textproto
diff --git a/test/trace_processor/diff_tests/profiling/heap_graph_interleaved.textproto b/test/trace_processor/diff_tests/parser/profiling/heap_graph_interleaved.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/heap_graph_interleaved.textproto
rename to test/trace_processor/diff_tests/parser/profiling/heap_graph_interleaved.textproto
diff --git a/test/trace_processor/diff_tests/profiling/heap_graph_interleaved_object.out b/test/trace_processor/diff_tests/parser/profiling/heap_graph_interleaved_object.out
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/heap_graph_interleaved_object.out
rename to test/trace_processor/diff_tests/parser/profiling/heap_graph_interleaved_object.out
diff --git a/test/trace_processor/diff_tests/profiling/heap_graph_interleaved_reference.out b/test/trace_processor/diff_tests/parser/profiling/heap_graph_interleaved_reference.out
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/heap_graph_interleaved_reference.out
rename to test/trace_processor/diff_tests/parser/profiling/heap_graph_interleaved_reference.out
diff --git a/test/trace_processor/diff_tests/profiling/heap_graph_legacy.textproto b/test/trace_processor/diff_tests/parser/profiling/heap_graph_legacy.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/heap_graph_legacy.textproto
rename to test/trace_processor/diff_tests/parser/profiling/heap_graph_legacy.textproto
diff --git a/test/trace_processor/diff_tests/profiling/heap_graph_native_size.textproto b/test/trace_processor/diff_tests/parser/profiling/heap_graph_native_size.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/heap_graph_native_size.textproto
rename to test/trace_processor/diff_tests/parser/profiling/heap_graph_native_size.textproto
diff --git a/test/trace_processor/diff_tests/profiling/heap_graph_object.out b/test/trace_processor/diff_tests/parser/profiling/heap_graph_object.out
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/heap_graph_object.out
rename to test/trace_processor/diff_tests/parser/profiling/heap_graph_object.out
diff --git a/test/trace_processor/diff_tests/profiling/heap_graph_reference.out b/test/trace_processor/diff_tests/parser/profiling/heap_graph_reference.out
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/heap_graph_reference.out
rename to test/trace_processor/diff_tests/parser/profiling/heap_graph_reference.out
diff --git a/test/trace_processor/diff_tests/profiling/heap_graph_superclass.textproto b/test/trace_processor/diff_tests/parser/profiling/heap_graph_superclass.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/heap_graph_superclass.textproto
rename to test/trace_processor/diff_tests/parser/profiling/heap_graph_superclass.textproto
diff --git a/test/trace_processor/diff_tests/profiling/heap_graph_two_locations.out b/test/trace_processor/diff_tests/parser/profiling/heap_graph_two_locations.out
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/heap_graph_two_locations.out
rename to test/trace_processor/diff_tests/parser/profiling/heap_graph_two_locations.out
diff --git a/test/trace_processor/diff_tests/profiling/heap_graph_two_locations.textproto b/test/trace_processor/diff_tests/parser/profiling/heap_graph_two_locations.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/heap_graph_two_locations.textproto
rename to test/trace_processor/diff_tests/parser/profiling/heap_graph_two_locations.textproto
diff --git a/test/trace_processor/diff_tests/profiling/heap_profile.textproto b/test/trace_processor/diff_tests/parser/profiling/heap_profile.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/heap_profile.textproto
rename to test/trace_processor/diff_tests/parser/profiling/heap_profile.textproto
diff --git a/test/trace_processor/diff_tests/profiling/heap_profile_data_local_tmp.textproto b/test/trace_processor/diff_tests/parser/profiling/heap_profile_data_local_tmp.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/heap_profile_data_local_tmp.textproto
rename to test/trace_processor/diff_tests/parser/profiling/heap_profile_data_local_tmp.textproto
diff --git a/test/trace_processor/diff_tests/profiling/heap_profile_deobfuscate.textproto b/test/trace_processor/diff_tests/parser/profiling/heap_profile_deobfuscate.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/heap_profile_deobfuscate.textproto
rename to test/trace_processor/diff_tests/parser/profiling/heap_profile_deobfuscate.textproto
diff --git a/test/trace_processor/diff_tests/profiling/heap_profile_deobfuscate_memfd.textproto b/test/trace_processor/diff_tests/parser/profiling/heap_profile_deobfuscate_memfd.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/heap_profile_deobfuscate_memfd.textproto
rename to test/trace_processor/diff_tests/parser/profiling/heap_profile_deobfuscate_memfd.textproto
diff --git a/test/trace_processor/diff_tests/profiling/heap_profile_deobfuscate_test.sql b/test/trace_processor/diff_tests/parser/profiling/heap_profile_deobfuscate_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/heap_profile_deobfuscate_test.sql
rename to test/trace_processor/diff_tests/parser/profiling/heap_profile_deobfuscate_test.sql
diff --git a/test/trace_processor/diff_tests/profiling/heap_profile_dump_max.textproto b/test/trace_processor/diff_tests/parser/profiling/heap_profile_dump_max.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/heap_profile_dump_max.textproto
rename to test/trace_processor/diff_tests/parser/profiling/heap_profile_dump_max.textproto
diff --git a/test/trace_processor/diff_tests/profiling/heap_profile_dump_max_legacy.textproto b/test/trace_processor/diff_tests/parser/profiling/heap_profile_dump_max_legacy.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/heap_profile_dump_max_legacy.textproto
rename to test/trace_processor/diff_tests/parser/profiling/heap_profile_dump_max_legacy.textproto
diff --git a/test/trace_processor/diff_tests/profiling/heap_profile_flamegraph_system-server-native-profile.out b/test/trace_processor/diff_tests/parser/profiling/heap_profile_flamegraph_system-server-native-profile.out
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/heap_profile_flamegraph_system-server-native-profile.out
rename to test/trace_processor/diff_tests/parser/profiling/heap_profile_flamegraph_system-server-native-profile.out
diff --git a/test/trace_processor/diff_tests/profiling/heap_profile_jit.textproto b/test/trace_processor/diff_tests/parser/profiling/heap_profile_jit.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/heap_profile_jit.textproto
rename to test/trace_processor/diff_tests/parser/profiling/heap_profile_jit.textproto
diff --git a/test/trace_processor/diff_tests/profiling/heap_profile_tracker_new_stack.textproto b/test/trace_processor/diff_tests/parser/profiling/heap_profile_tracker_new_stack.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/heap_profile_tracker_new_stack.textproto
rename to test/trace_processor/diff_tests/parser/profiling/heap_profile_tracker_new_stack.textproto
diff --git a/test/trace_processor/diff_tests/profiling/heap_profile_tracker_twoheaps.textproto b/test/trace_processor/diff_tests/parser/profiling/heap_profile_tracker_twoheaps.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/heap_profile_tracker_twoheaps.textproto
rename to test/trace_processor/diff_tests/parser/profiling/heap_profile_tracker_twoheaps.textproto
diff --git a/test/trace_processor/diff_tests/profiling/perf_sample_rvc.out b/test/trace_processor/diff_tests/parser/profiling/perf_sample_rvc.out
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/perf_sample_rvc.out
rename to test/trace_processor/diff_tests/parser/profiling/perf_sample_rvc.out
diff --git a/test/trace_processor/diff_tests/profiling/perf_sample_sc.out b/test/trace_processor/diff_tests/parser/profiling/perf_sample_sc.out
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/perf_sample_sc.out
rename to test/trace_processor/diff_tests/parser/profiling/perf_sample_sc.out
diff --git a/test/trace_processor/diff_tests/profiling/perf_sample_switch_interp.textproto b/test/trace_processor/diff_tests/parser/profiling/perf_sample_switch_interp.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/perf_sample_switch_interp.textproto
rename to test/trace_processor/diff_tests/parser/profiling/perf_sample_switch_interp.textproto
diff --git a/test/trace_processor/diff_tests/profiling/stack_profile_symbols.out b/test/trace_processor/diff_tests/parser/profiling/stack_profile_symbols.out
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/stack_profile_symbols.out
rename to test/trace_processor/diff_tests/parser/profiling/stack_profile_symbols.out
diff --git a/test/trace_processor/diff_tests/profiling/tests.py b/test/trace_processor/diff_tests/parser/profiling/tests.py
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/tests.py
rename to test/trace_processor/diff_tests/parser/profiling/tests.py
diff --git a/test/trace_processor/diff_tests/profiling/tests_heap_graph.py b/test/trace_processor/diff_tests/parser/profiling/tests_heap_graph.py
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/tests_heap_graph.py
rename to test/trace_processor/diff_tests/parser/profiling/tests_heap_graph.py
diff --git a/test/trace_processor/diff_tests/profiling/tests_heap_profiling.py b/test/trace_processor/diff_tests/parser/profiling/tests_heap_profiling.py
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/tests_heap_profiling.py
rename to test/trace_processor/diff_tests/parser/profiling/tests_heap_profiling.py
diff --git a/test/trace_processor/diff_tests/profiling/tests_llvm_symbolizer.py b/test/trace_processor/diff_tests/parser/profiling/tests_llvm_symbolizer.py
similarity index 100%
rename from test/trace_processor/diff_tests/profiling/tests_llvm_symbolizer.py
rename to test/trace_processor/diff_tests/parser/profiling/tests_llvm_symbolizer.py
diff --git a/test/trace_processor/diff_tests/performance/cpu_frequency_limits.textproto b/test/trace_processor/diff_tests/parser/sched/cpu_frequency_limits.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/performance/cpu_frequency_limits.textproto
rename to test/trace_processor/diff_tests/parser/sched/cpu_frequency_limits.textproto
diff --git a/test/trace_processor/diff_tests/scheduler/sched_cpu_util_cfs.textproto b/test/trace_processor/diff_tests/parser/sched/sched_cpu_util_cfs.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/scheduler/sched_cpu_util_cfs.textproto
rename to test/trace_processor/diff_tests/parser/sched/sched_cpu_util_cfs.textproto
diff --git a/test/trace_processor/diff_tests/scheduler/sched_cpu_util_cfs_test.sql b/test/trace_processor/diff_tests/parser/sched/sched_cpu_util_cfs_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/scheduler/sched_cpu_util_cfs_test.sql
rename to test/trace_processor/diff_tests/parser/sched/sched_cpu_util_cfs_test.sql
diff --git a/test/trace_processor/diff_tests/performance/tests.py b/test/trace_processor/diff_tests/parser/sched/tests.py
similarity index 74%
rename from test/trace_processor/diff_tests/performance/tests.py
rename to test/trace_processor/diff_tests/parser/sched/tests.py
index 7358373..ea04126 100644
--- a/test/trace_processor/diff_tests/performance/tests.py
+++ b/test/trace_processor/diff_tests/parser/sched/tests.py
@@ -19,14 +19,7 @@
from python.generators.diff_tests.testing import TestSuite
-class Performance(TestSuite):
- # IRQ max runtime and count over 1ms
- def test_irq_runtime_metric(self):
- return DiffTestBlueprint(
- trace=Path('irq_runtime_metric.textproto'),
- query=Metric('android_irq_runtime'),
- out=Path('irq_runtime_metric.out'))
-
+class SchedParser(TestSuite):
# CPU frequency maximum & minimum limits change
def test_cpu_frequency_limits(self):
return DiffTestBlueprint(
@@ -61,9 +54,22 @@
130000000,800000.000000,"Cpu 4 Min"
"""))
- # frame_timeline_metric collects App_Deadline_Missed metrics
- def test_frame_timeline_metric(self):
+ def test_sched_cpu_util_cfs(self):
return DiffTestBlueprint(
- trace=Path('frame_timeline_metric.py'),
- query=Metric('android_frame_timeline_metric'),
- out=Path('frame_timeline_metric.out'))
+ trace=Path('sched_cpu_util_cfs.textproto'),
+ query=Path('sched_cpu_util_cfs_test.sql'),
+ out=Csv("""
+ "name","ts","value"
+ "Cpu 6 Util",10000,1.000000
+ "Cpu 6 Cap",10000,1004.000000
+ "Cpu 6 Nr Running",10000,0.000000
+ "Cpu 7 Util",11000,1.000000
+ "Cpu 7 Cap",11000,1007.000000
+ "Cpu 7 Nr Running",11000,0.000000
+ "Cpu 4 Util",12000,43.000000
+ "Cpu 4 Cap",12000,760.000000
+ "Cpu 4 Nr Running",12000,0.000000
+ "Cpu 5 Util",13000,125.000000
+ "Cpu 5 Cap",13000,757.000000
+ "Cpu 5 Nr Running",13000,1.000000
+ """))
\ No newline at end of file
diff --git a/test/trace_processor/diff_tests/smoke/proxy_power.out b/test/trace_processor/diff_tests/parser/smoke/proxy_power.out
similarity index 100%
rename from test/trace_processor/diff_tests/smoke/proxy_power.out
rename to test/trace_processor/diff_tests/parser/smoke/proxy_power.out
diff --git a/test/trace_processor/diff_tests/smoke/tests.py b/test/trace_processor/diff_tests/parser/smoke/tests.py
similarity index 100%
rename from test/trace_processor/diff_tests/smoke/tests.py
rename to test/trace_processor/diff_tests/parser/smoke/tests.py
diff --git a/test/trace_processor/diff_tests/smoke/tests_compute_metrics.py b/test/trace_processor/diff_tests/parser/smoke/tests_compute_metrics.py
similarity index 100%
rename from test/trace_processor/diff_tests/smoke/tests_compute_metrics.py
rename to test/trace_processor/diff_tests/parser/smoke/tests_compute_metrics.py
diff --git a/test/trace_processor/diff_tests/smoke/tests_json.py b/test/trace_processor/diff_tests/parser/smoke/tests_json.py
similarity index 100%
rename from test/trace_processor/diff_tests/smoke/tests_json.py
rename to test/trace_processor/diff_tests/parser/smoke/tests_json.py
diff --git a/test/trace_processor/diff_tests/smoke/tests_sched_events.py b/test/trace_processor/diff_tests/parser/smoke/tests_sched_events.py
similarity index 97%
rename from test/trace_processor/diff_tests/smoke/tests_sched_events.py
rename to test/trace_processor/diff_tests/parser/smoke/tests_sched_events.py
index 86e39fd..fec730f 100644
--- a/test/trace_processor/diff_tests/smoke/tests_sched_events.py
+++ b/test/trace_processor/diff_tests/parser/smoke/tests_sched_events.py
@@ -56,7 +56,7 @@
# Sched events from sythetic trace
def test_synth_1_smoke(self):
return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
+ trace=Path('../../common/synth_1.py'),
query="""
SELECT
ts,
diff --git a/test/trace_processor/diff_tests/smoke/thread_cpu_time_example_android_trace_30s.out b/test/trace_processor/diff_tests/parser/smoke/thread_cpu_time_example_android_trace_30s.out
similarity index 100%
rename from test/trace_processor/diff_tests/smoke/thread_cpu_time_example_android_trace_30s.out
rename to test/trace_processor/diff_tests/parser/smoke/thread_cpu_time_example_android_trace_30s.out
diff --git a/test/trace_processor/diff_tests/track_event/experimental_slice_layout_depth.py b/test/trace_processor/diff_tests/parser/track_event/experimental_slice_layout_depth.py
similarity index 99%
rename from test/trace_processor/diff_tests/track_event/experimental_slice_layout_depth.py
rename to test/trace_processor/diff_tests/parser/track_event/experimental_slice_layout_depth.py
index 3baf368..25b7668 100644
--- a/test/trace_processor/diff_tests/track_event/experimental_slice_layout_depth.py
+++ b/test/trace_processor/diff_tests/parser/track_event/experimental_slice_layout_depth.py
@@ -21,6 +21,7 @@
import synth_common
from synth_common import ms_to_ns
+
trace = synth_common.create_trace()
track1 = 1234
diff --git a/test/trace_processor/diff_tests/track_event/flow_events_proto_v1.textproto b/test/trace_processor/diff_tests/parser/track_event/flow_events_proto_v1.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/track_event/flow_events_proto_v1.textproto
rename to test/trace_processor/diff_tests/parser/track_event/flow_events_proto_v1.textproto
diff --git a/test/trace_processor/diff_tests/track_event/flow_events_proto_v2.textproto b/test/trace_processor/diff_tests/parser/track_event/flow_events_proto_v2.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/track_event/flow_events_proto_v2.textproto
rename to test/trace_processor/diff_tests/parser/track_event/flow_events_proto_v2.textproto
diff --git a/test/trace_processor/diff_tests/track_event/flow_events_track_event.textproto b/test/trace_processor/diff_tests/parser/track_event/flow_events_track_event.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/track_event/flow_events_track_event.textproto
rename to test/trace_processor/diff_tests/parser/track_event/flow_events_track_event.textproto
diff --git a/test/trace_processor/diff_tests/track_event/legacy_async_event.out b/test/trace_processor/diff_tests/parser/track_event/legacy_async_event.out
similarity index 100%
rename from test/trace_processor/diff_tests/track_event/legacy_async_event.out
rename to test/trace_processor/diff_tests/parser/track_event/legacy_async_event.out
diff --git a/test/trace_processor/diff_tests/track_event/legacy_async_event.textproto b/test/trace_processor/diff_tests/parser/track_event/legacy_async_event.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/track_event/legacy_async_event.textproto
rename to test/trace_processor/diff_tests/parser/track_event/legacy_async_event.textproto
diff --git a/test/trace_processor/diff_tests/track_event/range_of_interest.textproto b/test/trace_processor/diff_tests/parser/track_event/range_of_interest.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/track_event/range_of_interest.textproto
rename to test/trace_processor/diff_tests/parser/track_event/range_of_interest.textproto
diff --git a/test/trace_processor/diff_tests/track_event/tests.py b/test/trace_processor/diff_tests/parser/track_event/tests.py
similarity index 100%
rename from test/trace_processor/diff_tests/track_event/tests.py
rename to test/trace_processor/diff_tests/parser/track_event/tests.py
diff --git a/test/trace_processor/diff_tests/track_event/track_event_args_test.sql b/test/trace_processor/diff_tests/parser/track_event/track_event_args_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/track_event/track_event_args_test.sql
rename to test/trace_processor/diff_tests/parser/track_event/track_event_args_test.sql
diff --git a/test/trace_processor/diff_tests/track_event/track_event_chrome_histogram_sample.textproto b/test/trace_processor/diff_tests/parser/track_event/track_event_chrome_histogram_sample.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/track_event/track_event_chrome_histogram_sample.textproto
rename to test/trace_processor/diff_tests/parser/track_event/track_event_chrome_histogram_sample.textproto
diff --git a/test/trace_processor/diff_tests/track_event/track_event_chrome_histogram_sample_args.out b/test/trace_processor/diff_tests/parser/track_event/track_event_chrome_histogram_sample_args.out
similarity index 100%
rename from test/trace_processor/diff_tests/track_event/track_event_chrome_histogram_sample_args.out
rename to test/trace_processor/diff_tests/parser/track_event/track_event_chrome_histogram_sample_args.out
diff --git a/test/trace_processor/diff_tests/track_event/track_event_counters.textproto b/test/trace_processor/diff_tests/parser/track_event/track_event_counters.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/track_event/track_event_counters.textproto
rename to test/trace_processor/diff_tests/parser/track_event/track_event_counters.textproto
diff --git a/test/trace_processor/diff_tests/track_event/track_event_counters_counters.out b/test/trace_processor/diff_tests/parser/track_event/track_event_counters_counters.out
similarity index 100%
rename from test/trace_processor/diff_tests/track_event/track_event_counters_counters.out
rename to test/trace_processor/diff_tests/parser/track_event/track_event_counters_counters.out
diff --git a/test/trace_processor/diff_tests/track_event/track_event_merged_debug_annotations.textproto b/test/trace_processor/diff_tests/parser/track_event/track_event_merged_debug_annotations.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/track_event/track_event_merged_debug_annotations.textproto
rename to test/trace_processor/diff_tests/parser/track_event/track_event_merged_debug_annotations.textproto
diff --git a/test/trace_processor/diff_tests/track_event/track_event_merged_debug_annotations_args.out b/test/trace_processor/diff_tests/parser/track_event/track_event_merged_debug_annotations_args.out
similarity index 100%
rename from test/trace_processor/diff_tests/track_event/track_event_merged_debug_annotations_args.out
rename to test/trace_processor/diff_tests/parser/track_event/track_event_merged_debug_annotations_args.out
diff --git a/test/trace_processor/diff_tests/track_event/track_event_tracks.textproto b/test/trace_processor/diff_tests/parser/track_event/track_event_tracks.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/track_event/track_event_tracks.textproto
rename to test/trace_processor/diff_tests/parser/track_event/track_event_tracks.textproto
diff --git a/test/trace_processor/diff_tests/track_event/track_event_tracks_slices.out b/test/trace_processor/diff_tests/parser/track_event/track_event_tracks_slices.out
similarity index 100%
rename from test/trace_processor/diff_tests/track_event/track_event_tracks_slices.out
rename to test/trace_processor/diff_tests/parser/track_event/track_event_tracks_slices.out
diff --git a/test/trace_processor/diff_tests/track_event/track_event_typed_args.textproto b/test/trace_processor/diff_tests/parser/track_event/track_event_typed_args.textproto
similarity index 82%
rename from test/trace_processor/diff_tests/track_event/track_event_typed_args.textproto
rename to test/trace_processor/diff_tests/parser/track_event/track_event_typed_args.textproto
index b2d9208..a85ef2c 100644
--- a/test/trace_processor/diff_tests/track_event/track_event_typed_args.textproto
+++ b/test/trace_processor/diff_tests/parser/track_event/track_event_typed_args.textproto
@@ -72,6 +72,8 @@
}
[perfetto.protos.TestExtension.string_extension_for_testing]:
"an extension string!"
+ [perfetto.protos.TestExtension.string_extension_for_testing2]:
+ "a second extension string!"
[perfetto.protos.TestExtension.int_extension_for_testing]: 42
[perfetto.protos.TestExtension.int_extension_for_testing]: 1337
[perfetto.protos.TestExtension.omitted_extension_for_testing]:
@@ -99,6 +101,7 @@
extension_set {
file {
package: "perfetto.protos"
+ name: "test_track_event_extensions.proto"
message_type {
extension {
name: "string_extension_for_testing"
@@ -143,6 +146,30 @@
}
}
}
+# Test that a field specified in a second descriptor for the same proto file is
+# also detected. This emulates the case of multiple instances of the same app
+# (e.g. Chrome Beta + Chrome Canary) both emitting a descriptor.
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 5001
+ extension_descriptor {
+ extension_set {
+ file {
+ package: "perfetto.protos"
+ name: "test_track_event_extensions.proto"
+ message_type {
+ extension {
+ name: "string_extension_for_testing2"
+ extendee: ".perfetto.protos.TrackEvent"
+ number: 9905
+ type: TYPE_STRING
+ label: LABEL_OPTIONAL
+ }
+ }
+ }
+ }
+ }
+}
packet {
trusted_packet_sequence_id: 1
timestamp: 6000
diff --git a/test/trace_processor/diff_tests/track_event/track_event_typed_args_args.out b/test/trace_processor/diff_tests/parser/track_event/track_event_typed_args_args.out
similarity index 96%
rename from test/trace_processor/diff_tests/track_event/track_event_typed_args_args.out
rename to test/trace_processor/diff_tests/parser/track_event/track_event_typed_args_args.out
index cb6ade4..47a173a 100644
--- a/test/trace_processor/diff_tests/track_event/track_event_typed_args_args.out
+++ b/test/trace_processor/diff_tests/parser/track_event/track_event_typed_args_args.out
@@ -37,3 +37,4 @@
"source_id","source_id",1,"[NULL]"
"source_location_iid","source_location_iid",1,"[NULL]"
"string_extension_for_testing","string_extension_for_testing","[NULL]","an extension string!"
+"string_extension_for_testing2","string_extension_for_testing2","[NULL]","a second extension string!"
diff --git a/test/trace_processor/diff_tests/track_event/track_event_with_atrace.textproto b/test/trace_processor/diff_tests/parser/track_event/track_event_with_atrace.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/track_event/track_event_with_atrace.textproto
rename to test/trace_processor/diff_tests/parser/track_event/track_event_with_atrace.textproto
diff --git a/test/trace_processor/diff_tests/track_event/track_event_with_atrace_separate_tracks.textproto b/test/trace_processor/diff_tests/parser/track_event/track_event_with_atrace_separate_tracks.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/track_event/track_event_with_atrace_separate_tracks.textproto
rename to test/trace_processor/diff_tests/parser/track_event/track_event_with_atrace_separate_tracks.textproto
diff --git a/test/trace_processor/diff_tests/translation/chrome_args_test.sql b/test/trace_processor/diff_tests/parser/translated_args/chrome_args_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/translation/chrome_args_test.sql
rename to test/trace_processor/diff_tests/parser/translated_args/chrome_args_test.sql
diff --git a/test/trace_processor/diff_tests/translation/chrome_histogram.out b/test/trace_processor/diff_tests/parser/translated_args/chrome_histogram.out
similarity index 100%
rename from test/trace_processor/diff_tests/translation/chrome_histogram.out
rename to test/trace_processor/diff_tests/parser/translated_args/chrome_histogram.out
diff --git a/test/trace_processor/diff_tests/translation/chrome_histogram.textproto b/test/trace_processor/diff_tests/parser/translated_args/chrome_histogram.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/translation/chrome_histogram.textproto
rename to test/trace_processor/diff_tests/parser/translated_args/chrome_histogram.textproto
diff --git a/test/trace_processor/diff_tests/translation/chrome_performance_mark.out b/test/trace_processor/diff_tests/parser/translated_args/chrome_performance_mark.out
similarity index 100%
rename from test/trace_processor/diff_tests/translation/chrome_performance_mark.out
rename to test/trace_processor/diff_tests/parser/translated_args/chrome_performance_mark.out
diff --git a/test/trace_processor/diff_tests/translation/chrome_user_event.out b/test/trace_processor/diff_tests/parser/translated_args/chrome_user_event.out
similarity index 100%
rename from test/trace_processor/diff_tests/translation/chrome_user_event.out
rename to test/trace_processor/diff_tests/parser/translated_args/chrome_user_event.out
diff --git a/test/trace_processor/diff_tests/translation/chrome_user_event.textproto b/test/trace_processor/diff_tests/parser/translated_args/chrome_user_event.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/translation/chrome_user_event.textproto
rename to test/trace_processor/diff_tests/parser/translated_args/chrome_user_event.textproto
diff --git a/test/trace_processor/diff_tests/translation/java_class_name_arg.out b/test/trace_processor/diff_tests/parser/translated_args/java_class_name_arg.out
similarity index 100%
rename from test/trace_processor/diff_tests/translation/java_class_name_arg.out
rename to test/trace_processor/diff_tests/parser/translated_args/java_class_name_arg.out
diff --git a/test/trace_processor/diff_tests/translation/java_class_name_arg.textproto b/test/trace_processor/diff_tests/parser/translated_args/java_class_name_arg.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/translation/java_class_name_arg.textproto
rename to test/trace_processor/diff_tests/parser/translated_args/java_class_name_arg.textproto
diff --git a/test/trace_processor/diff_tests/translation/native_symbol_arg.out b/test/trace_processor/diff_tests/parser/translated_args/native_symbol_arg.out
similarity index 100%
rename from test/trace_processor/diff_tests/translation/native_symbol_arg.out
rename to test/trace_processor/diff_tests/parser/translated_args/native_symbol_arg.out
diff --git a/test/trace_processor/diff_tests/translation/native_symbol_arg.textproto b/test/trace_processor/diff_tests/parser/translated_args/native_symbol_arg.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/translation/native_symbol_arg.textproto
rename to test/trace_processor/diff_tests/parser/translated_args/native_symbol_arg.textproto
diff --git a/test/trace_processor/diff_tests/translation/native_symbol_arg_incomplete.textproto b/test/trace_processor/diff_tests/parser/translated_args/native_symbol_arg_incomplete.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/translation/native_symbol_arg_incomplete.textproto
rename to test/trace_processor/diff_tests/parser/translated_args/native_symbol_arg_incomplete.textproto
diff --git a/test/trace_processor/diff_tests/translation/slice_name.textproto b/test/trace_processor/diff_tests/parser/translated_args/slice_name.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/translation/slice_name.textproto
rename to test/trace_processor/diff_tests/parser/translated_args/slice_name.textproto
diff --git a/test/trace_processor/diff_tests/translation/slice_name_negative_timestamp.textproto b/test/trace_processor/diff_tests/parser/translated_args/slice_name_negative_timestamp.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/translation/slice_name_negative_timestamp.textproto
rename to test/trace_processor/diff_tests/parser/translated_args/slice_name_negative_timestamp.textproto
diff --git a/test/trace_processor/diff_tests/translation/tests.py b/test/trace_processor/diff_tests/parser/translated_args/tests.py
similarity index 98%
rename from test/trace_processor/diff_tests/translation/tests.py
rename to test/trace_processor/diff_tests/parser/translated_args/tests.py
index 9856205..7e28f38 100644
--- a/test/trace_processor/diff_tests/translation/tests.py
+++ b/test/trace_processor/diff_tests/parser/translated_args/tests.py
@@ -19,7 +19,7 @@
from python.generators.diff_tests.testing import TestSuite
-class Translation(TestSuite):
+class TranslatedArgs(TestSuite):
def test_java_class_name_arg(self):
return DiffTestBlueprint(
diff --git a/test/trace_processor/diff_tests/ufs/tests.py b/test/trace_processor/diff_tests/parser/ufs/tests.py
similarity index 100%
rename from test/trace_processor/diff_tests/ufs/tests.py
rename to test/trace_processor/diff_tests/parser/ufs/tests.py
diff --git a/test/trace_processor/diff_tests/ufs/ufshcd_command.textproto b/test/trace_processor/diff_tests/parser/ufs/ufshcd_command.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/ufs/ufshcd_command.textproto
rename to test/trace_processor/diff_tests/parser/ufs/ufshcd_command.textproto
diff --git a/test/trace_processor/diff_tests/ufs/ufshcd_command_tag.textproto b/test/trace_processor/diff_tests/parser/ufs/ufshcd_command_tag.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/ufs/ufshcd_command_tag.textproto
rename to test/trace_processor/diff_tests/parser/ufs/ufshcd_command_tag.textproto
diff --git a/test/trace_processor/diff_tests/scheduler/tests.py b/test/trace_processor/diff_tests/scheduler/tests.py
deleted file mode 100644
index b935c6a..0000000
--- a/test/trace_processor/diff_tests/scheduler/tests.py
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/usr/bin/env python3
-# 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 a
-#
-# 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, Json, TextProto
-from python.generators.diff_tests.testing import DiffTestBlueprint
-from python.generators.diff_tests.testing import TestSuite
-
-
-class Scheduler(TestSuite):
- # Scheduler
- def test_sched_cpu_util_cfs(self):
- return DiffTestBlueprint(
- trace=Path('sched_cpu_util_cfs.textproto'),
- query=Path('sched_cpu_util_cfs_test.sql'),
- out=Csv("""
- "name","ts","value"
- "Cpu 6 Util",10000,1.000000
- "Cpu 6 Cap",10000,1004.000000
- "Cpu 6 Nr Running",10000,0.000000
- "Cpu 7 Util",11000,1.000000
- "Cpu 7 Cap",11000,1007.000000
- "Cpu 7 Nr Running",11000,0.000000
- "Cpu 4 Util",12000,43.000000
- "Cpu 4 Cap",12000,760.000000
- "Cpu 4 Nr Running",12000,0.000000
- "Cpu 5 Util",13000,125.000000
- "Cpu 5 Cap",13000,757.000000
- "Cpu 5 Nr Running",13000,1.000000
- """))
diff --git a/test/trace_processor/diff_tests/android/android_battery_stats_event_slices.out b/test/trace_processor/diff_tests/stdlib/android/android_battery_stats_event_slices.out
similarity index 100%
rename from test/trace_processor/diff_tests/android/android_battery_stats_event_slices.out
rename to test/trace_processor/diff_tests/stdlib/android/android_battery_stats_event_slices.out
diff --git a/test/trace_processor/diff_tests/android/android_battery_stats_state.out b/test/trace_processor/diff_tests/stdlib/android/android_battery_stats_state.out
similarity index 100%
rename from test/trace_processor/diff_tests/android/android_battery_stats_state.out
rename to test/trace_processor/diff_tests/stdlib/android/android_battery_stats_state.out
diff --git a/test/trace_processor/diff_tests/android/android_slice_standardization.out b/test/trace_processor/diff_tests/stdlib/android/android_slice_standardization.out
similarity index 100%
rename from test/trace_processor/diff_tests/android/android_slice_standardization.out
rename to test/trace_processor/diff_tests/stdlib/android/android_slice_standardization.out
diff --git a/test/trace_processor/diff_tests/android/android_slice_standardization.py b/test/trace_processor/diff_tests/stdlib/android/android_slice_standardization.py
similarity index 77%
rename from test/trace_processor/diff_tests/android/android_slice_standardization.py
rename to test/trace_processor/diff_tests/stdlib/android/android_slice_standardization.py
index a0556df..dc75d91 100644
--- a/test/trace_processor/diff_tests/android/android_slice_standardization.py
+++ b/test/trace_processor/diff_tests/stdlib/android/android_slice_standardization.py
@@ -21,13 +21,12 @@
trace = synth_common.create_trace()
trace.add_packet()
-trace.add_package_list(ts=0, name="com.android.systemui", uid=SYSUI_PID,
- version_code=1)
-trace.add_process(pid=SYSUI_PID, ppid=0, cmdline="com.android.systemui",
- uid=SYSUI_PID)
+trace.add_package_list(
+ ts=0, name="com.android.systemui", uid=SYSUI_PID, version_code=1)
+trace.add_process(
+ pid=SYSUI_PID, ppid=0, cmdline="com.android.systemui", uid=SYSUI_PID)
trace.add_ftrace_packet(cpu=0)
-
slices_to_standardize = [
"Lock contention on thread list lock (owner tid: 1665)",
"monitor contention with owner BG Thread #1 (30) at",
@@ -43,9 +42,9 @@
]
for name in slices_to_standardize:
- trace.add_atrace_async_begin(ts=1_000_000, tid=SYSUI_PID, pid=SYSUI_PID,
- buf=name)
- trace.add_atrace_async_end(ts=2_000_000, tid=SYSUI_PID, pid=SYSUI_PID,
- buf=name)
+ trace.add_atrace_async_begin(
+ ts=1_000_000, tid=SYSUI_PID, pid=SYSUI_PID, buf=name)
+ trace.add_atrace_async_end(
+ ts=2_000_000, tid=SYSUI_PID, pid=SYSUI_PID, buf=name)
sys.stdout.buffer.write(trace.trace.SerializeToString())
diff --git a/test/trace_processor/diff_tests/android/tests.py b/test/trace_processor/diff_tests/stdlib/android/tests.py
similarity index 72%
rename from test/trace_processor/diff_tests/android/tests.py
rename to test/trace_processor/diff_tests/stdlib/android/tests.py
index 8bbbeb7..3d143a8 100644
--- a/test/trace_processor/diff_tests/android/tests.py
+++ b/test/trace_processor/diff_tests/stdlib/android/tests.py
@@ -19,97 +19,8 @@
from python.generators.diff_tests.testing import TestSuite
from python.generators.diff_tests.testing import PrintProfileProto
-class Android(TestSuite):
- def test_android_system_property_counter(self):
- return DiffTestBlueprint(
- trace=TextProto(r"""
- packet {
- timestamp: 1000
- android_system_property {
- values {
- name: "debug.tracing.screen_state"
- value: "2"
- }
- values {
- name: "debug.tracing.device_state"
- value: "some_state_from_sysprops"
- }
- }
- }
- packet {
- ftrace_events {
- cpu: 1
- event {
- timestamp: 2000
- pid: 1
- print {
- buf: "C|1000|ScreenState|1\n"
- }
- }
- event {
- timestamp: 3000
- pid: 1
- print {
- buf: "N|1000|DeviceStateChanged|some_state_from_atrace\n"
- }
- }
- }
- }
- """),
- query="""
- SELECT t.type, t.name, c.id, c.ts, c.type, c.value
- FROM counter_track t JOIN counter c ON t.id = c.track_id
- WHERE name = 'ScreenState';
- """,
- out=Csv("""
- "type","name","id","ts","type","value"
- "counter_track","ScreenState",0,1000,"counter",2.000000
- "counter_track","ScreenState",1,2000,"counter",1.000000
- """))
-
- def test_android_system_property_slice(self):
- return DiffTestBlueprint(
- trace=TextProto(r"""
- packet {
- timestamp: 1000
- android_system_property {
- values {
- name: "debug.tracing.screen_state"
- value: "2"
- }
- values {
- name: "debug.tracing.device_state"
- value: "some_state_from_sysprops"
- }
- }
- }
- packet {
- ftrace_events {
- cpu: 1
- event {
- timestamp: 2000
- pid: 1
- print {
- buf: "C|1000|ScreenState|1\n"
- }
- }
- event {
- timestamp: 3000
- pid: 1
- print {
- buf: "N|1000|DeviceStateChanged|some_state_from_atrace\n"
- }
- }
- }
- }
- """),
- query="""
- SELECT t.type, t.name, s.id, s.ts, s.dur, s.type, s.name
- FROM track t JOIN slice s ON s.track_id = t.id
- WHERE t.name = 'DeviceStateChanged';
- """,
- out=Path('android_system_property_slice.out'))
+class AndroidStdlib(TestSuite):
def test_android_battery_stats_event_slices(self):
# The following has three events
@@ -196,90 +107,9 @@
""",
out=Path('android_battery_stats_state.out'))
- def test_android_network_activity(self):
- # The following should have three activity regions:
- # * uid=123 from 1000 to 2010 (note: end is max(ts)+idle_ns)
- # * uid=456 from 1005 to 3115 (note: doesn't group with above due to name)
- # * Also tests that groups form based on (ts+dur), not just start ts.
- # * uid=123 from 3000 to 5500 (note: gap between 1010 to 3000 > idle_ns)
- # Note: packet_timestamps are delta encoded from the base timestamp.
- return DiffTestBlueprint(
- trace=TextProto(r"""
- packet {
- timestamp: 0
- network_packet_bundle {
- ctx {
- direction: DIR_EGRESS
- interface: "wlan"
- uid: 123
- }
- packet_timestamps: [
- 1000, 1010,
- 3000, 3050, 4000, 4500
- ],
- packet_lengths: [
- 50, 50,
- 50, 50, 50, 50
- ],
- }
- }
- packet {
- timestamp: 1005
- network_packet_bundle {
- ctx {
- direction: DIR_EGRESS
- interface: "wlan"
- uid: 456
- }
- total_duration: 100
- total_packets: 2
- total_length: 300
- }
- }
- packet {
- timestamp: 2015
- network_packet_bundle {
- ctx {
- direction: DIR_EGRESS
- interface: "wlan"
- uid: 456
- }
- total_duration: 100
- total_packets: 1
- total_length: 50
- }
- }
- packet {
- timestamp: 0
- network_packet_bundle {
- ctx {
- direction: DIR_INGRESS
- interface: "loopback"
- uid: 123
- }
- packet_timestamps: [6000]
- packet_lengths: [100]
- }
- }
- """),
- query="""
- SELECT RUN_METRIC(
- 'android/network_activity_template.sql',
- 'view_name', 'android_network_activity',
- 'group_by', 'package_name',
- 'filter', 'iface = "wlan"',
- 'idle_ns', '1000',
- 'quant_ns', '100'
- );
-
- SELECT * FROM android_network_activity
- ORDER BY package_name, ts;
- """,
- out=Path('android_network_activity.out'))
-
def test_anrs(self):
return DiffTestBlueprint(
- trace=Path('android_anr_metric.py'),
+ trace=Path('../../metrics/android/android_anr_metric.py'),
query="""
INCLUDE PERFETTO MODULE android.anrs;
SELECT *
@@ -292,12 +122,6 @@
"com.google.android.app3","[NULL]","[NULL]","c25916a0-a8f0-41f3-87df-319e06471a0f",3000,"[NULL]"
"""))
- def test_anr_metric(self):
- return DiffTestBlueprint(
- trace=Path('android_anr_metric.py'),
- query=Metric('android_anr'),
- out=Path('android_anr_metric.out'))
-
def test_binder_sync_binder_metrics(self):
return DiffTestBlueprint(
trace=DataPath('android_binder_metric_trace.atr'),
@@ -390,116 +214,6 @@
34382,25505818197,492,34383,25505891588,1596,"binder_reply","filemap_fault",864664,1
"""))
- def test_binder_txn_sync_good(self):
- return DiffTestBlueprint(
- trace=Systrace(
-""" client-521390 [005] ..... 137012.464739: binder_command: cmd=0x40406300 BC_TRANSACTION
- client-521390 [005] ..... 137012.464741: binder_transaction: transaction=5149 dest_node=5143 dest_proc=521383 dest_thread=0 reply=0 flags=0x0 code=0x3
- server-521383 [004] ..... 137012.464771: binder_transaction_received: transaction=5149
- server-521383 [004] ..... 137012.464772: binder_return: cmd=0x80407202 BR_TRANSACTION
- server-521383 [004] ..... 137012.464815: binder_command: cmd=0x40086303 BC_FREE_BUFFER
- server-521383 [004] ..... 137012.464823: binder_command: cmd=0x40406301 BC_REPLY
- server-521383 [004] ..... 137012.464826: binder_transaction: transaction=5150 dest_node=0 dest_proc=521390 dest_thread=521390 reply=1 flags=0x20 code=0x3
- server-521383 [004] ..... 137012.464837: binder_return: cmd=0x7206 BR_TRANSACTION_COMPLETE
- client-521390 [005] ..... 137012.464847: binder_return: cmd=0x7206 BR_TRANSACTION_COMPLETE
- client-521390 [005] ..... 137012.464848: binder_transaction_received: transaction=5150
- client-521390 [005] ..... 137012.464849: binder_return: cmd=0x80407203 BR_REPLY
- """),
- query="""
- SELECT
- dur
- FROM slice
- ORDER BY dur;
- """,
- out=Csv("""
- "dur"
- 55000
- 107000
- """))
-
- def test_binder_txn_sync_bad_request(self):
- return DiffTestBlueprint(
- trace=Systrace(
-""" client-521349 [005] ..... 137004.281009: binder_command: cmd=0x40406300 BC_TRANSACTION
- client-521349 [005] ..... 137004.281010: binder_transaction: transaction=5135 dest_node=5129 dest_proc=521347 dest_thread=0 reply=0 flags=0x0 code=0x3
- client-521349 [005] ..... 137004.281410: binder_return: cmd=0x7211 BR_FAILED_REPLY
- """),
- query="""
- SELECT
- dur
- FROM slice
- ORDER BY dur;
- """,
- out=Csv("""
- "dur"
- 400000
- """))
-
- def test_binder_txn_sync_bad_reply(self):
- return DiffTestBlueprint(
- trace=Systrace(
-""" client-521332 [007] ..... 136996.112660: binder_command: cmd=0x40406300 BC_TRANSACTION
- client-521332 [007] ..... 136996.112662: binder_transaction: transaction=5120 dest_node=5114 dest_proc=521330 dest_thread=0 reply=0 flags=0x0 code=0x3
- server-521330 [000] ..... 136996.112714: binder_transaction_received: transaction=5120
- server-521330 [000] ..... 136996.112715: binder_return: cmd=0x80407202 BR_TRANSACTION
- server-521330 [000] ..... 136996.112752: binder_command: cmd=0x40086303 BC_FREE_BUFFER
- server-521330 [000] ..... 136996.112758: binder_command: cmd=0x40406301 BC_REPLY
- server-521330 [000] ..... 136996.112760: binder_transaction: transaction=5121 dest_node=0 dest_proc=521332 dest_thread=521332 reply=1 flags=0x20 code=0x3
- server-521330 [000] ..... 136996.113163: binder_return: cmd=0x7206 BR_TRANSACTION_COMPLETE
- client-521332 [007] ..... 136996.113201: binder_return: cmd=0x7206 BR_TRANSACTION_COMPLETE
- client-521332 [007] ..... 136996.113201: binder_return: cmd=0x7211 BR_FAILED_REPLY
- """),
- query="""
- SELECT
- dur
- FROM slice
- ORDER BY dur;
- """,
- out=Csv("""
- "dur"
- 46000
- 539000
- """))
-
- def test_binder_txn_oneway_good(self):
- return DiffTestBlueprint(
- trace=Systrace(
-""" client-521406 [003] ..... 137020.679833: binder_command: cmd=0x40406300 BC_TRANSACTION
- client-521406 [003] ..... 137020.679834: binder_transaction: transaction=5161 dest_node=5155 dest_proc=521404 dest_thread=0 reply=0 flags=0x1 code=0x3
- client-521406 [003] ..... 137020.679843: binder_return: cmd=0x7206 BR_TRANSACTION_COMPLETE
- server-521404 [006] ..... 137020.679890: binder_transaction_received: transaction=5161
- server-521404 [006] ..... 137020.679890: binder_return: cmd=0x80407202 BR_TRANSACTION
- """),
- query="""
- SELECT
- dur
- FROM slice
- ORDER BY dur;
- """,
- out=Csv("""
- "dur"
- 0
- 0
- """))
-
- def test_binder_metric(self):
- return DiffTestBlueprint(
- trace=DataPath('android_binder_metric_trace.atr'),
- query=Metric('android_binder'),
- out=Path('android_binder_metric.out'))
-
- def test_android_blocking_calls_cuj(self):
- return DiffTestBlueprint(
- trace=Path('android_blocking_calls_cuj_metric.py'),
- query=Metric('android_blocking_calls_cuj_metric'),
- out=Path('android_blocking_calls_cuj_metric.out'))
-
- def test_android_blocking_calls_on_jank_cujs(self):
- return DiffTestBlueprint(
- trace=Path('../graphics/android_jank_cuj.py'),
- query=Metric('android_blocking_calls_cuj_metric'),
- out=Path('android_blocking_calls_on_jank_cuj_metric.out'))
-
def test_android_slices_standardization_for_aggregation(self):
return DiffTestBlueprint(
trace=Path('android_slice_standardization.py'),
@@ -511,12 +225,6 @@
""",
out=Path('android_slice_standardization.out'))
- def test_android_sysui_notifications_blocking_calls(self):
- return DiffTestBlueprint(
- trace=Path('android_sysui_notifications_blocking_calls_metric.py'),
- query=Metric('android_sysui_notifications_blocking_calls_metric'),
- out=Path('android_sysui_notifications_blocking_calls_metric.out'))
-
def test_monitor_contention_extraction(self):
return DiffTestBlueprint(
trace=DataPath('android_monitor_contention_trace.atr'),
@@ -587,47 +295,6 @@
949,"void com.android.server.am.ActivityManagerService$AppDeathRecipient.binderDied()","int com.android.server.am.ActivityManagerService.getMemoryTrimLevel()","com.android.server.am.ActivityManagerService$AppDeathRecipient.binderDied","com.android.server.am.ActivityManagerService.getMemoryTrimLevel","ActivityManagerService.java:1478","ActivityManagerService.java:9183",1,250,"system_server",656,"binder:642_12",2720,250,"system_server",956,1737123891932,17577143,1215,1,642,0,2720,"[NULL]","[NULL]","[NULL]",642,"[NULL]"
"""))
- def test_monitor_contention_metric(self):
- return DiffTestBlueprint(
- trace=DataPath('android_monitor_contention_trace.atr'),
- query=Metric('android_monitor_contention'),
- out=Path('android_monitor_contention.out'))
-
- def test_monitor_contention_agg_metric(self):
- return DiffTestBlueprint(
- trace=DataPath('android_monitor_contention_trace.atr'),
- query=Metric('android_monitor_contention_agg'),
- out=TextProto(r"""
- android_monitor_contention_agg {
- process_aggregation {
- name: "android.process.media"
- total_contention_count: 12
- total_contention_dur: 12893198
- main_thread_contention_count: 12
- main_thread_contention_dur: 12893198
- }
- process_aggregation {
- name: "com.android.providers.media.module"
- total_contention_count: 7
- total_contention_dur: 169793
- }
- process_aggregation {
- name: "com.android.systemui"
- total_contention_count: 8
- total_contention_dur: 9445959
- main_thread_contention_count: 5
- main_thread_contention_dur: 9228582
- }
- process_aggregation {
- name: "system_server"
- total_contention_count: 354
- total_contention_dur: 358898613
- main_thread_contention_count: 27
- main_thread_contention_dur: 36904702
- }
- }
- """))
-
def test_monitor_contention_graph(self):
return DiffTestBlueprint(
trace=DataPath('android_monitor_contention_trace.atr'),
@@ -1173,16 +840,3 @@
/system/bin/servicemanager (0x0)
/system/bin/storaged (0x0)
"""))
-
- def test_android_boot(self):
- return DiffTestBlueprint(
- trace=DataPath('android_boot.pftrace'),
- query=Metric('android_boot'),
- out=TextProto(r"""
- android_boot {
- system_server_durations {
- total_dur: 267193980530
- uninterruptible_sleep_dur: 3843119529
- }
- }
- """))
diff --git a/test/trace_processor/diff_tests/chrome/chrome_scroll_check.py b/test/trace_processor/diff_tests/stdlib/chrome/chrome_scroll_check.py
similarity index 99%
rename from test/trace_processor/diff_tests/chrome/chrome_scroll_check.py
rename to test/trace_processor/diff_tests/stdlib/chrome/chrome_scroll_check.py
index 5b93959..909ea1d 100644
--- a/test/trace_processor/diff_tests/chrome/chrome_scroll_check.py
+++ b/test/trace_processor/diff_tests/stdlib/chrome/chrome_scroll_check.py
@@ -22,6 +22,7 @@
import synth_common
from synth_common import ms_to_ns
+
trace = synth_common.create_trace()
from chrome_scroll_helper import ChromeScrollHelper
diff --git a/test/trace_processor/diff_tests/chrome/chrome_scroll_helper.py b/test/trace_processor/diff_tests/stdlib/chrome/chrome_scroll_helper.py
similarity index 99%
copy from test/trace_processor/diff_tests/chrome/chrome_scroll_helper.py
copy to test/trace_processor/diff_tests/stdlib/chrome/chrome_scroll_helper.py
index 7b7cee1..77b6e05 100644
--- a/test/trace_processor/diff_tests/chrome/chrome_scroll_helper.py
+++ b/test/trace_processor/diff_tests/stdlib/chrome/chrome_scroll_helper.py
@@ -20,6 +20,7 @@
import synth_common
from synth_common import ms_to_ns
+
trace = synth_common.create_trace()
diff --git a/test/trace_processor/diff_tests/chrome/chrome_speedometer.out b/test/trace_processor/diff_tests/stdlib/chrome/chrome_speedometer.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/chrome_speedometer.out
rename to test/trace_processor/diff_tests/stdlib/chrome/chrome_speedometer.out
diff --git a/test/trace_processor/diff_tests/chrome/chrome_tasks.out b/test/trace_processor/diff_tests/stdlib/chrome/chrome_tasks.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/chrome_tasks.out
rename to test/trace_processor/diff_tests/stdlib/chrome/chrome_tasks.out
diff --git a/test/trace_processor/diff_tests/chrome/scroll_jank_v3.out b/test/trace_processor/diff_tests/stdlib/chrome/scroll_jank_v3.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/scroll_jank_v3.out
rename to test/trace_processor/diff_tests/stdlib/chrome/scroll_jank_v3.out
diff --git a/test/trace_processor/diff_tests/chrome/scroll_jank_v3_percentage.out b/test/trace_processor/diff_tests/stdlib/chrome/scroll_jank_v3_percentage.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/scroll_jank_v3_percentage.out
rename to test/trace_processor/diff_tests/stdlib/chrome/scroll_jank_v3_percentage.out
diff --git a/test/trace_processor/diff_tests/stdlib/chrome/tests.py b/test/trace_processor/diff_tests/stdlib/chrome/tests.py
new file mode 100644
index 0000000..cc709b1
--- /dev/null
+++ b/test/trace_processor/diff_tests/stdlib/chrome/tests.py
@@ -0,0 +1,162 @@
+#!/usr/bin/env python3
+# 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 a
+#
+# 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, Json, TextProto
+from python.generators.diff_tests.testing import DiffTestBlueprint
+from python.generators.diff_tests.testing import TestSuite
+
+
+class ChromeStdlib(TestSuite):
+ # Chrome tasks.
+ def test_chrome_tasks(self):
+ return DiffTestBlueprint(
+ trace=DataPath(
+ 'chrome_page_load_all_categories_not_extended.pftrace.gz'),
+ query="""
+ INCLUDE PERFETTO MODULE chrome.tasks;
+
+ SELECT full_name as name, task_type, count() AS count
+ FROM chrome_tasks
+ GROUP BY full_name, task_type
+ HAVING count >= 5
+ ORDER BY count DESC, name;
+ """,
+ out=Path('chrome_tasks.out'))
+
+ def test_top_level_java_choreographer_slices_top_level_java_chrome_tasks(
+ self):
+ return DiffTestBlueprint(
+ trace=DataPath('top_level_java_choreographer_slices'),
+ query="""
+ INCLUDE PERFETTO MODULE chrome.tasks;
+
+ SELECT
+ full_name,
+ task_type
+ FROM chrome_tasks
+ WHERE category = "toplevel,Java"
+ AND ts < 263904000000000
+ GROUP BY full_name, task_type;
+ """,
+ out=Path(
+ 'top_level_java_choreographer_slices_top_level_java_chrome_tasks_test.out'
+ ))
+
+ # Chrome custom navigation event names
+ def test_chrome_custom_navigation_tasks(self):
+ return DiffTestBlueprint(
+ trace=DataPath('chrome_custom_navigation_trace.gz'),
+ query="""
+ INCLUDE PERFETTO MODULE chrome.tasks;
+
+ SELECT full_name, task_type, count() AS count
+ FROM chrome_tasks
+ WHERE full_name GLOB 'FrameHost::BeginNavigation*'
+ OR full_name GLOB 'FrameHost::DidCommitProvisionalLoad*'
+ OR full_name GLOB 'FrameHost::DidCommitSameDocumentNavigation*'
+ OR full_name GLOB 'FrameHost::DidStopLoading*'
+ GROUP BY full_name, task_type
+ ORDER BY count DESC
+ LIMIT 50;
+ """,
+ out=Csv("""
+ "full_name","task_type","count"
+ "FrameHost::BeginNavigation (SUBFRAME)","navigation_task",5
+ "FrameHost::DidStopLoading (SUBFRAME)","navigation_task",3
+ "FrameHost::BeginNavigation (PRIMARY_MAIN_FRAME)","navigation_task",1
+ "FrameHost::DidCommitProvisionalLoad (SUBFRAME)","navigation_task",1
+ """))
+
+ # Chrome custom navigation event names
+ def test_chrome_histograms(self):
+ return DiffTestBlueprint(
+ trace=DataPath('chrome_5672_histograms.pftrace.gz'),
+ query="""
+ INCLUDE PERFETTO MODULE chrome.histograms;
+
+ SELECT
+ name,
+ count() as count
+ FROM chrome_histograms
+ GROUP BY name
+ ORDER BY count DESC, name
+ LIMIT 20;
+ """,
+ out=Csv("""
+ "name","count"
+ "Net.QuicSession.AsyncRead",19207
+ "Net.QuicSession.NumQueuedPacketsBeforeWrite",19193
+ "RendererScheduler.QueueingDuration.NormalPriority",9110
+ "Net.OnTransferSizeUpdated.Experimental.OverridenBy",8525
+ "Compositing.Renderer.AnimationUpdateOnMissingPropertyNode",3489
+ "Net.QuicConnection.WritePacketStatus",3099
+ "Net.QuicSession.PacketWriteTime.Synchronous",3082
+ "Net.QuicSession.SendPacketSize.ForwardSecure",3012
+ "Net.URLLoaderThrottleExecutionTime.WillStartRequest",1789
+ "Net.URLLoaderThrottleExecutionTime.BeforeWillProcessResponse",1773
+ "Net.URLLoaderThrottleExecutionTime.WillProcessResponse",1773
+ "UMA.StackProfiler.SampleInOrder",1534
+ "GPU.SharedImage.ContentConsumed",1037
+ "Gpu.Rasterization.Raster.MSAASampleCountLog2",825
+ "Scheduling.Renderer.DeadlineMode",637
+ "Blink.CullRect.UpdateTime",622
+ "Scheduling.Renderer.BeginImplFrameLatency2",591
+ "Net.QuicSession.CoalesceStreamFrameStatus",551
+ "API.StorageAccess.AllowedRequests2",541
+ "Net.HttpResponseCode",541
+ """))
+
+ def test_speedometer(self):
+ return DiffTestBlueprint(
+ trace=DataPath('speedometer.perfetto_trace.gz'),
+ query="""
+ INCLUDE PERFETTO MODULE chrome.speedometer;
+
+ SELECT
+ iteration,
+ ts,
+ dur,
+ total,
+ format('%.1f', mean) AS mean,
+ format('%.1f', geomean) AS geomean,
+ format('%.1f', score) AS score,
+ num_measurements
+ FROM
+ chrome_speedometer_iteration,
+ (
+ SELECT iteration, COUNT(*) AS num_measurements
+ FROM chrome_speedometer_measure
+ GROUP BY iteration
+ )
+ USING (iteration)
+ ORDER BY iteration;
+ """,
+ out=Path('chrome_speedometer.out'))
+
+ # CPU power ups
+ def test_cpu_powerups(self):
+ return DiffTestBlueprint(
+ trace=DataPath('cpu_powerups_1.pb'),
+ query="""
+ INCLUDE PERFETTO MODULE chrome.cpu_powerups;
+ SELECT * FROM chrome_cpu_power_first_toplevel_slice_after_powerup;
+ """,
+ out=Csv("""
+ "slice_id","previous_power_state"
+ 424,2
+ 703,2
+ 708,2
+ """))
\ No newline at end of file
diff --git a/test/trace_processor/diff_tests/stdlib/chrome/tests_chrome_interactions.py b/test/trace_processor/diff_tests/stdlib/chrome/tests_chrome_interactions.py
new file mode 100644
index 0000000..5019e54
--- /dev/null
+++ b/test/trace_processor/diff_tests/stdlib/chrome/tests_chrome_interactions.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python3
+# 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 a
+#
+# 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 DataPath
+from python.generators.diff_tests.testing import Csv
+from python.generators.diff_tests.testing import DiffTestBlueprint
+from python.generators.diff_tests.testing import TestSuite
+
+
+class ChromeInteractions(TestSuite):
+ def test_chrome_fcp_lcp_navigations(self):
+ return DiffTestBlueprint(
+ trace=DataPath('chrome_fcp_lcp_navigations.pftrace'),
+ query="""
+ INCLUDE PERFETTO MODULE chrome.page_loads;
+
+ SELECT
+ navigation_id,
+ navigation_start_ts,
+ fcp,
+ fcp_ts,
+ lcp,
+ lcp_ts,
+ browser_upid
+ FROM chrome_page_loads
+ ORDER by navigation_start_ts;
+ """,
+ out=Csv("""
+ "navigation_id","navigation_start_ts","fcp","fcp_ts","lcp","lcp_ts","browser_upid"
+ 6,687425601436243,950000000,687426551436243,950000000,687426551436243,1
+ 7,687427799068243,888000000,687428687068243,888000000,687428687068243,1
+ 8,687429970749243,1031000000,687431001749243,1132000000,687431102749243,1
+ 9,687432344113243,539000000,687432883113243,539000000,687432883113243,1
+ 10,687434796215243,475000000,687435271215243,475000000,687435271215243,1
+ 11,687435970742243,763000000,687436733742243,852000000,687436822742243,1
+ 13,687438343638243,1005000000,687439348638243,1005000000,687439348638243,1
+ 14,687440258111243,900000000,687441158111243,"[NULL]",0,1
+ """))
diff --git a/test/trace_processor/diff_tests/stdlib/chrome/tests_scroll_jank.py b/test/trace_processor/diff_tests/stdlib/chrome/tests_scroll_jank.py
new file mode 100644
index 0000000..c8e8f56
--- /dev/null
+++ b/test/trace_processor/diff_tests/stdlib/chrome/tests_scroll_jank.py
@@ -0,0 +1,140 @@
+#!/usr/bin/env python3
+# 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 a
+#
+# 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, Json, TextProto
+from python.generators.diff_tests.testing import DiffTestBlueprint
+from python.generators.diff_tests.testing import TestSuite
+
+
+class ChromeScrollJankStdlib(TestSuite):
+
+ def test_chrome_frames_with_missed_vsyncs(self):
+ return DiffTestBlueprint(
+ trace=DataPath('chrome_input_with_frame_view.pftrace'),
+ query="""
+ INCLUDE PERFETTO MODULE chrome.scroll_jank.scroll_jank_v3;
+
+ SELECT
+ cause_of_jank,
+ sub_cause_of_jank,
+ delay_since_last_frame,
+ vsync_interval
+ FROM chrome_janky_frames;
+ """,
+ out=Path('scroll_jank_v3.out'))
+
+ def test_chrome_frames_with_missed_vsyncs_percentage(self):
+ return DiffTestBlueprint(
+ trace=DataPath('chrome_input_with_frame_view.pftrace'),
+ query="""
+ INCLUDE PERFETTO MODULE chrome.scroll_jank.scroll_jank_v3;
+
+ SELECT
+ delayed_frame_percentage
+ FROM chrome_janky_frames_percentage;
+ """,
+ out=Path('scroll_jank_v3_percentage.out'))
+
+ def test_chrome_scrolls(self):
+ return DiffTestBlueprint(
+ trace=Path('chrome_scroll_check.py'),
+ query="""
+ INCLUDE PERFETTO MODULE chrome.chrome_scrolls;
+
+ SELECT
+ id,
+ ts,
+ dur,
+ gesture_scroll_begin_ts,
+ gesture_scroll_end_ts
+ FROM chrome_scrolls
+ ORDER by id;
+ """,
+ out=Csv("""
+ "id","ts","dur","gesture_scroll_begin_ts","gesture_scroll_end_ts"
+ 5678,0,55000000,0,45000000
+ 5679,60000000,40000000,60000000,90000000
+ 5680,80000000,30000000,80000000,100000000
+ 5681,120000000,70000000,120000000,"[NULL]"
+ """))
+
+ def test_chrome_scroll_intervals(self):
+ return DiffTestBlueprint(
+ trace=Path('chrome_scroll_check.py'),
+ query="""
+ INCLUDE PERFETTO MODULE chrome.chrome_scrolls;
+
+ SELECT
+ id,
+ ts,
+ dur
+ FROM chrome_scrolling_intervals
+ ORDER by id;
+ """,
+ out=Csv("""
+ "id","ts","dur"
+ 1,0,55000000
+ 2,60000000,50000000
+ 3,120000000,70000000
+ """))
+
+ def test_chrome_scroll_input_offsets(self):
+ return DiffTestBlueprint(
+ trace=DataPath('scroll_offsets.pftrace'),
+ query="""
+ INCLUDE PERFETTO MODULE chrome.scroll_jank.scroll_offsets;
+
+ SELECT
+ scroll_update_id,
+ ts,
+ delta_y,
+ offset_y
+ FROM chrome_scroll_input_offsets
+ ORDER by ts
+ LIMIT 5;
+ """,
+ out=Csv("""
+ "scroll_update_id","ts","delta_y","offset_y"
+ 1983,4687296612739,-36.999939,-36.999939
+ 1983,4687307175845,-39.000092,-76.000031
+ 1987,4687313206739,-35.999969,-112.000000
+ 1987,4687323152462,-35.000000,-147.000000
+ 1991,4687329240739,-28.999969,-175.999969
+ """))
+
+ def test_chrome_presented_scroll_offsets(self):
+ return DiffTestBlueprint(
+ trace=DataPath('scroll_offsets.pftrace'),
+ query="""
+ INCLUDE PERFETTO MODULE chrome.scroll_jank.scroll_offsets;
+
+ SELECT
+ scroll_update_id,
+ ts,
+ delta_y,
+ offset_y
+ FROM chrome_presented_scroll_offsets
+ ORDER by ts
+ LIMIT 5;
+ """,
+ out=Csv("""
+ "scroll_update_id","ts","delta_y","offset_y"
+ 1983,4687296612739,"[NULL]",0
+ 1987,4687313206739,-50,-50
+ 1991,4687329240739,-50,-100
+ 1993,4687336155739,-81,-181
+ 1996,4687346164739,-66,-247
+ """))
diff --git a/test/trace_processor/diff_tests/chrome/top_level_java_choreographer_slices_top_level_java_chrome_tasks_test.out b/test/trace_processor/diff_tests/stdlib/chrome/top_level_java_choreographer_slices_top_level_java_chrome_tasks_test.out
similarity index 100%
rename from test/trace_processor/diff_tests/chrome/top_level_java_choreographer_slices_top_level_java_chrome_tasks_test.out
rename to test/trace_processor/diff_tests/stdlib/chrome/top_level_java_choreographer_slices_top_level_java_chrome_tasks_test.out
diff --git a/test/trace_processor/diff_tests/stdlib/common/tests.py b/test/trace_processor/diff_tests/stdlib/common/tests.py
new file mode 100644
index 0000000..a902b5b
--- /dev/null
+++ b/test/trace_processor/diff_tests/stdlib/common/tests.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python3
+# 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 a
+#
+# 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, Json, TextProto
+from python.generators.diff_tests.testing import DiffTestBlueprint
+from python.generators.diff_tests.testing import TestSuite
+
+
+class StdlibCommon(TestSuite):
+
+ def test_thread_state_summary(self):
+ return DiffTestBlueprint(
+ trace=Path('../../common/synth_1.py'),
+ query="""
+ INCLUDE PERFETTO MODULE common.thread_states;
+
+ SELECT
+ state,
+ cpu,
+ dur
+ FROM thread_state_summary_for_interval(
+ 25,
+ 75,
+ (
+ SELECT utid
+ FROM thread
+ WHERE name = 'init'
+ )
+ )
+ """,
+ out=Csv("""
+ "state","cpu","dur"
+ "Running",1,50
+ "Runnable","[NULL]",25
+ """))
\ No newline at end of file
diff --git a/test/trace_processor/diff_tests/dynamic/ancestor_slice.out b/test/trace_processor/diff_tests/stdlib/dynamic_tables/ancestor_slice.out
similarity index 100%
rename from test/trace_processor/diff_tests/dynamic/ancestor_slice.out
rename to test/trace_processor/diff_tests/stdlib/dynamic_tables/ancestor_slice.out
diff --git a/test/trace_processor/diff_tests/dynamic/connected_flow.out b/test/trace_processor/diff_tests/stdlib/dynamic_tables/connected_flow.out
similarity index 100%
rename from test/trace_processor/diff_tests/dynamic/connected_flow.out
rename to test/trace_processor/diff_tests/stdlib/dynamic_tables/connected_flow.out
diff --git a/test/trace_processor/diff_tests/dynamic/connected_flow_data.json b/test/trace_processor/diff_tests/stdlib/dynamic_tables/connected_flow_data.json
similarity index 100%
rename from test/trace_processor/diff_tests/dynamic/connected_flow_data.json
rename to test/trace_processor/diff_tests/stdlib/dynamic_tables/connected_flow_data.json
diff --git a/test/trace_processor/diff_tests/dynamic/connected_flow_test.sql b/test/trace_processor/diff_tests/stdlib/dynamic_tables/connected_flow_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/dynamic/connected_flow_test.sql
rename to test/trace_processor/diff_tests/stdlib/dynamic_tables/connected_flow_test.sql
diff --git a/test/trace_processor/diff_tests/dynamic/descendant_slice.out b/test/trace_processor/diff_tests/stdlib/dynamic_tables/descendant_slice.out
similarity index 100%
rename from test/trace_processor/diff_tests/dynamic/descendant_slice.out
rename to test/trace_processor/diff_tests/stdlib/dynamic_tables/descendant_slice.out
diff --git a/test/trace_processor/diff_tests/dynamic/perf_sample_sc_annotated_callstack.out b/test/trace_processor/diff_tests/stdlib/dynamic_tables/perf_sample_sc_annotated_callstack.out
similarity index 100%
rename from test/trace_processor/diff_tests/dynamic/perf_sample_sc_annotated_callstack.out
rename to test/trace_processor/diff_tests/stdlib/dynamic_tables/perf_sample_sc_annotated_callstack.out
diff --git a/test/trace_processor/diff_tests/dynamic/relationship_tables.textproto b/test/trace_processor/diff_tests/stdlib/dynamic_tables/relationship_tables.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/dynamic/relationship_tables.textproto
rename to test/trace_processor/diff_tests/stdlib/dynamic_tables/relationship_tables.textproto
diff --git a/test/trace_processor/diff_tests/dynamic/slice_stacks.textproto b/test/trace_processor/diff_tests/stdlib/dynamic_tables/slice_stacks.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/dynamic/slice_stacks.textproto
rename to test/trace_processor/diff_tests/stdlib/dynamic_tables/slice_stacks.textproto
diff --git a/test/trace_processor/diff_tests/dynamic/tests.py b/test/trace_processor/diff_tests/stdlib/dynamic_tables/tests.py
similarity index 99%
rename from test/trace_processor/diff_tests/dynamic/tests.py
rename to test/trace_processor/diff_tests/stdlib/dynamic_tables/tests.py
index 3c79262..60b170c 100644
--- a/test/trace_processor/diff_tests/dynamic/tests.py
+++ b/test/trace_processor/diff_tests/stdlib/dynamic_tables/tests.py
@@ -19,7 +19,7 @@
from python.generators.diff_tests.testing import TestSuite
-class Dynamic(TestSuite):
+class DynamicTables(TestSuite):
# Tests for custom dynamic tables. Ancestor slice table.
def test_ancestor_slice(self):
return DiffTestBlueprint(
diff --git a/test/trace_processor/diff_tests/dynamic/various_clocks.textproto b/test/trace_processor/diff_tests/stdlib/dynamic_tables/various_clocks.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/dynamic/various_clocks.textproto
rename to test/trace_processor/diff_tests/stdlib/dynamic_tables/various_clocks.textproto
diff --git a/test/trace_processor/diff_tests/pkvm/pkvm_hypervisor_events.textproto b/test/trace_processor/diff_tests/stdlib/pkvm/pkvm_hypervisor_events.textproto
similarity index 100%
rename from test/trace_processor/diff_tests/pkvm/pkvm_hypervisor_events.textproto
rename to test/trace_processor/diff_tests/stdlib/pkvm/pkvm_hypervisor_events.textproto
diff --git a/test/trace_processor/diff_tests/pkvm/tests.py b/test/trace_processor/diff_tests/stdlib/pkvm/tests.py
similarity index 100%
rename from test/trace_processor/diff_tests/pkvm/tests.py
rename to test/trace_processor/diff_tests/stdlib/pkvm/tests.py
diff --git a/test/trace_processor/diff_tests/slices/tests.py b/test/trace_processor/diff_tests/stdlib/slices/tests.py
similarity index 100%
rename from test/trace_processor/diff_tests/slices/tests.py
rename to test/trace_processor/diff_tests/stdlib/slices/tests.py
diff --git a/test/trace_processor/diff_tests/slices/trace.py b/test/trace_processor/diff_tests/stdlib/slices/trace.py
similarity index 100%
rename from test/trace_processor/diff_tests/slices/trace.py
rename to test/trace_processor/diff_tests/stdlib/slices/trace.py
diff --git a/test/trace_processor/diff_tests/span_join/android_sched_and_ps_slice_span_join_b118665515.out b/test/trace_processor/diff_tests/stdlib/span_join/android_sched_and_ps_slice_span_join_b118665515.out
similarity index 100%
rename from test/trace_processor/diff_tests/span_join/android_sched_and_ps_slice_span_join_b118665515.out
rename to test/trace_processor/diff_tests/stdlib/span_join/android_sched_and_ps_slice_span_join_b118665515.out
diff --git a/test/trace_processor/diff_tests/span_join/slice_span_join_b118665515_test.sql b/test/trace_processor/diff_tests/stdlib/span_join/slice_span_join_b118665515_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/span_join/slice_span_join_b118665515_test.sql
rename to test/trace_processor/diff_tests/stdlib/span_join/slice_span_join_b118665515_test.sql
diff --git a/test/trace_processor/diff_tests/span_join/span_join_unordered_cols_reverse_test.sql b/test/trace_processor/diff_tests/stdlib/span_join/span_join_unordered_cols_reverse_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/span_join/span_join_unordered_cols_reverse_test.sql
rename to test/trace_processor/diff_tests/stdlib/span_join/span_join_unordered_cols_reverse_test.sql
diff --git a/test/trace_processor/diff_tests/span_join/span_join_unordered_cols_test.sql b/test/trace_processor/diff_tests/stdlib/span_join/span_join_unordered_cols_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/span_join/span_join_unordered_cols_test.sql
rename to test/trace_processor/diff_tests/stdlib/span_join/span_join_unordered_cols_test.sql
diff --git a/test/trace_processor/diff_tests/span_join/span_join_zero_negative_dur_test.sql b/test/trace_processor/diff_tests/stdlib/span_join/span_join_zero_negative_dur_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/span_join/span_join_zero_negative_dur_test.sql
rename to test/trace_processor/diff_tests/stdlib/span_join/span_join_zero_negative_dur_test.sql
diff --git a/test/trace_processor/diff_tests/span_join/span_left_join.out b/test/trace_processor/diff_tests/stdlib/span_join/span_left_join.out
similarity index 100%
rename from test/trace_processor/diff_tests/span_join/span_left_join.out
rename to test/trace_processor/diff_tests/stdlib/span_join/span_left_join.out
diff --git a/test/trace_processor/diff_tests/span_join/span_left_join_left_partitioned.out b/test/trace_processor/diff_tests/stdlib/span_join/span_left_join_left_partitioned.out
similarity index 100%
rename from test/trace_processor/diff_tests/span_join/span_left_join_left_partitioned.out
rename to test/trace_processor/diff_tests/stdlib/span_join/span_left_join_left_partitioned.out
diff --git a/test/trace_processor/diff_tests/span_join/span_left_join_left_partitioned_test.sql b/test/trace_processor/diff_tests/stdlib/span_join/span_left_join_left_partitioned_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/span_join/span_left_join_left_partitioned_test.sql
rename to test/trace_processor/diff_tests/stdlib/span_join/span_left_join_left_partitioned_test.sql
diff --git a/test/trace_processor/diff_tests/span_join/span_left_join_left_unpartitioned.out b/test/trace_processor/diff_tests/stdlib/span_join/span_left_join_left_unpartitioned.out
similarity index 100%
rename from test/trace_processor/diff_tests/span_join/span_left_join_left_unpartitioned.out
rename to test/trace_processor/diff_tests/stdlib/span_join/span_left_join_left_unpartitioned.out
diff --git a/test/trace_processor/diff_tests/span_join/span_left_join_left_unpartitioned_test.sql b/test/trace_processor/diff_tests/stdlib/span_join/span_left_join_left_unpartitioned_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/span_join/span_left_join_left_unpartitioned_test.sql
rename to test/trace_processor/diff_tests/stdlib/span_join/span_left_join_left_unpartitioned_test.sql
diff --git a/test/trace_processor/diff_tests/span_join/span_left_join_test.sql b/test/trace_processor/diff_tests/stdlib/span_join/span_left_join_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/span_join/span_left_join_test.sql
rename to test/trace_processor/diff_tests/stdlib/span_join/span_left_join_test.sql
diff --git a/test/trace_processor/diff_tests/span_join/span_left_join_unpartitioned.out b/test/trace_processor/diff_tests/stdlib/span_join/span_left_join_unpartitioned.out
similarity index 100%
rename from test/trace_processor/diff_tests/span_join/span_left_join_unpartitioned.out
rename to test/trace_processor/diff_tests/stdlib/span_join/span_left_join_unpartitioned.out
diff --git a/test/trace_processor/diff_tests/span_join/span_left_join_unpartitioned_test.sql b/test/trace_processor/diff_tests/stdlib/span_join/span_left_join_unpartitioned_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/span_join/span_left_join_unpartitioned_test.sql
rename to test/trace_processor/diff_tests/stdlib/span_join/span_left_join_unpartitioned_test.sql
diff --git a/test/trace_processor/diff_tests/span_join/span_outer_join.out b/test/trace_processor/diff_tests/stdlib/span_join/span_outer_join.out
similarity index 100%
rename from test/trace_processor/diff_tests/span_join/span_outer_join.out
rename to test/trace_processor/diff_tests/stdlib/span_join/span_outer_join.out
diff --git a/test/trace_processor/diff_tests/span_join/span_outer_join_mixed.out b/test/trace_processor/diff_tests/stdlib/span_join/span_outer_join_mixed.out
similarity index 100%
rename from test/trace_processor/diff_tests/span_join/span_outer_join_mixed.out
rename to test/trace_processor/diff_tests/stdlib/span_join/span_outer_join_mixed.out
diff --git a/test/trace_processor/diff_tests/span_join/span_outer_join_mixed_test.sql b/test/trace_processor/diff_tests/stdlib/span_join/span_outer_join_mixed_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/span_join/span_outer_join_mixed_test.sql
rename to test/trace_processor/diff_tests/stdlib/span_join/span_outer_join_mixed_test.sql
diff --git a/test/trace_processor/diff_tests/span_join/span_outer_join_test.sql b/test/trace_processor/diff_tests/stdlib/span_join/span_outer_join_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/span_join/span_outer_join_test.sql
rename to test/trace_processor/diff_tests/stdlib/span_join/span_outer_join_test.sql
diff --git a/test/trace_processor/diff_tests/span_join/span_outer_join_unpartitioned.out b/test/trace_processor/diff_tests/stdlib/span_join/span_outer_join_unpartitioned.out
similarity index 100%
rename from test/trace_processor/diff_tests/span_join/span_outer_join_unpartitioned.out
rename to test/trace_processor/diff_tests/stdlib/span_join/span_outer_join_unpartitioned.out
diff --git a/test/trace_processor/diff_tests/span_join/span_outer_join_unpartitioned_test.sql b/test/trace_processor/diff_tests/stdlib/span_join/span_outer_join_unpartitioned_test.sql
similarity index 100%
rename from test/trace_processor/diff_tests/span_join/span_outer_join_unpartitioned_test.sql
rename to test/trace_processor/diff_tests/stdlib/span_join/span_outer_join_unpartitioned_test.sql
diff --git a/test/trace_processor/diff_tests/span_join/tests_left_join.py b/test/trace_processor/diff_tests/stdlib/span_join/tests_left_join.py
similarity index 91%
rename from test/trace_processor/diff_tests/span_join/tests_left_join.py
rename to test/trace_processor/diff_tests/stdlib/span_join/tests_left_join.py
index 2bd2e58..30fd6ce 100644
--- a/test/trace_processor/diff_tests/span_join/tests_left_join.py
+++ b/test/trace_processor/diff_tests/stdlib/span_join/tests_left_join.py
@@ -23,31 +23,31 @@
def test_span_left_join(self):
return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
+ trace=Path('../../common/synth_1.py'),
query=Path('span_left_join_test.sql'),
out=Path('span_left_join.out'))
def test_span_left_join_unpartitioned(self):
return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
+ trace=Path('../../common/synth_1.py'),
query=Path('span_left_join_unpartitioned_test.sql'),
out=Path('span_left_join_unpartitioned.out'))
def test_span_left_join_left_unpartitioned(self):
return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
+ trace=Path('../../common/synth_1.py'),
query=Path('span_left_join_left_unpartitioned_test.sql'),
out=Path('span_left_join_left_unpartitioned.out'))
def test_span_left_join_left_partitioned(self):
return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
+ trace=Path('../../common/synth_1.py'),
query=Path('span_left_join_left_partitioned_test.sql'),
out=Path('span_left_join_left_partitioned.out'))
def test_span_left_join_empty_right(self):
return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
+ trace=Path('../../common/synth_1.py'),
query="""
CREATE TABLE t1(
ts BIGINT,
@@ -79,7 +79,7 @@
def test_span_left_join_unordered_android_sched_and_ps(self):
return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
+ trace=Path('../../common/synth_1.py'),
query="""
CREATE TABLE t1(
ts BIGINT,
diff --git a/test/trace_processor/diff_tests/span_join/tests_outer_join.py b/test/trace_processor/diff_tests/stdlib/span_join/tests_outer_join.py
similarity index 92%
rename from test/trace_processor/diff_tests/span_join/tests_outer_join.py
rename to test/trace_processor/diff_tests/stdlib/span_join/tests_outer_join.py
index c2ac4f5..d0354ca 100644
--- a/test/trace_processor/diff_tests/span_join/tests_outer_join.py
+++ b/test/trace_processor/diff_tests/stdlib/span_join/tests_outer_join.py
@@ -23,13 +23,13 @@
def test_span_outer_join(self):
return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
+ trace=Path('../../common/synth_1.py'),
query=Path('span_outer_join_test.sql'),
out=Path('span_outer_join.out'))
def test_span_outer_join_empty(self):
return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
+ trace=Path('../../common/synth_1.py'),
query="""
CREATE TABLE t1(
ts BIGINT,
@@ -61,7 +61,7 @@
def test_span_outer_join_unpartitioned_empty(self):
return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
+ trace=Path('../../common/synth_1.py'),
query="""
CREATE TABLE t1(
ts BIGINT,
@@ -86,7 +86,7 @@
def test_span_outer_join_unpartitioned_left_empty(self):
return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
+ trace=Path('../../common/synth_1.py'),
query="""
CREATE TABLE t1(
ts BIGINT,
@@ -119,7 +119,7 @@
def test_span_outer_join_unpartitioned_right_empty(self):
return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
+ trace=Path('../../common/synth_1.py'),
query="""
CREATE TABLE t1(
ts BIGINT,
@@ -152,13 +152,13 @@
def test_span_outer_join_mixed(self):
return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
+ trace=Path('../../common/synth_1.py'),
query=Path('span_outer_join_mixed_test.sql'),
out=Path('span_outer_join_mixed.out'))
def test_span_outer_join_mixed_empty(self):
return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
+ trace=Path('../../common/synth_1.py'),
query="""
CREATE TABLE t1(
ts BIGINT,
@@ -184,7 +184,7 @@
def test_span_outer_join_mixed_left_empty(self):
return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
+ trace=Path('../../common/synth_1.py'),
query="""
CREATE TABLE t1(
ts BIGINT,
@@ -215,7 +215,7 @@
def test_span_outer_join_mixed_left_empty_rev(self):
return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
+ trace=Path('../../common/synth_1.py'),
query="""
CREATE TABLE t1(
ts BIGINT,
@@ -249,7 +249,7 @@
def test_span_outer_join_mixed_right_empty(self):
return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
+ trace=Path('../../common/synth_1.py'),
query="""
CREATE TABLE t1(
ts BIGINT,
@@ -284,7 +284,7 @@
def test_span_outer_join_mixed_right_empty_rev(self):
return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
+ trace=Path('../../common/synth_1.py'),
query="""
CREATE TABLE t1(
ts BIGINT,
@@ -316,6 +316,6 @@
def test_span_outer_join_mixed_2(self):
return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
+ trace=Path('../../common/synth_1.py'),
query=Path('span_outer_join_mixed_test.sql'),
out=Path('span_outer_join_mixed.out'))
diff --git a/test/trace_processor/diff_tests/span_join/tests_regression.py b/test/trace_processor/diff_tests/stdlib/span_join/tests_regression.py
similarity index 100%
rename from test/trace_processor/diff_tests/span_join/tests_regression.py
rename to test/trace_processor/diff_tests/stdlib/span_join/tests_regression.py
diff --git a/test/trace_processor/diff_tests/span_join/tests_smoke.py b/test/trace_processor/diff_tests/stdlib/span_join/tests_smoke.py
similarity index 95%
rename from test/trace_processor/diff_tests/span_join/tests_smoke.py
rename to test/trace_processor/diff_tests/stdlib/span_join/tests_smoke.py
index e94a6c8..bacaa9a 100644
--- a/test/trace_processor/diff_tests/span_join/tests_smoke.py
+++ b/test/trace_processor/diff_tests/stdlib/span_join/tests_smoke.py
@@ -23,7 +23,7 @@
def test_span_join_unordered_cols_synth_1(self):
return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
+ trace=Path('../../common/synth_1.py'),
query=Path('span_join_unordered_cols_test.sql'),
out=Csv("""
"ts","dur","part","b1","b2","b3","a1","a2","a3"
@@ -38,7 +38,7 @@
def test_span_join_unordered_cols_synth_1_2(self):
return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
+ trace=Path('../../common/synth_1.py'),
query=Path('span_join_unordered_cols_reverse_test.sql'),
out=Csv("""
"ts","dur","part","b1","b2","b3","a1","a2","a3"
diff --git a/test/trace_processor/diff_tests/time/tests.py b/test/trace_processor/diff_tests/stdlib/timestamps/tests.py
similarity index 98%
rename from test/trace_processor/diff_tests/time/tests.py
rename to test/trace_processor/diff_tests/stdlib/timestamps/tests.py
index ee8771d..a029ce5 100644
--- a/test/trace_processor/diff_tests/time/tests.py
+++ b/test/trace_processor/diff_tests/stdlib/timestamps/tests.py
@@ -20,7 +20,7 @@
from google.protobuf import text_format
-class Time(TestSuite):
+class Timestamps(TestSuite):
def test_ns(self):
return DiffTestBlueprint(
diff --git a/test/trace_processor/diff_tests/functions/tests.py b/test/trace_processor/diff_tests/syntax/functions/tests.py
similarity index 99%
rename from test/trace_processor/diff_tests/functions/tests.py
rename to test/trace_processor/diff_tests/syntax/functions/tests.py
index 966e87d..f613fb5 100644
--- a/test/trace_processor/diff_tests/functions/tests.py
+++ b/test/trace_processor/diff_tests/syntax/functions/tests.py
@@ -20,6 +20,7 @@
from python.generators.diff_tests.testing import PrintProfileProto
from google.protobuf import text_format
+
class Functions(TestSuite):
def test_create_function(self):
diff --git a/test/trace_processor/diff_tests/perfetto_sql/tests.py b/test/trace_processor/diff_tests/syntax/perfetto_sql/tests.py
similarity index 100%
rename from test/trace_processor/diff_tests/perfetto_sql/tests.py
rename to test/trace_processor/diff_tests/syntax/perfetto_sql/tests.py
diff --git a/test/trace_processor/diff_tests/tables/tests.py b/test/trace_processor/diff_tests/tables/tests.py
index 83775a3..a6ff813 100644
--- a/test/trace_processor/diff_tests/tables/tests.py
+++ b/test/trace_processor/diff_tests/tables/tests.py
@@ -266,18 +266,52 @@
def test_thread_state_flattened_aggregated(self):
return DiffTestBlueprint(
- trace=DataPath('android_monitor_contention_trace.atr'),
- query="""
+ trace=DataPath('android_monitor_contention_trace.atr'),
+ query="""
INCLUDE PERFETTO MODULE experimental.thread_state_flattened;
select * from experimental_get_flattened_thread_state_aggregated(11155, NULL);
""",
- out=Path('thread_state_flattened_aggregated_csv.out'))
+ out=Path('thread_state_flattened_aggregated_csv.out'))
def test_thread_state_flattened(self):
return DiffTestBlueprint(
- trace=DataPath('android_monitor_contention_trace.atr'),
- query="""
+ trace=DataPath('android_monitor_contention_trace.atr'),
+ query="""
INCLUDE PERFETTO MODULE experimental.thread_state_flattened;
select * from experimental_get_flattened_thread_state(11155, NULL);
""",
- out=Path('thread_state_flattened_csv.out'))
+ out=Path('thread_state_flattened_csv.out'))
+
+ def test_metadata(self):
+ return DiffTestBlueprint(
+ trace=TextProto(r"""
+ packet {
+ system_info {
+ tracing_service_version: "Perfetto v38.0-0bb49ab54 (0bb49ab54dbe55ce5b9dfea3a2ada68b87aecb65)"
+ timezone_off_mins: 60
+ utsname {
+ sysname: "Darwin"
+ version: "Foobar"
+ machine: "x86_64"
+ release: "22.6.0"
+ }
+ }
+ trusted_uid: 158158
+ trusted_packet_sequence_id: 1
+ }
+ """),
+ query=r"""SELECT name, COALESCE(str_value, int_value) as val
+ FROM metadata
+ WHERE name IN (
+ "system_name", "system_version", "system_machine",
+ "system_release", "timezone_off_mins")
+ ORDER BY name
+ """,
+ out=Csv(r"""
+ "name","val"
+ "system_machine","x86_64"
+ "system_name","Darwin"
+ "system_release","22.6.0"
+ "system_version","Foobar"
+ "timezone_off_mins",60
+ """))
diff --git a/test/trace_processor/diff_tests/tables/tests_sched.py b/test/trace_processor/diff_tests/tables/tests_sched.py
index 14e9f32..d2c4c67 100644
--- a/test/trace_processor/diff_tests/tables/tests_sched.py
+++ b/test/trace_processor/diff_tests/tables/tests_sched.py
@@ -303,20 +303,21 @@
critical_path_utid
FROM experimental_thread_executing_span_critical_path_stack((select utid from thread where tid = 3487), start_ts, end_ts), trace_bounds
ORDER BY ts
- LIMIT 10
+ LIMIT 11
""",
out=Csv("""
"id","ts","dur","utid","stack_depth","name","table_name","critical_path_utid"
11889,1737349401439,57188,1477,0,"thread_state: R","thread_state",1477
11889,1737349401439,57188,1477,1,"[NULL]","thread_state",1477
- 11889,1737349401439,57188,1477,2,"process_name: com.android.providers.media.module","thread_state",1477
- 11889,1737349401439,57188,1477,3,"thread_name: rs.media.module","thread_state",1477
+ 11889,1737349401439,57188,1477,2,"[NULL]","thread_state",1477
+ 11889,1737349401439,57188,1477,3,"process_name: com.android.providers.media.module","thread_state",1477
+ 11889,1737349401439,57188,1477,4,"thread_name: rs.media.module","thread_state",1477
11891,1737349458627,1884896,1477,0,"thread_state: Running","thread_state",1477
11891,1737349458627,1884896,1477,1,"[NULL]","thread_state",1477
- 11891,1737349458627,1884896,1477,2,"process_name: com.android.providers.media.module","thread_state",1477
- 11891,1737349458627,1884896,1477,3,"thread_name: rs.media.module","thread_state",1477
- 11891,1737349458627,1884896,1477,4,"cpu: 0","thread_state",1477
- 11891,1737351343523,2494,1477,0,"thread_state: Running","thread_state",1477
+ 11891,1737349458627,1884896,1477,2,"[NULL]","thread_state",1477
+ 11891,1737349458627,1884896,1477,3,"process_name: com.android.providers.media.module","thread_state",1477
+ 11891,1737349458627,1884896,1477,4,"thread_name: rs.media.module","thread_state",1477
+ 11891,1737349458627,1884896,1477,5,"cpu: 0","thread_state",1477
"""))
def test_thread_executing_span_critical_path_graph(self):
diff --git a/tools/check_sql_metrics.py b/tools/check_sql_metrics.py
index ac70183..ea7c2ba 100755
--- a/tools/check_sql_metrics.py
+++ b/tools/check_sql_metrics.py
@@ -54,7 +54,16 @@
}
-def match_pattern_to_dict(sql: str, pattern: str) -> Dict[str, Tuple[int, str]]:
+def match_create_table_pattern_to_dict(
+ sql: str, pattern: str) -> Dict[str, Tuple[int, str]]:
+ res = {}
+ for line_num, matches in match_pattern(pattern, sql).items():
+ res[matches[2]] = [line_num, str(matches[1])]
+ return res
+
+
+def match_drop_view_pattern_to_dict(sql: str,
+ pattern: str) -> Dict[str, Tuple[int, str]]:
res = {}
for line_num, matches in match_pattern(pattern, sql).items():
res[matches[1]] = [line_num, str(matches[0])]
@@ -66,8 +75,10 @@
sql = f.read()
# Check that CREATE VIEW/TABLE has a matching DROP VIEW/TABLE before it.
- create_table_view_dir = match_pattern_to_dict(sql, CREATE_TABLE_VIEW_PATTERN)
- drop_table_view_dir = match_pattern_to_dict(sql, DROP_TABLE_VIEW_PATTERN)
+ create_table_view_dir = match_create_table_pattern_to_dict(
+ sql, CREATE_TABLE_VIEW_PATTERN)
+ drop_table_view_dir = match_drop_view_pattern_to_dict(
+ sql, DROP_TABLE_VIEW_PATTERN)
errors = check_banned_create_table_as(sql,
path.split(ROOT_DIR)[1],
CREATE_TABLE_ALLOWLIST)
diff --git a/tools/gen_android_bp b/tools/gen_android_bp
index 552c7d3..2a06847 100755
--- a/tools/gen_android_bp
+++ b/tools/gen_android_bp
@@ -182,7 +182,6 @@
# The directory where the generated perfetto_build_flags.h will be copied into.
buildflags_dir = 'include/perfetto/base/build_configs/android_tree'
-
def enumerate_data_deps():
with open(os.path.join(ROOT_DIR, 'tools', 'test_data.txt')) as f:
lines = f.readlines()
@@ -708,8 +707,11 @@
cmd = ['mkdir -p %s &&' % cpp_out_dir, '$(location aprotoc)']
cmd += ['--proto_path=%s' % tree_path]
+ tool_files = set()
if buildtools_protobuf_src in target.proto_paths:
cmd += ['--proto_path=%s' % android_protobuf_src]
+ # Add `google/protobuf/descriptor.proto` to implicit deps
+ tool_files.add(':libprotobuf-internal-descriptor-proto')
# Descriptor targets only generate a single target.
if target.proto_plugin == 'descriptor':
@@ -728,6 +730,12 @@
# add them to srcs.
descriptor_module.srcs.update(
gn_utils.label_to_path(src) for src in target.sources)
+ # Add the tool_files to srcs so that they get copied if this action is
+ # sandboxed in Soong.
+ # Add to `srcs` instead of `tool_files` (the latter will require a
+ # --proto_path that depends on Soong's sandbox implementation.)
+ descriptor_module.srcs.update(
+ src for src in tool_files)
for dep in target.transitive_proto_deps():
current_target = gn.get_target(dep.name)
descriptor_module.srcs.update(
@@ -740,11 +748,31 @@
# generated files needs to declare two different types of dependencies --
# source files in 'srcs' and headers in 'generated_headers' -- and it's not
# valid to generate .h files from a source dependency and vice versa.
+ #
+ # We create an additional filegroup for .proto
+ # The .proto filegroup will be added to `tool_files` of rdeps so that the
+ # genrules can be sandboxed.
+
+ tool_files = set()
+ for proto_dep in target.proto_deps().union(target.transitive_proto_deps()):
+ tool_files.add(":" + label_to_module_name(proto_dep.name))
+
+ filegroup_module = Module('filegroup', target_module_name, target.name)
+ filegroup_module.srcs.update(
+ gn_utils.label_to_path(src) for src in target.sources)
+ blueprint.add_module(filegroup_module)
+
source_module_name = target_module_name + '_gen'
source_module = Module('genrule', source_module_name, target.name)
- blueprint.add_module(source_module)
+ # Add the "root" .proto filegroup to srcs
+ source_module.srcs = set([':' + target_module_name])
+ # Add the tool_files to srcs so that they get copied if this action is
+ # sandboxed in Soong.
+ # Add to `srcs` instead of `tool_files` (the latter will require a
+ # --proto_path that depends on Soong's sandbox implementation.)
source_module.srcs.update(
- gn_utils.label_to_path(src) for src in target.sources)
+ src for src in tool_files)
+ blueprint.add_module(source_module)
header_module = Module('genrule', source_module_name + '_headers',
target.name)
@@ -789,19 +817,20 @@
else:
raise Error('Unsupported proto plugin: %s' % target.proto_plugin)
- cmd += ['$(in)']
+ cmd += ['$(locations :%s)' % target_module_name]
source_module.cmd = ' '.join(cmd)
header_module.cmd = source_module.cmd
source_module.tools = tools
header_module.tools = tools
+
for sfx in suffixes:
source_module.out.update('%s/%s' %
(tree_path, src.replace('.proto', '.%s.cc' % sfx))
- for src in source_module.srcs)
+ for src in filegroup_module.srcs)
header_module.out.update('%s/%s' %
(tree_path, src.replace('.proto', '.%s.h' % sfx))
- for src in header_module.srcs)
+ for src in filegroup_module.srcs)
return source_module
@@ -998,7 +1027,10 @@
module.host_supported = (name_without_toolchain in target_host_supported)
module.vendor_available = (name_without_toolchain in target_vendor_available)
module.init_rc.update(target_initrc.get(target.name, []))
- module.srcs.update(
+ if target.type != 'proto_library':
+ # proto_library embeds a "root" filegroup in its srcs.
+ # Skip to prevent adding dups
+ module.srcs.update(
gn_utils.label_to_path(src)
for src in target.sources
if is_supported_source_file(src))
diff --git a/tools/gen_stdlib_docs_json.py b/tools/gen_stdlib_docs_json.py
index 27a1d06..f5f8e5d 100755
--- a/tools/gen_stdlib_docs_json.py
+++ b/tools/gen_stdlib_docs_json.py
@@ -83,20 +83,40 @@
'name': table.name,
'desc': table.desc,
'type': table.type,
- 'cols': table.cols,
+ 'cols': {
+ col_name: {
+ 'type': col.type,
+ 'desc': col.description,
+ } for (col_name, col) in table.cols.items()
+ },
} for table in docs.table_views],
'functions': [{
'name': function.name,
'desc': function.desc,
- 'args': function.args,
+ 'args': {
+ arg_name: {
+ 'type': arg.type,
+ 'desc': arg.description,
+ } for (arg_name, arg) in function.args.items()
+ },
'return_type': function.return_type,
'return_desc': function.return_desc,
} for function in docs.functions],
'table_functions': [{
'name': function.name,
'desc': function.desc,
- 'args': function.args,
- 'cols': function.cols,
+ 'args': {
+ arg_name: {
+ 'type': arg.type,
+ 'desc': arg.description,
+ } for (arg_name, arg) in function.args.items()
+ },
+ 'cols': {
+ col_name: {
+ 'type': col.type,
+ 'desc': col.description,
+ } for (col_name, col) in function.cols.items()
+ },
} for function in docs.table_functions],
}
modules[module_name].append(file_dict)
diff --git a/tools/heap_profile b/tools/heap_profile
index 6c2a399..cd6770b 100755
--- a/tools/heap_profile
+++ b/tools/heap_profile
@@ -754,7 +754,7 @@
if binary_path is None:
binary_path = product_out_symbols
elif product_out_symbols is not None:
- binary_path += ":" + product_out_symbols
+ binary_path += os.pathsep + product_out_symbols
trace_file = os.path.join(profile_target, 'raw-trace')
concat_files = [trace_file]
diff --git a/tools/install-build-deps b/tools/install-build-deps
index de0f53c..c3822f6 100755
--- a/tools/install-build-deps
+++ b/tools/install-build-deps
@@ -649,12 +649,22 @@
parser.add_argument('--verify', help='Check all URLs', action='store_true')
parser.add_argument(
'--no-toolchain', help='Do not download toolchain', action='store_true')
+ parser.add_argument(
+ '--build-os',
+ default=system().lower(),
+ choices=['windows', 'darwin', 'linux'],
+ help='Override the autodetected build operating system')
+ parser.add_argument(
+ '--build-arch',
+ default=GetArch(),
+ choices=['arm64', 'x64'],
+ help='Override the autodetected build CPU architecture')
args = parser.parse_args()
if args.verify:
CheckHashes()
return 0
- target_os = system().lower()
+ target_os = args.build_os
if args.ui and target_os == 'windows':
print('Building the UI on Windows is unsupported')
return 1
@@ -680,7 +690,7 @@
RmtreeIfExists(os.path.join(ROOT_DIR, old_dir))
for dep in deps:
- target_arch = GetArch()
+ target_arch = args.build_arch
matches_os = dep.target_os == 'all' or target_os == dep.target_os
matches_arch = dep.target_arch == 'all' or target_arch == dep.target_arch
if not matches_os or not matches_arch:
diff --git a/tools/java_heap_dump b/tools/java_heap_dump
index 5ef3cfd..36e6428 100755
--- a/tools/java_heap_dump
+++ b/tools/java_heap_dump
@@ -344,7 +344,7 @@
subprocess.check_call(['adb', 'pull', PROFILE_PATH, output_file], stdout=NULL)
- subprocess.check_call(['adb', 'shell', 'rm', PROFILE_PATH], stdout=NULL)
+ subprocess.check_call(['adb', 'shell', 'rm', '-f', PROFILE_PATH], stdout=NULL)
print("Wrote profile to {}".format(output_file))
print("This can be viewed using https://ui.perfetto.dev.")
diff --git a/ui/src/base/comparison_utils.ts b/ui/src/base/comparison_utils.ts
index 842c812..4d84a4d 100644
--- a/ui/src/base/comparison_utils.ts
+++ b/ui/src/base/comparison_utils.ts
@@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import {isString} from './object_utils';
+
export type ComparisonFn<X> = (a: X, b: X) => number;
export type SortDirection = 'DESC'|'ASC';
@@ -49,7 +51,7 @@
if (typeof a === 'number') {
return 2;
}
- if (typeof a === 'string') {
+ if (isString(a)) {
return 3;
}
// a instanceof Uint8Array
@@ -66,7 +68,7 @@
if (typeof a === 'number' && typeof b === 'number') {
return a - b;
}
- if (typeof a === 'string' && typeof b === 'string') {
+ if (isString(a) && isString(b)) {
return a.localeCompare(b);
}
if (a instanceof Uint8Array && b instanceof Uint8Array) {
diff --git a/ui/src/base/disposable.ts b/ui/src/base/disposable.ts
index cc5e397..15b0346 100644
--- a/ui/src/base/disposable.ts
+++ b/ui/src/base/disposable.ts
@@ -51,6 +51,9 @@
}
}
+export class NullDisposable implements Disposable {
+ dispose() {}
+}
// A collection of Disposables.
// Disposables can be added one by one, (e.g. during the lifecycle of a
diff --git a/ui/src/base/mithril_utils.ts b/ui/src/base/mithril_utils.ts
index 854221f..1f07578 100644
--- a/ui/src/base/mithril_utils.ts
+++ b/ui/src/base/mithril_utils.ts
@@ -14,10 +14,8 @@
import m from 'mithril';
-import {exists} from './utils';
-
// Check if a mithril component vnode has children
export function hasChildren({children}: m.Vnode<any>): boolean {
return Array.isArray(children) && children.length > 0 &&
- children.some(exists);
+ children.some((value) => value);
}
diff --git a/ui/src/base/time.ts b/ui/src/base/time.ts
index 528fdbf..c8e5837 100644
--- a/ui/src/base/time.ts
+++ b/ui/src/base/time.ts
@@ -319,6 +319,10 @@
this.end = end;
}
+ static fromTimeAndDuration(start: time, duration: duration): TimeSpan {
+ return new TimeSpan(start, Time.add(start, duration));
+ }
+
get duration(): duration {
return this.end - this.start;
}
diff --git a/ui/src/base/validators.ts b/ui/src/base/validators.ts
index cc072b7..8125a2d 100644
--- a/ui/src/base/validators.ts
+++ b/ui/src/base/validators.ts
@@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import {isString} from './object_utils';
+
// Execution context of object validator
interface ValidatorContext {
// Path to the current value starting from the root. Object field names are
@@ -110,7 +112,7 @@
class StringValidator extends PrimitiveValidator<string> {
predicate(input: unknown): input is string {
- return typeof input === 'string';
+ return isString(input);
}
}
diff --git a/ui/src/common/actions.ts b/ui/src/common/actions.ts
index 0999b31..8e8297a 100644
--- a/ui/src/common/actions.ts
+++ b/ui/src/common/actions.ts
@@ -30,8 +30,7 @@
tableColumnEquals,
toggleEnabled,
} from '../frontend/pivot_table_types';
-import {PrimaryTrackSortKey, TrackTags} from '../public/index';
-import {DebugTrackV2Config} from '../tracks/debug/slice_track';
+import {PrimaryTrackSortKey} from '../public/index';
import {randomColor} from './colorizer';
import {
@@ -77,21 +76,16 @@
VisibleState,
} from './state';
-export const DEBUG_SLICE_TRACK_KIND = 'DebugSliceTrack';
-
type StateDraft = Draft<State>;
export interface AddTrackArgs {
- id?: string;
- engineId: string;
- kind: string;
+ key?: string;
+ uri: string;
name: string;
labels?: string[];
trackSortKey: TrackSortKey;
trackGroup?: string;
- config: {};
- tags?: TrackTags;
- uri?: string; // Only used for new PLUGIN_TRACK tracks
+ params?: unknown;
}
export interface PostedTrace {
@@ -140,15 +134,15 @@
// A helper to clean the state for a given removeable track.
// This is not exported as action to make it clear that not all
// tracks are removeable.
-function removeTrack(state: StateDraft, trackId: string) {
- const track = state.tracks[trackId];
+function removeTrack(state: StateDraft, trackKey: string) {
+ const track = state.tracks[trackKey];
if (track === undefined) {
return;
}
- delete state.tracks[trackId];
+ delete state.tracks[trackKey];
const removeTrackId = (arr: string[]) => {
- const index = arr.indexOf(trackId);
+ const index = arr.indexOf(trackKey);
if (index !== -1) arr.splice(index, 1);
};
@@ -160,7 +154,7 @@
removeTrackId(trackGroup.tracks);
}
}
- state.pinnedTracks = state.pinnedTracks.filter((id) => id !== trackId);
+ state.pinnedTracks = state.pinnedTracks.filter((key) => key !== trackKey);
}
let statusTraceEvent: TraceEventScope|undefined;
@@ -212,38 +206,24 @@
},
fillUiTrackIdByTraceTrackId(
- state: StateDraft, trackState: TrackState, uiTrackId: string) {
- const namespace = (trackState.config as {namespace?: string}).namespace;
- if (namespace !== undefined) return;
-
- const setUiTrackId = (trackId: number, uiTrackId: string) => {
- if (state.uiTrackIdByTraceTrackId[trackId] !== undefined &&
- state.uiTrackIdByTraceTrackId[trackId] !== uiTrackId) {
+ state: StateDraft, trackState: TrackState, trackKey: string) {
+ const setTrackKey = (trackId: number, trackKey: string) => {
+ if (state.trackKeyByTrackId[trackId] !== undefined &&
+ state.trackKeyByTrackId[trackId] !== trackKey) {
throw new Error(`Trying to map track id ${trackId} to UI track ${
- uiTrackId}, already mapped to ${
- state.uiTrackIdByTraceTrackId[trackId]}`);
+ trackKey}, already mapped to ${state.trackKeyByTrackId[trackId]}`);
}
- state.uiTrackIdByTraceTrackId[trackId] = uiTrackId;
+ state.trackKeyByTrackId[trackId] = trackKey;
};
- const {uri, config} = trackState;
+ const {uri} = trackState;
if (exists(uri)) {
// If track is a new "plugin" type track (i.e. it has a uri), resolve the
// track ids from through the pluginManager.
const trackInfo = pluginManager.resolveTrackInfo(uri);
if (trackInfo?.trackIds) {
for (const trackId of trackInfo.trackIds) {
- setUiTrackId(trackId, uiTrackId);
- }
- }
- } else {
- // Traditional track - resolve track ids through the config.
- const {trackId, trackIds} = config;
- if (exists(trackId)) {
- setUiTrackId(trackId, uiTrackId);
- } else if (exists(trackIds)) {
- for (const trackId of trackIds) {
- setUiTrackId(trackId, uiTrackId);
+ setTrackKey(trackId, trackKey);
}
}
}
@@ -251,33 +231,43 @@
addTracks(state: StateDraft, args: {tracks: AddTrackArgs[]}) {
args.tracks.forEach((track) => {
- const id = track.id === undefined ? generateNextId(state) : track.id;
+ const trackKey =
+ track.key === undefined ? generateNextId(state) : track.key;
const name = track.name;
- const tags = track.tags ?? {name};
- state.tracks[id] = {
- id,
- engineId: track.engineId,
- kind: track.kind,
+ state.tracks[trackKey] = {
+ key: trackKey,
name,
trackSortKey: track.trackSortKey,
trackGroup: track.trackGroup,
- tags,
- config: track.config,
labels: track.labels,
uri: track.uri,
+ params: track.params,
};
- this.fillUiTrackIdByTraceTrackId(state, track as TrackState, id);
+ this.fillUiTrackIdByTraceTrackId(state, track as TrackState, trackKey);
if (track.trackGroup === SCROLLING_TRACK_GROUP) {
- state.scrollingTracks.push(id);
+ state.scrollingTracks.push(trackKey);
} else if (track.trackGroup !== undefined) {
const group = state.trackGroups[track.trackGroup];
if (group !== undefined) {
- group.tracks.push(id);
+ group.tracks.push(trackKey);
}
}
});
},
+ // Note: While this action has traditionally been omitted, with more and more
+ // dynamic tracks being added and existing ones being moved to plugins, it
+ // makes sense to have a generic "removeTracks" action which is un-opinionated
+ // about what type of tracks we are removing.
+ // E.g. Once debug tracks have been moved to a plugin, it makes no sense to
+ // keep the "removeDebugTrack()" action, as the core should have no concept of
+ // what debug tracks are.
+ removeTracks(state: StateDraft, args: {trackKeys: string[]}) {
+ for (const trackKey of args.trackKeys) {
+ removeTrack(state, trackKey);
+ }
+ },
+
setUtidToTrackSortKey(
state: StateDraft, args: {threadOrderingMetadata: UtidToTrackSortKey}) {
state.utidToThreadSortKey = args.threadOrderingMetadata;
@@ -292,58 +282,18 @@
// Define ID in action so a track group can be referred to without running
// the reducer.
args: {
- engineId: string; name: string; id: string; summaryTrackId: string;
- collapsed: boolean;
+ name: string; id: string; summaryTrackKey: string; collapsed: boolean;
+ fixedOrdering?: boolean;
}): void {
state.trackGroups[args.id] = {
- engineId: args.engineId,
name: args.name,
id: args.id,
collapsed: args.collapsed,
- tracks: [args.summaryTrackId],
+ tracks: [args.summaryTrackKey],
+ fixedOrdering: args.fixedOrdering,
};
},
- addDebugTrack(
- state: StateDraft,
- args: {engineId: string, name: string, config: DebugTrackV2Config}):
- void {
- if (state.debugTrackId !== undefined) return;
- const trackId = generateNextId(state);
- this.addTrack(state, {
- id: trackId,
- engineId: args.engineId,
- kind: DEBUG_SLICE_TRACK_KIND,
- name: args.name,
- trackSortKey: PrimaryTrackSortKey.DEBUG_SLICE_TRACK,
- trackGroup: SCROLLING_TRACK_GROUP,
- config: args.config,
- });
- this.toggleTrackPinned(state, {trackId});
- },
-
- removeDebugTrack(state: StateDraft, args: {trackId: string}): void {
- const track = state.tracks[args.trackId];
- if (track !== undefined) {
- assertTrue(track.kind === DEBUG_SLICE_TRACK_KIND);
- removeTrack(state, args.trackId);
- }
- },
-
- removeVisualisedArgTracks(state: StateDraft, args: {trackIds: string[]}) {
- for (const trackId of args.trackIds) {
- const track = state.tracks[trackId];
-
- const namespace = (track.config as {namespace?: string}).namespace;
- if (namespace === undefined) {
- throw new Error(
- 'All visualised arg tracks should have non-empty namespace');
- }
-
- removeTrack(state, trackId);
- }
- },
-
maybeExpandOnlyTrackGroup(state: StateDraft, _: {}): void {
const trackGroups = Object.values(state.trackGroups);
if (trackGroups.length === 1) {
@@ -379,6 +329,8 @@
// rather than T1, T10, T11, ..., T2, T20, T21 .
const coll = new Intl.Collator([], {sensitivity: 'base', numeric: true});
for (const group of Object.values(state.trackGroups)) {
+ if (group.fixedOrdering) continue;
+
group.tracks.sort((a: string, b: string) => {
const aRank = getFullKey(a);
const bRank = getFullKey(b);
@@ -450,21 +402,21 @@
moveWithinTrackList(state.scrollingTracks);
},
- toggleTrackPinned(state: StateDraft, args: {trackId: string}): void {
- const id = args.trackId;
- const isPinned = state.pinnedTracks.includes(id);
- const trackGroup = assertExists(state.tracks[id]).trackGroup;
+ toggleTrackPinned(state: StateDraft, args: {trackKey: string}): void {
+ const key = args.trackKey;
+ const isPinned = state.pinnedTracks.includes(key);
+ const trackGroup = assertExists(state.tracks[key]).trackGroup;
if (isPinned) {
- state.pinnedTracks.splice(state.pinnedTracks.indexOf(id), 1);
+ state.pinnedTracks.splice(state.pinnedTracks.indexOf(key), 1);
if (trackGroup === SCROLLING_TRACK_GROUP) {
- state.scrollingTracks.unshift(id);
+ state.scrollingTracks.unshift(key);
}
} else {
if (trackGroup === SCROLLING_TRACK_GROUP) {
- state.scrollingTracks.splice(state.scrollingTracks.indexOf(id), 1);
+ state.scrollingTracks.splice(state.scrollingTracks.indexOf(key), 1);
}
- state.pinnedTracks.push(id);
+ state.pinnedTracks.push(key);
}
},
@@ -686,27 +638,26 @@
selectSlice(
state: StateDraft,
- args: {id: number, trackId: string, scroll?: boolean}): void {
+ args: {id: number, trackKey: string, scroll?: boolean}): void {
state.currentSelection = {
kind: 'SLICE',
id: args.id,
- trackId: args.trackId,
+ trackKey: args.trackKey,
};
state.pendingScrollId = args.scroll ? args.id : undefined;
},
selectCounter(
state: StateDraft,
- args: {leftTs: time, rightTs: time, id: number, trackId: string}):
- void {
- state.currentSelection = {
- kind: 'COUNTER',
- leftTs: args.leftTs,
- rightTs: args.rightTs,
- id: args.id,
- trackId: args.trackId,
- };
- },
+ args: {leftTs: time, rightTs: time, id: number, trackKey: string}): void {
+ state.currentSelection = {
+ kind: 'COUNTER',
+ leftTs: args.leftTs,
+ rightTs: args.rightTs,
+ id: args.id,
+ trackKey: args.trackKey,
+ };
+ },
selectHeapProfile(
state: StateDraft,
@@ -801,12 +752,12 @@
selectChromeSlice(
state: StateDraft,
- args: {id: number, trackId: string, table: string, scroll?: boolean}):
+ args: {id: number, trackKey: string, table?: string, scroll?: boolean}):
void {
state.currentSelection = {
kind: 'CHROME_SLICE',
id: args.id,
- trackId: args.trackId,
+ trackKey: args.trackKey,
table: args.table,
};
state.pendingScrollId = args.scroll ? args.id : undefined;
@@ -817,7 +768,7 @@
sqlTableName: string,
start: time,
duration: duration,
- trackId: string,
+ trackKey: string,
detailsPanelConfig:
{kind: string, config: GenericSliceDetailsTabConfigBase},
}): void {
@@ -832,7 +783,7 @@
sqlTableName: args.sqlTableName,
start: args.start,
duration: args.duration,
- trackId: args.trackId,
+ trackKey: args.trackKey,
detailsPanelConfig:
{kind: args.detailsPanelConfig.kind, config: detailsPanelConfig},
};
@@ -842,25 +793,25 @@
state.pendingScrollId = undefined;
},
- selectThreadState(state: StateDraft, args: {id: number, trackId: string}):
+ selectThreadState(state: StateDraft, args: {id: number, trackKey: string}):
void {
state.currentSelection = {
kind: 'THREAD_STATE',
id: args.id,
- trackId: args.trackId,
+ trackKey: args.trackKey,
};
},
selectLog(
- state: StateDraft, args: {id: number, trackId: string, scroll?: boolean}):
- void {
- state.currentSelection = {
- kind: 'LOG',
- id: args.id,
- trackId: args.trackId,
- };
- state.pendingScrollId = args.scroll ? args.id : undefined;
- },
+ state: StateDraft,
+ args: {id: number, trackKey: string, scroll?: boolean}): void {
+ state.currentSelection = {
+ kind: 'LOG',
+ id: args.id,
+ trackKey: args.trackKey,
+ };
+ state.pendingScrollId = args.scroll ? args.id : undefined;
+ },
deselect(state: StateDraft, _: {}): void {
state.currentSelection = null;
@@ -1066,8 +1017,8 @@
clearAllPinnedTracks(state: StateDraft, _: {}) {
const pinnedTracks = state.pinnedTracks.slice();
for (let index = pinnedTracks.length-1; index >= 0; index--) {
- const trackId = pinnedTracks[index];
- this.toggleTrackPinned(state, {trackId});
+ const trackKey = pinnedTracks[index];
+ this.toggleTrackPinned(state, {trackKey});
}
},
@@ -1138,17 +1089,6 @@
}));
},
- addVisualisedArg(state: StateDraft, args: {argName: string}) {
- if (!state.visualisedArgs.includes(args.argName)) {
- state.visualisedArgs.push(args.argName);
- }
- },
-
- removeVisualisedArg(state: StateDraft, args: {argName: string}) {
- state.visualisedArgs =
- state.visualisedArgs.filter((val) => val !== args.argName);
- },
-
setPivotTableArgumentNames(
state: StateDraft, args: {argumentNames: string[]}) {
state.nonSerializableState.pivotTable.argumentNames = args.argumentNames;
diff --git a/ui/src/common/actions_unittest.ts b/ui/src/common/actions_unittest.ts
index 8713c17..3fb0246 100644
--- a/ui/src/common/actions_unittest.ts
+++ b/ui/src/common/actions_unittest.ts
@@ -36,8 +36,8 @@
} from './state';
function fakeTrack(state: State, args: {
- id: string,
- kind?: string,
+ key: string,
+ uri?: string,
trackGroup?: string,
trackSortKey?: TrackSortKey,
name?: string,
@@ -45,15 +45,13 @@
}): State {
return produce(state, (draft) => {
StateActions.addTrack(draft, {
- id: args.id,
- engineId: '0',
- kind: args.kind || 'SOME_TRACK_KIND',
+ uri: args.uri || 'sometrack',
+ key: args.key,
name: args.name || 'A track',
trackSortKey: args.trackSortKey === undefined ?
PrimaryTrackSortKey.ORDINARY_TRACK :
args.trackSortKey,
trackGroup: args.trackGroup || SCROLLING_TRACK_GROUP,
- config: {tid: args.tid || '0'},
});
});
}
@@ -64,20 +62,19 @@
StateActions.addTrackGroup(draft, {
name: 'A group',
id: args.id,
- engineId: '0',
collapsed: false,
- summaryTrackId: args.summaryTrackId,
+ summaryTrackKey: args.summaryTrackId,
});
});
}
function pinnedAndScrollingTracks(
state: State,
- ids: string[],
+ keys: string[],
pinnedTracks: string[],
scrollingTracks: string[]): State {
- for (const id of ids) {
- state = fakeTrack(state, {id});
+ for (const key of keys) {
+ state = fakeTrack(state, {key});
}
state = produce(state, (draft) => {
draft.pinnedTracks = pinnedTracks;
@@ -89,22 +86,18 @@
test('add scrolling tracks', () => {
const once = produce(createEmptyState(), (draft) => {
StateActions.addTrack(draft, {
- engineId: '1',
- kind: 'cpu',
+ uri: 'cpu',
name: 'Cpu 1',
trackSortKey: PrimaryTrackSortKey.ORDINARY_TRACK,
trackGroup: SCROLLING_TRACK_GROUP,
- config: {},
});
});
const twice = produce(once, (draft) => {
StateActions.addTrack(draft, {
- engineId: '2',
- kind: 'cpu',
+ uri: 'cpu',
name: 'Cpu 2',
trackSortKey: PrimaryTrackSortKey.ORDINARY_TRACK,
trackGroup: SCROLLING_TRACK_GROUP,
- config: {},
});
});
@@ -114,27 +107,24 @@
test('add track to track group', () => {
let state = createEmptyState();
- state = fakeTrack(state, {id: 's'});
+ state = fakeTrack(state, {key: 's'});
const afterGroup = produce(state, (draft) => {
StateActions.addTrackGroup(draft, {
- engineId: '1',
name: 'A track group',
id: '123-123-123',
- summaryTrackId: 's',
+ summaryTrackKey: 's',
collapsed: false,
});
});
const afterTrackAdd = produce(afterGroup, (draft) => {
StateActions.addTrack(draft, {
- id: '1',
- engineId: '1',
- kind: 'slices',
+ key: '1',
+ uri: 'slices',
name: 'renderer 1',
trackSortKey: PrimaryTrackSortKey.ORDINARY_TRACK,
trackGroup: '123-123-123',
- config: {},
});
});
@@ -145,18 +135,14 @@
test('reorder tracks', () => {
const once = produce(createEmptyState(), (draft) => {
StateActions.addTrack(draft, {
- engineId: '1',
- kind: 'cpu',
+ uri: 'cpu',
name: 'Cpu 1',
trackSortKey: PrimaryTrackSortKey.ORDINARY_TRACK,
- config: {},
});
StateActions.addTrack(draft, {
- engineId: '2',
- kind: 'cpu',
+ uri: 'cpu',
name: 'Cpu 2',
trackSortKey: PrimaryTrackSortKey.ORDINARY_TRACK,
- config: {},
});
});
@@ -241,7 +227,7 @@
const after = produce(state, (draft) => {
StateActions.toggleTrackPinned(draft, {
- trackId: 'c',
+ trackKey: 'c',
});
});
expect(after.pinnedTracks).toEqual(['a', 'c']);
@@ -254,7 +240,7 @@
const after = produce(state, (draft) => {
StateActions.toggleTrackPinned(draft, {
- trackId: 'a',
+ trackKey: 'a',
});
});
expect(after.pinnedTracks).toEqual(['b']);
@@ -285,11 +271,9 @@
const twice = produce(once, (draft) => {
StateActions.addTrack(draft, {
- engineId: '1',
- kind: 'cpu',
+ uri: 'cpu',
name: 'Cpu 1',
trackSortKey: PrimaryTrackSortKey.ORDINARY_TRACK,
- config: {},
});
});
@@ -331,14 +315,14 @@
let state = createEmptyState();
state = fakeTrackGroup(state, {id: 'g', summaryTrackId: 'b'});
state = fakeTrack(state, {
- id: 'b',
- kind: HEAP_PROFILE_TRACK_KIND,
+ key: 'b',
+ uri: HEAP_PROFILE_TRACK_KIND,
trackSortKey: PrimaryTrackSortKey.HEAP_PROFILE_TRACK,
trackGroup: 'g',
});
state = fakeTrack(state, {
- id: 'a',
- kind: PROCESS_SCHEDULING_TRACK_KIND,
+ key: 'a',
+ uri: PROCESS_SCHEDULING_TRACK_KIND,
trackSortKey: PrimaryTrackSortKey.PROCESS_SCHEDULING_TRACK,
trackGroup: 'g',
});
@@ -356,35 +340,35 @@
let state = createEmptyState();
state = fakeTrackGroup(state, {id: 'g', summaryTrackId: 'b'});
state = fakeTrack(state, {
- id: 'a',
- kind: PROCESS_SCHEDULING_TRACK_KIND,
+ key: 'a',
+ uri: PROCESS_SCHEDULING_TRACK_KIND,
trackSortKey: PrimaryTrackSortKey.PROCESS_SCHEDULING_TRACK,
trackGroup: 'g',
});
state = fakeTrack(state, {
- id: 'b',
- kind: SLICE_TRACK_KIND,
+ key: 'b',
+ uri: SLICE_TRACK_KIND,
trackGroup: 'g',
trackSortKey: PrimaryTrackSortKey.MAIN_THREAD,
});
state = fakeTrack(state, {
- id: 'c',
- kind: SLICE_TRACK_KIND,
+ key: 'c',
+ uri: SLICE_TRACK_KIND,
trackGroup: 'g',
trackSortKey: PrimaryTrackSortKey.RENDER_THREAD,
});
state = fakeTrack(state, {
- id: 'd',
- kind: SLICE_TRACK_KIND,
+ key: 'd',
+ uri: SLICE_TRACK_KIND,
trackGroup: 'g',
trackSortKey: PrimaryTrackSortKey.GPU_COMPLETION_THREAD,
});
state = fakeTrack(
- state, {id: 'e', kind: HEAP_PROFILE_TRACK_KIND, trackGroup: 'g'});
+ state, {key: 'e', uri: HEAP_PROFILE_TRACK_KIND, trackGroup: 'g'});
state = fakeTrack(
- state, {id: 'f', kind: SLICE_TRACK_KIND, trackGroup: 'g', name: 'T2'});
+ state, {key: 'f', uri: SLICE_TRACK_KIND, trackGroup: 'g', name: 'T2'});
state = fakeTrack(
- state, {id: 'g', kind: SLICE_TRACK_KIND, trackGroup: 'g', name: 'T10'});
+ state, {key: 'g', uri: SLICE_TRACK_KIND, trackGroup: 'g', name: 'T10'});
const after = produce(state, (draft) => {
StateActions.sortThreadTracks(draft, {});
@@ -403,8 +387,8 @@
let state = createEmptyState();
state = fakeTrackGroup(state, {id: 'g', summaryTrackId: 'a'});
state = fakeTrack(state, {
- id: 'a',
- kind: SLICE_TRACK_KIND,
+ key: 'a',
+ uri: SLICE_TRACK_KIND,
trackSortKey: {
utid: 1,
priority: InThreadTrackSortKey.ORDINARY,
@@ -414,8 +398,8 @@
tid: '1',
});
state = fakeTrack(state, {
- id: 'b',
- kind: SLICE_TRACK_KIND,
+ key: 'b',
+ uri: SLICE_TRACK_KIND,
trackSortKey: {
utid: 2,
priority: InThreadTrackSortKey.ORDINARY,
@@ -425,8 +409,8 @@
tid: '2',
});
state = fakeTrack(state, {
- id: 'c',
- kind: THREAD_STATE_TRACK_KIND,
+ key: 'c',
+ uri: THREAD_STATE_TRACK_KIND,
trackSortKey: {
utid: 1,
priority: InThreadTrackSortKey.ORDINARY,
diff --git a/ui/src/common/array_buffer_builder.ts b/ui/src/common/array_buffer_builder.ts
index 58e6980..fd86c04 100644
--- a/ui/src/common/array_buffer_builder.ts
+++ b/ui/src/common/array_buffer_builder.ts
@@ -18,13 +18,14 @@
} from '@protobufjs/utf8';
import {assertTrue} from '../base/logging';
+import {isString} from '../base/object_utils';
// A token that can be appended to an `ArrayBufferBuilder`.
export type ArrayBufferToken = string|number|Uint8Array;
// Return the length, in bytes, of a token to be inserted.
function tokenLength(token: ArrayBufferToken): number {
- if (typeof token === 'string') {
+ if (isString(token)) {
return utf8Len(token);
} else if (token instanceof Uint8Array) {
return token.byteLength;
@@ -46,7 +47,7 @@
typedArray: Uint8Array,
byteOffset: number,
token: ArrayBufferToken): void {
- if (typeof token === 'string') {
+ if (isString(token)) {
// Encode the string in UTF-8
const written = utf8Write(token, typedArray, byteOffset);
assertTrue(written === utf8Len(token));
diff --git a/ui/src/common/basic_async_track.ts b/ui/src/common/basic_async_track.ts
index 2faf829..f22c333 100644
--- a/ui/src/common/basic_async_track.ts
+++ b/ui/src/common/basic_async_track.ts
@@ -19,8 +19,7 @@
import {globals} from '../frontend/globals';
import {PxSpan, TimeScale} from '../frontend/time_scale';
import {SliceRect} from '../frontend/track';
-import {TrackButtonAttrs} from '../frontend/track_panel';
-import {Track} from '../public';
+import {Track, TrackContext} from '../public';
import {TrackData} from './track_data';
@@ -46,7 +45,7 @@
private currentState?: TrackData;
protected data?: Data;
- onCreate(): void {}
+ onCreate(_ctx: TrackContext): void {}
onDestroy(): void {
this.queuedRequest = false;
@@ -67,14 +66,10 @@
abstract getHeight(): number;
- getTrackShellButtons(): m.Vnode<TrackButtonAttrs, {}>[] {
+ getTrackShellButtons(): m.Children {
return [];
}
- getContextMenu(): m.Vnode<any, {}>|null {
- return null;
- }
-
onMouseMove(_position: {x: number; y: number;}): void {}
onMouseClick(_position: {x: number; y: number;}): boolean {
diff --git a/ui/src/common/empty_state.ts b/ui/src/common/empty_state.ts
index 23644e5..de6e8f2 100644
--- a/ui/src/common/empty_state.ts
+++ b/ui/src/common/empty_state.ts
@@ -93,7 +93,7 @@
newEngineMode: 'USE_HTTP_RPC_IF_AVAILABLE',
traceTime: {...defaultTraceTime},
tracks: {},
- uiTrackIdByTraceTrackId: {},
+ trackKeyByTrackId: {},
utidToThreadSortKey: {},
aggregatePreferences: {},
trackGroups: {},
@@ -104,7 +104,6 @@
queries: {},
permalink: {},
notes: {},
- visualisedArgs: [],
recordConfig: AUTOLOAD_STARTED_CONFIG_FLAG.get() ?
autosaveConfigStore.get() :
diff --git a/ui/src/common/event_set.ts b/ui/src/common/event_set.ts
index 88e7319..c420296 100644
--- a/ui/src/common/event_set.ts
+++ b/ui/src/common/event_set.ts
@@ -13,6 +13,7 @@
// limitations under the License.
import {arrayEquals, isArrayOf} from '../base/array_utils';
+import {isString} from '../base/object_utils';
import {intersect} from '../base/set_utils';
// Contents:
@@ -796,7 +797,7 @@
const value = this.value;
if (value === null) {
return 'NULL';
- } else if (typeof value === 'string') {
+ } else if (isString(value)) {
return `'${value}'`;
} else if (typeof value === 'boolean') {
return value ? 'TRUE' : 'FALSE';
@@ -1000,7 +1001,7 @@
function primativeToRank(p: Primitive) {
if (p === null) {
return 0;
- } else if (typeof p === 'string') {
+ } else if (isString(p)) {
return 2;
} else {
return 1;
diff --git a/ui/src/common/plugins.ts b/ui/src/common/plugins.ts
index 13a4e10..cb27e61 100644
--- a/ui/src/common/plugins.ts
+++ b/ui/src/common/plugins.ts
@@ -15,29 +15,22 @@
import {Disposable, Trash} from '../base/disposable';
import {assertFalse} from '../base/logging';
import {ViewerImpl, ViewerProxy} from '../common/viewer';
-import {
- TrackControllerFactory,
- trackControllerRegistry,
-} from '../controller/track_controller';
import {globals} from '../frontend/globals';
-import {TrackCreator} from '../frontend/track';
-import {trackRegistry} from '../frontend/track_registry';
import {
- BasePlugin,
Command,
EngineProxy,
MetricVisualisation,
+ Migrate,
Plugin,
PluginClass,
PluginContext,
PluginContextTrace,
PluginDescriptor,
- StatefulPlugin,
Store,
Track,
TrackContext,
TrackDescriptor,
- TrackInstanceDescriptor,
+ TrackRef,
Viewer,
} from '../public';
@@ -73,18 +66,6 @@
});
}
- LEGACY_registerTrackController(track: TrackControllerFactory): void {
- if (!this.alive) return;
- const unregister = trackControllerRegistry.register(track);
- this.trash.add(unregister);
- }
-
- LEGACY_registerTrack(track: TrackCreator): void {
- if (!this.alive) return;
- const unregister = trackRegistry.register(track);
- this.trash.add(unregister);
- }
-
dispose(): void {
this.trash.dispose();
this.alive = false;
@@ -95,30 +76,16 @@
// related resources, such as the engine and the store.
// The TracePluginContext exists for the whole duration a plugin is active AND a
// trace is loaded.
-class TracePluginContextImpl<T> implements PluginContextTrace<T>, Disposable {
+class TracePluginContextImpl implements PluginContextTrace, Disposable {
private trash = new Trash();
private alive = true;
constructor(
- private ctx: PluginContext, readonly store: Store<T>,
- readonly engine: EngineProxy,
+ private ctx: PluginContext, readonly engine: EngineProxy,
readonly trackRegistry: Map<string, TrackDescriptor>,
- private suggestedTracks: Set<TrackInstanceDescriptor>,
+ private defaultTracks: Set<TrackRef>,
private commandRegistry: Map<string, Command>) {
this.trash.add(engine);
- this.trash.add(store);
- }
-
- LEGACY_registerTrackController(track: TrackControllerFactory): void {
- // Silently ignore if context is dead.
- if (!this.alive) return;
- this.ctx.LEGACY_registerTrackController(track);
- }
-
- LEGACY_registerTrack(track: TrackCreator): void {
- // Silently ignore if context is dead.
- if (!this.alive) return;
- this.ctx.LEGACY_registerTrack(track);
}
addCommand(cmd: Command): void {
@@ -140,51 +107,81 @@
return this.ctx.viewer;
}
+ get pluginId(): string {
+ return this.ctx.pluginId;
+ }
+
// Register a new track in this context.
// All tracks registered through this method are removed when this context is
// destroyed, i.e. when the trace is unloaded.
- addTrack(trackDetails: TrackDescriptor): void {
+ registerTrack(trackDesc: TrackDescriptor): void {
// Silently ignore if context is dead.
if (!this.alive) return;
- const {uri} = trackDetails;
- this.trackRegistry.set(uri, trackDetails);
- this.trash.addCallback(() => this.trackRegistry.delete(uri));
+
+ this.trackRegistry.set(trackDesc.uri, trackDesc);
+ this.trash.addCallback(() => this.trackRegistry.delete(trackDesc.uri));
}
- // Ask Perfetto to add a track to the track list when a fresh trace is loaded.
- // Ignored when a trace is loaded from a permalink.
- // This is a direct replacement for findPotentialTracks().
- // Note: This interface is likely to be deprecated soon, but is required while
- // both plugin and original type tracks coexist.
- suggestTrack(trackInfo: TrackInstanceDescriptor): void {
- this.suggestedTracks.add(trackInfo);
- this.trash.addCallback(() => this.suggestedTracks.delete(trackInfo));
+ addDefaultTrack(track: TrackRef): void {
+ // Silently ignore if context is dead.
+ if (!this.alive) return;
+
+ this.defaultTracks.add(track);
+ this.trash.addCallback(() => this.defaultTracks.delete(track));
+ }
+
+ registerStaticTrack(track: TrackDescriptor&TrackRef): void {
+ this.registerTrack(track);
+
+ // TODO(stevegolton): Once we've sorted out track_decider, we should also
+ // add this track to the default track list here. E.g.
+ // this.addDefaultTrack({
+ // uri: trackDetails.uri,
+ // displayName: trackDetails.displayName,
+ // sortKey: PrimaryTrackSortKey.ORDINARY_TRACK,
+ // });
}
dispose(): void {
this.trash.dispose();
this.alive = false;
}
+
+ mountStore<T>(migrate: Migrate<T>): Store<T> {
+ const globalStore = globals.store;
+
+ // Migrate initial state
+ const initialState = globalStore.state.plugins[this.pluginId];
+ const migratedState = migrate(initialState);
+
+ // Update global store with migrated plugin state
+ globalStore.edit((draft) => {
+ draft.plugins[this.pluginId] = migratedState;
+ });
+
+ // Return proxy store for this plugin
+ return globalStore.createProxy<T>(['plugins', this.pluginId]);
+ }
}
// 'Static' registry of all known plugins.
-export class PluginRegistry extends Registry<PluginDescriptor<unknown>> {
+export class PluginRegistry extends Registry<PluginDescriptor> {
constructor() {
super((info) => info.pluginId);
}
}
-interface PluginDetails<T> {
- plugin: Plugin<T>;
+interface PluginDetails {
+ plugin: Plugin;
context: PluginContext&Disposable;
- traceContext?: TracePluginContextImpl<unknown>;
+ traceContext?: TracePluginContextImpl;
}
-function isPluginClass<T>(v: unknown): v is PluginClass<T> {
+function isPluginClass(v: unknown): v is PluginClass {
return typeof v === 'function' && !!(v.prototype.onActivate);
}
-function makePlugin<T>(info: PluginDescriptor<T>): Plugin<T> {
+function makePlugin(info: PluginDescriptor): Plugin {
const {plugin} = info;
if (typeof plugin === 'function') {
@@ -201,11 +198,11 @@
export class PluginManager {
private registry: PluginRegistry;
- private plugins: Map<string, PluginDetails<unknown>>;
+ private plugins: Map<string, PluginDetails>;
private engine?: Engine;
readonly trackRegistry = new Map<string, TrackDescriptor>();
readonly commandRegistry = new Map<string, Command>();
- readonly suggestedTracks = new Set<TrackInstanceDescriptor>();
+ readonly defaultTracks = new Set<TrackRef>();
constructor(registry: PluginRegistry) {
this.registry = registry;
@@ -226,7 +223,7 @@
plugin.onActivate && plugin.onActivate(context);
- const pluginDetails: PluginDetails<unknown> = {
+ const pluginDetails: PluginDetails = {
plugin,
context,
};
@@ -259,12 +256,12 @@
return this.getPluginContext(pluginId) !== undefined;
}
- getPluginContext(pluginId: string): PluginDetails<unknown>|undefined {
+ getPluginContext(pluginId: string): PluginDetails|undefined {
return this.plugins.get(pluginId);
}
- findPotentialTracks(): TrackInstanceDescriptor[] {
- return Array.from(this.suggestedTracks);
+ findPotentialTracks(): TrackRef[] {
+ return Array.from(this.defaultTracks);
}
onTraceLoad(engine: Engine): void {
@@ -309,59 +306,26 @@
return trackInfo && trackInfo.track(trackCtx);
}
- private doPluginTraceLoad<T>(
- pluginDetails: PluginDetails<T>, engine: Engine, pluginId: string): void {
+ private doPluginTraceLoad(
+ pluginDetails: PluginDetails, engine: Engine, pluginId: string): void {
const {plugin, context} = pluginDetails;
const engineProxy = engine.getProxy(pluginId);
- // Migrate state & write back to store.
- if (isStatefulPlugin(plugin)) {
- const initialState = globals.store.state.plugins[pluginId];
- const migratedState = plugin.migrate(initialState);
- globals.store.edit((draft) => {
- draft.plugins[pluginId] = migratedState;
- });
+ const traceCtx = new TracePluginContextImpl(
+ context,
+ engineProxy,
+ this.trackRegistry,
+ this.defaultTracks,
+ this.commandRegistry);
+ pluginDetails.traceContext = traceCtx;
- const proxyStore = globals.store.createProxy<T>(['plugins', pluginId]);
- const traceCtx = new TracePluginContextImpl(
- context,
- proxyStore,
- engineProxy,
- this.trackRegistry,
- this.suggestedTracks,
- this.commandRegistry);
- pluginDetails.traceContext = traceCtx;
-
- // TODO(stevegolton): Await onTraceLoad.
- plugin.onTraceLoad && plugin.onTraceLoad(traceCtx);
- } else {
- // Stateless plugin i.e. the plugin's state type is undefined.
- // Just provide a store proxy over this plugin's state, the plugin can
- // work the state out for itself if it wants to, but we're not going to
- // help it out by calling migrate().
- const proxyStore = globals.store.createProxy<T>(['plugins', pluginId]);
- const traceCtx = new TracePluginContextImpl(
- context,
- proxyStore,
- engineProxy,
- this.trackRegistry,
- this.suggestedTracks,
- this.commandRegistry);
- pluginDetails.traceContext = traceCtx;
-
- // TODO(stevegolton): Await onTraceLoad.
- plugin.onTraceLoad && plugin.onTraceLoad(traceCtx);
- }
+ // TODO(stevegolton): Await onTraceLoad.
+ plugin.onTraceLoad && plugin.onTraceLoad(traceCtx);
}
}
-function isStatefulPlugin<T>(plugin: BasePlugin<T>|
- StatefulPlugin<T>): plugin is StatefulPlugin<T> {
- return 'migrate' in plugin;
-}
-
-function maybeDoPluginTraceUnload(pluginDetails: PluginDetails<unknown>): void {
+function maybeDoPluginTraceUnload(pluginDetails: PluginDetails): void {
const {traceContext, plugin} = pluginDetails;
if (traceContext) {
diff --git a/ui/src/common/plugins_unittest.ts b/ui/src/common/plugins_unittest.ts
index 5be1f4a..4d3d4c2 100644
--- a/ui/src/common/plugins_unittest.ts
+++ b/ui/src/common/plugins_unittest.ts
@@ -26,9 +26,8 @@
rpcSendRequestBytes(_data: Uint8Array) {}
}
-function makeMockPlugin(): Plugin<any> {
+function makeMockPlugin(): Plugin {
return {
- migrate: jest.fn(),
onActivate: jest.fn(),
onDeactivate: jest.fn(),
onTraceLoad: jest.fn(),
@@ -91,17 +90,4 @@
expect(mockPlugin.onTraceUnload).toHaveBeenCalledTimes(1);
});
-
- it('does not invoke migrate at activation time', () => {
- manager.activatePlugin('foo', viewer);
-
- expect(mockPlugin.migrate).not.toHaveBeenCalled();
- });
-
- it('invokes migrate when trace is loaded', () => {
- manager.activatePlugin('foo', viewer);
- manager.onTraceLoad(engine);
-
- expect(mockPlugin.migrate).toHaveBeenCalledTimes(1);
- });
});
diff --git a/ui/src/common/recordingV2/adb_connection_over_webusb.ts b/ui/src/common/recordingV2/adb_connection_over_webusb.ts
index 1c118b0..bd42c52 100644
--- a/ui/src/common/recordingV2/adb_connection_over_webusb.ts
+++ b/ui/src/common/recordingV2/adb_connection_over_webusb.ts
@@ -16,6 +16,7 @@
import {defer, Deferred} from '../../base/deferred';
import {assertExists, assertFalse, assertTrue} from '../../base/logging';
+import {isString} from '../../base/object_utils';
import {CmdType} from '../../controller/adb_interfaces';
import {AdbConnectionImpl} from './adb_connection_impl';
@@ -196,7 +197,7 @@
}
streamWrite(msg: string|Uint8Array, stream: AdbOverWebusbStream): void {
- const raw = (typeof msg === 'string') ? textEncoder.encode(msg) : msg;
+ const raw = (isString(msg)) ? textEncoder.encode(msg) : msg;
if (this.writeInProgress) {
this.writeQueue.push({message: raw, localStreamId: stream.localStreamId});
return;
@@ -604,7 +605,7 @@
static encodeData(data?: Uint8Array|string): Uint8Array {
if (data === undefined) return new Uint8Array([]);
- if (typeof data === 'string') return textEncoder.encode(data + '\0');
+ if (isString(data)) return textEncoder.encode(data + '\0');
return data;
}
}
diff --git a/ui/src/common/recordingV2/recording_config_utils.ts b/ui/src/common/recordingV2/recording_config_utils.ts
index dd33e36..a134f9a 100644
--- a/ui/src/common/recordingV2/recording_config_utils.ts
+++ b/ui/src/common/recordingV2/recording_config_utils.ts
@@ -13,6 +13,7 @@
// limitations under the License.
+import {isString} from '../../base/object_utils';
import {base64Encode} from '../../base/string_utils';
import {RecordConfig} from '../../controller/record_config_types';
import {
@@ -721,7 +722,7 @@
const isNested = typeof value === 'object' && !isRepeated;
for (const entry of (isRepeated ? value as Array<{}>: [value])) {
yield ' '.repeat(indent) + `${snakeCase(key)}${isNested ? '' : ':'} `;
- if (typeof entry === 'string') {
+ if (isString(entry)) {
if (isEnum(entry) || is64BitNumber(key)) {
yield entry;
} else {
diff --git a/ui/src/common/search_data.ts b/ui/src/common/search_data.ts
index 2854d3c..b81dfb2 100644
--- a/ui/src/common/search_data.ts
+++ b/ui/src/common/search_data.ts
@@ -22,7 +22,7 @@
sliceIds: Float64Array;
tsStarts: BigInt64Array;
utids: Float64Array;
- trackIds: string[];
+ trackKeys: string[];
sources: string[];
totalResults: number;
}
diff --git a/ui/src/common/state.ts b/ui/src/common/state.ts
index 1a8c68e..2fdf467 100644
--- a/ui/src/common/state.ts
+++ b/ui/src/common/state.ts
@@ -23,7 +23,7 @@
PivotTree,
TableColumn,
} from '../frontend/pivot_table_types';
-import {PrimaryTrackSortKey, TrackTags} from '../public/index';
+import {PrimaryTrackSortKey} from '../public/index';
import {Direction} from './event_set';
@@ -34,6 +34,11 @@
*/
export interface ObjectById<Class extends{id: string}> { [id: string]: Class; }
+// Same as ObjectById but the key parameter is called `key` rather than `id`.
+export interface ObjectByKey<Class extends {key: string}> {
+ [key: string]: Class;
+}
+
export interface Timestamped {
lastUpdate: number;
}
@@ -123,7 +128,9 @@
// state entries now require a URI and old track implementations are no
// longer registered.
// 40. Ported counter, process summary/sched, & cpu_freq to plugin tracks.
-export const STATE_VERSION = 40;
+// 41. Ported all remaining tracks.
+// 42. Rename trackId -> trackKey.
+export const STATE_VERSION = 42;
export const SCROLLING_TRACK_GROUP = 'ScrollingTracks';
@@ -218,29 +225,23 @@
TraceFileSource|TraceArrayBufferSource|TraceUrlSource|TraceHttpRpcSource;
export interface TrackState {
- id: string;
- engineId: string;
- kind: string;
+ uri: string;
+ key: string;
name: string;
labels?: string[];
trackSortKey: TrackSortKey;
trackGroup?: string;
- tags: TrackTags;
- config: {
- trackId?: number;
- trackIds?: number[];
- };
- uri?: string;
+ params?: unknown;
state?: unknown;
}
export interface TrackGroupState {
id: string;
- engineId: string;
name: string;
collapsed: boolean;
tracks: string[]; // Child track ids.
state?: unknown;
+ fixedOrdering?: boolean; // Render tracks without sorting.
}
export interface EngineConfig {
@@ -349,7 +350,7 @@
export interface ChromeSliceSelection {
kind: 'CHROME_SLICE';
id: number;
- table: string;
+ table?: string;
}
export interface ThreadStateSelection {
@@ -360,7 +361,7 @@
export interface LogSelection {
kind: 'LOG';
id: number;
- trackId: string;
+ trackKey: string;
}
export interface GenericSliceSelection {
@@ -377,7 +378,7 @@
(NoteSelection|SliceSelection|CounterSelection|HeapProfileSelection|
CpuProfileSampleSelection|ChromeSliceSelection|ThreadStateSelection|
AreaSelection|PerfSamplesSelection|LogSelection|GenericSliceSelection)&
- {trackId?: string};
+ {trackKey?: string};
export type SelectionKind = Selection['kind']; // 'THREAD_STATE' | 'SLICE' ...
export interface Pagination {
@@ -533,8 +534,8 @@
traceTime: TraceTime;
traceUuid?: string;
trackGroups: ObjectById<TrackGroupState>;
- tracks: ObjectById<TrackState>;
- uiTrackIdByTraceTrackId: {[key: number]: string;};
+ tracks: ObjectByKey<TrackState>;
+ trackKeyByTrackId: {[key: number]: string;};
utidToThreadSortKey: UtidToTrackSortKey;
areas: ObjectById<AreaById>;
aggregatePreferences: ObjectById<AggregationState>;
@@ -553,7 +554,6 @@
ftracePagination: Pagination;
ftraceFilter: FtraceFilterState;
traceConversionInProgress: boolean;
- visualisedArgs: string[];
/**
* This state is updated on the frontend at 60Hz and eventually syncronised to
@@ -944,9 +944,9 @@
];
}
-export function getContainingTrackId(state: State, trackId: string): null|
+export function getContainingTrackId(state: State, trackKey: string): null|
string {
- const track = state.tracks[trackId];
+ const track = state.tracks[trackKey];
if (!track) {
return null;
}
diff --git a/ui/src/common/state_unittest.ts b/ui/src/common/state_unittest.ts
index 34646ba..fa251fc 100644
--- a/ui/src/common/state_unittest.ts
+++ b/ui/src/common/state_unittest.ts
@@ -26,24 +26,18 @@
test('getContainingTrackId', () => {
const state: State = createEmptyState();
state.tracks['a'] = {
- id: 'a',
- engineId: 'engine',
- kind: 'Foo',
+ key: 'a',
+ uri: 'Foo',
name: 'a track',
trackSortKey: PrimaryTrackSortKey.ORDINARY_TRACK,
- config: {},
- tags: {},
};
state.tracks['b'] = {
- id: 'b',
- engineId: 'engine',
- kind: 'Foo',
+ key: 'b',
+ uri: 'Foo',
name: 'b track',
trackSortKey: PrimaryTrackSortKey.ORDINARY_TRACK,
- config: {},
trackGroup: 'containsB',
- tags: {},
};
expect(getContainingTrackId(state, 'z')).toEqual(null);
diff --git a/ui/src/common/track_adapter.ts b/ui/src/common/track_adapter.ts
index 1c145d3..16edb58 100644
--- a/ui/src/common/track_adapter.ts
+++ b/ui/src/common/track_adapter.ts
@@ -20,7 +20,6 @@
import {EngineProxy} from '../common/engine';
import {PxSpan, TimeScale} from '../frontend/time_scale';
import {NewTrackArgs, SliceRect} from '../frontend/track';
-import {TrackButtonAttrs} from '../frontend/track_panel';
import {BasicAsyncTrack} from './basic_async_track';
@@ -44,12 +43,12 @@
private isSetup = false;
constructor(
- engine: EngineProxy, trackInstanceId: string, config: Config,
+ engine: EngineProxy, trackKey: string, config: Config,
Track: TrackAdapterClass<Config, Data>,
Controller: TrackControllerAdapterClass<Config, Data>) {
super();
const args: NewTrackArgs = {
- trackId: trackInstanceId,
+ trackKey,
engine,
};
this.track = new Track(args);
@@ -76,14 +75,10 @@
return this.track.getHeight();
}
- getTrackShellButtons(): m.Vnode<TrackButtonAttrs, {}>[] {
+ getTrackShellButtons(): m.Children {
return this.track.getTrackShellButtons();
}
- getContextMenu(): m.Vnode<any, {}>|null {
- return this.track.getContextMenu();
- }
-
onMouseMove(position: {x: number; y: number;}): void {
this.track.onMouseMove(position);
}
@@ -119,7 +114,7 @@
export abstract class TrackAdapter<Config, Data> {
private _config?: Config;
private dataSource?: () => Data | undefined;
- protected id: string;
+ protected trackKey: string;
get config(): Config {
return assertExists(this._config);
@@ -139,7 +134,7 @@
}
constructor(args: NewTrackArgs) {
- this.id = args.trackId;
+ this.trackKey = args.trackKey;
}
abstract renderCanvas(ctx: CanvasRenderingContext2D): void;
@@ -155,14 +150,10 @@
return 40;
}
- getTrackShellButtons(): Array<m.Vnode<TrackButtonAttrs>> {
+ getTrackShellButtons(): m.Children {
return [];
}
- getContextMenu(): m.Vnode<any>|null {
- return null;
- }
-
onMouseMove(_position: {x: number, y: number}) {}
// Returns whether the mouse click has selected something.
diff --git a/ui/src/common/upload_utils.ts b/ui/src/common/upload_utils.ts
index 0c97921..8ffdc11 100644
--- a/ui/src/common/upload_utils.ts
+++ b/ui/src/common/upload_utils.ts
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import {isString} from '../base/object_utils';
import {RecordConfig} from '../controller/record_config_types';
export const BUCKET_NAME = 'perfetto-ui-data';
@@ -50,7 +51,7 @@
return false;
}
if ('__kind' in value && 'value' in value) {
- return value.__kind === 'bigint' && typeof value.value === 'string';
+ return value.__kind === 'bigint' && isString(value.value);
}
return false;
}
diff --git a/ui/src/common/viewer.ts b/ui/src/common/viewer.ts
index e380c5c..99318ea 100644
--- a/ui/src/common/viewer.ts
+++ b/ui/src/common/viewer.ts
@@ -44,9 +44,9 @@
const tags = {
name: track.name,
};
- if (predicate(tags) && !this.isPinned(track.id)) {
+ if (predicate(tags) && !this.isPinned(track.key)) {
globals.dispatch(Actions.toggleTrackPinned({
- trackId: track.id,
+ trackKey: track.key,
}));
}
}
@@ -58,9 +58,9 @@
const tags = {
name: track.name,
};
- if (predicate(tags) && this.isPinned(track.id)) {
+ if (predicate(tags) && this.isPinned(track.key)) {
globals.dispatch(Actions.toggleTrackPinned({
- trackId: track.id,
+ trackKey: track.key,
}));
}
}
diff --git a/ui/src/controller/adb.ts b/ui/src/controller/adb.ts
index 18ca7fe..2b592a2 100644
--- a/ui/src/controller/adb.ts
+++ b/ui/src/controller/adb.ts
@@ -15,6 +15,7 @@
import {_TextDecoder, _TextEncoder} from 'custom_utils';
import {assertExists} from '../base/logging';
+import {isString} from '../base/object_utils';
import {Adb, AdbMsg, AdbStream, CmdType} from './adb_interfaces';
@@ -435,7 +436,7 @@
}
async write(msg: string|Uint8Array) {
- const raw = (typeof msg === 'string') ? textEncoder.encode(msg) : msg;
+ const raw = (isString(msg)) ? textEncoder.encode(msg) : msg;
if (this.sendInProgress ||
this.state === AdbStreamState.WAITING_INITIAL_OKAY) {
this.writeQueue.push(raw);
@@ -579,7 +580,7 @@
static encodeData(data?: Uint8Array|string): Uint8Array {
if (data === undefined) return new Uint8Array([]);
- if (typeof data === 'string') return textEncoder.encode(data + '\0');
+ if (isString(data)) return textEncoder.encode(data + '\0');
return data;
}
}
diff --git a/ui/src/controller/aggregation/aggregation_controller.ts b/ui/src/controller/aggregation/aggregation_controller.ts
index f5c855b..522131a 100644
--- a/ui/src/controller/aggregation/aggregation_controller.ts
+++ b/ui/src/controller/aggregation/aggregation_controller.ts
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import {isString} from '../../base/object_utils';
import {
AggregateData,
Column,
@@ -144,7 +145,7 @@
const item = it.get(column.columnId);
if (item === null) {
column.data[i] = isStringColumn(column) ? internString('NULL') : 0;
- } else if (typeof item === 'string') {
+ } else if (isString(item)) {
column.data[i] = internString(item);
} else if (item instanceof Uint8Array) {
column.data[i] = internString('<Binary blob>');
diff --git a/ui/src/controller/aggregation/counter_aggregation_controller.ts b/ui/src/controller/aggregation/counter_aggregation_controller.ts
index ae3e1d7..fcdb4d0 100644
--- a/ui/src/controller/aggregation/counter_aggregation_controller.ts
+++ b/ui/src/controller/aggregation/counter_aggregation_controller.ts
@@ -27,8 +27,8 @@
await engine.query(`drop view if exists ${this.kind};`);
const trackIds: (string|number)[] = [];
- for (const trackId of area.tracks) {
- const track = globals.state.tracks[trackId];
+ for (const trackKey of area.tracks) {
+ const track = globals.state.tracks[trackKey];
if (track?.uri) {
const trackInfo = pluginManager.resolveTrackInfo(track.uri);
if (trackInfo?.kind === COUNTER_TRACK_KIND) {
diff --git a/ui/src/controller/aggregation/cpu_aggregation_controller.ts b/ui/src/controller/aggregation/cpu_aggregation_controller.ts
index db176d9..ec3cf61 100644
--- a/ui/src/controller/aggregation/cpu_aggregation_controller.ts
+++ b/ui/src/controller/aggregation/cpu_aggregation_controller.ts
@@ -27,8 +27,8 @@
await engine.query(`drop view if exists ${this.kind};`);
const selectedCpus: number[] = [];
- for (const trackId of area.tracks) {
- const track = globals.state.tracks[trackId];
+ for (const trackKey of area.tracks) {
+ const track = globals.state.tracks[trackKey];
if (track?.uri) {
const trackInfo = pluginManager.resolveTrackInfo(track.uri);
if (trackInfo?.kind === CPU_SLICE_TRACK_KIND) {
diff --git a/ui/src/controller/aggregation/cpu_by_process_aggregation_controller.ts b/ui/src/controller/aggregation/cpu_by_process_aggregation_controller.ts
index dbdf07c..deff299 100644
--- a/ui/src/controller/aggregation/cpu_by_process_aggregation_controller.ts
+++ b/ui/src/controller/aggregation/cpu_by_process_aggregation_controller.ts
@@ -26,8 +26,8 @@
await engine.query(`drop view if exists ${this.kind};`);
const selectedCpus: number[] = [];
- for (const trackId of area.tracks) {
- const track = globals.state.tracks[trackId];
+ for (const trackKey of area.tracks) {
+ const track = globals.state.tracks[trackKey];
if (track?.uri) {
const trackInfo = pluginManager.resolveTrackInfo(track.uri);
if (trackInfo?.kind === CPU_SLICE_TRACK_KIND) {
diff --git a/ui/src/controller/aggregation/frame_aggregation_controller.ts b/ui/src/controller/aggregation/frame_aggregation_controller.ts
index a22a83d..cbe2448 100644
--- a/ui/src/controller/aggregation/frame_aggregation_controller.ts
+++ b/ui/src/controller/aggregation/frame_aggregation_controller.ts
@@ -14,12 +14,10 @@
import {ColumnDef} from '../../common/aggregation_data';
import {Engine} from '../../common/engine';
+import {pluginManager} from '../../common/plugins';
import {Area, Sorting} from '../../common/state';
import {globals} from '../../frontend/globals';
-import {
- ACTUAL_FRAMES_SLICE_TRACK_KIND,
- Config,
-} from '../../tracks/actual_frames';
+import {ACTUAL_FRAMES_SLICE_TRACK_KIND} from '../../tracks/actual_frames';
import {AggregationController} from './aggregation_controller';
@@ -27,13 +25,15 @@
async createAggregateView(engine: Engine, area: Area) {
await engine.query(`drop view if exists ${this.kind};`);
- const selectedSqlTrackIds = [];
- for (const trackId of area.tracks) {
- const track = globals.state.tracks[trackId];
+ const selectedSqlTrackIds: number[] = [];
+ for (const trackKey of area.tracks) {
+ const track = globals.state.tracks[trackKey];
// Track will be undefined for track groups.
- if (track !== undefined &&
- track.kind === ACTUAL_FRAMES_SLICE_TRACK_KIND) {
- selectedSqlTrackIds.push((track.config as Config).trackIds);
+ if (track?.uri !== undefined) {
+ const trackInfo = pluginManager.resolveTrackInfo(track.uri);
+ if (trackInfo?.kind === ACTUAL_FRAMES_SLICE_TRACK_KIND) {
+ trackInfo.trackIds && selectedSqlTrackIds.push(...trackInfo.trackIds);
+ }
}
}
if (selectedSqlTrackIds.length === 0) return false;
diff --git a/ui/src/controller/aggregation/slice_aggregation_controller.ts b/ui/src/controller/aggregation/slice_aggregation_controller.ts
index 8dcaccc..cb5e6f4 100644
--- a/ui/src/controller/aggregation/slice_aggregation_controller.ts
+++ b/ui/src/controller/aggregation/slice_aggregation_controller.ts
@@ -14,46 +14,39 @@
import {ColumnDef} from '../../common/aggregation_data';
import {Engine} from '../../common/engine';
+import {pluginManager} from '../../common/plugins';
import {Area, Sorting} from '../../common/state';
import {globals} from '../../frontend/globals';
-import {
- ASYNC_SLICE_TRACK_KIND,
- Config as AsyncSliceConfig,
-} from '../../tracks/async_slices';
-import {
- Config as SliceConfig,
- SLICE_TRACK_KIND,
-} from '../../tracks/chrome_slices';
+import {ASYNC_SLICE_TRACK_KIND} from '../../tracks/async_slices';
+import {SLICE_TRACK_KIND} from '../../tracks/chrome_slices';
import {AggregationController} from './aggregation_controller';
-export function getSelectedTrackIds(area: Area): number[] {
- const selectedTrackIds = [];
- for (const trackId of area.tracks) {
- const track = globals.state.tracks[trackId];
+export function getSelectedTrackKeys(area: Area): number[] {
+ const selectedTrackKeys: number[] = [];
+ for (const trackKey of area.tracks) {
+ const track = globals.state.tracks[trackKey];
// Track will be undefined for track groups.
- if (track !== undefined) {
- if (track.kind === SLICE_TRACK_KIND) {
- selectedTrackIds.push((track.config as SliceConfig).trackId);
+ if (track?.uri !== undefined) {
+ const trackInfo = pluginManager.resolveTrackInfo(track.uri);
+ if (trackInfo?.kind === SLICE_TRACK_KIND) {
+ trackInfo.trackIds && selectedTrackKeys.push(...trackInfo.trackIds);
}
- if (track.kind === ASYNC_SLICE_TRACK_KIND) {
- const config = track.config as AsyncSliceConfig;
- for (const id of config.trackIds) {
- selectedTrackIds.push(id);
- }
+ if (trackInfo?.kind === ASYNC_SLICE_TRACK_KIND) {
+ trackInfo.trackIds && selectedTrackKeys.push(...trackInfo.trackIds);
}
}
}
- return selectedTrackIds;
+ return selectedTrackKeys;
}
export class SliceAggregationController extends AggregationController {
async createAggregateView(engine: Engine, area: Area) {
await engine.query(`drop view if exists ${this.kind};`);
- const selectedTrackIds = getSelectedTrackIds(area);
+ const selectedTrackKeys = getSelectedTrackKeys(area);
- if (selectedTrackIds.length === 0) return false;
+ if (selectedTrackKeys.length === 0) return false;
const query = `create view ${this.kind} as
SELECT
@@ -62,7 +55,7 @@
sum(dur)/count(1) as avg_dur,
count(1) as occurrences
FROM slices
- WHERE track_id IN (${selectedTrackIds}) AND
+ WHERE track_id IN (${selectedTrackKeys}) AND
ts + dur > ${area.start} AND
ts < ${area.end} group by name`;
diff --git a/ui/src/controller/aggregation/thread_aggregation_controller.ts b/ui/src/controller/aggregation/thread_aggregation_controller.ts
index 7436a57..6818cfb 100644
--- a/ui/src/controller/aggregation/thread_aggregation_controller.ts
+++ b/ui/src/controller/aggregation/thread_aggregation_controller.ts
@@ -14,14 +14,12 @@
import {ColumnDef, ThreadStateExtra} from '../../common/aggregation_data';
import {Engine} from '../../common/engine';
+import {pluginManager} from '../../common/plugins';
import {NUM, NUM_NULL, STR_NULL} from '../../common/query_result';
import {Area, Sorting} from '../../common/state';
import {translateState} from '../../common/thread_state';
import {globals} from '../../frontend/globals';
-import {
- Config,
- THREAD_STATE_TRACK_KIND,
-} from '../../tracks/thread_state';
+import {THREAD_STATE_TRACK_KIND} from '../../tracks/thread_state';
import {AggregationController} from './aggregation_controller';
@@ -33,8 +31,11 @@
for (const trackId of tracks) {
const track = globals.state.tracks[trackId];
// Track will be undefined for track groups.
- if (track !== undefined && track.kind === THREAD_STATE_TRACK_KIND) {
- this.utids.push((track.config as Config).utid);
+ if (track?.uri) {
+ const trackInfo = pluginManager.resolveTrackInfo(track.uri);
+ if (trackInfo?.kind === THREAD_STATE_TRACK_KIND) {
+ trackInfo.utid && this.utids.push(trackInfo.utid);
+ }
}
}
}
diff --git a/ui/src/controller/args_parser.ts b/ui/src/controller/args_parser.ts
index 97cd70e..b36c30b 100644
--- a/ui/src/controller/args_parser.ts
+++ b/ui/src/controller/args_parser.ts
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import {isString} from '../base/object_utils';
import {exists} from '../base/utils';
export type Key = string|number;
@@ -102,7 +103,7 @@
function parseNodes<A extends ArgLike<T>, T>(nodes: ArgNode<A>[]):
ObjectType<T> {
- if (nodes.every(({key}) => typeof key === 'string')) {
+ if (nodes.every(({key}) => isString(key))) {
const dict: ObjectType<T> = {};
for (const node of nodes) {
if (node.key in dict) {
diff --git a/ui/src/controller/flamegraph_controller.ts b/ui/src/controller/flamegraph_controller.ts
index 20bdb04..c9e6f02 100644
--- a/ui/src/controller/flamegraph_controller.ts
+++ b/ui/src/controller/flamegraph_controller.ts
@@ -26,14 +26,12 @@
PERF_SAMPLES_KEY,
SPACE_MEMORY_ALLOCATED_NOT_FREED_KEY,
} from '../common/flamegraph_util';
+import {pluginManager} from '../common/plugins';
import {NUM, STR} from '../common/query_result';
import {CallsiteInfo, FlamegraphState, ProfileType} from '../common/state';
import {FlamegraphDetails, globals} from '../frontend/globals';
import {publishFlamegraphDetails} from '../frontend/publish';
-import {
- Config as PerfSampleConfig,
- PERF_SAMPLES_PROFILE_TRACK_KIND,
-} from '../tracks/perf_samples_profile';
+import {PERF_SAMPLES_PROFILE_TRACK_KIND} from '../tracks/perf_samples_profile';
import {AreaSelectionHandler} from './area_selection_handler';
import {Controller} from './controller';
@@ -131,12 +129,13 @@
return;
}
for (const trackId of area.tracks) {
- const trackState = globals.state.tracks[trackId];
- if (!trackState ||
- trackState.kind !== PERF_SAMPLES_PROFILE_TRACK_KIND) {
- continue;
+ const track = globals.state.tracks[trackId];
+ if (track?.uri) {
+ const trackInfo = pluginManager.resolveTrackInfo(track.uri);
+ if (trackInfo?.kind === PERF_SAMPLES_PROFILE_TRACK_KIND) {
+ trackInfo.upid && upids.push(trackInfo.upid);
+ }
}
- upids.push((trackState.config as PerfSampleConfig).upid);
}
if (upids.length === 0) {
this.checkCompletionAndPublishFlamegraph(
diff --git a/ui/src/controller/flow_events_controller.ts b/ui/src/controller/flow_events_controller.ts
index a1c4170..bf586d9 100644
--- a/ui/src/controller/flow_events_controller.ts
+++ b/ui/src/controller/flow_events_controller.ts
@@ -21,14 +21,8 @@
import {Flow, globals} from '../frontend/globals';
import {publishConnectedFlows, publishSelectedFlows} from '../frontend/publish';
import {asSliceSqlId} from '../frontend/sql_types';
-import {
- ACTUAL_FRAMES_SLICE_TRACK_KIND,
- Config as ActualConfig,
-} from '../tracks/actual_frames';
-import {
- Config as SliceConfig,
- SLICE_TRACK_KIND,
-} from '../tracks/chrome_slices';
+import {ACTUAL_FRAMES_SLICE_TRACK_KIND} from '../tracks/actual_frames';
+import {SLICE_TRACK_KIND} from '../tracks/chrome_slices';
import {Controller} from './controller';
@@ -206,7 +200,7 @@
const uiTrackIdToInfo = new Map<string, null|Info>();
const trackIdToInfo = new Map<number, null|Info>();
- const trackIdToUiTrackId = globals.state.uiTrackIdByTraceTrackId;
+ const trackIdToUiTrackId = globals.state.trackKeyByTrackId;
const tracks = globals.state.tracks;
const getInfo = (trackId: number): null|Info => {
@@ -237,24 +231,14 @@
// anything if there is only one TP track in this async track. In
// that case experimental_slice_layout is just an expensive way
// to find out depth === layout_depth.
- const trackIds = track.config.trackIds;
+ const trackInfo = pluginManager.resolveTrackInfo(track.uri);
+ const trackIds = trackInfo?.trackIds;
if (trackIds === undefined || trackIds.length <= 1) {
uiTrackIdToInfo.set(uiTrackId, null);
trackIdToInfo.set(trackId, null);
return null;
}
- // Perform the same check for "plugin" style tracks.
- if (track.uri) {
- const trackInfo = pluginManager.resolveTrackInfo(track.uri);
- const trackIds = trackInfo?.trackIds;
- if (trackIds === undefined || trackIds.length <= 1) {
- uiTrackIdToInfo.set(uiTrackId, null);
- trackIdToInfo.set(trackId, null);
- return null;
- }
- }
-
const newInfo = {
uiTrackId,
siblingTrackIds: trackIds,
@@ -390,19 +374,16 @@
for (const uiTrackId of area.tracks) {
const track = globals.state.tracks[uiTrackId];
- if (track === undefined) {
- continue;
- }
- if (track.kind === SLICE_TRACK_KIND) {
- trackIds.push((track.config as SliceConfig).trackId);
- } else if (track.kind === ACTUAL_FRAMES_SLICE_TRACK_KIND) {
- const actualConfig = track.config as ActualConfig;
- for (const trackId of actualConfig.trackIds) {
- trackIds.push(trackId);
- }
- } else if (track.config.trackIds !== undefined) {
- for (const trackId of track.config.trackIds) {
- trackIds.push(trackId);
+ if (track?.uri !== undefined) {
+ const trackInfo = pluginManager.resolveTrackInfo(track.uri);
+ const kind = trackInfo?.kind;
+ if (kind === SLICE_TRACK_KIND ||
+ kind === ACTUAL_FRAMES_SLICE_TRACK_KIND) {
+ if (trackInfo?.trackIds) {
+ for (const trackId of trackInfo.trackIds) {
+ trackIds.push(trackId);
+ }
+ }
}
}
}
diff --git a/ui/src/controller/record_controller.ts b/ui/src/controller/record_controller.ts
index 32d5e75..fe22ffb 100644
--- a/ui/src/controller/record_controller.ts
+++ b/ui/src/controller/record_controller.ts
@@ -14,6 +14,7 @@
import {Message, Method, rpc, RPCImplCallback} from 'protobufjs';
+import {isString} from '../base/object_utils';
import {base64Encode} from '../base/string_utils';
import {Actions} from '../common/actions';
import {TRACE_SUFFIX} from '../common/constants';
@@ -153,7 +154,7 @@
const isNested = typeof value === 'object' && !isRepeated;
for (const entry of (isRepeated ? value as Array<{}> : [value])) {
yield ' '.repeat(indent) + `${snakeCase(key)}${isNested ? '' : ':'} `;
- if (typeof entry === 'string') {
+ if (isString(entry)) {
if (isEnum(entry) || is64BitNumber(key)) {
yield entry;
} else {
diff --git a/ui/src/controller/search_controller.ts b/ui/src/controller/search_controller.ts
index 6055221..28f8e55 100644
--- a/ui/src/controller/search_controller.ts
+++ b/ui/src/controller/search_controller.ts
@@ -108,7 +108,7 @@
tsStarts: new BigInt64Array(0),
utids: new Float64Array(0),
sources: [],
- trackIds: [],
+ trackKeys: [],
totalResults: 0,
});
return;
@@ -206,7 +206,7 @@
const trackInfo = pluginManager.resolveTrackInfo(track.uri);
if (trackInfo?.kind === CPU_SLICE_TRACK_KIND) {
const cpu = trackInfo?.cpu;
- cpu && cpuToTrackId.set(cpu, track.id);
+ cpu && cpuToTrackId.set(cpu, track.key);
}
}
}
@@ -268,7 +268,7 @@
sliceIds: new Float64Array(rows),
tsStarts: new BigInt64Array(rows),
utids: new Float64Array(rows),
- trackIds: [],
+ trackKeys: [],
sources: [],
totalResults: 0,
};
@@ -280,12 +280,15 @@
if (it.source === 'cpu') {
trackId = cpuToTrackId.get(it.sourceId);
} else if (it.source === 'track') {
- trackId = globals.state.uiTrackIdByTraceTrackId[it.sourceId];
+ trackId = globals.state.trackKeyByTrackId[it.sourceId];
} else if (it.source === 'log') {
- const logTracks = Object.values(globals.state.tracks)
- .filter((t) => t.kind === 'AndroidLogTrack');
+ const logTracks =
+ Object.values(globals.state.tracks).filter((track) => {
+ const trackDesc = pluginManager.resolveTrackInfo(track.uri);
+ return (trackDesc && trackDesc.kind === 'AndroidLogTrack');
+ });
if (logTracks.length > 0) {
- trackId = logTracks[0].id;
+ trackId = logTracks[0].key;
}
}
@@ -295,7 +298,7 @@
}
const i = searchResults.totalResults++;
- searchResults.trackIds.push(trackId);
+ searchResults.trackKeys.push(trackId);
searchResults.sources.push(it.source);
searchResults.sliceIds[i] = it.sliceId;
searchResults.tsStarts[i] = it.ts;
diff --git a/ui/src/controller/selection_controller.ts b/ui/src/controller/selection_controller.ts
index b2c8ee5..7c44935 100644
--- a/ui/src/controller/selection_controller.ts
+++ b/ui/src/controller/selection_controller.ts
@@ -16,6 +16,7 @@
import {Time, time} from '../base/time';
import {Args, ArgValue} from '../common/arg_types';
import {Engine} from '../common/engine';
+import {pluginManager} from '../common/plugins';
import {
durationFromSql,
LONG,
@@ -303,18 +304,23 @@
const trackIdQuery = `select track_id as trackId from slice
where slice_id = ${sliceId}`;
const result = await this.args.engine.query(trackIdQuery);
- const trackIdTp = result.firstRow({trackId: NUM}).trackId;
+ const trackId = result.firstRow({trackId: NUM}).trackId;
// TODO(hjd): If we had a consistent mapping from TP track_id
// UI track id for slice tracks this would be unnecessary.
- let trackId = '';
+ let trackKey = '';
for (const track of Object.values(globals.state.tracks)) {
- if (track.kind === SLICE_TRACK_KIND &&
- (track.config as {trackId: number}).trackId === Number(trackIdTp)) {
- trackId = track.id;
- break;
+ if (track.uri) {
+ const trackInfo = pluginManager.resolveTrackInfo(track.uri);
+ if (trackInfo?.kind === SLICE_TRACK_KIND) {
+ const trackIds = trackInfo?.trackIds;
+ if (trackIds && trackIds.length > 0 && trackIds[0] === trackId) {
+ trackKey = track.key;
+ break;
+ }
+ }
}
}
- return trackId;
+ return trackKey;
}
// TODO(altimin): We currently rely on the ThreadStateDetails for supporting
@@ -417,8 +423,8 @@
const endTs = rightTs !== -1n ? rightTs : globals.state.traceTime.end;
const delta = value - previousValue;
const duration = endTs - ts;
- const uiTrackId = globals.state.uiTrackIdByTraceTrackId[trackId];
- const name = uiTrackId ? globals.state.tracks[uiTrackId].name : undefined;
+ const trackKey = globals.state.trackKeyByTrackId[trackId];
+ const name = trackKey ? globals.state.tracks[trackKey].name : undefined;
return {startTime: ts, value, delta, duration, name};
}
diff --git a/ui/src/controller/trace_controller.ts b/ui/src/controller/trace_controller.ts
index 31000d6..f323cb6 100644
--- a/ui/src/controller/trace_controller.ts
+++ b/ui/src/controller/trace_controller.ts
@@ -128,9 +128,7 @@
TraceHttpStream,
TraceStream,
} from './trace_stream';
-import {TrackControllerArgs, trackControllerRegistry} from './track_controller';
import {decideTracks} from './track_decider';
-import {VisualisedArgController} from './visualised_args_controller';
type States = 'init' | 'loading_trace' | 'ready';
@@ -217,6 +215,31 @@
});
}
+// TODO(stevegolton): Move this into some global "SQL extensions" file and
+// ensure it's only run once.
+async function defineMaxLayoutDepthSqlFunction(engine: Engine): Promise<void> {
+ await engine.query(`
+ select create_function(
+ 'max_layout_depth(track_count INT, track_ids STRING)',
+ 'INT',
+ '
+ select iif(
+ $track_count = 1,
+ (
+ select max(depth)
+ from slice
+ where track_id = cast($track_ids AS int)
+ ),
+ (
+ select max(layout_depth)
+ from experimental_slice_layout($track_ids)
+ )
+ );
+ '
+ );
+ `);
+}
+
// TraceController handles handshakes with the frontend for everything that
// concerns a single trace. It owns the WASM trace processor engine, handles
// tracks data and SQL queries. There is one TraceController instance for each
@@ -262,21 +285,6 @@
const engine = assertExists(this.engine);
const childControllers: Children = [];
- // Create a TrackController for each track.
- for (const trackId of Object.keys(globals.state.tracks)) {
- const trackCfg = globals.state.tracks[trackId];
- if (trackCfg.engineId !== this.engineId) continue;
- if (!trackControllerRegistry.has(trackCfg.kind)) continue;
- const trackCtlFactory = trackControllerRegistry.get(trackCfg.kind);
- const trackArgs: TrackControllerArgs = {trackId, engine};
- childControllers.push(Child(trackId, trackCtlFactory, trackArgs));
- }
-
- for (const argName of globals.state.visualisedArgs) {
- childControllers.push(
- Child(argName, VisualisedArgController, {argName, engine}));
- }
-
const selectionArgs: SelectionControllerArgs = {engine};
childControllers.push(
Child('selection', SelectionController, selectionArgs));
@@ -499,6 +507,8 @@
// Make sure the helper views are available before we start adding tracks.
await this.initialiseHelperViews();
+ await defineMaxLayoutDepthSqlFunction(engine);
+
pluginManager.onTraceLoad(engine);
{
@@ -706,13 +716,13 @@
});
const id = row.traceProcessorTrackId;
- const trackId = globals.state.uiTrackIdByTraceTrackId[id];
- if (trackId === undefined) {
+ const trackKey = globals.state.trackKeyByTrackId[id];
+ if (trackKey === undefined) {
return;
}
globals.makeSelection(Actions.selectChromeSlice({
id: row.id,
- trackId,
+ trackKey,
table: '',
scroll: true,
}));
@@ -722,7 +732,7 @@
private async listTracks() {
this.updateStatus('Loading tracks');
const engine = assertExists<Engine>(this.engine);
- const actions = await decideTracks(this.engineId, engine);
+ const actions = await decideTracks(engine);
globals.dispatchMultiple(actions);
}
diff --git a/ui/src/controller/track_controller.ts b/ui/src/controller/track_controller.ts
deleted file mode 100644
index 539e561..0000000
--- a/ui/src/controller/track_controller.ts
+++ /dev/null
@@ -1,202 +0,0 @@
-// Copyright (C) 2018 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 {BigintMath} from '../base/bigint_math';
-import {assertExists} from '../base/logging';
-import {duration, time, Time, TimeSpan} from '../base/time';
-import {Engine} from '../common/engine';
-import {Registry} from '../common/registry';
-import {RESOLUTION_DEFAULT, TraceTime, TrackState} from '../common/state';
-import {LIMIT, TrackData} from '../common/track_data';
-import {globals} from '../frontend/globals';
-import {publishTrackData} from '../frontend/publish';
-
-import {Controller, ControllerFactory} from './controller';
-
-interface TrackConfig {}
-
-type TrackConfigWithNamespace = TrackConfig&{namespace: string};
-
-// TrackController is a base class overridden by track implementations (e.g.,
-// sched slices, nestable slices, counters).
-export abstract class TrackController<
- Config extends TrackConfig, Data extends TrackData = TrackData> extends
- Controller<'main'> {
- readonly trackId: string;
- readonly engine: Engine;
- private data?: TrackData;
- private requestingData = false;
- private queuedRequest = false;
- private isSetup = false;
- private lastReloadHandled = 0;
-
- constructor(args: TrackControllerArgs) {
- super('main');
- this.trackId = args.trackId;
- this.engine = args.engine;
- }
-
- // Can be overriden by the track implementation to allow one time setup work
- // to be performed before the first onBoundsChange invcation.
- async onSetup() {}
-
- // Can be overriden by the track implementation to allow some one-off work
- // when requested reload (e.g. recalculating height).
- async onReload() {}
-
- // Must be overridden by the track implementation. Is invoked when the track
- // frontend runs out of cached data. The derived track controller is expected
- // to publish new track data in response to this call.
- abstract onBoundsChange(start: time, end: time, resolution: duration):
- Promise<Data>;
-
- get trackState(): TrackState {
- return assertExists(globals.state.tracks[this.trackId]);
- }
-
- get config(): Config {
- return this.trackState.config as Config;
- }
-
- configHasNamespace(config: TrackConfig): config is TrackConfigWithNamespace {
- return 'namespace' in config;
- }
-
- namespaceTable(tableName: string): string {
- if (this.configHasNamespace(this.config)) {
- return this.config.namespace + '_' + tableName;
- } else {
- return tableName;
- }
- }
-
- publish(data: Data): void {
- this.data = data;
- publishTrackData({id: this.trackId, data});
- }
-
- // Returns a valid SQL table name with the given prefix that should be unique
- // for each track.
- tableName(prefix: string) {
- // Derive table name from, since that is unique for each track.
- // Track ID can be UUID but '-' is not valid for sql table name.
- const idSuffix = this.trackId.split('-').join('_');
- return `${prefix}_${idSuffix}`;
- }
-
- shouldSummarize(resolution: number): boolean {
- // |resolution| is in s/px (to nearest power of 10) assuming a display
- // of ~1000px 0.0008 is 0.8s.
- return resolution >= 0.0008;
- }
-
- protected async query(query: string) {
- const result = await this.engine.query(query);
- return result;
- }
-
- private shouldReload(): boolean {
- const {lastTrackReloadRequest} = globals.state;
- return !!lastTrackReloadRequest &&
- this.lastReloadHandled < lastTrackReloadRequest;
- }
-
- private markReloadHandled() {
- this.lastReloadHandled = globals.state.lastTrackReloadRequest || 0;
- }
-
- shouldRequestData(traceTime: TraceTime): boolean {
- const tspan = new TimeSpan(traceTime.start, traceTime.end);
- if (this.data === undefined) return true;
- if (this.shouldReload()) return true;
-
- // If at the limit only request more data if the view has moved.
- const atLimit = this.data.length === LIMIT;
- if (atLimit) {
- // We request more data than the window, so add window duration to find
- // the previous window.
- const prevWindowStart = this.data.start + tspan.duration;
- return tspan.start !== prevWindowStart;
- }
-
- // Otherwise request more data only when out of range of current data or
- // resolution has changed.
- const inRange =
- tspan.start >= this.data.start && tspan.end <= this.data.end;
- return !inRange ||
- this.data.resolution !==
- globals.state.frontendLocalState.visibleState.resolution;
- }
-
- run() {
- const visibleState = globals.state.frontendLocalState.visibleState;
- if (visibleState === undefined) {
- return;
- }
- const visibleTimeSpan = globals.stateVisibleTime();
- const dur = visibleTimeSpan.duration;
- if (globals.state.visibleTracks.includes(this.trackId) &&
- this.shouldRequestData(visibleState)) {
- if (this.requestingData) {
- this.queuedRequest = true;
- } else {
- this.requestingData = true;
- let promise = Promise.resolve();
- if (!this.isSetup) {
- promise = this.onSetup();
- } else if (this.shouldReload()) {
- promise = this.onReload().then(() => this.markReloadHandled());
- }
- promise
- .then(() => {
- this.isSetup = true;
- let resolution = visibleState.resolution;
-
- // If resolution is not a power of 2, reset to the default value
- if (BigintMath.popcount(resolution) !== 1) {
- resolution = RESOLUTION_DEFAULT;
- }
-
- return this.onBoundsChange(
- Time.sub(visibleTimeSpan.start, dur),
- Time.add(visibleTimeSpan.end, dur),
- resolution);
- })
- .then((data) => {
- this.publish(data);
- })
- .finally(() => {
- this.requestingData = false;
- if (this.queuedRequest) {
- this.queuedRequest = false;
- this.run();
- }
- });
- }
- }
- }
-}
-
-export interface TrackControllerArgs {
- trackId: string;
- engine: Engine;
-}
-
-export interface TrackControllerFactory extends
- ControllerFactory<TrackControllerArgs> {
- kind: string;
-}
-
-export const trackControllerRegistry =
- Registry.kindRegistry<TrackControllerFactory>();
diff --git a/ui/src/controller/track_decider.ts b/ui/src/controller/track_decider.ts
index b4a8228..c07c1ab 100644
--- a/ui/src/controller/track_decider.ts
+++ b/ui/src/controller/track_decider.ts
@@ -43,27 +43,18 @@
import {
ENABLE_SCROLL_JANK_PLUGIN_V2,
getScrollJankTracks,
- INPUT_LATENCY_TRACK,
} from '../tracks/chrome_scroll_jank';
import {
decideTracks as scrollJankDecideTracks,
} from '../tracks/chrome_scroll_jank/chrome_tasks_scroll_jank_track';
import {SLICE_TRACK_KIND} from '../tracks/chrome_slices';
import {COUNTER_TRACK_KIND} from '../tracks/counter';
-import {CPU_PROFILE_TRACK_KIND} from '../tracks/cpu_profile';
-import {
- EXPECTED_FRAMES_SLICE_TRACK_KIND,
-} from '../tracks/expected_frames';
-import {HEAP_PROFILE_TRACK_KIND} from '../tracks/heap_profile';
-import {NULL_TRACK_KIND} from '../tracks/null_track';
-import {
- PERF_SAMPLES_PROFILE_TRACK_KIND,
-} from '../tracks/perf_samples_profile';
+import {EXPECTED_FRAMES_SLICE_TRACK_KIND} from '../tracks/expected_frames';
+import {NULL_TRACK_URI} from '../tracks/null_track';
import {
decideTracks as screenshotDecideTracks,
} from '../tracks/screenshots';
import {THREAD_STATE_TRACK_KIND} from '../tracks/thread_state';
-import {THREAD_STATE_TRACK_V2_KIND} from '../tracks/thread_state_v2';
const TRACKS_V2_FLAG = featureFlags.register({
id: 'tracksV2.1',
@@ -80,11 +71,6 @@
defaultValue: false,
});
-// Special kind reserved for plugin tracks.
-// There is no significance to this value, it simply something that's unlikely
-// to be used as a key in the trackRegistry.
-const PLUGIN_TRACK_KIND = 'PLUGIN_TRACK';
-
function showV2(): boolean {
return TRACKS_V2_FLAG.get();
}
@@ -125,21 +111,18 @@
const CHROME_TRACK_GROUP = 'Chrome Global Tracks';
const MISC_GROUP = 'Misc Global Tracks';
-export async function decideTracks(
- engineId: string, engine: Engine): Promise<DeferredAction[]> {
- return (new TrackDecider(engineId, engine)).decideTracks();
+export async function decideTracks(engine: Engine): Promise<DeferredAction[]> {
+ return (new TrackDecider(engine)).decideTracks();
}
class TrackDecider {
- private engineId: string;
private engine: Engine;
private upidToUuid = new Map<number, string>();
private utidToUuid = new Map<number, string>();
private tracksToAdd: AddTrackArgs[] = [];
private addTrackGroupActions: DeferredAction[] = [];
- constructor(engineId: string, engine: Engine) {
- this.engineId = engineId;
+ constructor(engine: Engine) {
this.engine = engine;
}
@@ -175,29 +158,14 @@
const size = cpuToSize.get(cpu);
const name = size === undefined ? `Cpu ${cpu}` : `Cpu ${cpu} (${size})`;
this.tracksToAdd.push({
- engineId: this.engineId,
- kind: PLUGIN_TRACK_KIND,
+ uri: `perfetto.CpuSlices#cpu${cpu}`,
trackSortKey: PrimaryTrackSortKey.ORDINARY_TRACK,
name,
trackGroup: SCROLLING_TRACK_GROUP,
- config: {},
- uri: `perfetto.CpuSlices#cpu${cpu}`,
});
}
}
- async addScrollJankTracks(engine: Engine): Promise<void> {
- const scrollJankTracks = getScrollJankTracks(engine);
- const scrollJankTracksResult = await scrollJankTracks;
- const originalLength = this.tracksToAdd.length;
- this.tracksToAdd.length += scrollJankTracksResult.tracksToAdd.length;
-
- for (let i = 0; i < scrollJankTracksResult.tracksToAdd.length; ++i) {
- this.tracksToAdd[i + originalLength] =
- scrollJankTracksResult.tracksToAdd[i];
- }
- }
-
async addCpuFreqTracks(engine: EngineProxy): Promise<void> {
const cpus = await this.engine.getCpus();
@@ -223,13 +191,10 @@
if (cpuFreqIdleResult.numRows() > 0) {
this.tracksToAdd.push({
- engineId: this.engineId,
- kind: PLUGIN_TRACK_KIND,
+ uri: `perfetto.CpuFreq#${cpu}`,
trackSortKey: PrimaryTrackSortKey.ORDINARY_TRACK,
name: `Cpu ${cpu} Frequency`,
trackGroup: SCROLLING_TRACK_GROUP,
- config: {},
- uri: `perfetto.CpuFreq#${cpu}`,
});
}
}
@@ -276,20 +241,16 @@
name: STR_NULL,
parentName: STR_NULL,
parentId: NUM_NULL,
- trackIds: STR,
maxDepth: NUM_NULL,
});
const parentIdToGroupId = new Map<number, string>();
- let scrollJankRendered = false;
for (; it.valid(); it.next()) {
const kind = ASYNC_SLICE_TRACK_KIND;
const rawName = it.name === null ? undefined : it.name;
const rawParentName = it.parentName === null ? undefined : it.parentName;
const name = getTrackName({name: rawName, kind});
- const rawTrackIds = it.trackIds;
- const trackIds = rawTrackIds.split(',').map((v) => Number(v));
const parentTrackId = it.parentId;
const maxDepth = it.maxDepth;
let trackGroup = SCROLLING_TRACK_GROUP;
@@ -307,20 +268,17 @@
const parentName = getTrackName({name: rawParentName, kind});
- const summaryTrackId = uuidv4();
+ const summaryTrackKey = uuidv4();
this.tracksToAdd.push({
- id: summaryTrackId,
- engineId: this.engineId,
- kind: NULL_TRACK_KIND,
+ uri: NULL_TRACK_URI,
+ key: summaryTrackKey,
trackSortKey: PrimaryTrackSortKey.NULL_TRACK,
trackGroup: undefined,
name: parentName,
- config: {},
});
this.addTrackGroupActions.push(Actions.addTrackGroup({
- engineId: this.engineId,
- summaryTrackId,
+ summaryTrackKey: summaryTrackKey,
name: parentName,
id: trackGroup,
collapsed: true,
@@ -330,23 +288,11 @@
}
}
- if (ENABLE_SCROLL_JANK_PLUGIN_V2.get() && !scrollJankRendered &&
- name.includes(INPUT_LATENCY_TRACK)) {
- // This ensures that the scroll jank tracks render above the tracks
- // for GestureScrollUpdate.
- await this.addScrollJankTracks(this.engine);
- scrollJankRendered = true;
- }
- const track = {
- engineId: this.engineId,
- kind,
+ const track: AddTrackArgs = {
+ uri: `perfetto.AsyncSlices#${rawName}`,
trackSortKey: PrimaryTrackSortKey.ASYNC_SLICE_TRACK,
trackGroup,
name,
- config: {
- maxDepth,
- trackIds,
- },
};
this.tracksToAdd.push(track);
@@ -366,13 +312,10 @@
`);
if (freqExistsResult.numRows() > 0) {
this.tracksToAdd.push({
- engineId: this.engineId,
- kind: PLUGIN_TRACK_KIND,
+ uri: `perfetto.Counter#gpu_freq${gpu}`,
name: `Gpu ${gpu} Frequency`,
trackSortKey: PrimaryTrackSortKey.COUNTER_TRACK,
trackGroup: SCROLLING_TRACK_GROUP,
- config: {},
- uri: `perfetto.Counter#gpu_freq${gpu}`,
});
}
}
@@ -416,13 +359,10 @@
const name = it.name;
const trackId = it.id;
this.tracksToAdd.push({
- engineId: this.engineId,
- kind: PLUGIN_TRACK_KIND,
+ uri: `perfetto.Counter#cpu${trackId}`,
name,
trackSortKey: PrimaryTrackSortKey.COUNTER_TRACK,
trackGroup: SCROLLING_TRACK_GROUP,
- config: {},
- uri: `perfetto.Counter#cpu${trackId}`,
});
}
}
@@ -447,14 +387,14 @@
}
const id = uuidv4();
- const summaryTrackId = uuidv4();
+ const summaryTrackKey = uuidv4();
let foundSummary = false;
for (const track of ionTracks) {
if (!foundSummary &&
[MEM_DMA_COUNTER_NAME, MEM_ION].includes(track.name)) {
foundSummary = true;
- track.id = summaryTrackId;
+ track.key = summaryTrackKey;
track.trackGroup = undefined;
} else {
track.trackGroup = id;
@@ -462,8 +402,7 @@
}
const addGroup = Actions.addTrackGroup({
- engineId: this.engineId,
- summaryTrackId,
+ summaryTrackKey,
name: MEM_DMA_COUNTER_NAME,
id,
collapsed: true,
@@ -497,21 +436,18 @@
for (const [key, value] of devMap) {
const groupName = group + key;
- const summaryTrackId = uuidv4();
+ const summaryTrackKey = uuidv4();
this.tracksToAdd.push({
- id: summaryTrackId,
- engineId: this.engineId,
- kind: NULL_TRACK_KIND,
+ uri: NULL_TRACK_URI,
+ key: summaryTrackKey,
trackSortKey: PrimaryTrackSortKey.NULL_TRACK,
name: groupName,
trackGroup: undefined,
- config: {},
});
const addGroup = Actions.addTrackGroup({
- engineId: this.engineId,
- summaryTrackId,
+ summaryTrackKey,
name: groupName,
id: value,
collapsed: true,
@@ -534,15 +470,14 @@
}
const id = uuidv4();
- const summaryTrackId = uuidv4();
- ufsCmdTagTracks[0].id = summaryTrackId;
+ const summaryTrackKey = uuidv4();
+ ufsCmdTagTracks[0].key = summaryTrackKey;
for (const track of ufsCmdTagTracks) {
track.trackGroup = id;
}
const addGroup = Actions.addTrackGroup({
- engineId: this.engineId,
- summaryTrackId,
+ summaryTrackKey,
name: group,
id,
collapsed: true,
@@ -580,21 +515,18 @@
for (const [key, value] of devMap) {
const groupName = key;
- const summaryTrackId = uuidv4();
+ const summaryTrackKey = uuidv4();
this.tracksToAdd.push({
- id: summaryTrackId,
- engineId: this.engineId,
- kind: NULL_TRACK_KIND,
+ uri: NULL_TRACK_URI,
+ key: summaryTrackKey,
trackSortKey: PrimaryTrackSortKey.NULL_TRACK,
name: groupName,
trackGroup: undefined,
- config: {},
});
const addGroup = Actions.addTrackGroup({
- engineId: this.engineId,
- summaryTrackId,
+ summaryTrackKey,
name: groupName,
id: value,
collapsed: true,
@@ -614,7 +546,7 @@
track.trackGroup !== SCROLLING_TRACK_GROUP) {
continue;
}
- if (track.kind === NULL_TRACK_KIND) {
+ if (track.uri === NULL_TRACK_URI) {
continue;
}
if (groupUuid === undefined) {
@@ -625,20 +557,17 @@
}
if (groupUuid !== undefined) {
- const summaryTrackId = uuidv4();
+ const summaryTrackKey = uuidv4();
this.tracksToAdd.push({
- id: summaryTrackId,
- engineId: this.engineId,
- kind: NULL_TRACK_KIND,
+ uri: NULL_TRACK_URI,
+ key: summaryTrackKey,
trackSortKey: PrimaryTrackSortKey.NULL_TRACK,
name: groupName,
trackGroup: undefined,
- config: {},
});
const addGroup = Actions.addTrackGroup({
- engineId: this.engineId,
- summaryTrackId,
+ summaryTrackKey,
name: groupName,
id: groupUuid,
collapsed: true,
@@ -650,8 +579,8 @@
async groupMiscNonAllowlistedTracks(groupName: string): Promise<void> {
// List of allowlisted track names.
const ALLOWLIST_REGEXES = [
- new RegExp('^Cpu .*$'),
- new RegExp('^Gpu .*$'),
+ new RegExp('^Cpu .*$', 'i'),
+ new RegExp('^Gpu .*$', 'i'),
new RegExp('^Trace Triggers$'),
new RegExp('^Android App Startups$'),
];
@@ -662,7 +591,7 @@
track.trackGroup !== SCROLLING_TRACK_GROUP) {
continue;
}
- if (track.kind === NULL_TRACK_KIND) {
+ if (track.uri === NULL_TRACK_URI) {
continue;
}
let allowlisted = false;
@@ -679,20 +608,17 @@
}
if (groupUuid !== undefined) {
- const summaryTrackId = uuidv4();
+ const summaryTrackKey = uuidv4();
this.tracksToAdd.push({
- id: summaryTrackId,
- engineId: this.engineId,
- kind: NULL_TRACK_KIND,
+ uri: NULL_TRACK_URI,
+ key: summaryTrackKey,
trackSortKey: PrimaryTrackSortKey.NULL_TRACK,
name: groupName,
trackGroup: undefined,
- config: {},
});
const addGroup = Actions.addTrackGroup({
- engineId: this.engineId,
- summaryTrackId,
+ summaryTrackKey,
name: groupName,
id: groupUuid,
collapsed: true,
@@ -710,7 +636,7 @@
track.trackGroup !== SCROLLING_TRACK_GROUP) {
continue;
}
- if (track.kind === NULL_TRACK_KIND) {
+ if (track.uri === NULL_TRACK_URI) {
continue;
}
if (groupUuid === undefined) {
@@ -721,20 +647,17 @@
}
if (groupUuid !== undefined) {
- const summaryTrackId = uuidv4();
+ const summaryTrackKey = uuidv4();
this.tracksToAdd.push({
- id: summaryTrackId,
- engineId: this.engineId,
- kind: NULL_TRACK_KIND,
+ uri: NULL_TRACK_URI,
+ key: summaryTrackKey,
trackSortKey: PrimaryTrackSortKey.NULL_TRACK,
name: groupName,
trackGroup: undefined,
- config: {},
});
const addGroup = Actions.addTrackGroup({
- engineId: this.engineId,
- summaryTrackId,
+ summaryTrackKey: summaryTrackKey,
name: groupName,
id: groupUuid,
collapsed: true,
@@ -750,13 +673,10 @@
if (count > 0) {
this.tracksToAdd.push({
- engineId: this.engineId,
- kind: PLUGIN_TRACK_KIND,
+ uri: 'perfetto.AndroidLog',
name: 'Android logs',
trackSortKey: PrimaryTrackSortKey.ORDINARY_TRACK,
trackGroup: SCROLLING_TRACK_GROUP,
- config: {},
- uri: 'perfetto.AndroidLog',
});
}
}
@@ -768,41 +688,35 @@
const it = result.iter({cpu: NUM});
let groupUuid = undefined;
- let summaryTrackId = undefined;
+ let summaryTrackKey = undefined;
// use the first one as the summary track
for (let row = 0; it.valid(); it.next(), row++) {
if (groupUuid === undefined) {
groupUuid = 'ftrace-track-group';
- summaryTrackId = uuidv4();
+ summaryTrackKey = uuidv4();
this.tracksToAdd.push({
- engineId: this.engineId,
- kind: NULL_TRACK_KIND,
+ uri: NULL_TRACK_URI,
trackSortKey: PrimaryTrackSortKey.NULL_TRACK,
name: `Ftrace Events`,
trackGroup: undefined,
- config: {},
- id: summaryTrackId,
+ key: summaryTrackKey,
});
}
this.tracksToAdd.push({
- engineId: this.engineId,
- kind: PLUGIN_TRACK_KIND,
+ uri: `perfetto.FtraceRaw#cpu${it.cpu}`,
trackSortKey: PrimaryTrackSortKey.ORDINARY_TRACK,
name: `Ftrace Events Cpu ${it.cpu}`,
trackGroup: groupUuid,
- config: {},
- uri: `perfetto.FtraceRaw#cpu${it.cpu}`,
});
}
- if (groupUuid !== undefined && summaryTrackId !== undefined) {
+ if (groupUuid !== undefined && summaryTrackKey !== undefined) {
const addGroup = Actions.addTrackGroup({
- engineId: this.engineId,
name: 'Ftrace Events',
id: groupUuid,
collapsed: true,
- summaryTrackId,
+ summaryTrackKey,
});
this.addTrackGroupActions.push(addGroup);
}
@@ -824,7 +738,7 @@
interface GroupIds {
id: string;
- summaryTrackId: string;
+ summaryTrackKey: string;
}
const groupNameToIds = new Map<string, GroupIds>();
@@ -835,7 +749,7 @@
const upid = sliceIt.upid;
const groupName = sliceIt.group_name;
- let summaryTrackId = undefined;
+ let summaryTrackKey = undefined;
let trackGroupId =
upid === 0 ? SCROLLING_TRACK_GROUP : this.upidToUuid.get(upid);
@@ -848,33 +762,26 @@
trackGroupId = groupIds.id;
} else {
trackGroupId = uuidv4();
- summaryTrackId = uuidv4();
+ summaryTrackKey = uuidv4();
groupNameToIds.set(groupName, {
id: trackGroupId,
- summaryTrackId,
+ summaryTrackKey,
});
}
}
this.tracksToAdd.push({
- id: summaryTrackId,
- engineId: this.engineId,
- kind: SLICE_TRACK_KIND,
+ uri: `perfetto.Annotation#${id}`,
+ key: summaryTrackKey,
name,
trackSortKey: PrimaryTrackSortKey.ORDINARY_TRACK,
trackGroup: trackGroupId,
- config: {
- maxDepth: 0,
- namespace: 'annotation',
- trackId: id,
- },
});
}
for (const [groupName, groupIds] of groupNameToIds) {
const addGroup = Actions.addTrackGroup({
- engineId: this.engineId,
- summaryTrackId: groupIds.summaryTrackId,
+ summaryTrackKey: groupIds.summaryTrackKey,
name: groupName,
id: groupIds.id,
collapsed: true,
@@ -897,16 +804,11 @@
const name = counterIt.name;
const upid = counterIt.upid;
this.tracksToAdd.push({
- engineId: this.engineId,
- kind: PLUGIN_TRACK_KIND,
+ uri: `perfetto.Annotation#counter${id}`,
name,
trackSortKey: PrimaryTrackSortKey.COUNTER_TRACK,
trackGroup: upid === 0 ? SCROLLING_TRACK_GROUP :
this.upidToUuid.get(upid),
- config: {
- namespace: 'annotation',
- },
- uri: `perfetto.Annotation#counter${id}`,
});
}
}
@@ -951,30 +853,26 @@
if (showV1()) {
const kind = THREAD_STATE_TRACK_KIND;
this.tracksToAdd.push({
- engineId: this.engineId,
- kind: THREAD_STATE_TRACK_KIND,
+ uri: `perfetto.ThreadState#${upid}.${utid}`,
name: getTrackName({utid, tid, threadName, kind}),
trackGroup: uuid,
trackSortKey: {
utid,
priority,
},
- config: {utid, tid},
});
}
if (showV2()) {
- const kind = THREAD_STATE_TRACK_V2_KIND;
this.tracksToAdd.push({
- engineId: this.engineId,
- kind,
- name: getTrackName({utid, tid, threadName, kind}),
+ uri: `perfetto.ThreadState#${utid}.v2`,
+ name:
+ getTrackName({utid, tid, threadName, kind: 'ThreadStateTrackV2'}),
trackGroup: uuid,
trackSortKey: {
utid,
priority,
},
- config: {utid, tid},
});
}
}
@@ -1008,15 +906,13 @@
const threadName = it.threadName;
const uuid = this.getUuid(utid, upid);
this.tracksToAdd.push({
- engineId: this.engineId,
- kind: CPU_PROFILE_TRACK_KIND,
+ uri: `perfetto.CpuProfile#${utid}`,
trackSortKey: {
utid,
priority: InThreadTrackSortKey.CPU_STACK_SAMPLES_TRACK,
},
name: `${threadName} (CPU Stack Samples)`,
trackGroup: uuid,
- config: {utid},
});
}
}
@@ -1061,16 +957,13 @@
threadTrack: true,
});
this.tracksToAdd.push({
- engineId: this.engineId,
- kind: PLUGIN_TRACK_KIND,
+ uri: `perfetto.Counter#thread${trackId}`,
name,
trackSortKey: {
utid,
priority: InThreadTrackSortKey.ORDINARY,
},
trackGroup: uuid,
- config: {},
- uri: `perfetto.Counter#thread${trackId}`,
});
}
}
@@ -1112,7 +1005,6 @@
const upid = it.upid;
const trackName = it.trackName;
const rawTrackIds = it.trackIds;
- const trackIds = rawTrackIds.split(',').map((v) => Number(v));
const processName = it.processName;
const pid = it.pid;
const maxDepth = it.maxDepth;
@@ -1123,20 +1015,18 @@
}
const uuid = this.getUuid(0, upid);
-
- const kind = ASYNC_SLICE_TRACK_KIND;
- const name =
- getTrackName({name: trackName, upid, pid, processName, kind});
+ const name = getTrackName({
+ name: trackName,
+ upid,
+ pid,
+ processName,
+ kind: ASYNC_SLICE_TRACK_KIND,
+ });
this.tracksToAdd.push({
- engineId: this.engineId,
- kind,
+ uri: `perfetto.AsyncSlices#process.${pid}${rawTrackIds}`,
name,
trackSortKey: PrimaryTrackSortKey.ASYNC_SLICE_TRACK,
trackGroup: uuid,
- config: {
- trackIds,
- maxDepth,
- },
});
}
}
@@ -1167,7 +1057,6 @@
const it = result.iter({
upid: NUM,
trackName: STR_NULL,
- trackIds: STR,
processName: STR_NULL,
pid: NUM_NULL,
maxDepth: NUM_NULL,
@@ -1175,8 +1064,6 @@
for (; it.valid(); it.next()) {
const upid = it.upid;
const trackName = it.trackName;
- const rawTrackIds = it.trackIds;
- const trackIds = rawTrackIds.split(',').map((v) => Number(v));
const processName = it.processName;
const pid = it.pid;
const maxDepth = it.maxDepth;
@@ -1192,15 +1079,10 @@
const name =
getTrackName({name: trackName, upid, pid, processName, kind});
this.tracksToAdd.push({
- engineId: this.engineId,
- kind,
+ uri: `perfetto.ActualFrames#${upid}`,
name,
trackSortKey: PrimaryTrackSortKey.ACTUAL_FRAMES_SLICE_TRACK,
trackGroup: uuid,
- config: {
- trackIds,
- maxDepth,
- },
});
}
}
@@ -1231,7 +1113,6 @@
const it = result.iter({
upid: NUM,
trackName: STR_NULL,
- trackIds: STR,
processName: STR_NULL,
pid: NUM_NULL,
maxDepth: NUM_NULL,
@@ -1240,8 +1121,6 @@
for (; it.valid(); it.next()) {
const upid = it.upid;
const trackName = it.trackName;
- const rawTrackIds = it.trackIds;
- const trackIds = rawTrackIds.split(',').map((v) => Number(v));
const processName = it.processName;
const pid = it.pid;
const maxDepth = it.maxDepth;
@@ -1257,15 +1136,10 @@
const name =
getTrackName({name: trackName, upid, pid, processName, kind});
this.tracksToAdd.push({
- engineId: this.engineId,
- kind,
+ uri: `perfetto.ExpectedFrames#${upid}`,
name,
trackSortKey: PrimaryTrackSortKey.EXPECTED_FRAMES_SLICE_TRACK,
trackGroup: uuid,
- config: {
- trackIds,
- maxDepth,
- },
});
}
}
@@ -1280,7 +1154,6 @@
'is_root_in_scope') as isDefaultTrackForScope,
tid,
thread.name as threadName,
- max(slice.depth) as maxDepth,
process.upid as upid
from slice
join thread_track on slice.track_id = thread_track.id
@@ -1296,7 +1169,6 @@
isDefaultTrackForScope: NUM_NULL,
tid: NUM_NULL,
threadName: STR_NULL,
- maxDepth: NUM,
upid: NUM_NULL,
});
for (; it.valid(); it.next()) {
@@ -1308,7 +1180,6 @@
const tid = it.tid;
const threadName = it.threadName;
const upid = it.upid;
- const maxDepth = it.maxDepth;
const uuid = this.getUuid(utid, upid);
@@ -1316,8 +1187,7 @@
const name = getTrackName({name: trackName, utid, tid, threadName, kind});
if (showV1()) {
this.tracksToAdd.push({
- engineId: this.engineId,
- kind,
+ uri: `perfetto.ChromeSlices#${trackId}`,
name,
trackGroup: uuid,
trackSortKey: {
@@ -1326,18 +1196,12 @@
InThreadTrackSortKey.DEFAULT_TRACK :
InThreadTrackSortKey.ORDINARY,
},
- config: {
- trackId,
- maxDepth,
- tid,
- },
});
}
if (showV2()) {
this.tracksToAdd.push({
- engineId: this.engineId,
- kind: 'GenericSliceTrack',
+ uri: `perfetto.ChromeSlices#${trackId}.v2`,
name,
trackGroup: uuid,
trackSortKey: {
@@ -1346,7 +1210,6 @@
InThreadTrackSortKey.DEFAULT_TRACK :
InThreadTrackSortKey.ORDINARY,
},
- config: {sqlTrackId: trackId},
});
}
}
@@ -1380,14 +1243,11 @@
const name = getTrackName(
{name: trackName, upid, pid, kind: COUNTER_TRACK_KIND, processName});
this.tracksToAdd.push({
- engineId: this.engineId,
- kind: PLUGIN_TRACK_KIND,
+ uri: `perfetto.Counter#process${trackId}`,
name,
trackSortKey: await this.resolveTrackSortKeyForProcessCounterTrack(
upid, trackName || undefined),
trackGroup: uuid,
- config: {},
- uri: `perfetto.Counter#process${trackId}`,
});
}
}
@@ -1402,12 +1262,10 @@
const upid = it.upid;
const uuid = this.getUuid(0, upid);
this.tracksToAdd.push({
- engineId: this.engineId,
- kind: HEAP_PROFILE_TRACK_KIND,
+ uri: `perfetto.HeapProfile#${upid}`,
trackSortKey: PrimaryTrackSortKey.HEAP_PROFILE_TRACK,
name: `Heap Profile`,
trackGroup: uuid,
- config: {upid},
});
}
}
@@ -1423,12 +1281,10 @@
const pid = it.pid;
const uuid = this.getUuid(0, upid);
this.tracksToAdd.push({
- engineId: this.engineId,
- kind: PERF_SAMPLES_PROFILE_TRACK_KIND,
+ uri: `perfetto.PerfSamplesProfile#${upid}`,
trackSortKey: PrimaryTrackSortKey.PERF_SAMPLES_PROFILE_TRACK,
name: `Callstacks ${pid}`,
trackGroup: uuid,
- config: {upid},
});
}
}
@@ -1501,19 +1357,15 @@
// but creating a dedicated track type is out of scope at the time of
// writing.
const kthreadGroupUuid = uuidv4();
- const summaryTrackId = uuidv4();
+ const summaryTrackKey = uuidv4();
this.tracksToAdd.push({
- id: summaryTrackId,
- engineId: this.engineId,
- kind: PLUGIN_TRACK_KIND,
+ uri: 'perfetto.ProcessSummary#kernel',
+ key: summaryTrackKey,
trackSortKey: PrimaryTrackSortKey.PROCESS_SUMMARY_TRACK,
name: `Kernel thread summary`,
- config: {},
- uri: 'perfetto.ProcessSummary#kernel',
});
const addTrackGroup = Actions.addTrackGroup({
- engineId: this.engineId,
- summaryTrackId,
+ summaryTrackKey,
name: `Kernel threads`,
id: kthreadGroupUuid,
collapsed: true,
@@ -1675,28 +1527,24 @@
// These should only happen once for each track group.
if (pUuid === undefined) {
pUuid = this.getOrCreateUuid(utid, upid);
- const summaryTrackId = uuidv4();
+ const summaryTrackKey = uuidv4();
const type = hasSched ? 'schedule' : 'summary';
const uri = `perfetto.ProcessScheduling#${upid}.${utid}.${type}`;
this.tracksToAdd.push({
- id: summaryTrackId,
- engineId: this.engineId,
- kind: PLUGIN_TRACK_KIND,
+ uri,
+ key: summaryTrackKey,
trackSortKey: hasSched ?
PrimaryTrackSortKey.PROCESS_SCHEDULING_TRACK :
PrimaryTrackSortKey.PROCESS_SUMMARY_TRACK,
name: `${upid === null ? tid : pid} summary`,
- config: {},
labels: it.chromeProcessLabels.split(','),
- uri,
});
const name =
getTrackName({utid, processName, pid, threadName, tid, upid});
const addTrackGroup = Actions.addTrackGroup({
- engineId: this.engineId,
- summaryTrackId,
+ summaryTrackKey,
name,
id: pUuid,
// Perf profiling tracks remain collapsed, otherwise we would have too
@@ -1737,49 +1585,29 @@
return threadOrderingMetadata;
}
- private async defineMaxLayoutDepthSqlFunction(): Promise<void> {
- await this.engine.query(`
- select create_function(
- 'max_layout_depth(track_count INT, track_ids STRING)',
- 'INT',
- '
- select iif(
- $track_count = 1,
- (
- select max(depth)
- from slice
- where track_id = cast($track_ids AS int)
- ),
- (
- select max(layout_depth)
- from experimental_slice_layout($track_ids)
- )
- );
- '
- );
- `);
- }
-
addPluginTracks(): void {
const tracks = pluginManager.findPotentialTracks();
for (const info of tracks) {
this.tracksToAdd.push({
- engineId: this.engineId,
- kind: PLUGIN_TRACK_KIND,
- name: info.name,
uri: info.uri,
+ name: info.displayName,
// TODO(hjd): Fix how sorting works. Plugins should expose
// 'sort keys' which the user can use to choose a sort order.
- trackSortKey: info.sortKey,
+ trackSortKey: info.sortKey ?? PrimaryTrackSortKey.ORDINARY_TRACK,
trackGroup: SCROLLING_TRACK_GROUP,
- config: {},
});
}
}
- async decideTracks(): Promise<DeferredAction[]> {
- await this.defineMaxLayoutDepthSqlFunction();
+ async addScrollJankPluginTracks(): Promise<void> {
+ if (ENABLE_SCROLL_JANK_PLUGIN_V2.get()) {
+ const result = await getScrollJankTracks(this.engine);
+ this.tracksToAdd = this.tracksToAdd.concat(result.tracks.tracksToAdd);
+ this.addTrackGroupActions.push(result.addTrackGroup);
+ }
+ }
+ async decideTracks(): Promise<DeferredAction[]> {
{
const result = screenshotDecideTracks(this.engine);
if (result !== null) {
@@ -1789,6 +1617,7 @@
}
// Add first the global tracks that don't require per-process track groups.
+ await this.addScrollJankPluginTracks();
await this.addCpuSchedulingTracks();
await this.addFtraceTrack(
this.engine.getProxy('TrackDecider::addFtraceTrack'));
diff --git a/ui/src/controller/visualised_args_controller.ts b/ui/src/controller/visualised_args_controller.ts
deleted file mode 100644
index 8e709f5..0000000
--- a/ui/src/controller/visualised_args_controller.ts
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright (C) 2022 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import {v4 as uuidv4} from 'uuid';
-
-import {Actions, AddTrackArgs} from '../common/actions';
-import {Engine} from '../common/engine';
-import {NUM} from '../common/query_result';
-import {InThreadTrackSortKey} from '../common/state';
-import {globals} from '../frontend/globals';
-import {
- VISUALISED_ARGS_SLICE_TRACK_KIND,
-} from '../tracks/visualised_args/index';
-
-import {Controller} from './controller';
-
-export interface VisualisedArgControllerArgs {
- argName: string;
- engine: Engine;
-}
-
-export class VisualisedArgController extends Controller<'init'|'running'> {
- private engine: Engine;
- private argName: string;
- private escapedArgName: string;
- private tableName: string;
- private addedTrackIds: string[];
-
- constructor(args: VisualisedArgControllerArgs) {
- super('init');
- this.argName = args.argName;
- this.engine = args.engine;
- this.escapedArgName = this.argName.replace(/[^a-zA-Z]/g, '_');
- this.tableName = `__arg_visualisation_helper_${this.escapedArgName}_slice`;
- this.addedTrackIds = [];
- }
-
- onDestroy() {
- this.engine.query(`drop table if exists ${this.tableName}`);
- globals.dispatch(
- Actions.removeVisualisedArgTracks({trackIds: this.addedTrackIds}));
- }
-
- async createTracks() {
- const result = await this.engine.query(`
- drop table if exists ${this.tableName};
-
- create table ${this.tableName} as
- with slice_with_arg as (
- select
- slice.id,
- slice.track_id,
- slice.ts,
- slice.dur,
- slice.thread_dur,
- NULL as cat,
- args.display_value as name
- from slice
- join args using (arg_set_id)
- where args.key='${this.argName}'
- )
- select
- *,
- (select count()
- from ancestor_slice(s1.id) s2
- join slice_with_arg s3 on s2.id=s3.id
- ) as depth
- from slice_with_arg s1
- order by id;
-
- select
- track_id as trackId,
- max(depth) as maxDepth
- from ${this.tableName}
- group by track_id;
- `);
-
- const tracksToAdd: AddTrackArgs[] = [];
- const it = result.iter({'trackId': NUM, 'maxDepth': NUM});
- for (; it.valid(); it.next()) {
- const track =
- globals.state
- .tracks[globals.state.uiTrackIdByTraceTrackId[it.trackId]];
- const utid = (track.trackSortKey as {utid?: number}).utid;
- const id = uuidv4();
- this.addedTrackIds.push(id);
- tracksToAdd.push({
- id,
- trackGroup: track.trackGroup,
- engineId: this.engine.id,
- kind: VISUALISED_ARGS_SLICE_TRACK_KIND,
- name: this.argName,
- trackSortKey: utid === undefined ?
- track.trackSortKey :
- {utid, priority: InThreadTrackSortKey.VISUALISED_ARGS_TRACK},
- config: {
- maxDepth: it.maxDepth,
- namespace: `__arg_visualisation_helper_${this.escapedArgName}`,
- trackId: it.trackId,
- argName: this.argName,
- tid: (track.config as {tid?: number}).tid,
- },
- });
- }
- globals.dispatch(Actions.addTracks({tracks: tracksToAdd}));
- globals.dispatch(Actions.sortThreadTracks({}));
- }
-
- run() {
- switch (this.state) {
- case 'init':
- this.createTracks();
- this.setState('running');
- break;
- case 'running':
- // Nothing to do here.
- break;
- default:
- throw new Error(`Unexpected state ${this.state}`);
- }
- }
-}
diff --git a/ui/src/frontend/app.ts b/ui/src/frontend/app.ts
index 955df02..04d8012 100644
--- a/ui/src/frontend/app.ts
+++ b/ui/src/frontend/app.ts
@@ -336,14 +336,14 @@
.find(({uri}) => uri === selectedUri);
if (firstTrack) {
console.log(firstTrack);
- verticalScrollToTrack(firstTrack.id, true);
+ verticalScrollToTrack(firstTrack.key, true);
const traceTime = globals.stateTraceTimeTP();
globals.makeSelection(
Actions.selectArea({
area: {
start: traceTime.start,
end: traceTime.end,
- tracks: [firstTrack.id],
+ tracks: [firstTrack.key],
},
}),
);
diff --git a/ui/src/frontend/base_counter_track.ts b/ui/src/frontend/base_counter_track.ts
new file mode 100644
index 0000000..0f441de
--- /dev/null
+++ b/ui/src/frontend/base_counter_track.ts
@@ -0,0 +1,549 @@
+// 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 m from 'mithril';
+
+import {searchSegment} from '../base/binary_search';
+import {assertTrue} from '../base/logging';
+import {duration, Time, time} from '../base/time';
+import {drawTrackHoverTooltip} from '../common/canvas_utils';
+import {raf} from '../core/raf_scheduler';
+import {LONG, NUM} from '../public';
+import {CounterScaleOptions} from '../tracks/counter';
+import {Button} from '../widgets/button';
+import {MenuItem, PopupMenu2} from '../widgets/menu';
+
+import {checkerboardExcept} from './checkerboard';
+import {globals} from './globals';
+import {constraintsToQuerySuffix} from './sql_utils';
+import {NewTrackArgs, TrackBase} from './track';
+import {CacheKey, TrackCache} from './track_cache';
+
+interface CounterData {
+ timestamps: BigInt64Array;
+ minValues: Float64Array;
+ maxValues: Float64Array;
+ lastValues: Float64Array;
+ totalDeltas: Float64Array;
+ rate: Float64Array;
+ maximumValue: number;
+ minimumValue: number;
+ maximumDelta: number;
+ minimumDelta: number;
+ maximumRate: number;
+ minimumRate: number;
+}
+
+// 0.5 Makes the horizontal lines sharp.
+const MARGIN_TOP = 3.5;
+
+export abstract class BaseCounterTrack<Config> extends TrackBase<Config> {
+ protected readonly tableName: string;
+
+ // This is the over-skirted cached bounds:
+ private countersKey: CacheKey = CacheKey.zero();
+
+ private counters: CounterData = {
+ timestamps: new BigInt64Array(0),
+ minValues: new Float64Array(0),
+ maxValues: new Float64Array(0),
+ lastValues: new Float64Array(0),
+ totalDeltas: new Float64Array(0),
+ rate: new Float64Array(0),
+ maximumValue: 0,
+ minimumValue: 0,
+ maximumDelta: 0,
+ minimumDelta: 0,
+ maximumRate: 0,
+ minimumRate: 0,
+ };
+
+ private cache: TrackCache<CounterData> = new TrackCache(5);
+
+ private sqlState: 'UNINITIALIZED'|'INITIALIZING'|'QUERY_PENDING'|
+ 'QUERY_DONE' = 'UNINITIALIZED';
+ private isDestroyed: boolean = false;
+
+ private maximumValueSeen = 0;
+ private minimumValueSeen = 0;
+ private maximumDeltaSeen = 0;
+ private minimumDeltaSeen = 0;
+ private maxDurNs: duration = 0n;
+
+ private mousePos = {x: 0, y: 0};
+ private hoveredValue: number|undefined = undefined;
+ private hoveredTs: time|undefined = undefined;
+ private hoveredTsEnd: time|undefined = undefined;
+
+ private scale?: CounterScaleOptions;
+
+ // Extension points.
+ abstract initSqlTable(_tableName: string): Promise<void>;
+
+ constructor(args: NewTrackArgs) {
+ super(args);
+ this.tableName = `track_${this.trackKey}`.replace(/[^a-zA-Z0-9_]+/g, '_');
+ }
+
+ getHeight() {
+ return 30;
+ }
+
+ getCounterContextMenuItems(): m.Children {
+ const currentScale = this.scale;
+ const scales: {name: CounterScaleOptions, humanName: string}[] = [
+ {name: 'ZERO_BASED', humanName: 'Zero based'},
+ {name: 'MIN_MAX', humanName: 'Min/Max'},
+ {name: 'DELTA_FROM_PREVIOUS', humanName: 'Delta'},
+ {name: 'RATE', humanName: 'Rate'},
+ ];
+ return scales.map((scale) => {
+ return m(MenuItem, {
+ label: scale.humanName,
+ active: currentScale === scale.name,
+ onclick: () => {
+ this.scale = scale.name;
+ raf.scheduleFullRedraw();
+ },
+ });
+ });
+ }
+
+ getCounterContextMenu(): m.Child {
+ return m(
+ PopupMenu2,
+ {
+ trigger: m(Button, {icon: 'show_chart', minimal: true}),
+ },
+ this.getCounterContextMenuItems(),
+ );
+ }
+
+ getTrackShellButtons(): m.Children {
+ return this.getCounterContextMenu();
+ }
+
+ renderCanvas(ctx: CanvasRenderingContext2D) {
+ const {
+ visibleTimeScale: timeScale,
+ visibleWindowTime: vizTime,
+ windowSpan,
+ } = globals.frontendLocalState;
+
+ {
+ const windowSizePx = Math.max(1, timeScale.pxSpan.delta);
+ const rawStartNs = vizTime.start.toTime();
+ const rawEndNs = vizTime.end.toTime();
+ const rawCountersKey =
+ CacheKey.create(rawStartNs, rawEndNs, windowSizePx);
+
+ // If the visible time range is outside the cached area, requests
+ // asynchronously new data from the SQL engine.
+ this.maybeRequestData(rawCountersKey);
+ }
+
+ // In any case, draw whatever we have (which might be stale/incomplete).
+
+ if (this.counters === undefined || this.counters.timestamps.length === 0) {
+ return;
+ }
+
+ const data = this.counters;
+ assertTrue(data.timestamps.length === data.minValues.length);
+ assertTrue(data.timestamps.length === data.maxValues.length);
+ assertTrue(data.timestamps.length === data.lastValues.length);
+ assertTrue(data.timestamps.length === data.totalDeltas.length);
+ assertTrue(data.timestamps.length === data.rate.length);
+
+ const scale: CounterScaleOptions = this.scale ?? 'ZERO_BASED';
+
+ let minValues = data.minValues;
+ let maxValues = data.maxValues;
+ let lastValues = data.lastValues;
+ let maximumValue = data.maximumValue;
+ let minimumValue = data.minimumValue;
+ if (scale === 'DELTA_FROM_PREVIOUS') {
+ lastValues = data.totalDeltas;
+ minValues = data.totalDeltas;
+ maxValues = data.totalDeltas;
+ maximumValue = data.maximumDelta;
+ minimumValue = data.minimumDelta;
+ }
+ if (scale === 'RATE') {
+ lastValues = data.rate;
+ minValues = data.rate;
+ maxValues = data.rate;
+ maximumValue = data.maximumRate;
+ minimumValue = data.minimumRate;
+ }
+
+ const effectiveHeight = this.getHeight() - MARGIN_TOP;
+ const endPx = windowSpan.end;
+ const zeroY = MARGIN_TOP + effectiveHeight / (minimumValue < 0 ? 2 : 1);
+
+ // Quantize the Y axis to quarters of powers of tens (7.5K, 10K, 12.5K).
+ const maxValue = Math.max(maximumValue, 0);
+
+ let yMax = Math.max(Math.abs(minimumValue), maxValue);
+ const kUnits = ['', 'K', 'M', 'G', 'T', 'E'];
+ const exp = Math.ceil(Math.log10(Math.max(yMax, 1)));
+ const pow10 = Math.pow(10, exp);
+ yMax = Math.ceil(yMax / (pow10 / 4)) * (pow10 / 4);
+ let yRange = 0;
+ const unitGroup = Math.floor(exp / 3);
+ let yMin = 0;
+ let yLabel = '';
+ if (scale === 'MIN_MAX') {
+ yRange = maximumValue - minimumValue;
+ yMin = minimumValue;
+ yLabel = 'min - max';
+ } else {
+ yRange = minimumValue < 0 ? yMax * 2 : yMax;
+ yMin = minimumValue < 0 ? -yMax : 0;
+ yLabel = `${yMax / Math.pow(10, unitGroup * 3)} ${kUnits[unitGroup]}`;
+ if (scale === 'DELTA_FROM_PREVIOUS') {
+ yLabel += '\u0394';
+ } else if (scale === 'RATE') {
+ yLabel += '\u0394/t';
+ }
+ }
+
+ // There are 360deg of hue. We want a scale that starts at green with
+ // exp <= 3 (<= 1KB), goes orange around exp = 6 (~1MB) and red/violet
+ // around exp >= 9 (1GB).
+ // The hue scale looks like this:
+ // 0 180 360
+ // Red orange green | blue purple magenta
+ // So we want to start @ 180deg with pow=0, go down to 0deg and then wrap
+ // back from 360deg back to 180deg.
+ const expCapped = Math.min(Math.max(exp - 3), 9);
+ const hue = (180 - Math.floor(expCapped * (180 / 6)) + 360) % 360;
+
+ ctx.fillStyle = `hsl(${hue}, 45%, 75%)`;
+ ctx.strokeStyle = `hsl(${hue}, 45%, 45%)`;
+
+ const calculateX = (ts: time) => {
+ return Math.floor(timeScale.timeToPx(ts));
+ };
+ const calculateY = (value: number) => {
+ return MARGIN_TOP + effectiveHeight -
+ Math.round(((value - yMin) / yRange) * effectiveHeight);
+ };
+
+ ctx.beginPath();
+ const timestamp = Time.fromRaw(data.timestamps[0]);
+ ctx.moveTo(calculateX(timestamp), zeroY);
+ let lastDrawnY = zeroY;
+ for (let i = 0; i < this.counters.timestamps.length; i++) {
+ const timestamp = Time.fromRaw(data.timestamps[i]);
+ const x = calculateX(timestamp);
+ const minY = calculateY(minValues[i]);
+ const maxY = calculateY(maxValues[i]);
+ const lastY = calculateY(lastValues[i]);
+
+ ctx.lineTo(x, lastDrawnY);
+ if (minY === maxY) {
+ assertTrue(lastY === minY);
+ ctx.lineTo(x, lastY);
+ } else {
+ ctx.lineTo(x, minY);
+ ctx.lineTo(x, maxY);
+ ctx.lineTo(x, lastY);
+ }
+ lastDrawnY = lastY;
+ }
+ ctx.lineTo(endPx, lastDrawnY);
+ ctx.lineTo(endPx, zeroY);
+ ctx.closePath();
+ ctx.fill();
+ ctx.stroke();
+
+ // Draw the Y=0 dashed line.
+ ctx.strokeStyle = `hsl(${hue}, 10%, 71%)`;
+ ctx.beginPath();
+ ctx.setLineDash([2, 4]);
+ ctx.moveTo(0, zeroY);
+ ctx.lineTo(endPx, zeroY);
+ ctx.closePath();
+ ctx.stroke();
+ ctx.setLineDash([]);
+
+ ctx.font = '10px Roboto Condensed';
+
+ if (this.hoveredValue !== undefined && this.hoveredTs !== undefined) {
+ // TODO(hjd): Add units.
+ let text: string;
+ if (scale === 'DELTA_FROM_PREVIOUS') {
+ text = 'delta: ';
+ } else if (scale === 'RATE') {
+ text = 'delta/t: ';
+ } else {
+ text = 'value: ';
+ }
+
+ text += `${this.hoveredValue.toLocaleString()}`;
+
+ ctx.fillStyle = `hsl(${hue}, 45%, 75%)`;
+ ctx.strokeStyle = `hsl(${hue}, 45%, 45%)`;
+
+ const xStart = Math.floor(timeScale.timeToPx(this.hoveredTs));
+ const xEnd = this.hoveredTsEnd === undefined ?
+ endPx :
+ Math.floor(timeScale.timeToPx(this.hoveredTsEnd));
+ const y = MARGIN_TOP + effectiveHeight -
+ Math.round(((this.hoveredValue - yMin) / yRange) * effectiveHeight);
+
+ // Highlight line.
+ ctx.beginPath();
+ ctx.moveTo(xStart, y);
+ ctx.lineTo(xEnd, y);
+ ctx.lineWidth = 3;
+ ctx.stroke();
+ ctx.lineWidth = 1;
+
+ // Draw change marker.
+ ctx.beginPath();
+ ctx.arc(
+ xStart, y, 3 /* r*/, 0 /* start angle*/, 2 * Math.PI /* end angle*/);
+ ctx.fill();
+ ctx.stroke();
+
+ // Draw the tooltip.
+ drawTrackHoverTooltip(ctx, this.mousePos, this.getHeight(), text);
+ }
+
+ // Write the Y scale on the top left corner.
+ ctx.fillStyle = 'rgba(255, 255, 255, 0.6)';
+ ctx.fillRect(0, 0, 42, 16);
+ ctx.fillStyle = '#666';
+ ctx.textAlign = 'left';
+ ctx.textBaseline = 'alphabetic';
+ ctx.fillText(`${yLabel}`, 5, 14);
+
+ // TODO(hjd): Refactor this into checkerboardExcept
+ {
+ const counterEndPx = Infinity;
+ // Grey out RHS.
+ if (counterEndPx < endPx) {
+ ctx.fillStyle = '#0000001f';
+ ctx.fillRect(counterEndPx, 0, endPx - counterEndPx, this.getHeight());
+ }
+ }
+
+ // If the cached trace slices don't fully cover the visible time range,
+ // show a gray rectangle with a "Loading..." label.
+ checkerboardExcept(
+ ctx,
+ this.getHeight(),
+ windowSpan.start,
+ windowSpan.end,
+ timeScale.timeToPx(this.countersKey.start),
+ timeScale.timeToPx(this.countersKey.end));
+ }
+
+ onMouseMove(pos: {x: number, y: number}) {
+ const data = this.counters;
+ if (data === undefined) return;
+ this.mousePos = pos;
+ const {visibleTimeScale} = globals.frontendLocalState;
+ const time = visibleTimeScale.pxToHpTime(pos.x);
+
+ let values = data.lastValues;
+ if (this.scale === 'DELTA_FROM_PREVIOUS') {
+ values = data.totalDeltas;
+ }
+ if (this.scale === 'RATE') {
+ values = data.rate;
+ }
+
+ const [left, right] = searchSegment(data.timestamps, time.toTime());
+ this.hoveredTs =
+ left === -1 ? undefined : Time.fromRaw(data.timestamps[left]);
+ this.hoveredTsEnd =
+ right === -1 ? undefined : Time.fromRaw(data.timestamps[right]);
+ this.hoveredValue = left === -1 ? undefined : values[left];
+ }
+
+ onMouseOut() {
+ this.hoveredValue = undefined;
+ this.hoveredTs = undefined;
+ }
+
+ // The underlying table has `ts` and `value` columns, but we also want to
+ // query `dur` and `delta` - we create a CTE to help with that.
+ private getSqlPreamble(): string {
+ return `
+ WITH data AS (
+ SELECT
+ ts,
+ value,
+ lead(ts, 1, ts) over (order by ts) - ts as dur,
+ lead(value, 1, value) over (order by ts) - value as delta
+ FROM ${this.tableName}
+ )
+ `;
+ }
+
+ private async maybeRequestData(rawCountersKey: CacheKey) {
+ // Important: this method is async and is invoked on every frame. Care
+ // must be taken to avoid piling up queries on every frame, hence the FSM.
+ // TODO(altimin): Currently this is a copy of the logic in base_slice_track.
+ // Consider merging it.
+ if (this.sqlState === 'UNINITIALIZED') {
+ this.sqlState = 'INITIALIZING';
+
+ if (this.isDestroyed) {
+ return;
+ }
+ await this.initSqlTable(this.tableName);
+
+ if (this.isDestroyed) {
+ return;
+ }
+
+ {
+ const queryRes = (await this.engine.query(`
+ ${this.getSqlPreamble()}
+ SELECT
+ ifnull(max(value), 0) as maxValue,
+ ifnull(min(value), 0) as minValue,
+ ifnull(max(delta), 0) as maxDelta,
+ ifnull(min(delta), 0) as minDelta,
+ max(
+ iif(dur != -1, dur, (select end_ts from trace_bounds) - ts)
+ ) as maxDur
+ FROM data
+ `)).firstRow({
+ maxValue: NUM,
+ minValue: NUM,
+ maxDelta: NUM,
+ minDelta: NUM,
+ maxDur: LONG,
+ });
+
+ this.minimumValueSeen = queryRes.minValue;
+ this.maximumValueSeen = queryRes.maxValue;
+ this.minimumDeltaSeen = queryRes.minDelta;
+ this.maximumDeltaSeen = queryRes.maxDelta;
+ this.maxDurNs = queryRes.maxDur;
+ }
+
+ this.sqlState = 'QUERY_DONE';
+ } else if (
+ this.sqlState === 'INITIALIZING' || this.sqlState === 'QUERY_PENDING') {
+ return;
+ }
+
+ if (rawCountersKey.isCoveredBy(this.countersKey)) {
+ return; // We have the data already, no need to re-query.
+ }
+
+ const countersKey = rawCountersKey.normalize();
+ if (!rawCountersKey.isCoveredBy(countersKey)) {
+ throw new Error(`Normalization error ${countersKey.toString()} ${
+ rawCountersKey.toString()}`);
+ }
+
+ const maybeCachedCounters = this.cache.lookup(countersKey);
+ if (maybeCachedCounters) {
+ this.countersKey = countersKey;
+ this.counters = maybeCachedCounters;
+ }
+
+ this.sqlState = 'QUERY_PENDING';
+ const bucketNs = countersKey.bucketSize;
+
+ const constraint = constraintsToQuerySuffix({
+ filters: [
+ `ts >= ${countersKey.start} - ${this.maxDurNs}`,
+ `ts <= ${countersKey.end}`,
+ ],
+ groupBy: [
+ 'tsq',
+ ],
+ orderBy: [
+ 'tsq',
+ ],
+ });
+
+ if (this.isDestroyed) {
+ this.sqlState = 'QUERY_DONE';
+ return;
+ }
+
+ const queryRes = await this.engine.query(`
+ ${this.getSqlPreamble()}
+ SELECT
+ (ts + ${bucketNs / 2n}) / ${bucketNs} * ${bucketNs} as tsq,
+ min(value) as minValue,
+ max(value) as maxValue,
+ sum(delta) as totalDelta,
+ value_at_max_ts(ts, value) as lastValue
+ FROM data
+ ${constraint}
+ `);
+
+ const it = queryRes.iter({
+ tsq: LONG,
+ minValue: NUM,
+ maxValue: NUM,
+ totalDelta: NUM,
+ lastValue: NUM,
+ });
+
+ const numRows = queryRes.numRows();
+ const data: CounterData = {
+ maximumValue: this.maximumValueSeen,
+ minimumValue: this.minimumValueSeen,
+ maximumDelta: this.maximumDeltaSeen,
+ minimumDelta: this.minimumDeltaSeen,
+ maximumRate: 0,
+ minimumRate: 0,
+ timestamps: new BigInt64Array(numRows),
+ minValues: new Float64Array(numRows),
+ maxValues: new Float64Array(numRows),
+ lastValues: new Float64Array(numRows),
+ totalDeltas: new Float64Array(numRows),
+ rate: new Float64Array(numRows),
+ };
+
+ let lastValue = 0;
+ let lastTs = 0n;
+ for (let row = 0; it.valid(); it.next(), row++) {
+ const ts = Time.fromRaw(it.tsq);
+ const value = it.lastValue;
+ const rate = (value - lastValue) / (Time.toSeconds(Time.sub(ts, lastTs)));
+ lastTs = ts;
+ lastValue = value;
+
+ data.timestamps[row] = ts;
+ data.minValues[row] = it.minValue;
+ data.maxValues[row] = it.maxValue;
+ data.lastValues[row] = value;
+ data.totalDeltas[row] = it.totalDelta;
+ data.rate[row] = rate;
+ if (row > 0) {
+ data.rate[row - 1] = rate;
+ data.maximumRate = Math.max(data.maximumRate, rate);
+ data.minimumRate = Math.min(data.minimumRate, rate);
+ }
+ }
+
+ this.cache.insert(countersKey, data);
+ this.counters = data;
+
+ this.sqlState = 'QUERY_DONE';
+ raf.scheduleRedraw();
+ }
+}
diff --git a/ui/src/frontend/base_slice_track.ts b/ui/src/frontend/base_slice_track.ts
index e95fb20..efef610 100644
--- a/ui/src/frontend/base_slice_track.ts
+++ b/ui/src/frontend/base_slice_track.ts
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import {Disposable, NullDisposable} from '../base/disposable';
import {assertExists} from '../base/logging';
import {
duration,
@@ -144,12 +145,14 @@
// If you need temporally overlapping slices, look at AsyncSliceTrack, which
// merges several tracks into one visual track.
export const BASE_SLICE_ROW = {
- id: NUM, // The slice ID, for selection / lookups.
+ id: NUM, // The slice ID, for selection / lookups.
+ ts: LONG, // Start time in nanoseconds.
+ dur: LONG, // Duration in nanoseconds. -1 = incomplete, 0 = instant.
+ depth: NUM, // Vertical depth.
+
+ // These are computed by the base class:
tsq: LONG, // Quantized |ts|. This class owns the quantization logic.
tsqEnd: LONG, // Quantized |ts+dur|. The end bucket.
- ts: LONG, // Start time in nanoseconds.
- dur: LONG, // Duration in nanoseconds. -1 = incomplete, 0 = instant.
- depth: NUM, // Vertical depth.
};
export type BaseSliceRow = typeof BASE_SLICE_ROW;
@@ -203,7 +206,6 @@
// than just remembering it when we see it.
private selectedSlice?: CastInternal<T['slice']>;
- protected readonly tableName: string;
private maxDurNs: duration = 0n;
private sqlState: 'UNINITIALIZED'|'INITIALIZING'|'QUERY_PENDING'|
@@ -227,11 +229,30 @@
// TODO(hjd): Replace once we have cancellable query sequences.
private isDestroyed = false;
+ // Cleanup hook for onInit.
+ private initState?: Disposable;
+
// Extension points.
// Each extension point should take a dedicated argument type (e.g.,
// OnSliceOverArgs {slice?: T['slice']}) so it makes future extensions
// non-API-breaking (e.g. if we want to add the X position).
- abstract initSqlTable(_tableName: string): Promise<void>;
+
+ // onInit hook lets you do asynchronous set up e.g. creating a table
+ // etc. We guarantee that this will be resolved before doing any
+ // queries using the result of getSqlSource(). All persistent
+ // state in trace_processor should be cleaned up when dispose is
+ // called on the returned hook. In the common case of where
+ // the data for this track is d
+ async onInit(): Promise<Disposable> {
+ return new NullDisposable();
+ }
+
+ // This should be an SQL expression returning all the columns listed
+ // metioned by getRowSpec() exluding tsq and tsqEnd.
+ // For example you might return an SQL expression of the form:
+ // `select id, ts, dur, 0 as depth from foo where bar = 'baz'`
+ abstract getSqlSource(): string;
+
getRowSpec(): T['row'] {
return BASE_SLICE_ROW;
}
@@ -256,11 +277,6 @@
constructor(args: NewTrackArgs) {
super(args);
- this.frontendOnly = true; // Disable auto checkerboarding.
- // TODO(hjd): Handle pinned tracks, which current cause a crash
- // since the tableName we generate is the same for both.
- this.tableName = `track_${this.trackId}`.replace(/[^a-zA-Z0-9_]+/g, '_');
-
// Work out the extra columns.
// This is the union of the embedder-defined columns and the base columns
// we know about (ts, dur, ...).
@@ -508,7 +524,10 @@
onDestroy() {
super.onDestroy();
this.isDestroyed = true;
- this.engine.query(`DROP VIEW IF EXISTS ${this.tableName}`);
+ if (this.initState) {
+ this.initState.dispose();
+ this.initState = undefined;
+ }
}
// This method figures out if the visible window is outside the bounds of
@@ -523,14 +542,14 @@
if (this.isDestroyed) {
return;
}
- await this.initSqlTable(this.tableName);
+ this.initState = await this.onInit();
if (this.isDestroyed) {
return;
}
const queryRes = await this.engine.query(`select
ifnull(max(dur), 0) as maxDur, count(1) as rowCount
- from ${this.tableName}`);
+ from (${this.getSqlSource()})`);
const row = queryRes.firstRow({maxDur: LONG, rowCount: NUM});
this.maxDurNs = row.maxDur;
@@ -563,7 +582,7 @@
id,
${this.depthColumn()}
${extraCols ? ',' + extraCols : ''}
- from ${this.tableName}
+ from (${this.getSqlSource()})
where dur = -1;
`);
const incomplete =
@@ -650,7 +669,7 @@
id,
${this.depthColumn()}
${extraCols ? ',' + extraCols : ''}
- FROM ${this.tableName} ${constraint}
+ FROM (${this.getSqlSource()}) ${constraint}
`);
// Here convert each row to a Slice. We do what we can do
diff --git a/ui/src/frontend/chrome_slice_details_tab.ts b/ui/src/frontend/chrome_slice_details_tab.ts
index 93b5e15..e4210fe 100644
--- a/ui/src/frontend/chrome_slice_details_tab.ts
+++ b/ui/src/frontend/chrome_slice_details_tab.ts
@@ -15,12 +15,13 @@
import m from 'mithril';
import {Icons} from '../base/semantic_icons';
-import {duration, Time} from '../base/time';
+import {duration, Time, TimeSpan} from '../base/time';
import {exists} from '../base/utils';
import {EngineProxy} from '../common/engine';
import {runQuery} from '../common/queries';
import {LONG, LONG_NULL, NUM, STR_NULL} from '../common/query_result';
-import {addDebugTrack} from '../tracks/debug/slice_track';
+import {raf} from '../core/raf_scheduler';
+import {addDebugSliceTrack} from '../tracks/debug/slice_track';
import {Button} from '../widgets/button';
import {DetailsShell} from '../widgets/details_shell';
import {DurationWidget} from '../widgets/duration';
@@ -39,6 +40,10 @@
import {renderArguments} from './slice_args';
import {renderDetails} from './slice_details';
import {getSlice, SliceDetails, SliceRef} from './sql/slice';
+import {
+ BreakdownByThreadState,
+ breakDownIntervalByThreadState,
+} from './sql/thread_state';
import {asSliceSqlId} from './sql_types';
interface ContextMenuItem {
@@ -99,12 +104,14 @@
run: (slice: SliceDetails) => {
const engine = getEngine();
if (engine === undefined) return;
- runQuery(`
+ runQuery(
+ `
INCLUDE PERFETTO MODULE android.binder;
INCLUDE PERFETTO MODULE android.monitor_contention;
- `, engine)
+ `,
+ engine)
.then(
- () => addDebugTrack(
+ () => addDebugSliceTrack(
engine,
{
sqlSource: `
@@ -138,7 +145,8 @@
JOIN thread ON thread.utid = thread_track.utid
JOIN process ON process.upid = thread.upid
WHERE process.pid = ${getPidFromSlice(slice)}
- AND thread.tid = ${getTidFromSlice(slice)}
+ AND thread.tid = ${
+ getTidFromSlice(slice)}
AND short_blocked_method IS NOT NULL
ORDER BY depth
) SELECT ts, dur, name FROM merged`,
@@ -197,7 +205,7 @@
name: it.name ?? 'null',
ts: Time.fromRaw(it.ts),
dur: it.dur,
- sqlTrackId: it.trackId,
+ trackId: it.trackId,
threadDur: it.threadDur ?? undefined,
category: it.cat ?? undefined,
absTime: it.absTime ?? undefined,
@@ -223,6 +231,7 @@
static readonly kind = 'dev.perfetto.ChromeSliceDetailsTab';
private sliceDetails?: SliceDetails;
+ private breakdownByThreadState?: BreakdownByThreadState;
static create(args: NewBottomTabArgs): ChromeSliceDetailsTab {
return new ChromeSliceDetailsTab(args);
@@ -230,11 +239,23 @@
constructor(args: NewBottomTabArgs) {
super(args);
+ this.load();
+ }
+ async load() {
// Start loading the slice details
const {id, table} = this.config;
- getSliceDetails(this.engine, id, table)
- .then((sliceDetails) => this.sliceDetails = sliceDetails);
+ const details = await getSliceDetails(this.engine, id, table);
+
+ if (details !== undefined && details.thread !== undefined) {
+ this.breakdownByThreadState = await breakDownIntervalByThreadState(
+ this.engine,
+ TimeSpan.fromTimeAndDuration(details.ts, details.dur),
+ details.thread.utid);
+ }
+
+ this.sliceDetails = details;
+ raf.scheduleFullRedraw();
}
getTitle(): string {
@@ -242,24 +263,23 @@
}
viewTab() {
- if (exists(this.sliceDetails)) {
- const slice = this.sliceDetails;
- return m(
- DetailsShell,
- {
- title: 'Slice',
- description: slice.name,
- buttons: this.renderContextButton(slice),
- },
- m(
- GridLayout,
- renderDetails(slice),
- this.renderRhs(this.engine, slice),
- ),
- );
- } else {
+ if (!exists(this.sliceDetails)) {
return m(DetailsShell, {title: 'Slice', description: 'Loading...'});
}
+ const slice = this.sliceDetails;
+ return m(
+ DetailsShell,
+ {
+ title: 'Slice',
+ description: slice.name,
+ buttons: this.renderContextButton(slice),
+ },
+ m(
+ GridLayout,
+ renderDetails(slice, this.breakdownByThreadState),
+ this.renderRhs(this.engine, slice),
+ ),
+ );
}
isLoading() {
diff --git a/ui/src/frontend/flow_events_panel.ts b/ui/src/frontend/flow_events_panel.ts
index 7bf78ce..af17ae7 100644
--- a/ui/src/frontend/flow_events_panel.ts
+++ b/ui/src/frontend/flow_events_panel.ts
@@ -44,11 +44,10 @@
}
const flowClickHandler = (sliceId: number, trackId: number) => {
- const uiTrackId = globals.state.uiTrackIdByTraceTrackId[trackId];
- if (uiTrackId) {
+ const trackKey = globals.state.trackKeyByTrackId[trackId];
+ if (trackKey) {
globals.makeSelection(
- Actions.selectChromeSlice(
- {id: sliceId, trackId: uiTrackId, table: 'slice'}),
+ Actions.selectChromeSlice({id: sliceId, trackKey, table: 'slice'}),
{tab: 'bound_flows'});
}
};
diff --git a/ui/src/frontend/flow_events_renderer.ts b/ui/src/frontend/flow_events_renderer.ts
index c414454..f06704e 100644
--- a/ui/src/frontend/flow_events_renderer.ts
+++ b/ui/src/frontend/flow_events_renderer.ts
@@ -12,10 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {TrackState} from 'src/common/state';
-
import {time} from '../base/time';
import {pluginManager} from '../common/plugins';
+import {TrackState} from '../common/state';
import {TRACK_SHELL_WIDTH} from './css_constants';
import {ALL_CATEGORIES, getFlowCategories} from './flow_events_panel';
@@ -54,16 +53,8 @@
height: number;
}
-function hasTrackId(obj: {}): obj is {trackId: number} {
- return (obj as {trackId?: number}).trackId !== undefined;
-}
-
-function hasManyTrackIds(obj: {}): obj is {trackIds: number[]} {
- return (obj as {trackIds?: number}).trackIds !== undefined;
-}
-
-function hasId(obj: {}): obj is {id: number} {
- return (obj as {id?: number}).id !== undefined;
+function hasTrackKey(obj: {}): obj is {trackKey: number} {
+ return (obj as {trackKey?: number}).trackKey !== undefined;
}
function hasTrackGroupId(obj: {}): obj is {trackGroupId: string} {
@@ -71,19 +62,8 @@
}
function getTrackIds(track: TrackState): number[] {
- if (track.uri) {
- const trackInfo = pluginManager.resolveTrackInfo(track.uri);
- if (trackInfo?.trackIds) return trackInfo?.trackIds;
- } else {
- const config = track.config;
- if (hasTrackId(config)) {
- return [config.trackId];
- }
- if (hasManyTrackIds(config)) {
- return config.trackIds;
- }
- }
- return [];
+ const trackDesc = pluginManager.resolveTrackInfo(track.uri);
+ return trackDesc?.trackIds ?? [];
}
export class FlowEventsRendererArgs {
@@ -96,11 +76,22 @@
}
registerPanel(panel: PanelVNode, yStart: number, height: number) {
- if (panel.state instanceof TrackPanel && hasId(panel.attrs)) {
- const track = globals.state.tracks[panel.attrs.id];
+ if (panel.state instanceof TrackPanel && hasTrackKey(panel.attrs)) {
+ const track = globals.state.tracks[panel.attrs.trackKey];
for (const trackId of getTrackIds(track)) {
this.trackIdToTrackPanel.set(trackId, {panel: panel.state, yStart});
}
+
+ // Register new "plugin track" ids
+ const trackState = globals.state.tracks[panel.attrs.trackKey];
+ if (trackState.uri) {
+ const trackInfo = pluginManager.resolveTrackInfo(trackState.uri);
+ if (trackInfo?.trackIds) {
+ for (const trackId of trackInfo.trackIds) {
+ this.trackIdToTrackPanel.set(trackId, {panel: panel.state, yStart});
+ }
+ }
+ }
} else if (
panel.state instanceof TrackGroupPanel &&
hasTrackGroupId(panel.attrs)) {
@@ -112,8 +103,8 @@
export class FlowEventsRenderer {
private getTrackGroupIdByTrackId(trackId: number): string|undefined {
- const uiTrackId = globals.state.uiTrackIdByTraceTrackId[trackId];
- return uiTrackId ? globals.state.tracks[uiTrackId].trackGroup : undefined;
+ const trackKey = globals.state.trackKeyByTrackId[trackId];
+ return trackKey ? globals.state.tracks[trackKey].trackGroup : undefined;
}
private getTrackGroupYCoordinate(
diff --git a/ui/src/frontend/frontend_local_state.ts b/ui/src/frontend/frontend_local_state.ts
index d9d36d9..fb6d045 100644
--- a/ui/src/frontend/frontend_local_state.ts
+++ b/ui/src/frontend/frontend_local_state.ts
@@ -159,7 +159,7 @@
showCookieConsent = false;
visibleTracks = new Set<string>();
prevVisibleTracks = new Set<string>();
- scrollToTrackId?: string|number;
+ scrollToTrackKey?: string|number;
httpRpcState: HttpRpcState = {connected: false};
newVersionAvailable = false;
@@ -193,8 +193,8 @@
raf.scheduleFullRedraw();
}
- addVisibleTrack(trackId: string) {
- this.visibleTracks.add(trackId);
+ addVisibleTrack(trackKey: string) {
+ this.visibleTracks.add(trackKey);
}
// Called when beginning a canvas redraw.
diff --git a/ui/src/frontend/globals.ts b/ui/src/frontend/globals.ts
index 037a65f..b1b6d3e 100644
--- a/ui/src/frontend/globals.ts
+++ b/ui/src/frontend/globals.ts
@@ -283,7 +283,7 @@
sliceIds: new Float64Array(0),
tsStarts: new BigInt64Array(0),
utids: new Float64Array(0),
- trackIds: [],
+ trackKeys: [],
sources: [],
totalResults: 0,
};
@@ -663,7 +663,7 @@
sliceIds: new Float64Array(0),
tsStarts: new BigInt64Array(0),
utids: new Float64Array(0),
- trackIds: [],
+ trackKeys: [],
sources: [],
totalResults: 0,
};
diff --git a/ui/src/frontend/keyboard_event_handler.ts b/ui/src/frontend/keyboard_event_handler.ts
index 92863c3..e27f83c 100644
--- a/ui/src/frontend/keyboard_event_handler.ts
+++ b/ui/src/frontend/keyboard_event_handler.ts
@@ -172,12 +172,11 @@
for (const flow of globals.connectedFlows) {
if (flow.id === flowId) {
const flowPoint = (direction === 'Backward' ? flow.begin : flow.end);
- const uiTrackId =
- globals.state.uiTrackIdByTraceTrackId[flowPoint.trackId];
- if (uiTrackId) {
+ const trackKey = globals.state.trackKeyByTrackId[flowPoint.trackId];
+ if (trackKey) {
globals.makeSelection(Actions.selectChromeSlice({
id: flowPoint.sliceId,
- trackId: uiTrackId,
+ trackKey,
table: 'slice',
scroll: true,
}));
@@ -190,8 +189,8 @@
const range = globals.findTimeRangeOfSelection();
if (range.start !== -1n && range.end !== -1n &&
globals.state.currentSelection !== null) {
- const tracks = globals.state.currentSelection.trackId ?
- [globals.state.currentSelection.trackId] :
+ const tracks = globals.state.currentSelection.trackKey ?
+ [globals.state.currentSelection.trackKey] :
[];
const area: Area = {start: range.start, end: range.end, tracks};
globals.dispatch(Actions.markArea({area, persistent}));
@@ -207,7 +206,7 @@
focusHorizontalRange(range.start, range.end);
}
- if (selection.trackId) {
- verticalScrollToTrack(selection.trackId, true);
+ if (selection.trackKey) {
+ verticalScrollToTrack(selection.trackKey, true);
}
}
diff --git a/ui/src/frontend/legacy_trace_viewer.ts b/ui/src/frontend/legacy_trace_viewer.ts
index e5242a9..657758f 100644
--- a/ui/src/frontend/legacy_trace_viewer.ts
+++ b/ui/src/frontend/legacy_trace_viewer.ts
@@ -14,7 +14,10 @@
import m from 'mithril';
import {inflate} from 'pako';
+
import {assertTrue} from '../base/logging';
+import {isString} from '../base/object_utils';
+
import {globals} from './globals';
import {showModal} from './modal';
@@ -43,7 +46,7 @@
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => {
- if (typeof reader.result === 'string') {
+ if (isString(reader.result)) {
return resolve(reader.result);
}
};
diff --git a/ui/src/frontend/named_slice_track.ts b/ui/src/frontend/named_slice_track.ts
index 1601b70..759acb9 100644
--- a/ui/src/frontend/named_slice_track.ts
+++ b/ui/src/frontend/named_slice_track.ts
@@ -70,7 +70,7 @@
onSliceClick(args: OnSliceClickArgs<T['slice']>) {
globals.makeSelection(Actions.selectChromeSlice({
id: args.slice.id,
- trackId: this.trackId,
+ trackKey: this.trackKey,
// |table| here can be either 'slice' or 'annotation'. The
// AnnotationSliceTrack overrides the onSliceClick and sets this to
diff --git a/ui/src/frontend/omnibox.ts b/ui/src/frontend/omnibox.ts
index fc36b56..634abc9 100644
--- a/ui/src/frontend/omnibox.ts
+++ b/ui/src/frontend/omnibox.ts
@@ -16,6 +16,7 @@
import {classNames} from '../base/classnames';
import {FuzzySegment} from '../base/fuzzy';
+import {isString} from '../base/object_utils';
import {exists} from '../base/utils';
import {raf} from '../core/raf_scheduler';
import {EmptyState} from '../widgets/empty_state';
@@ -62,7 +63,7 @@
}
private renderTitle(title: FuzzySegment[]|string): m.Children {
- if (typeof title === 'string') {
+ if (isString(title)) {
return title;
} else {
return title.map(({matching, value}) => {
diff --git a/ui/src/frontend/pivot_table_query_generator.ts b/ui/src/frontend/pivot_table_query_generator.ts
index b59aebe..8641c11 100644
--- a/ui/src/frontend/pivot_table_query_generator.ts
+++ b/ui/src/frontend/pivot_table_query_generator.ts
@@ -21,7 +21,7 @@
PivotTableState,
} from '../common/state';
import {
- getSelectedTrackIds,
+ getSelectedTrackKeys,
} from '../controller/aggregation/slice_aggregation_controller';
import {globals} from './globals';
@@ -101,7 +101,7 @@
return [
`ts + dur > ${area.start}`,
`ts < ${area.end}`,
- `track_id in (${getSelectedTrackIds(area).join(', ')})`,
+ `track_id in (${getSelectedTrackKeys(area).join(', ')})`,
];
}
diff --git a/ui/src/frontend/post_message_handler.ts b/ui/src/frontend/post_message_handler.ts
index ed9d078..c6b5546 100644
--- a/ui/src/frontend/post_message_handler.ts
+++ b/ui/src/frontend/post_message_handler.ts
@@ -22,6 +22,8 @@
import {showModal} from './modal';
import {focusHorizontalRange} from './scroll_helper';
+const TRUSTED_ORIGINS_KEY = 'trustedOrigins';
+
interface PostedTraceWrapped {
perfetto: PostedTrace;
}
@@ -40,6 +42,7 @@
];
if (origin === window.origin) return true;
if (TRUSTED_ORIGINS.includes(origin)) return true;
+ if (isUserTrustedOrigin(origin)) return true;
const hostname = new URL(origin).hostname;
if (hostname.endsWith('corp.google.com')) return true;
@@ -47,6 +50,33 @@
return false;
}
+// Returns whether the user saved this as an always-trusted origin.
+function isUserTrustedOrigin(hostname: string): boolean {
+ const trustedOrigins = window.localStorage.getItem(TRUSTED_ORIGINS_KEY);
+ if (trustedOrigins === null) return false;
+ try {
+ return JSON.parse(trustedOrigins).includes(hostname);
+ } catch {
+ return false;
+ }
+}
+
+// Saves the given hostname as a trusted origin.
+// This is used for user convenience: if it fails for any reason, it's not a
+// big deal.
+function saveUserTrustedOrigin(hostname: string) {
+ const s = window.localStorage.getItem(TRUSTED_ORIGINS_KEY);
+ let origins: string[];
+ try {
+ origins = JSON.parse(s || '[]');
+ if (origins.includes(hostname)) return;
+ origins.push(hostname);
+ window.localStorage.setItem(TRUSTED_ORIGINS_KEY, JSON.stringify(origins));
+ } catch (e) {
+ console.warn('unable to save trusted origins to localStorage', e);
+ }
+}
+
// Returns whether we should ignore a given message based on the value of
// the 'perfettoIgnore' field in the event data.
function shouldGracefullyIgnoreMessage(messageEvent: MessageEvent) {
@@ -162,6 +192,11 @@
globals.dispatch(Actions.openTraceFromBuffer(postedTrace));
};
+ const trustAndOpenTrace = () => {
+ saveUserTrustedOrigin(messageEvent.origin);
+ openTrace();
+ };
+
// If the origin is trusted open the trace directly.
if (isTrustedOrigin(messageEvent.origin)) {
openTrace();
@@ -176,8 +211,9 @@
m('div', `${messageEvent.origin} is trying to open a trace file.`),
m('div', 'Do you trust the origin and want to proceed?')),
buttons: [
- {text: 'NO', primary: true},
- {text: 'YES', primary: false, action: openTrace},
+ {text: 'No', primary: true},
+ {text: 'Yes', primary: false, action: openTrace},
+ {text: 'Always trust', primary: false, action: trustAndOpenTrace},
],
});
}
diff --git a/ui/src/frontend/query_history.ts b/ui/src/frontend/query_history.ts
index 59690e9..4bc3480 100644
--- a/ui/src/frontend/query_history.ts
+++ b/ui/src/frontend/query_history.ts
@@ -32,18 +32,20 @@
export interface QueryHistoryComponentAttrs {
runQuery: (query: string) => void;
+ setQuery: (query: string) => void;
}
export class QueryHistoryComponent implements
m.ClassComponent<QueryHistoryComponentAttrs> {
view({attrs}: m.CVnode<QueryHistoryComponentAttrs>): m.Child {
const runQuery = attrs.runQuery;
+ const setQuery = attrs.setQuery;
const unstarred: HistoryItemComponentAttrs[] = [];
const starred: HistoryItemComponentAttrs[] = [];
for (let i = queryHistoryStorage.data.length - 1; i >= 0; i--) {
const entry = queryHistoryStorage.data[i];
const arr = entry.starred ? starred : unstarred;
- arr.push({index: i, entry, runQuery});
+ arr.push({index: i, entry, runQuery, setQuery});
}
return m(
'.query-history',
@@ -58,6 +60,7 @@
index: number;
entry: QueryHistoryEntry;
runQuery: (query: string) => void;
+ setQuery: (query: string) => void;
}
export class HistoryItemComponent implements
@@ -80,6 +83,11 @@
),
m('button',
{
+ onclick: () => vnode.attrs.setQuery(query),
+ },
+ m(Icon, {icon: 'edit'})),
+ m('button',
+ {
onclick: () => vnode.attrs.runQuery(query),
},
m(Icon, {icon: 'play_arrow'})),
diff --git a/ui/src/frontend/query_page.ts b/ui/src/frontend/query_page.ts
index 97a655d..711ef17 100644
--- a/ui/src/frontend/query_page.ts
+++ b/ui/src/frontend/query_page.ts
@@ -36,11 +36,13 @@
executedQuery?: string;
queryResult?: QueryResponse;
heightPx: string;
+ generation: number;
}
const state: QueryPageState = {
enteredText: '',
heightPx: '100px',
+ generation: 0,
};
function runManualQuery(query: string) {
@@ -99,6 +101,7 @@
view() {
return m(Editor, {
+ generation: state.generation,
initialText: state.enteredText,
onExecute: (text: string) => {
@@ -112,6 +115,7 @@
onUpdate: (text: string) => {
state.enteredText = text;
},
+
});
}
}
@@ -134,6 +138,11 @@
}),
m(QueryHistoryComponent, {
runQuery: runManualQuery,
+ setQuery: (q: string) => {
+ state.enteredText = q;
+ state.generation++;
+ raf.scheduleFullRedraw();
+ },
}));
},
});
diff --git a/ui/src/frontend/query_table.ts b/ui/src/frontend/query_table.ts
index c84e7af..6676794 100644
--- a/ui/src/frontend/query_table.ts
+++ b/ui/src/frontend/query_table.ts
@@ -17,6 +17,7 @@
import {BigintMath} from '../base/bigint_math';
import {copyToClipboard} from '../base/clipboard';
+import {isString} from '../base/object_utils';
import {Duration, Time} from '../base/time';
import {Actions} from '../common/actions';
import {QueryResponse} from '../common/queries';
@@ -57,7 +58,7 @@
}
function hasType(row: Row): row is Row&{type: string} {
- return ('type' in row && typeof row.type === 'string');
+ return ('type' in row && isString(row.type));
}
function hasId(row: Row): row is Row&{id: Numeric} {
@@ -141,20 +142,20 @@
const sliceStart = Time.fromRaw(BigInt(row.ts));
// row.dur can be negative. Clamp to 1ns.
const sliceDur = BigintMath.max(BigInt(row.dur), 1n);
- const uiTrackId = globals.state.uiTrackIdByTraceTrackId[trackId];
- if (uiTrackId !== undefined) {
- reveal(uiTrackId, sliceStart, Time.add(sliceStart, sliceDur), true);
+ const trackKey = globals.state.trackKeyByTrackId[trackId];
+ if (trackKey !== undefined) {
+ reveal(trackKey, sliceStart, Time.add(sliceStart, sliceDur), true);
const sliceId = getSliceId(row);
if (sliceId !== undefined) {
- this.selectSlice(sliceId, uiTrackId, nextTab);
+ this.selectSlice(sliceId, trackKey, nextTab);
}
}
}
- private selectSlice(sliceId: number, uiTrackId: string, nextTab?: string) {
+ private selectSlice(sliceId: number, trackKey: string, nextTab?: string) {
const action = Actions.selectChromeSlice({
id: sliceId,
- trackId: uiTrackId,
+ trackKey,
table: 'slice',
});
globals.makeSelection(action, {tab: nextTab});
diff --git a/ui/src/frontend/scroll_helper.ts b/ui/src/frontend/scroll_helper.ts
index 38c5eb4..dccad06 100644
--- a/ui/src/frontend/scroll_helper.ts
+++ b/ui/src/frontend/scroll_helper.ts
@@ -109,9 +109,9 @@
// track is nested inside a track group, scroll to that track group instead.
// If |openGroup| then open the track group and scroll to the track.
export function verticalScrollToTrack(
- trackId: string|number, openGroup = false) {
- const trackIdString = `${trackId}`;
- const track = document.querySelector('#track_' + trackIdString);
+ trackKey: string|number, openGroup = false) {
+ const trackKeyString = `${trackKey}`;
+ const track = document.querySelector('#track_' + trackKeyString);
if (track) {
// block: 'nearest' means that it will only scroll if the track is not
@@ -121,13 +121,13 @@
}
let trackGroup = null;
- const trackGroupId = getContainingTrackId(globals.state, trackIdString);
+ const trackGroupId = getContainingTrackId(globals.state, trackKeyString);
if (trackGroupId) {
trackGroup = document.querySelector('#track_' + trackGroupId);
}
if (!trackGroupId || !trackGroup) {
- console.error(`Can't scroll, track (${trackIdString}) not found.`);
+ console.error(`Can't scroll, track (${trackKeyString}) not found.`);
return;
}
@@ -135,7 +135,7 @@
// group and scroll to the track or just scroll to the track group.
if (openGroup) {
// After the track exists in the dom, it will be scrolled to.
- globals.frontendLocalState.scrollToTrackId = trackId;
+ globals.frontendLocalState.scrollToTrackKey = trackKey;
globals.dispatch(Actions.toggleTrackGroupCollapsed({trackGroupId}));
return;
} else {
@@ -144,18 +144,18 @@
}
-// Scroll vertically and horizontally to reach track (|trackId|) at |ts|.
+// Scroll vertically and horizontally to reach track (|trackKey|) at |ts|.
export function scrollToTrackAndTs(
- trackId: string|number|undefined, ts: time, openGroup = false) {
- if (trackId !== undefined) {
- verticalScrollToTrack(trackId, openGroup);
+ trackKey: string|number|undefined, ts: time, openGroup = false) {
+ if (trackKey !== undefined) {
+ verticalScrollToTrack(trackKey, openGroup);
}
horizontalScrollToTs(ts);
}
// Scroll vertically and horizontally to a track and time range
export function reveal(
- trackId: string|number, start: time, end: time, openGroup = false) {
- verticalScrollToTrack(trackId, openGroup);
+ trackKey: string|number, start: time, end: time, openGroup = false) {
+ verticalScrollToTrack(trackKey, openGroup);
focusHorizontalRange(start, end);
}
diff --git a/ui/src/frontend/search_handler.ts b/ui/src/frontend/search_handler.ts
index c0ef384..76dd4bf 100644
--- a/ui/src/frontend/search_handler.ts
+++ b/ui/src/frontend/search_handler.ts
@@ -80,18 +80,18 @@
const searchIndex = globals.state.searchIndex;
const source = globals.currentSearchResults.sources[searchIndex];
const currentId = globals.currentSearchResults.sliceIds[searchIndex];
- const trackId = globals.currentSearchResults.trackIds[searchIndex];
+ const trackKey = globals.currentSearchResults.trackKeys[searchIndex];
if (currentId === undefined) return;
if (source === 'cpu') {
globals.makeSelection(
- Actions.selectSlice({id: currentId, trackId, scroll: true}),
+ Actions.selectSlice({id: currentId, trackKey, scroll: true}),
{clearSearch: false},
);
} else if (source === 'log') {
globals.makeSelection(
- Actions.selectLog({id: currentId, trackId, scroll: true}),
+ Actions.selectLog({id: currentId, trackKey, scroll: true}),
{clearSearch: false},
);
} else {
@@ -99,7 +99,7 @@
// When we include annotations we need to pass the correct table.
globals.makeSelection(
Actions.selectChromeSlice(
- {id: currentId, trackId, table: 'slice', scroll: true}),
+ {id: currentId, trackKey, table: 'slice', scroll: true}),
{clearSearch: false},
);
}
diff --git a/ui/src/frontend/sidebar.ts b/ui/src/frontend/sidebar.ts
index 6fc7615..9960af0 100644
--- a/ui/src/frontend/sidebar.ts
+++ b/ui/src/frontend/sidebar.ts
@@ -15,6 +15,7 @@
import m from 'mithril';
import {assertExists, assertTrue} from '../base/logging';
+import {isString} from '../base/object_utils';
import {Actions} from '../common/actions';
import {getCurrentChannel} from '../common/channels';
import {TRACE_SUFFIX} from '../common/constants';
@@ -769,8 +770,8 @@
let css = '';
let attrs = {
onclick: typeof item.a === 'function' ? item.a : null,
- href: typeof item.a === 'string' ? item.a : '#',
- target: typeof item.a === 'string' ? '_blank' : null,
+ href: isString(item.a) ? item.a : '#',
+ target: isString(item.a) ? '_blank' : null,
disabled: false,
id: item.t.toLowerCase().replace(/[^\w]/g, '_'),
};
diff --git a/ui/src/frontend/slice_args.ts b/ui/src/frontend/slice_args.ts
index 5bb8a8c..893fc5b 100644
--- a/ui/src/frontend/slice_args.ts
+++ b/ui/src/frontend/slice_args.ts
@@ -13,13 +13,21 @@
// limitations under the License.
import m from 'mithril';
+import {v4 as uuidv4} from 'uuid';
+import {isString} from '../base/object_utils';
import {Icons} from '../base/semantic_icons';
import {sqliteString} from '../base/string_utils';
import {exists} from '../base/utils';
-import {Actions} from '../common/actions';
+import {Actions, AddTrackArgs} from '../common/actions';
import {EngineProxy} from '../common/engine';
+import {NUM} from '../common/query_result';
+import {InThreadTrackSortKey} from '../common/state';
import {ArgNode, convertArgsToTree, Key} from '../controller/args_parser';
+import {
+ VISUALISED_ARGS_SLICE_TRACK_URI,
+ VisualisedArgsState,
+} from '../tracks/visualised_args';
import {Anchor} from '../widgets/anchor';
import {MenuItem, PopupMenu2} from '../widgets/menu';
import {Section} from '../widgets/section';
@@ -62,7 +70,7 @@
return m(
TreeNode,
{
- left: renderArgKey(stringifyKey(key), value),
+ left: renderArgKey(engine, stringifyKey(key), value),
right: exists(value) && renderArgValue(value),
summary: children && renderSummary(children),
},
@@ -72,7 +80,8 @@
});
}
-function renderArgKey(key: string, value?: Arg): m.Children {
+function renderArgKey(
+ engine: EngineProxy, key: string, value?: Arg): m.Children {
if (value === undefined) {
return key;
} else {
@@ -107,13 +116,84 @@
label: 'Visualise argument values',
icon: 'query_stats',
onclick: () => {
- globals.dispatch(Actions.addVisualisedArg({argName: fullKey}));
+ addVisualisedArg(engine, fullKey);
},
}),
);
}
}
+async function addVisualisedArg(engine: EngineProxy, argName: string) {
+ const escapedArgName = argName.replace(/[^a-zA-Z]/g, '_');
+ const tableName = `__arg_visualisation_helper_${escapedArgName}_slice`;
+
+ const result = await engine.query(`
+ drop table if exists ${tableName};
+
+ create table ${tableName} as
+ with slice_with_arg as (
+ select
+ slice.id,
+ slice.track_id,
+ slice.ts,
+ slice.dur,
+ slice.thread_dur,
+ NULL as cat,
+ args.display_value as name
+ from slice
+ join args using (arg_set_id)
+ where args.key='${argName}'
+ )
+ select
+ *,
+ (select count()
+ from ancestor_slice(s1.id) s2
+ join slice_with_arg s3 on s2.id=s3.id
+ ) as depth
+ from slice_with_arg s1
+ order by id;
+
+ select
+ track_id as trackId,
+ max(depth) as maxDepth
+ from ${tableName}
+ group by track_id;
+ `);
+
+ const tracksToAdd: AddTrackArgs[] = [];
+ const it = result.iter({'trackId': NUM, 'maxDepth': NUM});
+ const addedTrackKeys: string[] = [];
+ for (; it.valid(); it.next()) {
+ const track =
+ globals.state.tracks[globals.state.trackKeyByTrackId[it.trackId]];
+ const utid = (track.trackSortKey as {utid?: number}).utid;
+ const key = uuidv4();
+ addedTrackKeys.push(key);
+
+ const params: VisualisedArgsState = {
+ maxDepth: it.maxDepth,
+ trackId: it.trackId,
+ argName: argName,
+ };
+
+ tracksToAdd.push({
+ key,
+ trackGroup: track.trackGroup,
+ name: argName,
+ trackSortKey: utid === undefined ?
+ track.trackSortKey :
+ {utid, priority: InThreadTrackSortKey.VISUALISED_ARGS_TRACK},
+ params,
+ uri: VISUALISED_ARGS_SLICE_TRACK_URI,
+ });
+ }
+
+ globals.dispatchMultiple([
+ Actions.addTracks({tracks: tracksToAdd}),
+ Actions.sortThreadTracks({}),
+ ]);
+}
+
function renderArgValue({value}: Arg): m.Children {
if (isWebLink(value)) {
return renderWebLink(value);
@@ -145,7 +225,7 @@
}
function isWebLink(value: unknown): value is string {
- return typeof value === 'string' &&
+ return isString(value) &&
(value.startsWith('http://') || value.startsWith('https://'));
}
diff --git a/ui/src/frontend/slice_details.ts b/ui/src/frontend/slice_details.ts
index 1f782a7..6056bbc 100644
--- a/ui/src/frontend/slice_details.ts
+++ b/ui/src/frontend/slice_details.ts
@@ -28,6 +28,10 @@
import {addTab} from './bottom_tab';
import {globals} from './globals';
import {SliceDetails} from './sql/slice';
+import {
+ BreakdownByThreadState,
+ BreakdownByThreadStateTreeNode,
+} from './sql/thread_state';
import {SqlTableTab} from './sql_table/tab';
import {SqlTables} from './sql_table/well_known_tables';
import {getProcessName, getThreadName} from './thread_and_process_info';
@@ -44,7 +48,8 @@
// Renders a widget storing all of the generic details for a slice from the
// slice table.
-export function renderDetails(slice: SliceDetails) {
+export function renderDetails(
+ slice: SliceDetails, durationBreakdown?: BreakdownByThreadState) {
return m(
Section,
{title: 'Details'},
@@ -84,10 +89,18 @@
}),
exists(slice.absTime) &&
m(TreeNode, {left: 'Absolute Time', right: slice.absTime}),
- m(TreeNode, {
- left: 'Duration',
- right: computeDuration(slice.ts, slice.dur),
- }),
+ m(
+ TreeNode,
+ {
+ left: 'Duration',
+ right: computeDuration(slice.ts, slice.dur),
+ },
+ exists(durationBreakdown) && slice.dur > 0 &&
+ m(BreakdownByThreadStateTreeNode, {
+ data: durationBreakdown,
+ dur: slice.dur,
+ }),
+ ),
renderThreadDuration(slice),
slice.thread && m(TreeNode, {
left: 'Thread',
diff --git a/ui/src/frontend/slice_details_panel.ts b/ui/src/frontend/slice_details_panel.ts
index 28bd796..c212249 100644
--- a/ui/src/frontend/slice_details_panel.ts
+++ b/ui/src/frontend/slice_details_panel.ts
@@ -15,7 +15,9 @@
import m from 'mithril';
import {Actions} from '../common/actions';
+import {pluginManager} from '../common/plugins';
import {translateState} from '../common/thread_state';
+import {THREAD_STATE_TRACK_KIND} from '../tracks/thread_state';
import {Anchor} from '../widgets/anchor';
import {DetailsShell} from '../widgets/details_shell';
import {DurationWidget} from '../widgets/duration';
@@ -204,21 +206,23 @@
return;
}
- let trackId: string|number|undefined;
+ let trackKey: string|number|undefined;
for (const track of Object.values(globals.state.tracks)) {
- if (track.kind === 'ThreadStateTrack' &&
- (track.config as {utid: number}).utid === threadInfo.utid) {
- trackId = track.id;
+ const trackDesc = pluginManager.resolveTrackInfo(track.uri);
+ // TODO(stevegolton): Handle v2.
+ if (trackDesc && trackDesc.kind === THREAD_STATE_TRACK_KIND &&
+ trackDesc.utid === threadInfo.utid) {
+ trackKey = track.key;
}
}
- if (trackId && sliceInfo.threadStateId) {
+ if (trackKey && sliceInfo.threadStateId) {
globals.makeSelection(Actions.selectThreadState({
id: sliceInfo.threadStateId,
- trackId: trackId.toString(),
+ trackKey: trackKey.toString(),
}));
- scrollToTrackAndTs(trackId, sliceInfo.ts, true);
+ scrollToTrackAndTs(trackKey, sliceInfo.ts, true);
}
}
diff --git a/ui/src/frontend/slice_track_base.ts b/ui/src/frontend/slice_track_base.ts
new file mode 100644
index 0000000..99eddc3
--- /dev/null
+++ b/ui/src/frontend/slice_track_base.ts
@@ -0,0 +1,339 @@
+// 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 {duration, Span, Time, time} from '../base/time';
+import {Actions} from '../common/actions';
+import {BasicAsyncTrack} from '../common/basic_async_track';
+import {cropText, drawIncompleteSlice} from '../common/canvas_utils';
+import {
+ colorForThreadIdleSlice,
+ getColorForSlice,
+} from '../common/colorizer';
+import {HighPrecisionTime} from '../common/high_precision_time';
+import {TrackData} from '../common/track_data';
+
+import {checkerboardExcept} from './checkerboard';
+import {globals} from './globals';
+import {cachedHsluvToHex} from './hsluv_cache';
+import {PxSpan, TimeScale} from './time_scale';
+import {SliceRect} from './track';
+
+export const SLICE_TRACK_KIND = 'ChromeSliceTrack';
+const SLICE_HEIGHT = 18;
+const TRACK_PADDING = 2;
+const CHEVRON_WIDTH_PX = 10;
+const HALF_CHEVRON_WIDTH_PX = CHEVRON_WIDTH_PX / 2;
+
+export interface SliceData extends TrackData {
+ // Slices are stored in a columnar fashion.
+ strings: string[];
+ sliceIds: Float64Array;
+ starts: BigInt64Array;
+ ends: BigInt64Array;
+ depths: Uint16Array;
+ titles: Uint16Array; // Index into strings.
+ colors?: Uint16Array; // Index into strings.
+ isInstant: Uint16Array;
+ isIncomplete: Uint16Array;
+ cpuTimeRatio?: Float64Array;
+}
+
+// Track base class which handles rendering slices in a generic way.
+// This is the old way of rendering slices - i.e. "track v1" format - and
+// exists as a patch to allow old tracks to be converted to controller-less
+// tracks before they are ported to v2.
+// Slice tracks should extend this class and implement the abstract methods,
+// notably onBoundsChange().
+export abstract class SliceTrackBase extends BasicAsyncTrack<SliceData> {
+ constructor(
+ private maxDepth: number, protected trackKey: string,
+ private tableName: string, private namespace?: string) {
+ super();
+ }
+
+ protected namespaceTable(tableName: string = this.tableName): string {
+ if (this.namespace) {
+ return this.namespace + '_' + tableName;
+ } else {
+ return tableName;
+ }
+ }
+
+ private hoveredTitleId = -1;
+
+ // Font used to render the slice name on the current track.
+ protected getFont() {
+ return '12px Roboto Condensed';
+ }
+
+ renderCanvas(ctx: CanvasRenderingContext2D): void {
+ // TODO: fonts and colors should come from the CSS and not hardcoded here.
+ const data = this.data;
+ if (data === undefined) return; // Can't possibly draw anything.
+
+ const {visibleTimeSpan, visibleWindowTime, visibleTimeScale, windowSpan} =
+ globals.frontendLocalState;
+
+ // If the cached trace slices don't fully cover the visible time range,
+ // show a gray rectangle with a "Loading..." label.
+ checkerboardExcept(
+ ctx,
+ this.getHeight(),
+ visibleTimeScale.hpTimeToPx(visibleWindowTime.start),
+ visibleTimeScale.hpTimeToPx(visibleWindowTime.end),
+ visibleTimeScale.timeToPx(data.start),
+ visibleTimeScale.timeToPx(data.end),
+ );
+
+ ctx.textAlign = 'center';
+
+ // measuretext is expensive so we only use it once.
+ const charWidth = ctx.measureText('ACBDLqsdfg').width / 10;
+
+ // The draw of the rect on the selected slice must happen after the other
+ // drawings, otherwise it would result under another rect.
+ let drawRectOnSelected = () => {};
+
+
+ for (let i = 0; i < data.starts.length; i++) {
+ const tStart = Time.fromRaw(data.starts[i]);
+ let tEnd = Time.fromRaw(data.ends[i]);
+ const depth = data.depths[i];
+ const titleId = data.titles[i];
+ const sliceId = data.sliceIds[i];
+ const isInstant = data.isInstant[i];
+ const isIncomplete = data.isIncomplete[i];
+ const title = data.strings[titleId];
+ const colorOverride = data.colors && data.strings[data.colors[i]];
+ if (isIncomplete) { // incomplete slice
+ // TODO(stevegolton): This isn't exactly equivalent, ideally we should
+ // choose tEnd once we've converted to screen space coords.
+ tEnd = visibleWindowTime.end.toTime('ceil');
+ }
+
+ if (!visibleTimeSpan.intersects(tStart, tEnd)) {
+ continue;
+ }
+
+ const rect = this.getSliceRect(
+ visibleTimeScale, visibleTimeSpan, windowSpan, tStart, tEnd, depth);
+ if (!rect || !rect.visible) {
+ continue;
+ }
+
+ const currentSelection = globals.state.currentSelection;
+ const isSelected = currentSelection &&
+ currentSelection.kind === 'CHROME_SLICE' &&
+ currentSelection.id !== undefined && currentSelection.id === sliceId;
+
+ const highlighted = titleId === this.hoveredTitleId ||
+ globals.state.highlightedSliceId === sliceId;
+
+ const hasFocus = highlighted || isSelected;
+ const colorObj = getColorForSlice(title, hasFocus);
+
+ let color: string;
+ if (colorOverride === undefined) {
+ color = colorObj.c;
+ } else {
+ color = colorOverride;
+ }
+ ctx.fillStyle = color;
+
+ // We draw instant events as upward facing chevrons starting at A:
+ // A
+ // ###
+ // ##C##
+ // ## ##
+ // D B
+ // Then B, C, D and back to A:
+ if (isInstant) {
+ if (isSelected) {
+ drawRectOnSelected = () => {
+ ctx.save();
+ ctx.translate(rect.left, rect.top);
+
+ // Draw a rectangle around the selected slice
+ ctx.strokeStyle = cachedHsluvToHex(colorObj.h, 100, 10);
+ ctx.beginPath();
+ ctx.lineWidth = 3;
+ ctx.strokeRect(
+ -HALF_CHEVRON_WIDTH_PX, 0, CHEVRON_WIDTH_PX, SLICE_HEIGHT);
+ ctx.closePath();
+
+ // Draw inner chevron as interior
+ ctx.fillStyle = color;
+ this.drawChevron(ctx);
+
+ ctx.restore();
+ };
+ } else {
+ ctx.save();
+ ctx.translate(rect.left, rect.top);
+ this.drawChevron(ctx);
+ ctx.restore();
+ }
+ continue;
+ }
+
+ if (isIncomplete && rect.width > SLICE_HEIGHT / 4) {
+ drawIncompleteSlice(ctx, rect.left, rect.top, rect.width, SLICE_HEIGHT);
+ } else if (
+ data.cpuTimeRatio !== undefined && data.cpuTimeRatio[i] < 1 - 1e-9) {
+ // We draw two rectangles, representing the ratio between wall time and
+ // time spent on cpu.
+ const cpuTimeRatio = data.cpuTimeRatio![i];
+ const firstPartWidth = rect.width * cpuTimeRatio;
+ const secondPartWidth = rect.width * (1 - cpuTimeRatio);
+ ctx.fillRect(rect.left, rect.top, firstPartWidth, SLICE_HEIGHT);
+ ctx.fillStyle = colorForThreadIdleSlice(
+ colorObj.h, colorObj.s, colorObj.l, hasFocus);
+ ctx.fillRect(
+ rect.left + firstPartWidth,
+ rect.top,
+ secondPartWidth,
+ SLICE_HEIGHT);
+ } else {
+ ctx.fillRect(rect.left, rect.top, rect.width, SLICE_HEIGHT);
+ }
+
+ // Selected case
+ if (isSelected) {
+ drawRectOnSelected = () => {
+ ctx.strokeStyle = cachedHsluvToHex(colorObj.h, 100, 10);
+ ctx.beginPath();
+ ctx.lineWidth = 3;
+ ctx.strokeRect(
+ rect.left, rect.top - 1.5, rect.width, SLICE_HEIGHT + 3);
+ ctx.closePath();
+ };
+ }
+
+ // Don't render text when we have less than 5px to play with.
+ if (rect.width >= 5) {
+ ctx.fillStyle = colorObj.l > 65 ? '#404040' : 'white';
+ const displayText = cropText(title, charWidth, rect.width);
+ const rectXCenter = rect.left + rect.width / 2;
+ ctx.textBaseline = 'middle';
+ ctx.font = this.getFont();
+ ctx.fillText(displayText, rectXCenter, rect.top + SLICE_HEIGHT / 2);
+ }
+ }
+ drawRectOnSelected();
+ }
+
+ drawChevron(ctx: CanvasRenderingContext2D) {
+ // Draw a chevron at a fixed location and size. Should be used with
+ // ctx.translate and ctx.scale to alter location and size.
+ ctx.beginPath();
+ ctx.moveTo(0, 0);
+ ctx.lineTo(HALF_CHEVRON_WIDTH_PX, SLICE_HEIGHT);
+ ctx.lineTo(0, SLICE_HEIGHT - HALF_CHEVRON_WIDTH_PX);
+ ctx.lineTo(-HALF_CHEVRON_WIDTH_PX, SLICE_HEIGHT);
+ ctx.lineTo(0, 0);
+ ctx.fill();
+ }
+
+ getSliceIndex({x, y}: {x: number, y: number}): number|void {
+ const data = this.data;
+ if (data === undefined) return;
+ const {
+ visibleTimeScale: timeScale,
+ visibleWindowTime: visibleHPTimeSpan,
+ } = globals.frontendLocalState;
+ if (y < TRACK_PADDING) return;
+ const instantWidthTime = timeScale.pxDeltaToDuration(HALF_CHEVRON_WIDTH_PX);
+ const t = timeScale.pxToHpTime(x);
+ const depth = Math.floor((y - TRACK_PADDING) / SLICE_HEIGHT);
+
+ for (let i = 0; i < data.starts.length; i++) {
+ if (depth !== data.depths[i]) {
+ continue;
+ }
+ const start = Time.fromRaw(data.starts[i]);
+ const tStart = HighPrecisionTime.fromTime(start);
+ if (data.isInstant[i]) {
+ if (tStart.sub(t).abs().lt(instantWidthTime)) {
+ return i;
+ }
+ } else {
+ const end = Time.fromRaw(data.ends[i]);
+ let tEnd = HighPrecisionTime.fromTime(end);
+ if (data.isIncomplete[i]) {
+ tEnd = visibleHPTimeSpan.end;
+ }
+ if (tStart.lte(t) && t.lte(tEnd)) {
+ return i;
+ }
+ }
+ }
+ }
+
+ onMouseMove({x, y}: {x: number, y: number}) {
+ this.hoveredTitleId = -1;
+ globals.dispatch(Actions.setHighlightedSliceId({sliceId: -1}));
+ const sliceIndex = this.getSliceIndex({x, y});
+ if (sliceIndex === undefined) return;
+ const data = this.data;
+ if (data === undefined) return;
+ this.hoveredTitleId = data.titles[sliceIndex];
+ const sliceId = data.sliceIds[sliceIndex];
+ globals.dispatch(Actions.setHighlightedSliceId({sliceId}));
+ }
+
+ onMouseOut() {
+ this.hoveredTitleId = -1;
+ globals.dispatch(Actions.setHighlightedSliceId({sliceId: -1}));
+ }
+
+ onMouseClick({x, y}: {x: number, y: number}): boolean {
+ const sliceIndex = this.getSliceIndex({x, y});
+ if (sliceIndex === undefined) return false;
+ const data = this.data;
+ if (data === undefined) return false;
+ const sliceId = data.sliceIds[sliceIndex];
+ if (sliceId !== undefined && sliceId !== -1) {
+ globals.makeSelection(Actions.selectChromeSlice({
+ id: sliceId,
+ trackKey: this.trackKey,
+ table: this.namespace,
+ }));
+ return true;
+ }
+ return false;
+ }
+
+ getHeight() {
+ return SLICE_HEIGHT * (this.maxDepth + 1) + 2 * TRACK_PADDING;
+ }
+
+ getSliceRect(
+ visibleTimeScale: TimeScale, visibleWindow: Span<time, duration>,
+ windowSpan: PxSpan, tStart: time, tEnd: time, depth: number): SliceRect
+ |undefined {
+ const pxEnd = windowSpan.end;
+ const left = Math.max(visibleTimeScale.timeToPx(tStart), 0);
+ const right = Math.min(visibleTimeScale.timeToPx(tEnd), pxEnd);
+
+ const visible = visibleWindow.intersects(tStart, tEnd);
+
+ return {
+ left,
+ width: Math.max(right - left, 1),
+ top: TRACK_PADDING + depth * SLICE_HEIGHT,
+ height: SLICE_HEIGHT,
+ visible,
+ };
+ }
+}
diff --git a/ui/src/frontend/sql/slice.ts b/ui/src/frontend/sql/slice.ts
index 8247487..8be8134 100644
--- a/ui/src/frontend/sql/slice.ts
+++ b/ui/src/frontend/sql/slice.ts
@@ -55,7 +55,7 @@
ts: time;
absTime?: string;
dur: duration;
- sqlTrackId: number;
+ trackId: number;
thread?: ThreadInfo;
process?: ProcessInfo;
threadTs?: time;
@@ -150,7 +150,7 @@
name: it.name,
ts: Time.fromRaw(it.ts),
dur: it.dur,
- sqlTrackId: it.trackId,
+ trackId: it.trackId,
thread,
process,
threadDur: it.threadDur ?? undefined,
@@ -198,17 +198,17 @@
{
icon: Icons.UpdateSelection,
onclick: () => {
- const uiTrackId =
- globals.state.uiTrackIdByTraceTrackId[vnode.attrs.sqlTrackId];
- if (uiTrackId === undefined) return;
- verticalScrollToTrack(uiTrackId, true);
+ const trackKey =
+ globals.state.trackKeyByTrackId[vnode.attrs.sqlTrackId];
+ if (trackKey === undefined) return;
+ verticalScrollToTrack(trackKey, true);
// Clamp duration to 1 - i.e. for instant events
const dur = BigintMath.max(1n, vnode.attrs.dur);
focusHorizontalRange(
vnode.attrs.ts, Time.fromRaw(vnode.attrs.ts + dur));
globals.makeSelection(
Actions.selectChromeSlice(
- {id: vnode.attrs.id, trackId: uiTrackId, table: 'slice'}),
+ {id: vnode.attrs.id, trackKey, table: 'slice'}),
{tab: switchTab ? 'current_selection' : null});
},
},
@@ -222,6 +222,6 @@
name: name ?? slice.name,
ts: slice.ts,
dur: slice.dur,
- sqlTrackId: slice.sqlTrackId,
+ sqlTrackId: slice.trackId,
});
}
diff --git a/ui/src/frontend/sql/thread_state.ts b/ui/src/frontend/sql/thread_state.ts
new file mode 100644
index 0000000..2de948b
--- /dev/null
+++ b/ui/src/frontend/sql/thread_state.ts
@@ -0,0 +1,139 @@
+// 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 m from 'mithril';
+
+import {Duration, duration, TimeSpan} from '../../base/time';
+import {LONG, NUM_NULL, STR, STR_NULL} from '../../common/query_result';
+import {EngineProxy} from '../../public';
+import {TreeNode} from '../../widgets/tree';
+import {Utid} from '../sql_types';
+
+// An individual node of the thread state breakdown tree.
+class Node {
+ parent?: Node;
+ children: Map<string, Node>;
+ dur: duration;
+ startsCollapsed: boolean = true;
+
+ constructor(parent?: Node) {
+ this.parent = parent;
+ this.children = new Map();
+ this.dur = 0n;
+ }
+
+ getOrCreateChild(name: string) {
+ let child = this.children.get(name);
+ if (!child) {
+ child = new Node(this);
+ this.children.set(name, child);
+ }
+ return child;
+ }
+
+ addDuration(dur: duration) {
+ let node: Node|undefined = this;
+ while (node !== undefined) {
+ node.dur += dur;
+ node = node.parent;
+ }
+ }
+}
+
+// Thread state breakdown data (tree).
+// Can be passed to ThreadStateBreakdownTreeNode to be rendered as a part of a
+// tree.
+export interface BreakdownByThreadState {
+ root: Node;
+}
+
+// Compute a breakdown of thread states for a given thread for a given time
+// interval.
+export async function breakDownIntervalByThreadState(
+ engine: EngineProxy, range: TimeSpan, utid: Utid):
+ Promise<BreakdownByThreadState> {
+ // TODO(altimin): this probably should share some code with pivot tables when
+ // we actually get some pivot tables we like.
+ const query = await engine.query(`
+ INCLUDE PERFETTO MODULE common.thread_states;
+
+ SELECT
+ state,
+ raw_state as rawState,
+ cpu_type as cpuType,
+ cpu,
+ blocked_function as blockedFunction,
+ dur
+ FROM thread_state_summary_for_interval(${range.start}, ${range.duration}, ${
+ utid});
+ `);
+ const it = query.iter({
+ state: STR,
+ rawState: STR,
+ cpuType: STR_NULL,
+ cpu: NUM_NULL,
+ blockedFunction: STR_NULL,
+ dur: LONG,
+ });
+ const root = new Node();
+ for (; it.valid(); it.next()) {
+ let currentNode = root;
+ currentNode = currentNode.getOrCreateChild(it.state);
+ // If the CPU time is not null, add it to the breakdown.
+ if (it.cpuType !== null) {
+ currentNode = currentNode.getOrCreateChild(it.cpuType);
+ }
+ if (it.cpu !== null) {
+ currentNode = currentNode.getOrCreateChild(`CPU ${it.cpu}`);
+ }
+ if (it.blockedFunction !== null) {
+ currentNode = currentNode.getOrCreateChild(`${it.blockedFunction}`);
+ }
+ currentNode.addDuration(it.dur);
+ }
+ return {
+ root,
+ };
+}
+
+function renderChildren(node: Node, totalDur: duration): m.Child[] {
+ const res = Array.from(node.children.entries())
+ .map(([name, child]) => renderNode(child, name, totalDur));
+ return res;
+}
+
+function renderNode(node: Node, name: string, totalDur: duration): m.Child {
+ const durPercent = 100. * Number(node.dur) / Number(totalDur);
+ return m(
+ TreeNode,
+ {
+ left: name,
+ right: `${Duration.humanise(node.dur)} (${durPercent.toFixed(2)}%)`,
+ startsCollapsed: node.startsCollapsed,
+ },
+ renderChildren(node, totalDur));
+}
+
+interface BreakdownByThreadStateTreeNodeAttrs {
+ dur: duration;
+ data: BreakdownByThreadState;
+}
+
+// A tree node that displays a nested breakdown a time interval by thread state.
+export class BreakdownByThreadStateTreeNode implements
+ m.ClassComponent<BreakdownByThreadStateTreeNodeAttrs> {
+ view({attrs}: m.Vnode<BreakdownByThreadStateTreeNodeAttrs>): m.Child[] {
+ return renderChildren(attrs.data.root, attrs.dur);
+ }
+}
diff --git a/ui/src/frontend/sql_table/render_cell.ts b/ui/src/frontend/sql_table/render_cell.ts
index e5d5b1c..b871142 100644
--- a/ui/src/frontend/sql_table/render_cell.ts
+++ b/ui/src/frontend/sql_table/render_cell.ts
@@ -15,6 +15,7 @@
import m from 'mithril';
import {copyToClipboard} from '../../base/clipboard';
+import {isString} from '../../base/object_utils';
import {Icons} from '../../base/semantic_icons';
import {sqliteString} from '../../base/string_utils';
import {duration, Duration, Time} from '../../base/time';
@@ -52,7 +53,7 @@
filterOptionMenuItem('is not null', `${c.expression} is not null`, state),
];
}
- if (typeof value === 'string') {
+ if (isString(value)) {
return [
filterOptionMenuItem(
'equals to', `${c.expression} = ${sqliteString(value)}`, state),
@@ -125,7 +126,7 @@
result.push(
copyMenuItem('Copy formatted duration', displayDuration(value)));
}
- if (typeof value === 'string') {
+ if (isString(value)) {
result.push(copyMenuItem('Copy', value));
}
diff --git a/ui/src/frontend/sql_table/state.ts b/ui/src/frontend/sql_table/state.ts
index 806c330..423b35a 100644
--- a/ui/src/frontend/sql_table/state.ts
+++ b/ui/src/frontend/sql_table/state.ts
@@ -14,6 +14,7 @@
import {arrayEquals} from '../../base/array_utils';
import {SortDirection} from '../../base/comparison_utils';
+import {isString} from '../../base/object_utils';
import {sqliteString} from '../../base/string_utils';
import {EngineProxy} from '../../common/engine';
import {NUM, Row} from '../../common/query_result';
@@ -134,7 +135,7 @@
};
let cteId = 0;
for (const filter of this.filters) {
- if (typeof filter === 'string') {
+ if (isString(filter)) {
result.filters!.push(filter);
} else {
const cteName = `arg_sets_${cteId++}`;
diff --git a/ui/src/frontend/sql_table/table.ts b/ui/src/frontend/sql_table/table.ts
index 92f8fc9..578a75e 100644
--- a/ui/src/frontend/sql_table/table.ts
+++ b/ui/src/frontend/sql_table/table.ts
@@ -14,6 +14,7 @@
import m from 'mithril';
+import {isString} from '../../base/object_utils';
import {Icons} from '../../base/semantic_icons';
import {EngineProxy} from '../../common/engine';
import {Row} from '../../common/query_result';
@@ -48,9 +49,8 @@
renderFilters(): m.Children {
const filters: m.Child[] = [];
for (const filter of this.state.getFilters()) {
- const label = typeof filter === 'string' ?
- filter :
- `Arg(${filter.argName}) ${filter.op}`;
+ const label =
+ isString(filter) ? filter : `Arg(${filter.argName}) ${filter.op}`;
filters.push(m(Button, {
label,
icon: 'close',
diff --git a/ui/src/frontend/sql_utils.ts b/ui/src/frontend/sql_utils.ts
index 990090c..b201de1 100644
--- a/ui/src/frontend/sql_utils.ts
+++ b/ui/src/frontend/sql_utils.ts
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import {isString} from '../base/object_utils';
import {EngineProxy} from '../common/engine';
import {ColumnType, NUM} from '../common/query_result';
import {SortDirection} from '../common/state';
@@ -68,7 +69,7 @@
const orderBy = (c.orderBy ?? []).filter(isDefined);
if (orderBy.length > 0) {
const orderBys = orderBy.map((clause) => {
- if (typeof clause === 'string') {
+ if (isString(clause)) {
return clause;
} else {
const direction = clause.direction ? ` ${clause.direction}` : '';
diff --git a/ui/src/frontend/thread_state.ts b/ui/src/frontend/thread_state.ts
index 80f690b..c1989c4 100644
--- a/ui/src/frontend/thread_state.ts
+++ b/ui/src/frontend/thread_state.ts
@@ -27,6 +27,7 @@
import {LONG, NUM, NUM_NULL, STR_NULL} from '../common/query_result';
import {translateState} from '../common/thread_state';
import {CPU_SLICE_TRACK_KIND} from '../tracks/cpu_slices';
+import {THREAD_STATE_TRACK_KIND} from '../tracks/thread_state';
import {Anchor} from '../widgets/anchor';
import {globals} from './globals';
@@ -148,7 +149,7 @@
const trackInfo = pluginManager.resolveTrackInfo(track.uri);
if (trackInfo?.kind === CPU_SLICE_TRACK_KIND) {
if (trackInfo?.cpu === cpu) {
- trackId = track.id;
+ trackId = track.key;
break;
}
}
@@ -157,7 +158,7 @@
if (trackId === undefined) {
return;
}
- globals.makeSelection(Actions.selectSlice({id, trackId}));
+ globals.makeSelection(Actions.selectSlice({id, trackKey: trackId}));
scrollToTrackAndTs(trackId, ts);
}
@@ -177,21 +178,23 @@
{
icon: Icons.UpdateSelection,
onclick: () => {
- let trackId: string|number|undefined;
+ let trackKey: string|number|undefined;
for (const track of Object.values(globals.state.tracks)) {
- if (track.kind === 'ThreadStateTrack' &&
- (track.config as {utid: number}).utid === vnode.attrs.utid) {
- trackId = track.id;
+ const trackDesc = pluginManager.resolveTrackInfo(track.uri);
+ // TODO(stevegolton): Handle v2.
+ if (trackDesc && trackDesc.kind === THREAD_STATE_TRACK_KIND &&
+ trackDesc.utid === vnode.attrs.utid) {
+ trackKey = track.key;
}
}
- if (trackId) {
+ if (trackKey) {
globals.makeSelection(Actions.selectThreadState({
id: vnode.attrs.id,
- trackId: trackId.toString(),
+ trackKey: trackKey.toString(),
}));
- scrollToTrackAndTs(trackId, vnode.attrs.ts, true);
+ scrollToTrackAndTs(trackKey, vnode.attrs.ts, true);
}
},
},
diff --git a/ui/src/frontend/thread_state_tab.ts b/ui/src/frontend/thread_state_tab.ts
index 4e25723..35d3b9f 100644
--- a/ui/src/frontend/thread_state_tab.ts
+++ b/ui/src/frontend/thread_state_tab.ts
@@ -17,7 +17,7 @@
import {Duration, time} from '../base/time';
import {runQuery} from '../common/queries';
import {raf} from '../core/raf_scheduler';
-import {addDebugTrack} from '../tracks/debug/slice_track';
+import {addDebugSliceTrack} from '../tracks/debug/slice_track';
import {Anchor} from '../widgets/anchor';
import {Button} from '../widgets/button';
import {DetailsShell} from '../widgets/details_shell';
@@ -292,7 +292,7 @@
{
label: 'Critical path lite',
onclick: () => runQuery(`INCLUDE PERFETTO MODULE experimental.thread_executing_span;`, this.engine)
- .then(() => addDebugTrack(
+ .then(() => addDebugSliceTrack(
this.engine,
{
sqlSource:
@@ -324,7 +324,7 @@
{
label: 'Critical path',
onclick: () => runQuery(`INCLUDE PERFETTO MODULE experimental.thread_executing_span;`, this.engine)
- .then(() => addDebugTrack(
+ .then(() => addDebugSliceTrack(
this.engine,
{
sqlSource:
diff --git a/ui/src/frontend/track.ts b/ui/src/frontend/track.ts
index 6ddbc51..15f4f4e 100644
--- a/ui/src/frontend/track.ts
+++ b/ui/src/frontend/track.ts
@@ -17,18 +17,14 @@
import {assertExists} from '../base/logging';
import {duration, Span, time} from '../base/time';
import {EngineProxy} from '../common/engine';
-import {TrackState} from '../common/state';
-import {TrackData} from '../common/track_data';
-import {Track} from '../public';
+import {Track, TrackContext} from '../public';
-import {checkerboard} from './checkerboard';
import {globals} from './globals';
import {PxSpan, TimeScale} from './time_scale';
-import {TrackButtonAttrs} from './track_panel';
// Args passed to the track constructors when creating a new track.
export interface NewTrackArgs {
- trackId: string;
+ trackKey: string;
engine: EngineProxy;
}
@@ -54,28 +50,25 @@
}
// The abstract class that needs to be implemented by all tracks.
-export abstract class TrackBase<Config = {}, Data extends TrackData = TrackData>
- implements Track {
- // The UI-generated track ID (not to be confused with the SQL track.id).
- protected readonly trackId: string;
+export abstract class TrackBase<Config = {}> implements Track {
+ protected readonly trackKey: string;
protected readonly engine: EngineProxy;
+ private _config?: Config;
- // When true this is a new controller-less track type.
- // TODO(hjd): eventually all tracks will be controller-less and this
- // should be removed then.
- protected frontendOnly = false;
-
- // Caches the last state.track[this.trackId]. This is to deal with track
- // deletion, see comments in trackState() below.
- private lastTrackState: TrackState;
-
- constructor(args: NewTrackArgs) {
- this.trackId = args.trackId;
- this.engine = args.engine;
- this.lastTrackState = assertExists(globals.state.tracks[this.trackId]);
+ get config(): Config {
+ return assertExists(this._config);
}
- onCreate() {}
+ set config(x: Config) {
+ this._config = x;
+ }
+
+ constructor(args: NewTrackArgs) {
+ this.trackKey = args.trackKey;
+ this.engine = args.engine;
+ }
+
+ onCreate(_ctx: TrackContext) {}
// Last call the track will receive. Called just before the last reference to
// this object is removed.
@@ -83,44 +76,14 @@
protected abstract renderCanvas(ctx: CanvasRenderingContext2D): void;
- protected get trackState(): TrackState {
- // We can end up in a state where a Track is still in the mithril renderer
- // tree but its corresponding state has been deleted. This can happen in the
- // interval of time between a track being removed from the state and the
- // next animation frame that would remove the Track object. If a mouse event
- // is dispatched in the meanwhile (or a promise is resolved), we need to be
- // able to access the state. Hence the caching logic here.
- const trackState = globals.state.tracks[this.trackId];
- if (trackState === undefined) {
- return this.lastTrackState;
- }
- this.lastTrackState = trackState;
- return trackState;
- }
-
- get config(): Config {
- return this.trackState.config as Config;
- }
-
- data(): Data|undefined {
- if (this.frontendOnly) {
- return undefined;
- }
- return globals.trackDataStore.get(this.trackId) as Data;
- }
-
getHeight(): number {
return 40;
}
- getTrackShellButtons(): Array<m.Vnode<TrackButtonAttrs>> {
+ getTrackShellButtons(): m.Children {
return [];
}
- getContextMenu(): m.Vnode<any>|null {
- return null;
- }
-
onMouseMove(_position: {x: number, y: number}) {}
// Returns whether the mouse click has selected something.
@@ -134,17 +97,8 @@
onFullRedraw(): void {}
render(ctx: CanvasRenderingContext2D) {
- globals.frontendLocalState.addVisibleTrack(this.trackState.id);
- if (this.data() === undefined && !this.frontendOnly) {
- const {visibleWindowTime, visibleTimeScale} = globals.frontendLocalState;
- const startPx =
- Math.floor(visibleTimeScale.hpTimeToPx(visibleWindowTime.start));
- const endPx =
- Math.ceil(visibleTimeScale.hpTimeToPx(visibleWindowTime.end));
- checkerboard(ctx, this.getHeight(), startPx, endPx);
- } else {
- this.renderCanvas(ctx);
- }
+ globals.frontendLocalState.addVisibleTrack(this.trackKey);
+ this.renderCanvas(ctx);
}
// Returns a place where a given slice should be drawn. Should be implemented
diff --git a/ui/src/frontend/track_group_panel.ts b/ui/src/frontend/track_group_panel.ts
index b378189..a524dfb 100644
--- a/ui/src/frontend/track_group_panel.ts
+++ b/ui/src/frontend/track_group_panel.ts
@@ -19,7 +19,6 @@
import {Icons} from '../base/semantic_icons';
import {Actions} from '../common/actions';
import {pluginManager} from '../common/plugins';
-import {RegistryError} from '../common/registry';
import {
getContainingTrackId,
TrackGroupState,
@@ -31,7 +30,6 @@
import {drawGridLines} from './gridline_helper';
import {Panel, PanelSize} from './panel';
import {renderChips, TrackContent} from './track_panel';
-import {trackRegistry} from './track_registry';
import {
drawVerticalLineAtTime,
} from './vertical_line_helper';
@@ -53,25 +51,25 @@
}
private tryLoadTrack() {
- const trackId = this.trackGroupId;
+ const groupId = this.trackGroupId;
const trackState = this.summaryTrackState;
- const {id, uri} = trackState;
+ const {key, uri, params} = trackState;
const ctx: TrackContext = {
- trackInstanceId: id,
+ trackKey: key,
mountStore: <T>(migrate: Migrate<T>) => {
const {store, state} = globals;
- const migratedState = migrate(state.trackGroups[trackId].state);
+ const migratedState = migrate(state.trackGroups[groupId].state);
store.edit((draft) => {
- draft.trackGroups[trackId].state = migratedState;
+ draft.trackGroups[groupId].state = migratedState;
});
- return store.createProxy<T>(['trackGroups', trackId, 'state']);
+ return store.createProxy<T>(['trackGroups', groupId, 'state']);
},
+ params,
};
- this.summaryTrack =
- uri ? pluginManager.createTrack(uri, ctx) : loadTrack(trackState, id);
+ this.summaryTrack = pluginManager.createTrack(uri, ctx);
}
get trackGroupState(): TrackGroupState {
@@ -98,8 +96,8 @@
let highlightClass = '';
const searchIndex = globals.state.searchIndex;
if (searchIndex !== -1) {
- const trackId = globals.currentSearchResults.trackIds[searchIndex];
- const parentTrackId = getContainingTrackId(globals.state, trackId);
+ const trackKey = globals.currentSearchResults.trackKeys[searchIndex];
+ const parentTrackId = getContainingTrackId(globals.state, trackKey);
if (parentTrackId === attrs.trackGroupId) {
highlightClass = 'flash';
}
@@ -304,25 +302,3 @@
function StripPathFromExecutable(path: string) {
return path.split('/').slice(-1)[0];
}
-
-function loadTrack(trackState: TrackState, trackId: string): Track|undefined {
- const engine = globals.engines.get(trackState.engineId);
- if (engine === undefined) {
- return undefined;
- }
-
- try {
- const trackCreator = trackRegistry.get(trackState.kind);
- return trackCreator.create({
- trackId,
- engine:
- engine.getProxy(`Track; kind: ${trackState.kind}; id: ${trackId}`),
- });
- } catch (e) {
- if (e instanceof RegistryError) {
- return undefined;
- } else {
- throw e;
- }
- }
-}
diff --git a/ui/src/frontend/track_panel.ts b/ui/src/frontend/track_panel.ts
index c280ced..90a593a 100644
--- a/ui/src/frontend/track_panel.ts
+++ b/ui/src/frontend/track_panel.ts
@@ -18,10 +18,8 @@
import {currentTargetOffset} from '../base/dom_utils';
import {Icons} from '../base/semantic_icons';
import {duration, Span, time} from '../base/time';
-import {exists} from '../base/utils';
import {Actions} from '../common/actions';
import {pluginManager} from '../common/plugins';
-import {RegistryError} from '../common/registry';
import {TrackState} from '../common/state';
import {raf} from '../core/raf_scheduler';
import {Migrate, Track, TrackContext} from '../public';
@@ -33,7 +31,6 @@
import {verticalScrollToTrack} from './scroll_helper';
import {PxSpan, TimeScale} from './time_scale';
import {SliceRect} from './track';
-import {trackRegistry} from './track_registry';
import {
drawVerticalLineAtTime,
} from './vertical_line_helper';
@@ -79,24 +76,12 @@
}
}
-export function renderChips({uri, config}: TrackState) {
+export function renderChips({uri}: TrackState) {
const tagElements: m.Children = [];
- if (exists(uri)) {
- const trackInfo = pluginManager.resolveTrackInfo(uri);
- const tags = trackInfo?.tags;
- tags?.metric && tagElements.push(m(TrackChip, {text: 'metric'}));
- tags?.debuggable && tagElements.push(m(TrackChip, {text: 'debuggable'}));
- } else {
- if (config && typeof config === 'object') {
- if ('namespace' in config) {
- tagElements.push(m(TrackChip, {text: 'metric'}));
- }
- if ('isDebuggable' in config && config.isDebuggable) {
- tagElements.push(m(TrackChip, {text: 'debuggable'}));
- }
- }
- }
-
+ const trackInfo = pluginManager.resolveTrackInfo(uri);
+ const tags = trackInfo?.tags;
+ tags?.metric && tagElements.push(m(TrackChip, {text: 'metric'}));
+ tags?.debuggable && tagElements.push(m(TrackChip, {text: 'debuggable'}));
return tagElements;
}
@@ -121,8 +106,8 @@
let highlightClass = '';
const searchIndex = globals.state.searchIndex;
if (searchIndex !== -1) {
- const trackId = globals.currentSearchResults.trackIds[searchIndex];
- if (trackId === attrs.trackState.id) {
+ const trackKey = globals.currentSearchResults.trackKeys[searchIndex];
+ if (trackKey === attrs.trackState.key) {
highlightClass = 'flash';
}
}
@@ -152,16 +137,15 @@
),
m('.track-buttons',
attrs.track.getTrackShellButtons(),
- attrs.track.getContextMenu(),
m(TrackButton, {
action: () => {
globals.dispatch(
- Actions.toggleTrackPinned({trackId: attrs.trackState.id}));
+ Actions.toggleTrackPinned({trackKey: attrs.trackState.key}));
},
i: Icons.Pin,
- filledIcon: isPinned(attrs.trackState.id),
- tooltip: isPinned(attrs.trackState.id) ? 'Unpin' : 'Pin to top',
- showButton: isPinned(attrs.trackState.id),
+ filledIcon: isPinned(attrs.trackState.key),
+ tooltip: isPinned(attrs.trackState.key) ? 'Unpin' : 'Pin to top',
+ showButton: isPinned(attrs.trackState.key),
fullHeight: true,
}),
globals.state.currentSelection !== null &&
@@ -169,12 +153,12 @@
m(TrackButton, {
action: (e: MouseEvent) => {
globals.dispatch(Actions.toggleTrackSelection(
- {id: attrs.trackState.id, isTrackGroup: false}));
+ {id: attrs.trackState.key, isTrackGroup: false}));
e.stopPropagation();
},
- i: isSelected(attrs.trackState.id) ? Icons.Checkbox :
- Icons.BlankCheckbox,
- tooltip: isSelected(attrs.trackState.id) ?
+ i: isSelected(attrs.trackState.key) ? Icons.Checkbox :
+ Icons.BlankCheckbox,
+ tooltip: isSelected(attrs.trackState.key) ?
'Remove track' :
'Add track to selection',
showButton: true,
@@ -187,7 +171,7 @@
if (dataTransfer === null) return;
this.dragging = true;
raf.scheduleFullRedraw();
- dataTransfer.setData('perfetto/track', `${this.attrs!.trackState.id}`);
+ dataTransfer.setData('perfetto/track', `${this.attrs!.trackState.key}`);
dataTransfer.setDragImage(new Image(), 0, 0);
}
@@ -226,7 +210,7 @@
if (dataTransfer === null) return;
raf.scheduleFullRedraw();
const srcId = dataTransfer.getData('perfetto/track');
- const dstId = this.attrs!.trackState.id;
+ const dstId = this.attrs!.trackState.key;
globals.dispatch(Actions.moveTrack({srcId, op: this.dropping, dstId}));
this.dropping = undefined;
}
@@ -305,7 +289,7 @@
style: {
height: `${Math.max(18, attrs.track.getHeight())}px`,
},
- id: 'track_' + attrs.trackState.id,
+ id: 'track_' + attrs.trackState.key,
},
[
m(TrackShell, {track: attrs.track, trackState: attrs.trackState}),
@@ -314,9 +298,9 @@
}
oncreate({attrs}: m.CVnode<TrackComponentAttrs>) {
- if (globals.frontendLocalState.scrollToTrackId === attrs.trackState.id) {
- verticalScrollToTrack(attrs.trackState.id);
- globals.frontendLocalState.scrollToTrackId = undefined;
+ if (globals.frontendLocalState.scrollToTrackKey === attrs.trackState.key) {
+ verticalScrollToTrack(attrs.trackState.key);
+ globals.frontendLocalState.scrollToTrackKey = undefined;
}
}
}
@@ -348,7 +332,7 @@
}
interface TrackPanelAttrs {
- id: string;
+ trackKey: string;
selectable: boolean;
}
@@ -360,29 +344,29 @@
private trackState: TrackState|undefined;
private tryLoadTrack(vnode: m.CVnode<TrackPanelAttrs>) {
- const trackId = vnode.attrs.id;
- const trackState = globals.state.tracks[trackId];
+ const trackKey = vnode.attrs.trackKey;
+ const trackState = globals.state.tracks[trackKey];
if (!trackState) return;
- const {id, uri} = trackState;
+ const {uri, params} = trackState;
const trackCtx: TrackContext = {
- trackInstanceId: id,
+ trackKey,
mountStore: <T>(migrate: Migrate<T>) => {
const {store, state} = globals;
- const migratedState = migrate(state.tracks[trackId].state);
+ const migratedState = migrate(state.tracks[trackKey].state);
globals.store.edit((draft) => {
- draft.tracks[trackId].state = migratedState;
+ draft.tracks[trackKey].state = migratedState;
});
- return store.createProxy<T>(['tracks', trackId, 'state']);
+ return store.createProxy<T>(['tracks', trackKey, 'state']);
},
+ params,
};
- this.track = uri ? pluginManager.createTrack(uri, trackCtx) :
- loadTrack(trackState, id);
+ this.track = pluginManager.createTrack(uri, trackCtx);
- this.track?.onCreate();
+ this.track?.onCreate(trackCtx);
this.trackState = trackState;
}
@@ -425,7 +409,7 @@
}
const selectedArea = globals.state.areas[selection.areaId];
const selectedAreaDuration = selectedArea.end - selectedArea.start;
- if (selectedArea.tracks.includes(trackState.id)) {
+ if (selectedArea.tracks.includes(trackState.key)) {
ctx.fillStyle = SELECTION_FILL_COLOR;
ctx.fillRect(
visibleTimeScale.timeToPx(selectedArea.start) + TRACK_SHELL_WIDTH,
@@ -519,25 +503,3 @@
visibleTimeScale, visibleWindow, windowSpan, tStart, tDur, depth);
}
}
-
-function loadTrack(trackState: TrackState, trackId: string): Track|undefined {
- const engine = globals.engines.get(trackState.engineId);
- if (engine === undefined) {
- return undefined;
- }
-
- try {
- const trackCreator = trackRegistry.get(trackState.kind);
- return trackCreator.create({
- trackId,
- engine:
- engine.getProxy(`Track; kind: ${trackState.kind}; id: ${trackId}`),
- });
- } catch (e) {
- if (e instanceof RegistryError) {
- return undefined;
- } else {
- throw e;
- }
- }
-}
diff --git a/ui/src/frontend/viewer_page.ts b/ui/src/frontend/viewer_page.ts
index 0297f81..86c8357 100644
--- a/ui/src/frontend/viewer_page.ts
+++ b/ui/src/frontend/viewer_page.ts
@@ -228,7 +228,7 @@
view() {
const scrollingPanels: AnyAttrsVnode[] = globals.state.scrollingTracks.map(
- (id) => m(TrackPanel, {key: id, id, selectable: true}));
+ (key) => m(TrackPanel, {key, trackKey: key, selectable: true}));
for (const group of Object.values(globals.state.trackGroups)) {
const headerPanel = m(TrackGroupPanel, {
@@ -245,7 +245,7 @@
const id = group.tracks[i];
childTracks.push(m(TrackPanel, {
key: `track-${group.id}-${id}`,
- id,
+ trackKey: id,
selectable: true,
}));
}
@@ -285,7 +285,9 @@
m(NotesPanel, {key: 'notes'}),
m(TickmarkPanel, {key: 'searchTickmarks'}),
...globals.state.pinnedTracks.map(
- (id) => m(TrackPanel, {key: id, id, selectable: true})),
+ (id) =>
+ m(TrackPanel,
+ {key: id, trackKey: id, selectable: true})),
],
kind: 'OVERVIEW',
})),
diff --git a/ui/src/frontend/widgets/vega_view.ts b/ui/src/frontend/widgets/vega_view.ts
index 5dd3a1a..05c4f93 100644
--- a/ui/src/frontend/widgets/vega_view.ts
+++ b/ui/src/frontend/widgets/vega_view.ts
@@ -17,7 +17,7 @@
import * as vegaLite from 'vega-lite';
import {Disposable} from '../../base/disposable';
-import {shallowEquals} from '../../base/object_utils';
+import {isString, shallowEquals} from '../../base/object_utils';
import {SimpleResizeObserver} from '../../base/resize_observer';
import {EngineProxy} from '../../common/engine';
import {getErrorMessage} from '../../common/errors';
@@ -28,7 +28,7 @@
function isVegaLite(spec: unknown): boolean {
if (typeof spec === 'object') {
const schema = (spec as {'$schema': unknown})['$schema'];
- if (schema !== undefined && typeof schema === 'string') {
+ if (schema !== undefined && isString(schema)) {
// If the schema is available use that:
return schema.includes('vega-lite');
}
diff --git a/ui/src/frontend/widgets_page.ts b/ui/src/frontend/widgets_page.ts
index c3b6787..7743df9 100644
--- a/ui/src/frontend/widgets_page.ts
+++ b/ui/src/frontend/widgets_page.ts
@@ -16,6 +16,7 @@
import {classNames} from '../base/classnames';
import {Hotkey, Platform} from '../base/hotkeys';
+import {isString} from '../base/object_utils';
import {Icons} from '../base/semantic_icons';
import {raf} from '../core/raf_scheduler';
import {Anchor} from '../widgets/anchor';
@@ -381,7 +382,7 @@
this.optValues[key] = option.initial;
} else if (typeof option === 'boolean') {
this.optValues[key] = option;
- } else if (typeof option === 'string') {
+ } else if (isString(option)) {
this.optValues[key] = option;
}
}
@@ -428,7 +429,7 @@
return this.renderEnumOption(key, value);
} else if (typeof value === 'boolean') {
return this.renderBooleanOption(key);
- } else if (typeof value === 'string') {
+ } else if (isString(value)) {
return this.renderStringOption(key);
} else {
return null;
diff --git a/ui/src/plugins/com.example.Skeleton/index.ts b/ui/src/plugins/com.example.Skeleton/index.ts
index 354cb7f..282d615 100644
--- a/ui/src/plugins/com.example.Skeleton/index.ts
+++ b/ui/src/plugins/com.example.Skeleton/index.ts
@@ -13,12 +13,13 @@
// limitations under the License.
import {
+ createStore,
MetricVisualisation,
Plugin,
PluginContext,
PluginContextTrace,
PluginDescriptor,
- TrackInstanceDescriptor,
+ Store,
} from '../../public';
interface State {
@@ -26,20 +27,24 @@
}
// SKELETON: Rename this class to match your plugin.
-class Skeleton implements Plugin<State> {
+class Skeleton implements Plugin {
+ private store: Store<State> = createStore({foo: 'foo'});
+
onActivate(_: PluginContext): void {
//
}
- migrate(_initialState: unknown): State {
- return {foo: 'bar'};
+ async onTraceLoad(ctx: PluginContextTrace): Promise<void> {
+ this.store = ctx.mountStore((_: unknown): State => {
+ return {foo: 'bar'};
+ });
+
+ this.store.edit((state) => {
+ state.foo = 'baz';
+ });
}
- async onTraceLoad(_: PluginContextTrace<State>): Promise<void> {
- //
- }
-
- async onTraceUnload(_: PluginContextTrace<State>): Promise<void> {
+ async onTraceUnload(_: PluginContextTrace): Promise<void> {
//
}
@@ -47,17 +52,12 @@
//
}
- async findPotentialTracks(_: PluginContextTrace<State>):
- Promise<TrackInstanceDescriptor[]> {
- return [];
- }
-
- metricVisualisations(_: PluginContextTrace<State>): MetricVisualisation[] {
+ metricVisualisations(_: PluginContextTrace): MetricVisualisation[] {
return [];
}
}
-export const plugin: PluginDescriptor<State> = {
+export const plugin: PluginDescriptor = {
// SKELETON: Update pluginId to match the directory of the plugin.
pluginId: 'com.example.Skeleton',
plugin: Skeleton,
diff --git a/ui/src/plugins/dev.perfetto.ExampleState/index.ts b/ui/src/plugins/dev.perfetto.ExampleState/index.ts
index a18cfe2..9e4e31c 100644
--- a/ui/src/plugins/dev.perfetto.ExampleState/index.ts
+++ b/ui/src/plugins/dev.perfetto.ExampleState/index.ts
@@ -25,8 +25,8 @@
// This example plugin shows using state that is persisted in the
// permalink.
-class ExampleState implements Plugin<State> {
- migrate(initialState: unknown): State {
+class ExampleState implements Plugin {
+ private migrate(initialState: unknown): State {
if (initialState && typeof initialState === 'object' &&
'counter' in initialState && typeof initialState.counter === 'number') {
return {counter: initialState.counter};
@@ -39,8 +39,10 @@
//
}
- async onTraceLoad(ctx: PluginContextTrace<State>): Promise<void> {
- const {viewer, store} = ctx;
+ async onTraceLoad(ctx: PluginContextTrace): Promise<void> {
+ const {viewer} = ctx;
+ const store = ctx.mountStore((init: unknown) => this.migrate(init));
+
ctx.addCommand({
id: 'dev.perfetto.ExampleState#ShowCounter',
name: 'Show ExampleState counter',
@@ -54,7 +56,7 @@
}
}
-export const plugin: PluginDescriptor<State> = {
+export const plugin: PluginDescriptor = {
pluginId: 'dev.perfetto.ExampleState',
plugin: ExampleState,
};
diff --git a/ui/src/public/index.ts b/ui/src/public/index.ts
index 60ab2b8..bd61971 100644
--- a/ui/src/public/index.ts
+++ b/ui/src/public/index.ts
@@ -17,11 +17,9 @@
import {Hotkey} from '../base/hotkeys';
import {duration, Span, time} from '../base/time';
import {EngineProxy} from '../common/engine';
-import {TrackControllerFactory} from '../controller/track_controller';
import {Store} from '../frontend/store';
import {PxSpan, TimeScale} from '../frontend/time_scale';
-import {SliceRect, TrackCreator} from '../frontend/track';
-import {TrackButtonAttrs} from '../frontend/track_panel';
+import {SliceRect} from '../frontend/track';
export {EngineProxy} from '../common/engine';
export {
@@ -32,7 +30,7 @@
STR,
STR_NULL,
} from '../common/query_result';
-export {Store} from '../frontend/store';
+export {createStore, Store} from '../frontend/store';
// An imperative API for plugins to change the UI.
@@ -112,60 +110,15 @@
path: string[];
}
-export interface MetricVisualisation {
- // The name of the metric e.g. 'android_camera'
- metric: string;
-
- // A vega or vega-lite visualisation spec.
- // The data from the metric under path will be exposed as a
- // datasource named "metric" in Vega(-Lite)
- spec: string;
-
- // A path index into the metric.
- // For example if the metric returns the folowing protobuf:
- // {
- // foo {
- // bar {
- // baz: { name: "a" }
- // baz: { name: "b" }
- // baz: { name: "c" }
- // }
- // }
- // }
- // That becomes the following json:
- // { "foo": { "bar": { "baz": [
- // {"name": "a"},
- // {"name": "b"},
- // {"name": "c"},
- // ]}}}
- // And given path = ["foo", "bar", "baz"]
- // We extract:
- // [ {"name": "a"}, {"name": "b"}, {"name": "c"} ]
- // And pass that to the vega(-lite) visualisation.
- path: string[];
-}
-
// This interface defines a context for a plugin, which is an object passed to
// most hooks within the plugin. It should be used to interact with Perfetto.
export interface PluginContext {
+ // The unique ID for this plugin.
+ readonly pluginId: string;
+
+ // The viewer API, used to interface with Perfetto.
readonly viewer: Viewer;
- // DEPRECATED. In prior versions of the UI tracks were split into a
- // 'TrackController' and a 'Track'. In more recent versions of the UI
- // the functionality of |TrackController| has been merged into Track so
- // |TrackController|s are not necessary in new code.
- LEGACY_registerTrackController(track: TrackControllerFactory): void;
-
- // Register a track factory. The core UI invokes |TrackCreator| to
- // construct tracks discovered by invoking |TrackProvider|s.
- // The split between 'construction' and 'discovery' allows
- // plugins to reuse common tracks for new data. For example: the
- // dev.perfetto.AndroidGpu plugin could register a TrackProvider
- // which returns GPU counter tracks. The counter track factory itself
- // could be registered in dev.perfetto.CounterTrack - a whole
- // different plugin.
- LEGACY_registerTrack(track: TrackCreator): void;
-
// Add a command.
addCommand(command: Command): void;
}
@@ -173,8 +126,11 @@
export type Migrate<State> = (init: unknown) => State;
export interface TrackContext {
- // The ID of this track instance.
- trackInstanceId: string;
+ // This track's key, used for making selections et al.
+ trackKey: string;
+
+ // Set of params passed in when the track was created.
+ params: unknown;
// Creates a new store overlaying the track instance's state object.
// A migrate function must be passed to convert any existing state to a
@@ -188,7 +144,7 @@
}
export interface Track {
- onCreate(): void;
+ onCreate(ctx: TrackContext): void;
render(ctx: CanvasRenderingContext2D): void;
onFullRedraw(): void;
getSliceRect(
@@ -196,32 +152,28 @@
windowSpan: PxSpan, tStart: time, tEnd: time, depth: number): SliceRect
|undefined;
getHeight(): number;
- getTrackShellButtons(): Array<m.Vnode<TrackButtonAttrs>>;
- getContextMenu(): m.Vnode<any>|null;
+ getTrackShellButtons(): m.Children;
onMouseMove(position: {x: number, y: number}): void;
onMouseClick(position: {x: number, y: number}): boolean;
onMouseOut(): void;
onDestroy(): void;
}
+// A definition of a track, including a renderer implementation and metadata.
export interface TrackDescriptor {
- // A unique identifier for the track. This must be unique within all tracks.
+ // A unique identifier for this track.
uri: string;
- // A human friendly name for this track. Used when displaying the list of
- // tracks to the user. E.g. when adding a new track to the workspace.
- displayName: string;
-
- // A factory function returning the track object.
+ // A factory function returning a track object.
track: (ctx: TrackContext) => Track;
- // The track "kind" Uued by various subsystems e.g. aggregation controllers.
+ // The track "kind", used by various subsystems e.g. aggregation controllers.
// This is where "XXX_TRACK_KIND" values should be placed.
// TODO(stevegolton): This will be deprecated once we handle group selections
// in a more generic way - i.e. EventSet.
- kind: string;
+ kind?: string;
- // An optional list of track IDs represented by this trace.
+ // Optional: list of track IDs represented by this trace.
// This list is used for participation in track indexing by track ID.
// This index is used by various subsystems to find links between tracks based
// on the track IDs used by trace processor.
@@ -230,6 +182,12 @@
// Optional: The CPU number associated with this track.
cpu?: number;
+ // Optional: The UTID associated with this track.
+ utid?: number;
+
+ // Optional: The UPID associated with this track.
+ upid?: number;
+
// Optional: A list of tags used for sorting, grouping and "chips".
tags?: TrackTags;
}
@@ -245,7 +203,7 @@
// (for non-thread tracks) or a tid and secondary sort key (mapping of tid to
// primary sort key is done independently).
export enum PrimaryTrackSortKey {
- DEBUG_SLICE_TRACK,
+ DEBUG_TRACK,
NULL_TRACK,
PROCESS_SCHEDULING_TRACK,
PROCESS_SUMMARY_TRACK,
@@ -264,45 +222,45 @@
ORDINARY_TRACK,
}
-// Similar to PluginContext but with additional properties to operate on the
-// currently loaded trace. Passed to trace-relevant hooks instead of
+// Similar to PluginContext but with additional methods to operate on the
+// currently loaded trace. Passed to trace-relevant hooks on a plugin instead of
// PluginContext.
-export interface PluginContextTrace<T = undefined> extends PluginContext {
+export interface PluginContextTrace extends PluginContext {
readonly engine: EngineProxy;
- readonly store: Store<T>;
- // Add a new track from this plugin. The track is just made available here,
- // it's not automatically shown until it's added to a workspace.
- addTrack(trackDetails: TrackDescriptor): void;
+ // Register a new track against a unique key known as a URI.
+ // Once a track is registered it can be referenced multiple times on the
+ // timeline.
+ registerTrack(trackDesc: TrackDescriptor): void;
- // Suggest a track be added to the workspace on a fresh trace load.
- // Supersedes `findPotentialTracks()` which has been removed.
- // Note: this API will be deprecated soon.
- suggestTrack(trackInfo: TrackInstanceDescriptor): void;
+ // Add a new entry to the pool of default tracks. Default tracks are a list of
+ // track references that describe the list of tracks that should be added to
+ // the main timeline on startup.
+ // Default tracks are only used when a trace is first loaded, not when loading
+ // from a permalink, where the existing list of tracks from the shared state
+ // is used instead.
+ addDefaultTrack(track: TrackRef): void;
+
+ // Simultaneously register a track and add it as a default track in one go.
+ // This is simply a helper which calls registerTrack() then addDefaultTrack()
+ // with the same URI.
+ registerStaticTrack(track: TrackDescriptor&TrackRef): void;
+
+ // Create a store mounted over the top of this plugin's persistent state.
+ mountStore<T>(migrate: Migrate<T>): Store<T>;
}
-export interface BasePlugin<State> {
+export interface Plugin {
// Lifecycle methods.
onActivate(ctx: PluginContext): void;
- onTraceLoad?(ctx: PluginContextTrace<State>): Promise<void>;
- onTraceUnload?(ctx: PluginContextTrace<State>): Promise<void>;
+ onTraceLoad?(ctx: PluginContextTrace): Promise<void>;
+ onTraceUnload?(ctx: PluginContextTrace): Promise<void>;
onDeactivate?(ctx: PluginContext): void;
// Extension points.
metricVisualisations?(ctx: PluginContext): MetricVisualisation[];
}
-export interface StatefulPlugin<State> extends BasePlugin<State> {
- // Function to migrate the persistent state.
- migrate(initialState: unknown): State;
-}
-
-// Generic interface all plugins must implement.
-// If a state type is passed, the plugin must implement migrate(). Otherwise if
-// the state type is omitted, migrate need not be defined.
-export type Plugin<State = undefined> =
- State extends undefined ? BasePlugin<State>: StatefulPlugin<State>;
-
// This interface defines what a plugin factory should look like.
// This can be defined in the plugin class definition by defining a constructor
// and the relevant static methods:
@@ -313,22 +271,25 @@
// ... methods from the TracePlugin interface go here ...
// }
// ... which can then be passed around by class i.e. MyPlugin
-export interface PluginClass<T> {
+export interface PluginClass {
// Instantiate the plugin.
- new(): Plugin<T>;
+ new(): Plugin;
}
-export interface TrackInstanceDescriptor {
- // A human readable name for this specific track. It will normally be
- // displayed on the left-hand-side of the track.
- name: string;
-
- // Used to define default sort order for new traces.
- // Note: sortKey will be deprecated soon in favour of tags.
- sortKey: PrimaryTrackSortKey;
-
- // URI of the suggested track.
+// Describes a reference to a registered track.
+export interface TrackRef {
+ // URI of the registered track.
uri: string;
+
+ // A human readable name for this track - displayed in the track shell.
+ displayName: string;
+
+ // Optional: An opaque object used to customize this instance of the track.
+ params?: unknown;
+
+ // Optional: Used to define default sort order for new traces.
+ // Note: This will be deprecated soon in favour of tags & sort rules.
+ sortKey?: PrimaryTrackSortKey;
}
// A predicate for selecting a groups of tracks.
@@ -357,9 +318,9 @@
// Plugins can be passed as class refs, factory functions, or concrete plugin
// implementations.
-export type PluginFactory<T> = PluginClass<T>|Plugin<T>|(() => Plugin<T>);
+export type PluginFactory = PluginClass|Plugin|(() => Plugin);
-export interface PluginDescriptor<T = undefined> {
+export interface PluginDescriptor {
// A unique string for your plugin. To ensure the name is unique you
// may wish to use a URL with reversed components in the manner of
// Java package names.
@@ -367,5 +328,5 @@
// The plugin factory used to instantiate the plugin object, or if this is
// an actual plugin implementation, it's just used as-is.
- plugin: PluginFactory<T>;
+ plugin: PluginFactory;
}
diff --git a/ui/src/tracks/actual_frames/index.ts b/ui/src/tracks/actual_frames/index.ts
index 90de29a..00c9e00 100644
--- a/ui/src/tracks/actual_frames/index.ts
+++ b/ui/src/tracks/actual_frames/index.ts
@@ -14,33 +14,26 @@
import {BigintMath as BIMath} from '../../base/bigint_math';
import {duration, time} from '../../base/time';
-import {LONG, LONG_NULL, NUM, STR} from '../../common/query_result';
-import {TrackData} from '../../common/track_data';
-import {TrackController} from '../../controller/track_controller';
-import {NewTrackArgs, TrackBase} from '../../frontend/track';
-import {Plugin, PluginContext, PluginDescriptor} from '../../public';
-import {ChromeSliceTrack} from '../chrome_slices';
+import {
+ LONG,
+ LONG_NULL,
+ NUM,
+ NUM_NULL,
+ STR,
+ STR_NULL,
+} from '../../common/query_result';
+import {SliceData, SliceTrackBase} from '../../frontend/slice_track_base';
+import {
+ EngineProxy,
+ Plugin,
+ PluginContext,
+ PluginContextTrace,
+ PluginDescriptor,
+} from '../../public';
+import {getTrackName} from '../../public/utils';
export const ACTUAL_FRAMES_SLICE_TRACK_KIND = 'ActualFramesSliceTrack';
-export interface Config {
- maxDepth: number;
- trackIds: number[];
-}
-
-export interface Data extends TrackData {
- // Slices are stored in a columnar fashion. All fields have the same length.
- strings: string[];
- sliceIds: Float64Array;
- starts: BigInt64Array;
- ends: BigInt64Array;
- depths: Uint16Array;
- titles: Uint16Array; // Index in |strings|.
- colors?: Uint16Array; // Index in |strings|.
- isInstant: Uint16Array;
- isIncomplete: Uint16Array;
-}
-
const BLUE_COLOR = '#03A9F4'; // Blue 500
const GREEN_COLOR = '#4CAF50'; // Green 500
const YELLOW_COLOR = '#FFEB3B'; // Yellow 500
@@ -48,55 +41,60 @@
const LIGHT_GREEN_COLOR = '#C0D588'; // Light Green 500
const PINK_COLOR = '#F515E0'; // Pink 500
-class ActualFramesSliceTrackController extends TrackController<Config, Data> {
- static readonly kind = ACTUAL_FRAMES_SLICE_TRACK_KIND;
+class SliceTrack extends SliceTrackBase {
private maxDur = 0n;
+ constructor(
+ private engine: EngineProxy, maxDepth: number, trackKey: string,
+ private trackIds: number[], namespace?: string) {
+ super(maxDepth, trackKey, 'actual_frame_timeline_slice', namespace);
+ }
+
async onBoundsChange(start: time, end: time, resolution: duration):
- Promise<Data> {
+ Promise<SliceData> {
if (this.maxDur === 0n) {
- const maxDurResult = await this.query(`
- select
- max(iif(dur = -1, (SELECT end_ts FROM trace_bounds) - ts, dur))
- as maxDur
- from experimental_slice_layout
- where filter_track_ids = '${this.config.trackIds.join(',')}'
- `);
+ const maxDurResult = await this.engine.query(`
+ select
+ max(iif(dur = -1, (SELECT end_ts FROM trace_bounds) - ts, dur))
+ as maxDur
+ from experimental_slice_layout
+ where filter_track_ids = '${this.trackIds.join(',')}'
+ `);
this.maxDur = maxDurResult.firstRow({maxDur: LONG_NULL}).maxDur || 0n;
}
- const rawResult = await this.query(`
- SELECT
- (s.ts + ${resolution / 2n}) / ${resolution} * ${resolution} as tsq,
- s.ts as ts,
- max(iif(s.dur = -1, (SELECT end_ts FROM trace_bounds) - s.ts, s.dur))
- as dur,
- s.layout_depth as layoutDepth,
- s.name as name,
- s.id as id,
- s.dur = 0 as isInstant,
- s.dur = -1 as isIncomplete,
- CASE afs.jank_tag
- WHEN 'Self Jank' THEN '${RED_COLOR}'
- WHEN 'Other Jank' THEN '${YELLOW_COLOR}'
- WHEN 'Dropped Frame' THEN '${BLUE_COLOR}'
- WHEN 'Buffer Stuffing' THEN '${LIGHT_GREEN_COLOR}'
- WHEN 'SurfaceFlinger Stuffing' THEN '${LIGHT_GREEN_COLOR}'
- WHEN 'No Jank' THEN '${GREEN_COLOR}'
- ELSE '${PINK_COLOR}'
- END as color
- from experimental_slice_layout s
- join actual_frame_timeline_slice afs using(id)
- where
- filter_track_ids = '${this.config.trackIds.join(',')}' and
- s.ts >= ${start - this.maxDur} and
- s.ts <= ${end}
- group by tsq, s.layout_depth
- order by tsq, s.layout_depth
- `);
+ const rawResult = await this.engine.query(`
+ SELECT
+ (s.ts + ${resolution / 2n}) / ${resolution} * ${resolution} as tsq,
+ s.ts as ts,
+ max(iif(s.dur = -1, (SELECT end_ts FROM trace_bounds) - s.ts, s.dur))
+ as dur,
+ s.layout_depth as layoutDepth,
+ s.name as name,
+ s.id as id,
+ s.dur = 0 as isInstant,
+ s.dur = -1 as isIncomplete,
+ CASE afs.jank_tag
+ WHEN 'Self Jank' THEN '${RED_COLOR}'
+ WHEN 'Other Jank' THEN '${YELLOW_COLOR}'
+ WHEN 'Dropped Frame' THEN '${BLUE_COLOR}'
+ WHEN 'Buffer Stuffing' THEN '${LIGHT_GREEN_COLOR}'
+ WHEN 'SurfaceFlinger Stuffing' THEN '${LIGHT_GREEN_COLOR}'
+ WHEN 'No Jank' THEN '${GREEN_COLOR}'
+ ELSE '${PINK_COLOR}'
+ END as color
+ from experimental_slice_layout s
+ join actual_frame_timeline_slice afs using(id)
+ where
+ filter_track_ids = '${this.trackIds.join(',')}' and
+ s.ts >= ${start - this.maxDur} and
+ s.ts <= ${end}
+ group by tsq, s.layout_depth
+ order by tsq, s.layout_depth
+`);
const numRows = rawResult.numRows();
- const slices: Data = {
+ const slices: SliceData = {
start,
end,
resolution,
@@ -154,17 +152,74 @@
}
}
-export class ActualFramesSliceTrack extends ChromeSliceTrack {
- static readonly kind = ACTUAL_FRAMES_SLICE_TRACK_KIND;
- static create(args: NewTrackArgs): TrackBase {
- return new ActualFramesSliceTrack(args);
- }
-}
-
class ActualFrames implements Plugin {
- onActivate(ctx: PluginContext): void {
- ctx.LEGACY_registerTrackController(ActualFramesSliceTrackController);
- ctx.LEGACY_registerTrack(ActualFramesSliceTrack);
+ onActivate(_ctx: PluginContext): void {}
+
+ async onTraceLoad(ctx: PluginContextTrace): Promise<void> {
+ const {engine} = ctx;
+ const result = await engine.query(`
+ with process_async_tracks as materialized (
+ select
+ process_track.upid as upid,
+ process_track.name as trackName,
+ process.name as processName,
+ process.pid as pid,
+ group_concat(process_track.id) as trackIds,
+ count(1) as trackCount
+ from process_track
+ left join process using(upid)
+ where process_track.name = "Actual Timeline"
+ group by
+ process_track.upid,
+ process_track.name
+ )
+ select
+ t.*,
+ max_layout_depth(t.trackCount, t.trackIds) as maxDepth
+ from process_async_tracks t;
+ `);
+
+ const it = result.iter({
+ upid: NUM,
+ trackName: STR_NULL,
+ trackIds: STR,
+ processName: STR_NULL,
+ pid: NUM_NULL,
+ maxDepth: NUM_NULL,
+ });
+ for (; it.valid(); it.next()) {
+ const upid = it.upid;
+ const trackName = it.trackName;
+ const rawTrackIds = it.trackIds;
+ const trackIds = rawTrackIds.split(',').map((v) => Number(v));
+ const processName = it.processName;
+ const pid = it.pid;
+ const maxDepth = it.maxDepth;
+
+ if (maxDepth === null) {
+ // If there are no slices in this track, skip it.
+ continue;
+ }
+
+ const kind = 'ActualFrames';
+ const displayName =
+ getTrackName({name: trackName, upid, pid, processName, kind});
+
+ ctx.registerStaticTrack({
+ uri: `perfetto.ActualFrames#${upid}`,
+ displayName,
+ trackIds,
+ kind: ACTUAL_FRAMES_SLICE_TRACK_KIND,
+ track: ({trackKey}) => {
+ return new SliceTrack(
+ engine,
+ maxDepth,
+ trackKey,
+ trackIds,
+ );
+ },
+ });
+ }
}
}
diff --git a/ui/src/tracks/android_log/index.ts b/ui/src/tracks/android_log/index.ts
index 743d665..bc26268 100644
--- a/ui/src/tracks/android_log/index.ts
+++ b/ui/src/tracks/android_log/index.ts
@@ -154,14 +154,14 @@
await ctx.engine.query(`select count(1) as cnt from android_logs`);
const count = result.firstRow({cnt: NUM}).cnt;
if (count > 0) {
- ctx.addTrack({
+ ctx.registerStaticTrack({
uri: 'perfetto.AndroidLog',
displayName: 'Android logs',
kind: ANDROID_LOGS_TRACK_KIND,
- track: ({trackInstanceId}) => {
+ track: ({trackKey}) => {
return new TrackWithControllerAdapter<Config, Data>(
ctx.engine,
- trackInstanceId,
+ trackKey,
{},
AndroidLogTrack,
AndroidLogTrackController);
diff --git a/ui/src/tracks/annotation/index.ts b/ui/src/tracks/annotation/index.ts
index 2c8649a..860ee20 100644
--- a/ui/src/tracks/annotation/index.ts
+++ b/ui/src/tracks/annotation/index.ts
@@ -23,6 +23,7 @@
PluginContextTrace,
PluginDescriptor,
} from '../../public';
+import {ChromeSliceTrack, SLICE_TRACK_KIND} from '../chrome_slices/';
import {
Config as CounterTrackConfig,
COUNTER_TRACK_KIND,
@@ -33,9 +34,48 @@
onActivate(_ctx: PluginContext): void {}
async onTraceLoad(ctx: PluginContextTrace): Promise<void> {
+ await this.addAnnotationTracks(ctx);
await this.addAnnotationCounterTracks(ctx);
}
+ private async addAnnotationTracks(ctx: PluginContextTrace) {
+ const {engine} = ctx;
+
+ const result = await engine.query(`
+ select id, name
+ from annotation_slice_track
+ order by name
+ `);
+
+ const it = result.iter({
+ id: NUM,
+ name: STR,
+ });
+
+ for (; it.valid(); it.next()) {
+ const id = it.id;
+ const name = it.name;
+
+ ctx.registerStaticTrack({
+ uri: `perfetto.Annotation#${id}`,
+ displayName: name,
+ kind: SLICE_TRACK_KIND,
+ tags: {
+ metric: true,
+ },
+ track: (({trackKey}) => {
+ return new ChromeSliceTrack(
+ engine,
+ 0,
+ trackKey,
+ id,
+ 'annotation',
+ );
+ }),
+ });
+ }
+ }
+
private async addAnnotationCounterTracks(ctx: PluginContextTrace) {
const {engine} = ctx;
const counterResult = await engine.query(`
@@ -69,7 +109,7 @@
maximumValue,
};
- ctx.addTrack({
+ ctx.registerStaticTrack({
uri: `perfetto.Annotation#counter${id}`,
displayName: name,
kind: COUNTER_TRACK_KIND,
diff --git a/ui/src/tracks/async_slices/index.ts b/ui/src/tracks/async_slices/index.ts
index 09d0dda..787ec7b 100644
--- a/ui/src/tracks/async_slices/index.ts
+++ b/ui/src/tracks/async_slices/index.ts
@@ -14,62 +14,57 @@
import {BigintMath as BIMath} from '../../base/bigint_math';
import {duration, time} from '../../base/time';
-import {LONG, LONG_NULL, NUM, STR} from '../../common/query_result';
-import {TrackData} from '../../common/track_data';
import {
- TrackController,
-} from '../../controller/track_controller';
-import {NewTrackArgs, TrackBase} from '../../frontend/track';
-import {Plugin, PluginContext, PluginDescriptor} from '../../public';
-import {ChromeSliceTrack} from '../chrome_slices';
+ LONG,
+ LONG_NULL,
+ NUM,
+ NUM_NULL,
+ STR,
+ STR_NULL,
+} from '../../common/query_result';
+import {SliceData, SliceTrackBase} from '../../frontend/slice_track_base';
+import {
+ EngineProxy,
+ Plugin,
+ PluginContext,
+ PluginContextTrace,
+ PluginDescriptor,
+} from '../../public';
+import {getTrackName} from '../../public/utils';
export const ASYNC_SLICE_TRACK_KIND = 'AsyncSliceTrack';
-export interface Config {
- maxDepth: number;
- trackIds: number[];
-}
-
-export interface Data extends TrackData {
- // Slices are stored in a columnar fashion. All fields have the same length.
- strings: string[];
- sliceIds: Float64Array;
- starts: BigInt64Array;
- ends: BigInt64Array;
- depths: Uint16Array;
- titles: Uint16Array; // Index in |strings|.
- isInstant: Uint16Array;
- isIncomplete: Uint16Array;
-}
-
-class AsyncSliceTrackController extends TrackController<Config, Data> {
- static readonly kind = ASYNC_SLICE_TRACK_KIND;
+class AsyncSliceTrack extends SliceTrackBase {
private maxDurNs: duration = 0n;
+ constructor(
+ private engine: EngineProxy, maxDepth: number, trackKey: string,
+ private trackIds: number[], namespace?: string) {
+ // TODO is 'slice' right here?
+ super(maxDepth, trackKey, 'slice', namespace);
+ }
+
async onBoundsChange(start: time, end: time, resolution: duration):
- Promise<Data> {
+ Promise<SliceData> {
if (this.maxDurNs === 0n) {
- const maxDurResult = await this.query(`
- select max(iif(dur = -1, (SELECT end_ts FROM trace_bounds) - ts, dur))
- as maxDur from experimental_slice_layout
- where filter_track_ids = '${this.config.trackIds.join(',')}'
+ const maxDurResult = await this.engine.query(`
+ select max(iif(dur = -1, (SELECT end_ts FROM trace_bounds) - ts,
+ dur)) as maxDur from experimental_slice_layout where filter_track_ids
+ = '${this.trackIds.join(',')}'
`);
this.maxDurNs = maxDurResult.firstRow({maxDur: LONG_NULL}).maxDur || 0n;
}
- const queryRes = await this.query(`
+ const queryRes = await this.engine.query(`
SELECT
(ts + ${resolution / 2n}) / ${resolution} * ${resolution} as tsq,
ts,
- max(iif(dur = -1, (SELECT end_ts FROM trace_bounds) - ts, dur)) as dur,
- layout_depth as depth,
- ifnull(name, '[null]') as name,
- id,
- dur = 0 as isInstant,
- dur = -1 as isIncomplete
+ max(iif(dur = -1, (SELECT end_ts FROM trace_bounds) - ts, dur)) as
+ dur, layout_depth as depth, ifnull(name, '[null]') as name, id, dur =
+ 0 as isInstant, dur = -1 as isIncomplete
from experimental_slice_layout
where
- filter_track_ids = '${this.config.trackIds.join(',')}' and
+ filter_track_ids = '${this.trackIds.join(',')}' and
ts >= ${start - this.maxDurNs} and
ts <= ${end}
group by tsq, layout_depth
@@ -77,7 +72,7 @@
`);
const numRows = queryRes.numRows();
- const slices: Data = {
+ const slices: SliceData = {
start,
end,
resolution,
@@ -132,17 +127,168 @@
}
}
-export class AsyncSliceTrack extends ChromeSliceTrack {
- static readonly kind = ASYNC_SLICE_TRACK_KIND;
- static create(args: NewTrackArgs): TrackBase {
- return new AsyncSliceTrack(args);
- }
-}
-
class AsyncSlicePlugin implements Plugin {
- onActivate(ctx: PluginContext) {
- ctx.LEGACY_registerTrackController(AsyncSliceTrackController);
- ctx.LEGACY_registerTrack(AsyncSliceTrack);
+ onActivate(_ctx: PluginContext) {}
+
+ async onTraceLoad(ctx: PluginContextTrace): Promise<void> {
+ await this.addGlobalAsyncTracks(ctx);
+ await this.addProcessAsyncSliceTracks(ctx);
+ }
+
+ async addGlobalAsyncTracks(ctx: PluginContextTrace): Promise<void> {
+ const {engine} = ctx;
+ const rawGlobalAsyncTracks = await engine.query(`
+ with tracks_with_slices as materialized (
+ select distinct track_id
+ from slice
+ ),
+ global_tracks as (
+ select
+ track.parent_id as parent_id,
+ track.id as track_id,
+ track.name as name
+ from track
+ join tracks_with_slices on tracks_with_slices.track_id = track.id
+ where
+ track.type = "track"
+ or track.type = "gpu_track"
+ or track.type = "cpu_track"
+ ),
+ global_tracks_grouped as (
+ select
+ parent_id,
+ name,
+ group_concat(track_id) as trackIds,
+ count(track_id) as trackCount
+ from global_tracks track
+ group by parent_id, name
+ )
+ select
+ t.parent_id as parentId,
+ p.name as parentName,
+ t.name as name,
+ t.trackIds as trackIds,
+ max_layout_depth(t.trackCount, t.trackIds) as maxDepth
+ from global_tracks_grouped AS t
+ left join track p on (t.parent_id = p.id)
+ order by p.name, t.name;
+ `);
+ const it = rawGlobalAsyncTracks.iter({
+ name: STR_NULL,
+ parentName: STR_NULL,
+ parentId: NUM_NULL,
+ trackIds: STR,
+ maxDepth: NUM_NULL,
+ });
+
+ // let scrollJankRendered = false;
+
+ for (; it.valid(); it.next()) {
+ const rawName = it.name === null ? undefined : it.name;
+ // const rawParentName = it.parentName === null ? undefined :
+ // it.parentName;
+ const displayName = getTrackName({name: rawName, kind: 'AsyncSlice'});
+ const rawTrackIds = it.trackIds;
+ const trackIds = rawTrackIds.split(',').map((v) => Number(v));
+ // const parentTrackId = it.parentId;
+ const maxDepth = it.maxDepth;
+
+ // If there are no slices in this track, skip it.
+ if (maxDepth === null) {
+ continue;
+ }
+
+ // if (ENABLE_SCROLL_JANK_PLUGIN_V2.get() && !scrollJankRendered &&
+ // name.includes(INPUT_LATENCY_TRACK)) {
+ // // This ensures that the scroll jank tracks render above the tracks
+ // // for GestureScrollUpdate.
+ // await this.addScrollJankTracks(this.engine);
+ // scrollJankRendered = true;
+ // }
+
+ ctx.registerStaticTrack({
+ uri: `perfetto.AsyncSlices#${rawName}`,
+ displayName,
+ trackIds,
+ kind: ASYNC_SLICE_TRACK_KIND,
+ track: ({trackKey}) => {
+ return new AsyncSliceTrack(
+ engine,
+ maxDepth,
+ trackKey,
+ trackIds,
+ );
+ },
+ });
+ }
+ }
+
+ async addProcessAsyncSliceTracks(ctx: PluginContextTrace): Promise<void> {
+ const result = await ctx.engine.query(`
+ with process_async_tracks as materialized (
+ select
+ process_track.upid as upid,
+ process_track.name as trackName,
+ process.name as processName,
+ process.pid as pid,
+ group_concat(process_track.id) as trackIds,
+ count(1) as trackCount
+ from process_track
+ left join process using(upid)
+ where
+ process_track.name is null or
+ process_track.name not like "% Timeline"
+ group by
+ process_track.upid,
+ process_track.name
+ )
+ select
+ t.*,
+ max_layout_depth(t.trackCount, t.trackIds) as maxDepth
+ from process_async_tracks t;
+ `);
+
+ const it = result.iter({
+ upid: NUM,
+ trackName: STR_NULL,
+ trackIds: STR,
+ processName: STR_NULL,
+ pid: NUM_NULL,
+ maxDepth: NUM_NULL,
+ });
+ for (; it.valid(); it.next()) {
+ const upid = it.upid;
+ const trackName = it.trackName;
+ const rawTrackIds = it.trackIds;
+ const trackIds = rawTrackIds.split(',').map((v) => Number(v));
+ const processName = it.processName;
+ const pid = it.pid;
+ const maxDepth = it.maxDepth;
+
+ if (maxDepth === null) {
+ // If there are no slices in this track, skip it.
+ continue;
+ }
+
+ const kind = ASYNC_SLICE_TRACK_KIND;
+ const displayName =
+ getTrackName({name: trackName, upid, pid, processName, kind});
+
+ ctx.registerStaticTrack({
+ uri: `perfetto.AsyncSlices#process.${pid}${rawTrackIds}`,
+ displayName,
+ trackIds,
+ kind: ASYNC_SLICE_TRACK_KIND,
+ track: ({trackKey}) => {
+ return new AsyncSliceTrack(
+ ctx.engine,
+ maxDepth,
+ trackKey,
+ trackIds,
+ );
+ },
+ });
+ }
}
}
diff --git a/ui/src/tracks/chrome_critical_user_interactions/details_panel.ts b/ui/src/tracks/chrome_critical_user_interactions/details_panel.ts
new file mode 100644
index 0000000..9eea78f
--- /dev/null
+++ b/ui/src/tracks/chrome_critical_user_interactions/details_panel.ts
@@ -0,0 +1,236 @@
+// 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 m from 'mithril';
+
+import {duration, Time, time} from '../../base/time';
+import {exists} from '../../base/utils';
+import {LONG, LONG_NULL, NUM, STR} from '../../common/query_result';
+import {raf} from '../../core/raf_scheduler';
+import {
+ BottomTab,
+ bottomTabRegistry,
+ NewBottomTabArgs,
+} from '../../frontend/bottom_tab';
+import {
+ GenericSliceDetailsTabConfig,
+} from '../../frontend/generic_slice_details_tab';
+import {sqlValueToString} from '../../frontend/sql_utils';
+import {Timestamp} from '../../frontend/widgets/timestamp';
+import {Anchor} from '../../widgets/anchor';
+import {DetailsShell} from '../../widgets/details_shell';
+import {DurationWidget} from '../../widgets/duration';
+import {GridLayout, GridLayoutColumn} from '../../widgets/grid_layout';
+import {Section} from '../../widgets/section';
+import {SqlRef} from '../../widgets/sql_ref';
+import {dictToTreeNodes, Tree} from '../../widgets/tree';
+
+interface PageLoadMetrics {
+ url: string;
+ navigationId: number;
+ fcpDuration?: duration;
+ lcpDuration?: duration;
+ fcpTs: time, lcpTs?: time,
+}
+
+enum CriticalUserJourneyType {
+ UNKNOWN = 'Unknown',
+ PAGE_LOAD = 'PageLoad',
+}
+
+function convertToCriticalUserJourneyType(cujType: string):
+ CriticalUserJourneyType {
+ switch (cujType) {
+ case CriticalUserJourneyType.PAGE_LOAD:
+ return CriticalUserJourneyType.PAGE_LOAD;
+ default:
+ return CriticalUserJourneyType.UNKNOWN;
+ }
+}
+
+interface Data {
+ name: string;
+ // Timestamp of the beginning of this slice in nanoseconds.
+ ts: time;
+ // Duration of this slice in nanoseconds.
+ dur: duration;
+ type: CriticalUserJourneyType;
+ tableName: string;
+ // Metrics for |type| = CriticalUserJourney.PAGE_LOAD
+ pageLoadMetrics?: PageLoadMetrics;
+}
+
+export class CriticalUserInteractionDetailsPanel extends
+ BottomTab<GenericSliceDetailsTabConfig> {
+ static readonly kind = 'org.perfetto.CriticalUserInteractionDetailsPanel';
+ data: Data|undefined;
+ loaded = false;
+
+ static create(args: NewBottomTabArgs): CriticalUserInteractionDetailsPanel {
+ return new CriticalUserInteractionDetailsPanel(args);
+ }
+
+ constructor(args: NewBottomTabArgs) {
+ super(args);
+ this.loadData();
+ }
+
+ private async loadData() {
+ const queryResult = await this.engine.query(`
+ SELECT
+ name,
+ ts,
+ dur,
+ type AS tableName
+ FROM chrome_interactions
+ WHERE scoped_id = ${this.config.id}`);
+
+ const iter = queryResult.firstRow({
+ name: STR,
+ ts: LONG,
+ dur: LONG,
+ tableName: STR,
+ });
+
+ this.data = {
+ name: iter.name,
+ ts: Time.fromRaw(iter.ts),
+ dur: iter.dur,
+ type: convertToCriticalUserJourneyType(iter.name),
+ tableName: iter.tableName,
+ };
+
+ await this.loadMetrics();
+
+ this.loaded = true;
+ raf.scheduleFullRedraw();
+ }
+
+ private async loadMetrics() {
+ if (exists(this.data)) {
+ switch (this.data.type) {
+ case CriticalUserJourneyType.PAGE_LOAD:
+ await this.loadPageLoadMetrics();
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ private async loadPageLoadMetrics() {
+ if (exists(this.data)) {
+ const queryResult = await this.engine.query(`
+ SELECT
+ navigation_id AS navigationId,
+ url,
+ fcp AS fcpDuration,
+ lcp AS lcpDuration,
+ fcp_ts AS fcpTs,
+ lcp_ts AS lcpTs
+ FROM chrome_page_loads
+ WHERE navigation_id = ${this.config.id}`);
+
+ const iter = queryResult.firstRow({
+ navigationId: NUM,
+ url: STR,
+ fcpDuration: LONG_NULL,
+ lcpDuration: LONG_NULL,
+ fcpTs: LONG,
+ lcpTs: LONG,
+ });
+
+ this.data.pageLoadMetrics = {
+ navigationId: iter.navigationId,
+ url: iter.url,
+ fcpTs: Time.fromRaw(iter.fcpTs),
+ };
+
+ if (exists(iter.fcpDuration)) {
+ this.data.pageLoadMetrics.fcpDuration = iter.fcpDuration;
+ }
+
+ if (exists(iter.lcpDuration)) {
+ this.data.pageLoadMetrics.lcpDuration = iter.lcpDuration;
+ }
+
+ if (Number(iter.lcpTs) != 0) {
+ this.data.pageLoadMetrics.lcpTs = Time.fromRaw(iter.lcpTs);
+ }
+ }
+ }
+
+ private renderDetailsDictionary(): m.Child[] {
+ const details: {[key: string]: m.Child} = {};
+ if (exists(this.data)) {
+ details['Name'] = sqlValueToString(this.data.name);
+ details['Timestamp'] = m(Timestamp, {ts: this.data.ts});
+ if (exists(this.data.pageLoadMetrics)) {
+ details['FCP Timestamp'] =
+ m(Timestamp, {ts: this.data.pageLoadMetrics.fcpTs});
+ if (exists(this.data.pageLoadMetrics.fcpDuration)) {
+ details['FCP Duration'] =
+ m(DurationWidget, {dur: this.data.pageLoadMetrics.fcpDuration});
+ }
+ if (exists(this.data.pageLoadMetrics.lcpTs)) {
+ details['LCP Timestamp'] =
+ m(Timestamp, {ts: this.data.pageLoadMetrics.lcpTs});
+ }
+ if (exists(this.data.pageLoadMetrics.lcpDuration)) {
+ details['LCP Duration'] =
+ m(DurationWidget, {dur: this.data.pageLoadMetrics.lcpDuration});
+ }
+ details['Navigation ID'] = this.data.pageLoadMetrics.navigationId;
+ const url = this.data.pageLoadMetrics.url;
+ details['URL'] =
+ m(Anchor, {href: url, target: '_blank', icon: 'open_in_new'}, url);
+ }
+ details['SQL ID'] =
+ m(SqlRef, {table: 'chrome_interactions', id: this.config.id});
+ }
+
+ return dictToTreeNodes(details);
+ }
+
+ viewTab() {
+ if (this.data === undefined) {
+ return m('h2', 'Loading');
+ }
+
+ return m(
+ DetailsShell,
+ {
+ title: this.getTitle(),
+ },
+ m(GridLayout,
+ m(
+ GridLayoutColumn,
+ m(
+ Section,
+ {title: 'Details'},
+ m(Tree, this.renderDetailsDictionary()),
+ ),
+ )));
+ }
+
+ getTitle(): string {
+ return this.config.title;
+ }
+
+ isLoading() {
+ return !this.loaded;
+ }
+}
+
+bottomTabRegistry.register(CriticalUserInteractionDetailsPanel);
diff --git a/ui/src/tracks/chrome_critical_user_interactions/index.ts b/ui/src/tracks/chrome_critical_user_interactions/index.ts
new file mode 100644
index 0000000..3d1b498
--- /dev/null
+++ b/ui/src/tracks/chrome_critical_user_interactions/index.ts
@@ -0,0 +1,110 @@
+// 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 {v4 as uuidv4} from 'uuid';
+
+import {Actions} from '../../common/actions';
+import {SCROLLING_TRACK_GROUP} from '../../common/state';
+import {globals} from '../../frontend/globals';
+import {NamedSliceTrackTypes} from '../../frontend/named_slice_track';
+import {NewTrackArgs, TrackBase} from '../../frontend/track';
+import {
+ Plugin,
+ PluginContext,
+ PluginContextTrace,
+ PluginDescriptor,
+ PrimaryTrackSortKey,
+} from '../../public';
+import {
+ CustomSqlDetailsPanelConfig,
+ CustomSqlImportConfig,
+ CustomSqlTableDefConfig,
+ CustomSqlTableSliceTrack,
+} from '../custom_sql_table_slices';
+
+import {CriticalUserInteractionDetailsPanel} from './details_panel';
+
+export const CRITICAL_USER_INTERACTIONS_KIND =
+ 'org.chromium.TopLevelScrolls.scrolls';
+
+export class CriticalUserInteractionTrack extends
+ CustomSqlTableSliceTrack<NamedSliceTrackTypes> {
+ static readonly kind = CRITICAL_USER_INTERACTIONS_KIND;
+
+ static create(args: NewTrackArgs): TrackBase {
+ return new CriticalUserInteractionTrack(args);
+ }
+
+ getSqlDataSource(): CustomSqlTableDefConfig {
+ return {
+ columns: ['scoped_id AS id', 'name', 'ts', 'dur', 'type'],
+ sqlTableName: 'chrome_interactions',
+ };
+ }
+
+ getDetailsPanel(): CustomSqlDetailsPanelConfig {
+ return {
+ kind: CriticalUserInteractionDetailsPanel.kind,
+ config: {
+ sqlTableName: this.tableName,
+ title: 'Chrome Critical User Interaction',
+ },
+ };
+ }
+
+ getSqlImports(): CustomSqlImportConfig {
+ return {
+ modules: ['chrome.interactions'],
+ };
+ }
+}
+
+export function addCriticalUserInteractionTrack() {
+ const trackKey = uuidv4();
+ globals.dispatchMultiple([
+ Actions.addTrack({
+ key: trackKey,
+ uri: CriticalUserInteractionTrack.kind,
+ name: `Chrome Interactions`,
+ trackSortKey: PrimaryTrackSortKey.DEBUG_TRACK,
+ trackGroup: SCROLLING_TRACK_GROUP,
+ }),
+ Actions.toggleTrackPinned({trackKey}),
+ ]);
+}
+
+class CriticalUserInteractionPlugin implements Plugin {
+ async onTraceLoad(ctx: PluginContextTrace): Promise<void> {
+ ctx.registerStaticTrack({
+ uri: CriticalUserInteractionTrack.kind,
+ kind: CriticalUserInteractionTrack.kind,
+ displayName: 'Chrome Interactions',
+ track: (trackCtx) => new CriticalUserInteractionTrack(
+ {engine: ctx.engine, trackKey: trackCtx.trackKey}),
+ });
+ }
+
+ onActivate(ctx: PluginContext): void {
+ ctx.addCommand({
+ id: 'perfetto.CriticalUserInteraction.AddInteractionTrack',
+ name: 'Add Chrome Interactions track',
+ callback: () => addCriticalUserInteractionTrack(),
+ });
+ }
+}
+
+export const plugin: PluginDescriptor = {
+ pluginId: 'perfetto.CriticalUserInteraction',
+ plugin: CriticalUserInteractionPlugin,
+};
diff --git a/ui/src/tracks/chrome_scroll_jank/chrome_tasks_scroll_jank_track.ts b/ui/src/tracks/chrome_scroll_jank/chrome_tasks_scroll_jank_track.ts
index 1026328..e9d1fa4 100644
--- a/ui/src/tracks/chrome_scroll_jank/chrome_tasks_scroll_jank_track.ts
+++ b/ui/src/tracks/chrome_scroll_jank/chrome_tasks_scroll_jank_track.ts
@@ -12,8 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {v4 as uuidv4} from 'uuid';
-
import {Engine} from '../../common/engine';
import {NUM} from '../../common/query_result';
import {InThreadTrackSortKey} from '../../common/state';
@@ -42,13 +40,14 @@
return new ChromeTasksScrollJankTrack(args);
}
- async initSqlTable(tableName: string) {
- await this.engine.query(`
-create view ${tableName} as
-select s2.ts, s2.dur, s2.id, 0 as depth, s1.full_name as name
+ constructor(args: NewTrackArgs) {
+ super(args);
+ }
+
+ getSqlSource(): string {
+ return `select s2.ts as ts, s2.dur as dur, s2.id as id, 0 as depth, s1.full_name as name
from chrome_tasks_delaying_input_processing s1
-join slice s2 on s2.id=s1.slice_id
- `);
+join slice s2 on s2.id=s1.slice_id`;
}
}
export type GetTrackGroupUuidFn = (utid: number, upid: number|null) => string;
@@ -79,20 +78,18 @@
}
result.tracksToAdd.push({
- id: uuidv4(),
- engineId: engine.id,
- kind: ChromeTasksScrollJankTrack.kind,
+ uri: 'perfetto.ChromeScrollJank',
trackSortKey: {
utid: it.utid,
priority: InThreadTrackSortKey.ORDINARY,
},
name: 'Scroll Jank causes - long tasks',
- config: {},
trackGroup: getTrackGroupUuid(it.utid, it.upid),
});
// Initialise the chrome_tasks_delaying_input_processing table. It will be
// used in the sql table above.
+ // TODO(stevegolton): Use viewer.tabs.openQuery().
await engine.query(`
select RUN_METRIC(
'chrome/chrome_tasks_delaying_input_processing.sql',
diff --git a/ui/src/tracks/chrome_scroll_jank/event_latency_track.ts b/ui/src/tracks/chrome_scroll_jank/event_latency_track.ts
index cfcaada..498591e 100644
--- a/ui/src/tracks/chrome_scroll_jank/event_latency_track.ts
+++ b/ui/src/tracks/chrome_scroll_jank/event_latency_track.ts
@@ -12,16 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {v4 as uuidv4} from 'uuid';
-
import {
getColorForSlice,
} from '../../common/colorizer';
-import {Engine} from '../../common/engine';
-import {
- generateSqlWithInternalLayout,
-} from '../../common/internal_layout_utils';
-import {SCROLLING_TRACK_GROUP} from '../../common/state';
import {globals} from '../../frontend/globals';
import {
NamedSliceTrackTypes,
@@ -36,20 +29,24 @@
import {EventLatencySliceDetailsPanel} from './event_latency_details_panel';
import {
+ SCROLL_JANK_GROUP_ID,
ScrollJankPluginState,
ScrollJankTracks as DecideTracksResult,
} from './index';
import {DEEP_RED_COLOR, RED_COLOR} from './jank_colors';
-const JANKY_LATENCY_NAME = 'Janky EventLatency';
+export const JANKY_LATENCY_NAME = 'Janky EventLatency';
export interface EventLatencyTrackTypes extends NamedSliceTrackTypes {
config: {baseTable: string;}
}
+const CHROME_EVENT_LATENCY_TRACK_KIND =
+ 'org.chromium.ScrollJank.event_latencies';
+
export class EventLatencyTrack extends
CustomSqlTableSliceTrack<EventLatencyTrackTypes> {
- static readonly kind = 'org.chromium.ScrollJank.event_latencies';
+ static readonly kind = CHROME_EVENT_LATENCY_TRACK_KIND;
static create(args: NewTrackArgs): TrackBase {
return new EventLatencyTrack(args);
@@ -59,7 +56,7 @@
super(args);
ScrollJankPluginState.getInstance().registerTrack({
kind: EventLatencyTrack.kind,
- trackId: this.trackId,
+ trackKey: this.trackKey,
tableName: this.tableName,
detailsPanelConfig: this.getDetailsPanel(),
});
@@ -70,11 +67,8 @@
ScrollJankPluginState.getInstance().unregisterTrack(EventLatencyTrack.kind);
}
- async initSqlTable(tableName: string) {
- const sql =
- `CREATE VIEW ${tableName} AS SELECT * FROM ${this.config.baseTable}`;
-
- await this.engine.query(sql);
+ getSqlSource(): string {
+ return `SELECT * FROM ${this.config.baseTable}`;
}
getDetailsPanel(): CustomSqlDetailsPanelConfig {
@@ -117,84 +111,16 @@
// this behavior should be customized to show jank-related data.
}
-export async function addLatencyTracks(engine: Engine):
- Promise<DecideTracksResult> {
+export async function addLatencyTracks(): Promise<DecideTracksResult> {
const result: DecideTracksResult = {
tracksToAdd: [],
};
- const subTableSql = generateSqlWithInternalLayout({
- columns: ['id', 'ts', 'dur', 'track_id', 'name'],
- sourceTable: 'slice',
- ts: 'ts',
- dur: 'dur',
- whereClause: `
- EXTRACT_ARG(arg_set_id, 'event_latency.event_type') IN (
- 'FIRST_GESTURE_SCROLL_UPDATE',
- 'GESTURE_SCROLL_UPDATE',
- 'INERTIAL_GESTURE_SCROLL_UPDATE')
- AND HAS_DESCENDANT_SLICE_WITH_NAME(
- id,
- 'SubmitCompositorFrameToPresentationCompositorFrame')`,
- });
-
- // Table name must be unique - it cannot include '-' characters or begin with
- // a numeric value.
- const baseTable =
- `table_${uuidv4().split('-').join('_')}_janky_event_latencies_v3`;
- const tableDefSql = `CREATE TABLE ${baseTable} AS
- WITH event_latencies AS (
- ${subTableSql}
- ), latency_stages AS (
- SELECT
- d.id,
- d.ts,
- d.dur,
- d.track_id,
- d.name,
- d.depth,
- min(a.id) AS parent_id
- FROM slice s
- JOIN descendant_slice(s.id) d
- JOIN ancestor_slice(d.id) a
- WHERE s.id IN (SELECT id FROM event_latencies)
- GROUP BY d.id, d.ts, d.dur, d.track_id, d.name, d.parent_id, d.depth)
- SELECT
- id,
- ts,
- dur,
- CASE
- WHEN id IN (
- SELECT id FROM chrome_janky_event_latencies_v3)
- THEN '${JANKY_LATENCY_NAME}'
- ELSE name
- END
- AS name,
- depth * 3 AS depth
- FROM event_latencies
- UNION ALL
- SELECT
- ls.id,
- ls.ts,
- ls.dur,
- ls.name,
- depth + (
- (SELECT depth FROM event_latencies
- WHERE id = ls.parent_id LIMIT 1) * 3) AS depth
- FROM latency_stages ls;`;
-
- await engine.query(
- `INCLUDE PERFETTO MODULE chrome.scroll_jank.scroll_jank_intervals`);
- await engine.query(tableDefSql);
-
result.tracksToAdd.push({
- id: uuidv4(),
- engineId: engine.id,
- kind: EventLatencyTrack.kind,
+ uri: 'perfetto.ChromeScrollJank#eventLatency',
trackSortKey: PrimaryTrackSortKey.ASYNC_SLICE_TRACK,
name: 'Chrome Scroll Input Latencies',
- config: {baseTable: baseTable},
- trackGroup: SCROLLING_TRACK_GROUP,
+ trackGroup: SCROLL_JANK_GROUP_ID,
});
return result;
diff --git a/ui/src/tracks/chrome_scroll_jank/index.ts b/ui/src/tracks/chrome_scroll_jank/index.ts
index 592d9a5..7aedb64 100644
--- a/ui/src/tracks/chrome_scroll_jank/index.ts
+++ b/ui/src/tracks/chrome_scroll_jank/index.ts
@@ -12,22 +12,40 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {AddTrackArgs} from '../../common/actions';
+import {v4 as uuidv4} from 'uuid';
+
+import {Actions, AddTrackArgs, DeferredAction} from '../../common/actions';
import {Engine} from '../../common/engine';
import {featureFlags} from '../../common/feature_flags';
-import {ObjectById} from '../../common/state';
-import {Plugin, PluginContext, PluginDescriptor} from '../../public';
+import {
+ generateSqlWithInternalLayout,
+} from '../../common/internal_layout_utils';
+import {ObjectByKey} from '../../common/state';
+import {
+ Plugin,
+ PluginContext,
+ PluginContextTrace,
+ PluginDescriptor,
+ PrimaryTrackSortKey,
+} from '../../public';
import {CustomSqlDetailsPanelConfig} from '../custom_sql_table_slices';
+import {NULL_TRACK_URI} from '../null_track';
import {ChromeTasksScrollJankTrack} from './chrome_tasks_scroll_jank_track';
-import {addLatencyTracks, EventLatencyTrack} from './event_latency_track';
+import {
+ addLatencyTracks,
+ EventLatencyTrack,
+ JANKY_LATENCY_NAME,
+} from './event_latency_track';
import {
addScrollJankV3ScrollTrack,
ScrollJankV3Track,
} from './scroll_jank_v3_track';
-import {addTopLevelScrollTrack, TopLevelScrollTrack} from './scroll_track';
-
-export {Data} from '../chrome_slices';
+import {
+ addTopLevelScrollTrack,
+ CHROME_TOPLEVEL_SCROLLS_KIND,
+ TopLevelScrollTrack,
+} from './scroll_track';
export const ENABLE_CHROME_SCROLL_JANK_PLUGIN = featureFlags.register({
id: 'enableChromeScrollJankPlugin',
@@ -36,8 +54,6 @@
defaultValue: false,
});
-export const INPUT_LATENCY_TRACK = 'InputLatency::';
-
export const ENABLE_SCROLL_JANK_PLUGIN_V2 = featureFlags.register({
id: 'enableScrollJankPluginV2',
name: 'Enable Scroll Jank plugin V2',
@@ -45,12 +61,18 @@
defaultValue: false,
});
+export const SCROLL_JANK_GROUP_ID = 'chrome-scroll-jank-track-group';
+
export type ScrollJankTracks = {
tracksToAdd: AddTrackArgs[],
};
+export type ScrollJankTrackGroup = {
+ tracks: ScrollJankTracks; addTrackGroup: DeferredAction
+}
+
export interface ScrollJankTrackSpec {
- id: string;
+ key: string;
sqlTableName: string;
detailsPanelConfig: CustomSqlDetailsPanelConfig;
}
@@ -58,7 +80,7 @@
// Global state for the scroll jank plugin.
export class ScrollJankPluginState {
private static instance: ScrollJankPluginState;
- private tracks: ObjectById<ScrollJankTrackSpec>;
+ private tracks: ObjectByKey<ScrollJankTrackSpec>;
private constructor() {
this.tracks = {};
@@ -74,12 +96,12 @@
public registerTrack(args: {
kind: string,
- trackId: string,
+ trackKey: string,
tableName: string,
detailsPanelConfig: CustomSqlDetailsPanelConfig,
}): void {
this.tracks[args.kind] = {
- id: args.trackId,
+ key: args.trackKey,
sqlTableName: args.tableName,
detailsPanelConfig: args.detailsPanelConfig,
};
@@ -94,45 +116,185 @@
}
}
-export async function getScrollJankTracks(engine: Engine):
- Promise<ScrollJankTracks> {
+export async function getScrollJankTracks(_engine: Engine):
+ Promise<ScrollJankTrackGroup> {
const result: ScrollJankTracks = {
tracksToAdd: [],
};
- const scrolls = addTopLevelScrollTrack(engine);
- const scrollsResult = await scrolls;
- let originalLength = result.tracksToAdd.length;
- result.tracksToAdd.length += scrollsResult.tracksToAdd.length;
- for (let i = 0; i < scrollsResult.tracksToAdd.length; ++i) {
- result.tracksToAdd[i + originalLength] = scrollsResult.tracksToAdd[i];
- }
+ const scrolls = await addTopLevelScrollTrack();
+ result.tracksToAdd = result.tracksToAdd.concat(scrolls.tracksToAdd);
- const janks = addScrollJankV3ScrollTrack(engine);
- const janksResult = await janks;
- originalLength = result.tracksToAdd.length;
- result.tracksToAdd.length += janksResult.tracksToAdd.length;
- for (let i = 0; i < janksResult.tracksToAdd.length; ++i) {
- result.tracksToAdd[i + originalLength] = janksResult.tracksToAdd[i];
- }
+ const janks = await addScrollJankV3ScrollTrack();
+ result.tracksToAdd = result.tracksToAdd.concat(janks.tracksToAdd);
- originalLength = result.tracksToAdd.length;
- const eventLatencies = addLatencyTracks(engine);
- const eventLatencyResult = await eventLatencies;
- result.tracksToAdd.length += eventLatencyResult.tracksToAdd.length;
- for (let i = 0; i < eventLatencyResult.tracksToAdd.length; ++i) {
- result.tracksToAdd[i + originalLength] = eventLatencyResult.tracksToAdd[i];
- }
+ const eventLatencies = await addLatencyTracks();
+ result.tracksToAdd = result.tracksToAdd.concat(eventLatencies.tracksToAdd);
- return result;
+ const summaryTrackKey = uuidv4();
+ result.tracksToAdd.push({
+ uri: NULL_TRACK_URI,
+ trackSortKey: PrimaryTrackSortKey.ASYNC_SLICE_TRACK,
+ name: '', // TODO(stevegolton): We should probably put some name here.
+ trackGroup: undefined,
+ key: summaryTrackKey,
+ });
+
+ const addTrackGroup = Actions.addTrackGroup({
+ name: 'Chrome Scroll Jank',
+ id: SCROLL_JANK_GROUP_ID,
+ collapsed: false,
+ summaryTrackKey,
+ fixedOrdering: true,
+ });
+
+ return {tracks: result, addTrackGroup};
}
class ChromeScrollJankPlugin implements Plugin {
- onActivate(ctx: PluginContext): void {
- ctx.LEGACY_registerTrack(ChromeTasksScrollJankTrack);
- ctx.LEGACY_registerTrack(EventLatencyTrack);
- ctx.LEGACY_registerTrack(ScrollJankV3Track);
- ctx.LEGACY_registerTrack(TopLevelScrollTrack);
+ onActivate(_ctx: PluginContext): void {}
+
+ async onTraceLoad(ctx: PluginContextTrace): Promise<void> {
+ await this.addChromeScrollJankTrack(ctx);
+ await this.addTopLevelScrollTrack(ctx);
+ await this.addEventLatencyTrack(ctx);
+ await this.addScrollJankV3ScrollTrack(ctx);
+ }
+
+ private async addChromeScrollJankTrack(ctx: PluginContextTrace):
+ Promise<void> {
+ ctx.registerStaticTrack({
+ uri: 'perfetto.ChromeScrollJank',
+ displayName: 'Scroll Jank causes - long tasks',
+ kind: ChromeTasksScrollJankTrack.kind,
+ track: ({trackKey}) => {
+ return new ChromeTasksScrollJankTrack({
+ engine: ctx.engine,
+ trackKey,
+ });
+ },
+ });
+ }
+
+ private async addTopLevelScrollTrack(ctx: PluginContextTrace): Promise<void> {
+ await ctx.engine.query(`
+ INCLUDE PERFETTO MODULE chrome.chrome_scrolls;
+ INCLUDE PERFETTO MODULE chrome.scroll_jank.scroll_offsets;
+ `);
+
+ ctx.registerStaticTrack({
+ uri: 'perfetto.ChromeScrollJank#toplevelScrolls',
+ displayName: 'Chrome Scrolls',
+ kind: CHROME_TOPLEVEL_SCROLLS_KIND,
+ track: ({trackKey}) => {
+ return new TopLevelScrollTrack({
+ engine: ctx.engine,
+ trackKey,
+ });
+ },
+ });
+ }
+
+ private async addEventLatencyTrack(ctx: PluginContextTrace): Promise<void> {
+ const subTableSql = generateSqlWithInternalLayout({
+ columns: ['id', 'ts', 'dur', 'track_id', 'name'],
+ sourceTable: 'slice',
+ ts: 'ts',
+ dur: 'dur',
+ whereClause: `
+ EXTRACT_ARG(arg_set_id, 'event_latency.event_type') IN (
+ 'FIRST_GESTURE_SCROLL_UPDATE',
+ 'GESTURE_SCROLL_UPDATE',
+ 'INERTIAL_GESTURE_SCROLL_UPDATE')
+ AND HAS_DESCENDANT_SLICE_WITH_NAME(
+ id,
+ 'SubmitCompositorFrameToPresentationCompositorFrame')`,
+ });
+
+ // Table name must be unique - it cannot include '-' characters or begin
+ // with a numeric value.
+ const baseTable =
+ `table_${uuidv4().split('-').join('_')}_janky_event_latencies_v3`;
+ const tableDefSql = `CREATE TABLE ${baseTable} AS
+ WITH event_latencies AS (
+ ${subTableSql}
+ ), latency_stages AS (
+ SELECT
+ d.id,
+ d.ts,
+ d.dur,
+ d.track_id,
+ d.name,
+ d.depth,
+ min(a.id) AS parent_id
+ FROM slice s
+ JOIN descendant_slice(s.id) d
+ JOIN ancestor_slice(d.id) a
+ WHERE s.id IN (SELECT id FROM event_latencies)
+ GROUP BY d.id, d.ts, d.dur, d.track_id, d.name, d.parent_id, d.depth)
+ SELECT
+ id,
+ ts,
+ dur,
+ CASE
+ WHEN id IN (
+ SELECT id FROM chrome_janky_event_latencies_v3)
+ THEN '${JANKY_LATENCY_NAME}'
+ ELSE name
+ END
+ AS name,
+ depth * 3 AS depth
+ FROM event_latencies
+ UNION ALL
+ SELECT
+ ls.id,
+ ls.ts,
+ ls.dur,
+ ls.name,
+ depth + (
+ (SELECT depth FROM event_latencies
+ WHERE id = ls.parent_id LIMIT 1) * 3) AS depth
+ FROM latency_stages ls;`;
+
+ await ctx.engine.query(
+ `INCLUDE PERFETTO MODULE chrome.scroll_jank.scroll_jank_intervals`);
+ await ctx.engine.query(tableDefSql);
+
+ ctx.registerStaticTrack({
+ uri: 'perfetto.ChromeScrollJank#eventLatency',
+ displayName: 'Chrome Scroll Input Latencies',
+ kind: EventLatencyTrack.kind,
+ track: ({trackKey}) => {
+ const track = new EventLatencyTrack({
+ engine: ctx.engine,
+ trackKey,
+ });
+
+ track.config = {
+ baseTable,
+ };
+
+ return track;
+ },
+ });
+ }
+
+ private async addScrollJankV3ScrollTrack(ctx: PluginContextTrace):
+ Promise<void> {
+ await ctx.engine.query(
+ `INCLUDE PERFETTO MODULE chrome.scroll_jank.scroll_jank_intervals`);
+
+ ctx.registerStaticTrack({
+ uri: 'perfetto.ChromeScrollJank#scrollJankV3',
+ displayName: 'Chrome Scroll Janks',
+ kind: ScrollJankV3Track.kind,
+ track: ({trackKey}) => {
+ return new ScrollJankV3Track({
+ engine: ctx.engine,
+ trackKey,
+ });
+ },
+ });
}
}
diff --git a/ui/src/tracks/chrome_scroll_jank/scroll_jank_slice.ts b/ui/src/tracks/chrome_scroll_jank/scroll_jank_slice.ts
index 00d8d8c..f07c41e 100644
--- a/ui/src/tracks/chrome_scroll_jank/scroll_jank_slice.ts
+++ b/ui/src/tracks/chrome_scroll_jank/scroll_jank_slice.ts
@@ -171,11 +171,11 @@
sqlTableName: track.sqlTableName,
start: vnode.attrs.ts,
duration: vnode.attrs.dur,
- trackId: track.id,
+ trackKey: track.key,
detailsPanelConfig: track.detailsPanelConfig,
}));
- scrollToTrackAndTs(track.id, vnode.attrs.ts, true);
+ scrollToTrackAndTs(track.key, vnode.attrs.ts, true);
},
},
vnode.attrs.name,
diff --git a/ui/src/tracks/chrome_scroll_jank/scroll_jank_v3_track.ts b/ui/src/tracks/chrome_scroll_jank/scroll_jank_v3_track.ts
index f1db56e..70f6f0a 100644
--- a/ui/src/tracks/chrome_scroll_jank/scroll_jank_v3_track.ts
+++ b/ui/src/tracks/chrome_scroll_jank/scroll_jank_v3_track.ts
@@ -12,15 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {v4 as uuidv4} from 'uuid';
-
import {
getColorForSlice,
} from '../../common/colorizer';
-import {Engine} from '../../common/engine';
-import {
- SCROLLING_TRACK_GROUP,
-} from '../../common/state';
import {globals} from '../../frontend/globals';
import {NamedSliceTrackTypes} from '../../frontend/named_slice_track';
import {NewTrackArgs, TrackBase} from '../../frontend/track';
@@ -33,14 +27,13 @@
import {EventLatencyTrackTypes} from './event_latency_track';
import {
+ SCROLL_JANK_GROUP_ID,
ScrollJankPluginState,
ScrollJankTracks as DecideTracksResult,
} from './index';
import {DEEP_RED_COLOR, RED_COLOR} from './jank_colors';
import {ScrollJankV3DetailsPanel} from './scroll_jank_v3_details_panel';
-export {Data} from '../chrome_slices';
-
const UNKNOWN_SLICE_NAME = 'Unknown';
const JANK_SLICE_NAME = ' Jank';
@@ -56,7 +49,7 @@
super(args);
ScrollJankPluginState.getInstance().registerTrack({
kind: ScrollJankV3Track.kind,
- trackId: this.trackId,
+ trackKey: this.trackKey,
tableName: this.tableName,
detailsPanelConfig: this.getDetailsPanel(),
});
@@ -127,23 +120,17 @@
}
}
-export async function addScrollJankV3ScrollTrack(engine: Engine):
+export async function addScrollJankV3ScrollTrack():
Promise<DecideTracksResult> {
const result: DecideTracksResult = {
tracksToAdd: [],
};
- await engine.query(
- `INCLUDE PERFETTO MODULE chrome.scroll_jank.scroll_jank_intervals`);
-
result.tracksToAdd.push({
- id: uuidv4(),
- engineId: engine.id,
- kind: ScrollJankV3Track.kind,
+ uri: 'perfetto.ChromeScrollJank#scrollJankV3',
trackSortKey: PrimaryTrackSortKey.ASYNC_SLICE_TRACK,
name: 'Chrome Scroll Janks',
- config: {},
- trackGroup: SCROLLING_TRACK_GROUP,
+ trackGroup: SCROLL_JANK_GROUP_ID,
});
return result;
diff --git a/ui/src/tracks/chrome_scroll_jank/scroll_track.ts b/ui/src/tracks/chrome_scroll_jank/scroll_track.ts
index 97ccc4a..7eaba65 100644
--- a/ui/src/tracks/chrome_scroll_jank/scroll_track.ts
+++ b/ui/src/tracks/chrome_scroll_jank/scroll_track.ts
@@ -12,10 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {v4 as uuidv4} from 'uuid';
-
-import {Engine} from '../../common/engine';
-import {SCROLLING_TRACK_GROUP} from '../../common/state';
import {NamedSliceTrackTypes} from '../../frontend/named_slice_track';
import {NewTrackArgs, TrackBase} from '../../frontend/track';
import {PrimaryTrackSortKey} from '../../public';
@@ -24,19 +20,19 @@
CustomSqlTableDefConfig,
CustomSqlTableSliceTrack,
} from '../custom_sql_table_slices';
-
import {
+ SCROLL_JANK_GROUP_ID,
ScrollJankPluginState,
ScrollJankTracks as DecideTracksResult,
} from './index';
import {ScrollDetailsPanel} from './scroll_details_panel';
-export {Data} from '../chrome_slices';
+export const CHROME_TOPLEVEL_SCROLLS_KIND =
+ 'org.chromium.TopLevelScrolls.scrolls';
export class TopLevelScrollTrack extends
CustomSqlTableSliceTrack<NamedSliceTrackTypes> {
- static readonly kind = 'org.chromium.TopLevelScrolls.scrolls';
-
+ public static kind = CHROME_TOPLEVEL_SCROLLS_KIND;
static create(args: NewTrackArgs): TrackBase {
return new TopLevelScrollTrack(args);
}
@@ -63,7 +59,7 @@
ScrollJankPluginState.getInstance().registerTrack({
kind: TopLevelScrollTrack.kind,
- trackId: this.trackId,
+ trackKey: this.trackKey,
tableName: this.tableName,
detailsPanelConfig: this.getDetailsPanel(),
});
@@ -76,25 +72,16 @@
}
}
-export async function addTopLevelScrollTrack(engine: Engine):
- Promise<DecideTracksResult> {
+export async function addTopLevelScrollTrack(): Promise<DecideTracksResult> {
const result: DecideTracksResult = {
tracksToAdd: [],
};
- await engine.query(`
- INCLUDE PERFETTO MODULE chrome.chrome_scrolls;
- INCLUDE PERFETTO MODULE chrome.scroll_jank.scroll_offsets;
- `);
-
result.tracksToAdd.push({
- id: uuidv4(),
- engineId: engine.id,
- kind: TopLevelScrollTrack.kind,
+ uri: 'perfetto.ChromeScrollJank#toplevelScrolls',
trackSortKey: PrimaryTrackSortKey.ASYNC_SLICE_TRACK,
name: 'Chrome Scrolls',
- config: {},
- trackGroup: SCROLLING_TRACK_GROUP,
+ trackGroup: SCROLL_JANK_GROUP_ID,
});
return result;
diff --git a/ui/src/tracks/generic_slice_track/index.ts b/ui/src/tracks/chrome_slices/generic_slice_track.ts
similarity index 69%
rename from ui/src/tracks/generic_slice_track/index.ts
rename to ui/src/tracks/chrome_slices/generic_slice_track.ts
index 6053621..d19f3db 100644
--- a/ui/src/tracks/generic_slice_track/index.ts
+++ b/ui/src/tracks/chrome_slices/generic_slice_track.ts
@@ -17,7 +17,6 @@
NamedSliceTrackTypes,
} from '../../frontend/named_slice_track';
import {NewTrackArgs} from '../../frontend/track';
-import {Plugin, PluginContext, PluginDescriptor} from '../../public';
export interface GenericSliceTrackConfig {
sqlTrackId: number;
@@ -37,21 +36,8 @@
super(args);
}
- async initSqlTable(tableName: string): Promise<void> {
- const sql = `create view ${tableName} as
- select ts, dur, id, depth, ifnull(name, '') as name
+ getSqlSource(): string {
+ return `select ts, dur, id, depth, ifnull(name, '') as name
from slice where track_id = ${this.config.sqlTrackId}`;
- await this.engine.query(sql);
}
}
-
-class GenericSliceTrackPlugin implements Plugin {
- onActivate(ctx: PluginContext): void {
- ctx.LEGACY_registerTrack(GenericSliceTrack);
- }
-}
-
-export const plugin: PluginDescriptor = {
- pluginId: 'perfetto.GenericSliceTrack',
- plugin: GenericSliceTrackPlugin,
-};
diff --git a/ui/src/tracks/chrome_slices/index.ts b/ui/src/tracks/chrome_slices/index.ts
index 28efb24..12fe4d9 100644
--- a/ui/src/tracks/chrome_slices/index.ts
+++ b/ui/src/tracks/chrome_slices/index.ts
@@ -13,63 +13,50 @@
// limitations under the License.
import {BigintMath as BIMath} from '../../base/bigint_math';
-import {duration, Span, Time, time} from '../../base/time';
-import {Actions} from '../../common/actions';
-import {cropText, drawIncompleteSlice} from '../../common/canvas_utils';
+import {Duration, duration, time} from '../../base/time';
import {
- colorForThreadIdleSlice,
- getColorForSlice,
-} from '../../common/colorizer';
-import {HighPrecisionTime} from '../../common/high_precision_time';
-import {LONG, LONG_NULL, NUM, STR} from '../../common/query_result';
-import {TrackData} from '../../common/track_data';
-import {TrackController} from '../../controller/track_controller';
-import {checkerboardExcept} from '../../frontend/checkerboard';
-import {globals} from '../../frontend/globals';
-import {cachedHsluvToHex} from '../../frontend/hsluv_cache';
-import {PxSpan, TimeScale} from '../../frontend/time_scale';
-import {NewTrackArgs, SliceRect, TrackBase} from '../../frontend/track';
-import {Plugin, PluginContext, PluginDescriptor} from '../../public';
+ LONG,
+ LONG_NULL,
+ NUM,
+ NUM_NULL,
+ STR,
+ STR_NULL,
+} from '../../common/query_result';
+import {
+ SliceData,
+ SliceTrackBase,
+} from '../../frontend/slice_track_base';
+import {
+ EngineProxy,
+ Plugin,
+ PluginContext,
+ PluginContextTrace,
+ PluginDescriptor,
+} from '../../public';
+import {getTrackName} from '../../public/utils';
+
+import {GenericSliceTrack} from './generic_slice_track';
export const SLICE_TRACK_KIND = 'ChromeSliceTrack';
-const SLICE_HEIGHT = 18;
-const TRACK_PADDING = 2;
-const CHEVRON_WIDTH_PX = 10;
-const HALF_CHEVRON_WIDTH_PX = CHEVRON_WIDTH_PX / 2;
-export interface Config {
- maxDepth: number;
- namespace: string;
- trackId: number;
-}
-
-export interface Data extends TrackData {
- // Slices are stored in a columnar fashion.
- strings: string[];
- sliceIds: Float64Array;
- starts: BigInt64Array;
- ends: BigInt64Array;
- depths: Uint16Array;
- titles: Uint16Array; // Index into strings.
- colors?: Uint16Array; // Index into strings.
- isInstant: Uint16Array;
- isIncomplete: Uint16Array;
- cpuTimeRatio?: Float64Array;
-}
-
-export class ChromeSliceTrackController extends TrackController<Config, Data> {
- static kind = SLICE_TRACK_KIND;
+export class ChromeSliceTrack extends SliceTrackBase {
private maxDurNs: duration = 0n;
+ constructor(
+ protected engine: EngineProxy, maxDepth: number, trackKey: string,
+ private trackId: number, namespace?: string) {
+ super(maxDepth, trackKey, 'slice', namespace);
+ }
+
async onBoundsChange(start: time, end: time, resolution: duration):
- Promise<Data> {
+ Promise<SliceData> {
const tableName = this.namespaceTable('slice');
- if (this.maxDurNs === 0n) {
+ if (this.maxDurNs === Duration.ZERO) {
const query = `
SELECT max(iif(dur = -1, (SELECT end_ts FROM trace_bounds) - ts, dur))
- AS maxDur FROM ${tableName} WHERE track_id = ${this.config.trackId}`;
- const queryRes = await this.query(query);
+ AS maxDur FROM ${tableName} WHERE track_id = ${this.trackId}`;
+ const queryRes = await this.engine.query(query);
this.maxDurNs = queryRes.firstRow({maxDur: LONG_NULL}).maxDur || 0n;
}
@@ -85,14 +72,14 @@
dur = -1 as isIncomplete,
thread_dur as threadDur
FROM ${tableName}
- WHERE track_id = ${this.config.trackId} AND
+ WHERE track_id = ${this.trackId} AND
ts >= (${start - this.maxDurNs}) AND
ts <= ${end}
GROUP BY depth, tsq`;
- const queryRes = await this.query(query);
+ const queryRes = await this.engine.query(query);
const numRows = queryRes.numRows();
- const slices: Data = {
+ const slices: SliceData = {
start,
end,
resolution,
@@ -159,288 +146,87 @@
}
}
-export class ChromeSliceTrack extends TrackBase<Config, Data> {
- static readonly kind: string = SLICE_TRACK_KIND;
- static create(args: NewTrackArgs): TrackBase {
- return new ChromeSliceTrack(args);
- }
-
- private hoveredTitleId = -1;
-
- constructor(args: NewTrackArgs) {
- super(args);
- }
-
- // Font used to render the slice name on the current track.
- protected getFont() {
- return '12px Roboto Condensed';
- }
-
- renderCanvas(ctx: CanvasRenderingContext2D): void {
- // TODO: fonts and colors should come from the CSS and not hardcoded here.
- const data = this.data();
- if (data === undefined) return; // Can't possibly draw anything.
-
- const {visibleTimeSpan, visibleWindowTime, visibleTimeScale, windowSpan} =
- globals.frontendLocalState;
-
- // If the cached trace slices don't fully cover the visible time range,
- // show a gray rectangle with a "Loading..." label.
- checkerboardExcept(
- ctx,
- this.getHeight(),
- visibleTimeScale.hpTimeToPx(visibleWindowTime.start),
- visibleTimeScale.hpTimeToPx(visibleWindowTime.end),
- visibleTimeScale.timeToPx(data.start),
- visibleTimeScale.timeToPx(data.end),
- );
-
- ctx.textAlign = 'center';
-
- // measuretext is expensive so we only use it once.
- const charWidth = ctx.measureText('ACBDLqsdfg').width / 10;
-
- // The draw of the rect on the selected slice must happen after the other
- // drawings, otherwise it would result under another rect.
- let drawRectOnSelected = () => {};
-
-
- for (let i = 0; i < data.starts.length; i++) {
- const tStart = Time.fromRaw(data.starts[i]);
- let tEnd = Time.fromRaw(data.ends[i]);
- const depth = data.depths[i];
- const titleId = data.titles[i];
- const sliceId = data.sliceIds[i];
- const isInstant = data.isInstant[i];
- const isIncomplete = data.isIncomplete[i];
- const title = data.strings[titleId];
- const colorOverride = data.colors && data.strings[data.colors[i]];
- if (isIncomplete) { // incomplete slice
- // TODO(stevegolton): This isn't exactly equivalent, ideally we should
- // choose tEnd once we've conerted to screen space coords.
- tEnd = visibleWindowTime.end.toTime('ceil');
- }
-
- if (!visibleTimeSpan.intersects(tStart, tEnd)) {
- continue;
- }
-
- const rect = this.getSliceRect(
- visibleTimeScale, visibleTimeSpan, windowSpan, tStart, tEnd, depth);
- if (!rect || !rect.visible) {
- continue;
- }
-
- const currentSelection = globals.state.currentSelection;
- const isSelected = currentSelection &&
- currentSelection.kind === 'CHROME_SLICE' &&
- currentSelection.id !== undefined && currentSelection.id === sliceId;
-
- const highlighted = titleId === this.hoveredTitleId ||
- globals.state.highlightedSliceId === sliceId;
-
- const hasFocus = highlighted || isSelected;
- const colorObj = getColorForSlice(title, hasFocus);
-
- let color: string;
- if (colorOverride === undefined) {
- color = colorObj.c;
- } else {
- color = colorOverride;
- }
- ctx.fillStyle = color;
-
- // We draw instant events as upward facing chevrons starting at A:
- // A
- // ###
- // ##C##
- // ## ##
- // D B
- // Then B, C, D and back to A:
- if (isInstant) {
- if (isSelected) {
- drawRectOnSelected = () => {
- ctx.save();
- ctx.translate(rect.left, rect.top);
-
- // Draw a rectangle around the selected slice
- ctx.strokeStyle = cachedHsluvToHex(colorObj.h, 100, 10);
- ctx.beginPath();
- ctx.lineWidth = 3;
- ctx.strokeRect(
- -HALF_CHEVRON_WIDTH_PX, 0, CHEVRON_WIDTH_PX, SLICE_HEIGHT);
- ctx.closePath();
-
- // Draw inner chevron as interior
- ctx.fillStyle = color;
- this.drawChevron(ctx);
-
- ctx.restore();
- };
- } else {
- ctx.save();
- ctx.translate(rect.left, rect.top);
- this.drawChevron(ctx);
- ctx.restore();
- }
- continue;
- }
-
- if (isIncomplete && rect.width > SLICE_HEIGHT / 4) {
- drawIncompleteSlice(ctx, rect.left, rect.top, rect.width, SLICE_HEIGHT);
- } else if (
- data.cpuTimeRatio !== undefined && data.cpuTimeRatio[i] < 1 - 1e-9) {
- // We draw two rectangles, representing the ratio between wall time and
- // time spent on cpu.
- const cpuTimeRatio = data.cpuTimeRatio![i];
- const firstPartWidth = rect.width * cpuTimeRatio;
- const secondPartWidth = rect.width * (1 - cpuTimeRatio);
- ctx.fillRect(rect.left, rect.top, firstPartWidth, SLICE_HEIGHT);
- ctx.fillStyle = colorForThreadIdleSlice(
- colorObj.h, colorObj.s, colorObj.l, hasFocus);
- ctx.fillRect(
- rect.left + firstPartWidth,
- rect.top,
- secondPartWidth,
- SLICE_HEIGHT);
- } else {
- ctx.fillRect(rect.left, rect.top, rect.width, SLICE_HEIGHT);
- }
-
- // Selected case
- if (isSelected) {
- drawRectOnSelected = () => {
- ctx.strokeStyle = cachedHsluvToHex(colorObj.h, 100, 10);
- ctx.beginPath();
- ctx.lineWidth = 3;
- ctx.strokeRect(
- rect.left, rect.top - 1.5, rect.width, SLICE_HEIGHT + 3);
- ctx.closePath();
- };
- }
-
- // Don't render text when we have less than 5px to play with.
- if (rect.width >= 5) {
- ctx.fillStyle = colorObj.l > 65 ? '#404040' : 'white';
- const displayText = cropText(title, charWidth, rect.width);
- const rectXCenter = rect.left + rect.width / 2;
- ctx.textBaseline = 'middle';
- ctx.font = this.getFont();
- ctx.fillText(displayText, rectXCenter, rect.top + SLICE_HEIGHT / 2);
- }
- }
- drawRectOnSelected();
- }
-
- drawChevron(ctx: CanvasRenderingContext2D) {
- // Draw a chevron at a fixed location and size. Should be used with
- // ctx.translate and ctx.scale to alter location and size.
- ctx.beginPath();
- ctx.moveTo(0, 0);
- ctx.lineTo(HALF_CHEVRON_WIDTH_PX, SLICE_HEIGHT);
- ctx.lineTo(0, SLICE_HEIGHT - HALF_CHEVRON_WIDTH_PX);
- ctx.lineTo(-HALF_CHEVRON_WIDTH_PX, SLICE_HEIGHT);
- ctx.lineTo(0, 0);
- ctx.fill();
- }
-
- getSliceIndex({x, y}: {x: number, y: number}): number|void {
- const data = this.data();
- if (data === undefined) return;
- const {
- visibleTimeScale: timeScale,
- visibleWindowTime: visibleHPTimeSpan,
- } = globals.frontendLocalState;
- if (y < TRACK_PADDING) return;
- const instantWidthTime = timeScale.pxDeltaToDuration(HALF_CHEVRON_WIDTH_PX);
- const t = timeScale.pxToHpTime(x);
- const depth = Math.floor((y - TRACK_PADDING) / SLICE_HEIGHT);
-
- for (let i = 0; i < data.starts.length; i++) {
- if (depth !== data.depths[i]) {
- continue;
- }
- const start = Time.fromRaw(data.starts[i]);
- const tStart = HighPrecisionTime.fromTime(start);
- if (data.isInstant[i]) {
- if (tStart.sub(t).abs().lt(instantWidthTime)) {
- return i;
- }
- } else {
- const end = Time.fromRaw(data.ends[i]);
- let tEnd = HighPrecisionTime.fromTime(end);
- if (data.isIncomplete[i]) {
- tEnd = visibleHPTimeSpan.end;
- }
- if (tStart.lte(t) && t.lte(tEnd)) {
- return i;
- }
- }
- }
- }
-
- onMouseMove({x, y}: {x: number, y: number}) {
- this.hoveredTitleId = -1;
- globals.dispatch(Actions.setHighlightedSliceId({sliceId: -1}));
- const sliceIndex = this.getSliceIndex({x, y});
- if (sliceIndex === undefined) return;
- const data = this.data();
- if (data === undefined) return;
- this.hoveredTitleId = data.titles[sliceIndex];
- const sliceId = data.sliceIds[sliceIndex];
- globals.dispatch(Actions.setHighlightedSliceId({sliceId}));
- }
-
- onMouseOut() {
- this.hoveredTitleId = -1;
- globals.dispatch(Actions.setHighlightedSliceId({sliceId: -1}));
- }
-
- onMouseClick({x, y}: {x: number, y: number}): boolean {
- const sliceIndex = this.getSliceIndex({x, y});
- if (sliceIndex === undefined) return false;
- const data = this.data();
- if (data === undefined) return false;
- const sliceId = data.sliceIds[sliceIndex];
- if (sliceId !== undefined && sliceId !== -1) {
- globals.makeSelection(Actions.selectChromeSlice({
- id: sliceId,
- trackId: this.trackState.id,
- table: this.config.namespace,
- }));
- return true;
- }
- return false;
- }
-
- getHeight() {
- return SLICE_HEIGHT * (this.config.maxDepth + 1) + 2 * TRACK_PADDING;
- }
-
- getSliceRect(
- visibleTimeScale: TimeScale, visibleWindow: Span<time, duration>,
- windowSpan: PxSpan, tStart: time, tEnd: time, depth: number): SliceRect
- |undefined {
- const pxEnd = windowSpan.end;
- const left = Math.max(visibleTimeScale.timeToPx(tStart), 0);
- const right = Math.min(visibleTimeScale.timeToPx(tEnd), pxEnd);
-
- const visible = visibleWindow.intersects(tStart, tEnd);
-
- return {
- left,
- width: Math.max(right - left, 1),
- top: TRACK_PADDING + depth * SLICE_HEIGHT,
- height: SLICE_HEIGHT,
- visible,
- };
- }
-}
-
class ChromeSlicesPlugin implements Plugin {
- onActivate(ctx: PluginContext): void {
- ctx.LEGACY_registerTrackController(ChromeSliceTrackController);
- ctx.LEGACY_registerTrack(ChromeSliceTrack);
+ onActivate(_ctx: PluginContext): void {}
+
+ async onTraceLoad(ctx: PluginContextTrace): Promise<void> {
+ const {engine} = ctx;
+ const result = await engine.query(`
+ select
+ thread_track.utid as utid,
+ thread_track.id as trackId,
+ thread_track.name as trackName,
+ EXTRACT_ARG(thread_track.source_arg_set_id,
+ 'is_root_in_scope') as isDefaultTrackForScope,
+ tid,
+ thread.name as threadName,
+ max(slice.depth) as maxDepth,
+ process.upid as upid
+ from slice
+ join thread_track on slice.track_id = thread_track.id
+ join thread using(utid)
+ left join process using(upid)
+ group by thread_track.id
+ `);
+
+ const it = result.iter({
+ utid: NUM,
+ trackId: NUM,
+ trackName: STR_NULL,
+ isDefaultTrackForScope: NUM_NULL,
+ tid: NUM_NULL,
+ threadName: STR_NULL,
+ maxDepth: NUM,
+ upid: NUM_NULL,
+ });
+
+ for (; it.valid(); it.next()) {
+ const utid = it.utid;
+ const trackId = it.trackId;
+ const trackName = it.trackName;
+ const tid = it.tid;
+ const threadName = it.threadName;
+ const maxDepth = it.maxDepth;
+
+ const displayName = getTrackName({
+ name: trackName,
+ utid,
+ tid,
+ threadName,
+ kind: 'Slices',
+ });
+
+ ctx.registerStaticTrack({
+ uri: `perfetto.ChromeSlices#${trackId}`,
+ displayName,
+ trackIds: [trackId],
+ kind: SLICE_TRACK_KIND,
+ track: ({trackKey}) => {
+ return new ChromeSliceTrack(
+ engine,
+ maxDepth,
+ trackKey,
+ trackId,
+ );
+ },
+ });
+
+ // trackIds can only be registered by one track at a time.
+ // TODO(hjd): Move trackIds to only be on V2.
+ ctx.registerStaticTrack({
+ uri: `perfetto.ChromeSlices#${trackId}.v2`,
+ displayName,
+ kind: SLICE_TRACK_KIND,
+ track: ({trackKey}) => {
+ const track = GenericSliceTrack.create({
+ engine: ctx.engine,
+ trackKey,
+ });
+ track.config = {sqlTrackId: trackId};
+ return track;
+ },
+ });
+ }
}
}
diff --git a/ui/src/tracks/counter/index.ts b/ui/src/tracks/counter/index.ts
index 1fbc53f..21ef5e6 100644
--- a/ui/src/tracks/counter/index.ts
+++ b/ui/src/tracks/counter/index.ts
@@ -17,6 +17,7 @@
import {searchSegment} from '../../base/binary_search';
import {assertTrue} from '../../base/logging';
+import {isString} from '../../base/object_utils';
import {duration, time, Time} from '../../base/time';
import {Actions} from '../../common/actions';
import {
@@ -115,7 +116,7 @@
function isCounterState(x: unknown): x is CounterTrackState {
if (x && typeof x === 'object' && 'scale' in x) {
- if (typeof x.scale === 'string') {
+ if (isString(x.scale)) {
return true;
} else {
return false;
@@ -132,14 +133,14 @@
private minimumDeltaSeen = 0;
private maxDurNs: duration = 0n;
private store: Store<CounterTrackState>;
- private id: string;
+ private trackKey: string;
private uuid = uuidv4();
private isSetup = false;
constructor(
ctx: TrackContext, private config: Config, private engine: EngineProxy) {
super();
- this.id = ctx.trackInstanceId;
+ this.trackKey = ctx.trackKey;
this.store = ctx.mountStore<CounterTrackState>((init: unknown) => {
if (isCounterState(init)) {
return init;
@@ -318,7 +319,7 @@
return MARGIN_TOP + RECT_HEIGHT;
}
- getContextMenu(): m.Vnode<any> {
+ getTrackShellButtons(): m.Children {
const currentScale = this.store.state.scale;
const scales: {name: CounterScaleOptions, humanName: string}[] = [
{name: 'ZERO_BASED', humanName: 'Zero based'},
@@ -598,7 +599,7 @@
leftTs: Time.fromRaw(data.timestamps[left]),
rightTs: Time.fromRaw(right !== -1 ? data.timestamps[right] : -1n),
id: counterId,
- trackId: this.id,
+ trackKey: this.trackKey,
}));
return true;
}
@@ -633,7 +634,7 @@
const config:
Config = {name, trackId, defaultScale: getCounterScale(name)};
const uri = `perfetto.Counter#${trackId}`;
- ctx.addTrack({
+ ctx.registerStaticTrack({
uri,
displayName: name,
kind: COUNTER_TRACK_KIND,
@@ -642,9 +643,9 @@
return new CounterTrack(trackCtx, config, ctx.engine);
},
});
- ctx.suggestTrack({
+ ctx.addDefaultTrack({
uri,
- name,
+ displayName: name,
sortKey: PrimaryTrackSortKey.COUNTER_TRACK,
});
}
@@ -712,7 +713,7 @@
maximumValue,
defaultScale: getCounterScale(name),
};
- ctx.addTrack({
+ ctx.registerStaticTrack({
uri,
displayName: name,
kind: COUNTER_TRACK_KIND,
@@ -768,7 +769,7 @@
trackId,
defaultScale: getCounterScale(name),
};
- ctx.addTrack({
+ ctx.registerStaticTrack({
uri: `perfetto.Counter#cpu${trackId}`,
displayName: name,
kind: COUNTER_TRACK_KIND,
@@ -831,7 +832,7 @@
endTs: Time.fromRaw(endTs),
defaultScale: getCounterScale(name),
};
- ctx.addTrack({
+ ctx.registerStaticTrack({
uri: `perfetto.Counter#thread${trackId}`,
displayName: name,
kind,
@@ -888,7 +889,7 @@
endTs: Time.fromRaw(endTs),
defaultScale: getCounterScale(name),
};
- ctx.addTrack({
+ ctx.registerStaticTrack({
uri: `perfetto.Counter#process${trackId}`,
displayName: name,
kind: COUNTER_TRACK_KIND,
diff --git a/ui/src/tracks/cpu_freq/index.ts b/ui/src/tracks/cpu_freq/index.ts
index 35faefc..923940a 100644
--- a/ui/src/tracks/cpu_freq/index.ts
+++ b/ui/src/tracks/cpu_freq/index.ts
@@ -533,15 +533,15 @@
const freqTrackId = row.cpuFreqId;
const idleTrackId = row.cpuIdleId === null ? undefined : row.cpuIdleId;
- ctx.addTrack({
+ ctx.registerStaticTrack({
uri: `perfetto.CpuFreq#${cpu}`,
displayName: `Cpu ${cpu} Frequency`,
kind: CPU_FREQ_TRACK_KIND,
cpu,
- track: ({trackInstanceId}) => {
+ track: ({trackKey}) => {
return new TrackWithControllerAdapter<Config, Data>(
engine,
- trackInstanceId,
+ trackKey,
{
cpu,
maximumValue: maxCpuFreq,
diff --git a/ui/src/tracks/cpu_profile/index.ts b/ui/src/tracks/cpu_profile/index.ts
index 616e9a2..d41a5ed 100644
--- a/ui/src/tracks/cpu_profile/index.ts
+++ b/ui/src/tracks/cpu_profile/index.ts
@@ -17,16 +17,23 @@
import {duration, Time, time} from '../../base/time';
import {Actions} from '../../common/actions';
import {hslForSlice} from '../../common/colorizer';
-import {LONG, NUM} from '../../common/query_result';
-import {TrackData} from '../../common/track_data';
+import {LONG, NUM, NUM_NULL, STR_NULL} from '../../common/query_result';
import {
- TrackController,
-} from '../../controller/track_controller';
+ TrackAdapter,
+ TrackControllerAdapter,
+ TrackWithControllerAdapter,
+} from '../../common/track_adapter';
+import {TrackData} from '../../common/track_data';
import {globals} from '../../frontend/globals';
import {cachedHsluvToHex} from '../../frontend/hsluv_cache';
import {TimeScale} from '../../frontend/time_scale';
-import {NewTrackArgs, TrackBase} from '../../frontend/track';
-import {Plugin, PluginContext, PluginDescriptor} from '../../public';
+import {NewTrackArgs} from '../../frontend/track';
+import {
+ Plugin,
+ PluginContext,
+ PluginContextTrace,
+ PluginDescriptor,
+} from '../../public';
const BAR_HEIGHT = 3;
const MARGIN_TOP = 4.5;
@@ -44,8 +51,7 @@
utid: number;
}
-class CpuProfileTrackController extends TrackController<Config, Data> {
- static readonly kind = CPU_PROFILE_TRACK_KIND;
+class CpuProfileTrackController extends TrackControllerAdapter<Config, Data> {
async onBoundsChange(start: time, end: time, resolution: duration):
Promise<Data> {
const query = `select
@@ -85,8 +91,7 @@
return cachedHsluvToHex(hue, saturation, lightness);
}
-class CpuProfileTrack extends TrackBase<Config, Data> {
- static readonly kind = CPU_PROFILE_TRACK_KIND;
+class CpuProfileTrack extends TrackAdapter<Config, Data> {
static create(args: NewTrackArgs): CpuProfileTrack {
return new CpuProfileTrack(args);
}
@@ -245,9 +250,48 @@
}
class CpuProfile implements Plugin {
- onActivate(ctx: PluginContext): void {
- ctx.LEGACY_registerTrackController(CpuProfileTrackController);
- ctx.LEGACY_registerTrack(CpuProfileTrack);
+ onActivate(_ctx: PluginContext): void {}
+
+ async onTraceLoad(ctx: PluginContextTrace): Promise<void> {
+ const result = await ctx.engine.query(`
+ select
+ utid,
+ tid,
+ upid,
+ thread.name as threadName
+ from
+ thread
+ join (select utid
+ from cpu_profile_stack_sample group by utid
+ ) using(utid)
+ left join process using(upid)
+ where utid != 0
+ group by utid`);
+
+ const it = result.iter({
+ utid: NUM,
+ upid: NUM_NULL,
+ tid: NUM_NULL,
+ threadName: STR_NULL,
+ });
+ for (; it.valid(); it.next()) {
+ const utid = it.utid;
+ const threadName = it.threadName;
+ ctx.registerStaticTrack({
+ uri: `perfetto.CpuProfile#${utid}`,
+ displayName: `${threadName} (CPU Stack Samples)`,
+ kind: CPU_PROFILE_TRACK_KIND,
+ utid,
+ track: ({trackKey}) => {
+ return new TrackWithControllerAdapter(
+ ctx.engine,
+ trackKey,
+ {utid},
+ CpuProfileTrack,
+ CpuProfileTrackController);
+ },
+ });
+ }
}
}
diff --git a/ui/src/tracks/cpu_slices/index.ts b/ui/src/tracks/cpu_slices/index.ts
index c2de3f6..88a020f 100644
--- a/ui/src/tracks/cpu_slices/index.ts
+++ b/ui/src/tracks/cpu_slices/index.ts
@@ -454,7 +454,6 @@
}
onMouseClick({x}: {x: number}) {
- console.log(this.mousePos);
const data = this.data();
if (data === undefined) return false;
const {visibleTimeScale} = globals.frontendLocalState;
@@ -462,7 +461,7 @@
const index = search(data.starts, time.toTime());
const id = index === -1 ? undefined : data.ids[index];
if (!id || this.utidHoveredInThisTrack === -1) return false;
- globals.makeSelection(Actions.selectSlice({id, trackId: this.id}));
+ globals.makeSelection(Actions.selectSlice({id, trackKey: this.trackKey}));
return true;
}
}
@@ -481,15 +480,15 @@
const uri = `perfetto.CpuSlices#cpu${cpu}`;
const name = size === undefined ? `Cpu ${cpu}` : `Cpu ${cpu} (${size})`;
const config: Config = {cpu};
- ctx.addTrack({
+ ctx.registerStaticTrack({
uri,
displayName: name,
kind: CPU_SLICE_TRACK_KIND,
cpu,
- track: ({trackInstanceId}) => {
+ track: ({trackKey}) => {
return new TrackWithControllerAdapter<Config, Data>(
ctx.engine,
- trackInstanceId,
+ trackKey,
config,
CpuSliceTrack,
CpuSliceTrackController);
diff --git a/ui/src/tracks/custom_sql_table_slices/index.ts b/ui/src/tracks/custom_sql_table_slices/index.ts
index 8ffe388..8389a8e 100644
--- a/ui/src/tracks/custom_sql_table_slices/index.ts
+++ b/ui/src/tracks/custom_sql_table_slices/index.ts
@@ -12,6 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import {v4 as uuidv4} from 'uuid';
+
+import {Disposable, DisposableCallback} from '../../base/disposable';
import {Actions} from '../../common/actions';
import {
generateSqlWithInternalLayout,
@@ -29,6 +32,10 @@
import {NewTrackArgs} from '../../frontend/track';
import {Plugin, PluginContext, PluginDescriptor} from '../../public';
+export interface CustomSqlImportConfig {
+ modules: string[];
+}
+
export interface CustomSqlTableDefConfig {
// Table name
sqlTableName: string;
@@ -46,8 +53,12 @@
export abstract class CustomSqlTableSliceTrack<
T extends NamedSliceTrackTypes> extends NamedSliceTrack<T> {
+ protected readonly tableName;
+
constructor(args: NewTrackArgs) {
super(args);
+ this.tableName =
+ `customsqltableslicetrack_${uuidv4().split('-').join('_')}`;
}
abstract getSqlDataSource(): CustomSqlTableDefConfig;
@@ -55,29 +66,43 @@
// Override by subclasses.
abstract getDetailsPanel(): CustomSqlDetailsPanelConfig;
- async initSqlTable(tableName: string) {
+ getSqlImports(): CustomSqlImportConfig {
+ return {
+ modules: [] as string[],
+ };
+ }
+
+ async onInit(): Promise<Disposable> {
+ await this.loadImports();
const config = this.getSqlDataSource();
let columns = ['*'];
if (config.columns !== undefined) {
columns = config.columns;
}
- const sql = `CREATE VIEW ${tableName} AS ` + generateSqlWithInternalLayout({
- columns: columns,
- sourceTable: config.sqlTableName,
- ts: 'ts',
- dur: 'dur',
- whereClause: config.whereClause,
- });
-
+ const sql =
+ `CREATE VIEW ${this.tableName} AS ` + generateSqlWithInternalLayout({
+ columns: columns,
+ sourceTable: config.sqlTableName,
+ ts: 'ts',
+ dur: 'dur',
+ whereClause: config.whereClause,
+ });
await this.engine.query(sql);
+ return DisposableCallback.from(() => {
+ this.engine.query(`DROP VIEW ${this.tableName}`);
+ });
+ }
+
+ getSqlSource(): string {
+ return `SELECT * FROM ${this.tableName}`;
}
isSelectionHandled(selection: Selection) {
if (selection.kind !== 'GENERIC_SLICE') {
return false;
}
- return selection.trackId === this.trackId;
+ return selection.trackKey === this.trackKey;
}
onSliceClick(args: OnSliceClickArgs<NamedSliceTrackTypes['slice']>) {
@@ -91,13 +116,19 @@
sqlTableName: this.tableName,
start: args.slice.ts,
duration: args.slice.dur,
- trackId: this.trackId,
+ trackKey: this.trackKey,
detailsPanelConfig: {
kind: detailsPanelConfig.kind,
config: detailsPanelConfig.config,
},
}));
}
+
+ async loadImports() {
+ for (const importModule of this.getSqlImports().modules) {
+ await this.engine.query(`INCLUDE PERFETTO MODULE ${importModule};`);
+ }
+ }
}
class CustomSqlTrackPlugin implements Plugin {
diff --git a/ui/src/tracks/debug/add_debug_track_menu.ts b/ui/src/tracks/debug/add_debug_track_menu.ts
index e7712a0..ccdc71d 100644
--- a/ui/src/tracks/debug/add_debug_track_menu.ts
+++ b/ui/src/tracks/debug/add_debug_track_menu.ts
@@ -16,11 +16,13 @@
import {findRef} from '../../base/dom_utils';
import {EngineProxy} from '../../common/engine';
+import {raf} from '../../core/raf_scheduler';
import {Form, FormLabel} from '../../widgets/form';
import {Select} from '../../widgets/select';
import {TextInput} from '../../widgets/text_input';
-import {addDebugTrack, SliceColumns, SqlDataSource} from './slice_track';
+import {addDebugCounterTrack} from './counter_track';
+import {addDebugSliceTrack, SqlDataSource} from './slice_track';
export const ARG_PREFIX = 'arg_';
@@ -40,11 +42,13 @@
readonly columns: string[];
name: string = '';
- sliceColumns: SliceColumns;
- arrangeBy?: {
- type: 'thread'|'process',
- column: string,
- };
+ trackType: 'slice'|'counter' = 'slice';
+ // Names of columns which will be used as data sources for rendering.
+ // We store the config for all possible columns used for rendering (i.e.
+ // 'value' for slice and 'name' for counter) and then just don't the values
+ // which don't match the currently selected track type (so changing track type
+ // from A to B and back to A is a no-op).
+ renderParams: {ts: string; dur: string; name: string; value: string;};
constructor(vnode: m.Vnode<AddDebugTrackMenuAttrs>) {
this.columns = [...vnode.attrs.dataSource.columns];
@@ -64,10 +68,11 @@
return this.columns[0];
};
- this.sliceColumns = {
+ this.renderParams = {
ts: chooseDefaultOption('ts'),
dur: chooseDefaultOption('dur'),
name: chooseDefaultOption('name'),
+ value: chooseDefaultOption('value'),
};
}
@@ -84,21 +89,46 @@
}
}
+ private renderTrackTypeSelect() {
+ const options = [];
+ for (const type of ['slice', 'counter']) {
+ options.push(
+ m('option',
+ {
+ value: type,
+ selected: this.trackType === type ? true : undefined,
+ },
+ type));
+ }
+ return m(
+ Select,
+ {
+ id: 'track_type',
+ oninput: (e: Event) => {
+ if (!e.target) return;
+ this.trackType =
+ (e.target as HTMLSelectElement).value as 'slice' | 'counter';
+ raf.scheduleFullRedraw();
+ },
+ },
+ options);
+ }
+
view(vnode: m.Vnode<AddDebugTrackMenuAttrs>) {
- const renderSelect = (name: 'ts'|'dur'|'name') => {
+ const renderSelect = (name: 'ts'|'dur'|'name'|'value') => {
const options = [];
for (const column of this.columns) {
options.push(
m('option',
{
- selected: this.sliceColumns[name] === column ? true : undefined,
+ selected: this.renderParams[name] === column ? true : undefined,
},
column));
}
if (name === 'dur') {
options.push(
m('option',
- {selected: this.sliceColumns[name] === '0' ? true : undefined},
+ {selected: this.renderParams[name] === '0' ? true : undefined},
m('i', '0')));
}
return [
@@ -111,7 +141,7 @@
id: name,
oninput: (e: Event) => {
if (!e.target) return;
- this.sliceColumns[name] = (e.target as HTMLSelectElement).value;
+ this.renderParams[name] = (e.target as HTMLSelectElement).value;
},
},
options),
@@ -121,12 +151,27 @@
Form,
{
onSubmit: () => {
- addDebugTrack(
- vnode.attrs.engine,
- vnode.attrs.dataSource,
- this.name,
- this.sliceColumns,
- this.columns);
+ switch (this.trackType) {
+ case 'slice':
+ addDebugSliceTrack(
+ vnode.attrs.engine,
+ vnode.attrs.dataSource,
+ this.name,
+ {
+ ts: this.renderParams.ts,
+ dur: this.renderParams.dur,
+ name: this.renderParams.name,
+ },
+ this.columns);
+ break;
+ case 'counter':
+ addDebugCounterTrack(
+ vnode.attrs.engine, vnode.attrs.dataSource, this.name, {
+ ts: this.renderParams.ts,
+ value: this.renderParams.value,
+ });
+ break;
+ }
},
submitLabel: 'Show',
},
@@ -146,9 +191,15 @@
this.name = (e.target as HTMLInputElement).value;
},
}),
+ m(FormLabel,
+ {for: 'track_type',
+ },
+ 'Track type'),
+ this.renderTrackTypeSelect(),
renderSelect('ts'),
- renderSelect('dur'),
- renderSelect('name'),
+ this.trackType === 'slice' && renderSelect('dur'),
+ this.trackType === 'slice' && renderSelect('name'),
+ this.trackType === 'counter' && renderSelect('value'),
);
}
}
diff --git a/ui/src/tracks/debug/counter_track.ts b/ui/src/tracks/debug/counter_track.ts
new file mode 100644
index 0000000..fd6aa30
--- /dev/null
+++ b/ui/src/tracks/debug/counter_track.ts
@@ -0,0 +1,124 @@
+// 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 m from 'mithril';
+import {v4 as uuidv4} from 'uuid';
+
+import {Actions} from '../../common/actions';
+import {EngineProxy} from '../../common/engine';
+import {SCROLLING_TRACK_GROUP} from '../../common/state';
+import {BaseCounterTrack} from '../../frontend/base_counter_track';
+import {globals} from '../../frontend/globals';
+import {TrackButton} from '../../frontend/track_panel';
+import {PrimaryTrackSortKey, TrackContext} from '../../public';
+
+import {DEBUG_COUNTER_TRACK_URI} from '.';
+
+// Names of the columns of the underlying view to be used as ts / dur / name.
+export interface CounterColumns {
+ ts: string;
+ value: string;
+}
+
+export interface CounterDebugTrackConfig {
+ sqlTableName: string;
+ columns: CounterColumns;
+}
+
+export class DebugCounterTrack extends
+ BaseCounterTrack<CounterDebugTrackConfig> {
+ constructor(engine: EngineProxy, trackKey: string) {
+ super({
+ engine,
+ trackKey,
+ });
+ }
+
+ onCreate(ctx: TrackContext): void {
+ // TODO(stevegolton): Validate params before type asserting.
+ // TODO(stevegolton): Avoid just pushing this config up for some base
+ // class to use. Be more explicit.
+ this.config = ctx.params as CounterDebugTrackConfig;
+ }
+
+ getTrackShellButtons(): m.Children {
+ return [
+ this.getCounterContextMenu(),
+ m(TrackButton, {
+ action: () => {
+ globals.dispatch(Actions.removeTracks({trackKeys: [this.trackKey]}));
+ },
+ i: 'close',
+ tooltip: 'Close',
+ showButton: true,
+ }),
+ ];
+ }
+
+ async initSqlTable(tableName: string): Promise<void> {
+ await this.engine.query(`
+ create view ${tableName} as
+ select * from ${this.config.sqlTableName};
+ `);
+ }
+}
+
+let debugTrackCount = 0;
+
+export interface SqlDataSource {
+ // SQL source selecting the necessary data.
+ sqlSource: string;
+ // The caller is responsible for ensuring that the number of items in this
+ // list matches the number of columns returned by sqlSource.
+ columns: string[];
+}
+
+export async function addDebugCounterTrack(
+ engine: EngineProxy,
+ data: SqlDataSource,
+ trackName: string,
+ columns: CounterColumns) {
+ // To prepare displaying the provided data as a track, materialize it and
+ // compute depths.
+ const debugTrackId = ++debugTrackCount;
+ const sqlTableName = `__debug_counter_${debugTrackId}`;
+
+ // TODO(altimin): Support removing this table when the track is closed.
+ await engine.query(`
+ create table ${sqlTableName} as
+ with data as (
+ ${data.sqlSource}
+ )
+ select
+ ${columns.ts} as ts,
+ ${columns.value} as value
+ from data
+ order by ts;`);
+
+ const trackKey = uuidv4();
+ globals.dispatchMultiple([
+ Actions.addTrack({
+ key: trackKey,
+ uri: DEBUG_COUNTER_TRACK_URI,
+ name: trackName.trim() || `Debug Track ${debugTrackId}`,
+ trackSortKey: PrimaryTrackSortKey.DEBUG_TRACK,
+ trackGroup: SCROLLING_TRACK_GROUP,
+ params: {
+ sqlTableName,
+ columns,
+ },
+ }),
+ Actions.toggleTrackPinned({trackKey}),
+ ]);
+}
diff --git a/ui/src/tracks/debug/details_tab.ts b/ui/src/tracks/debug/details_tab.ts
index 8b89ec9..ee27bee 100644
--- a/ui/src/tracks/debug/details_tab.ts
+++ b/ui/src/tracks/debug/details_tab.ts
@@ -140,15 +140,14 @@
private async maybeLoadSlice(
id: number|undefined, ts: time, dur: duration, table: string|undefined,
- sqlTrackId?: number): Promise<SliceDetails|undefined> {
+ trackId?: number): Promise<SliceDetails|undefined> {
if (id === undefined) return undefined;
- if ((table !== 'slice') && sqlTrackId === undefined) return undefined;
+ if ((table !== 'slice') && trackId === undefined) return undefined;
const slice = await getSlice(this.engine, asSliceSqlId(id));
if (slice === undefined) return undefined;
if ((table === 'slice') ||
- (slice.ts === ts && slice.dur === dur &&
- slice.sqlTrackId === sqlTrackId)) {
+ (slice.ts === ts && slice.dur === dur && slice.trackId === trackId)) {
return slice;
} else {
return undefined;
diff --git a/ui/src/tracks/debug/index.ts b/ui/src/tracks/debug/index.ts
index 78c12e7..985f068 100644
--- a/ui/src/tracks/debug/index.ts
+++ b/ui/src/tracks/debug/index.ts
@@ -12,13 +12,31 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {Plugin, PluginContext, PluginDescriptor} from '../../public';
+import {
+ Plugin,
+ PluginContext,
+ PluginContextTrace,
+ PluginDescriptor,
+} from '../../public';
+import {DebugCounterTrack} from './counter_track';
import {DebugTrackV2} from './slice_track';
+export const DEBUG_SLICE_TRACK_URI = 'perfetto.DebugSlices';
+export const DEBUG_COUNTER_TRACK_URI = 'perfetto.DebugCounter';
+
class DebugTrackPlugin implements Plugin {
- onActivate(ctx: PluginContext): void {
- ctx.LEGACY_registerTrack(DebugTrackV2);
+ onActivate(_ctx: PluginContext): void {}
+
+ async onTraceLoad(ctx: PluginContextTrace): Promise<void> {
+ ctx.registerTrack({
+ uri: DEBUG_SLICE_TRACK_URI,
+ track: ({trackKey}) => new DebugTrackV2(ctx.engine, trackKey),
+ });
+ ctx.registerTrack({
+ uri: DEBUG_COUNTER_TRACK_URI,
+ track: ({trackKey}) => new DebugCounterTrack(ctx.engine, trackKey),
+ });
}
}
diff --git a/ui/src/tracks/debug/slice_track.ts b/ui/src/tracks/debug/slice_track.ts
index 739980a..bce33f2 100644
--- a/ui/src/tracks/debug/slice_track.ts
+++ b/ui/src/tracks/debug/slice_track.ts
@@ -13,21 +13,25 @@
// limitations under the License.
import m from 'mithril';
+import {v4 as uuidv4} from 'uuid';
-import {Actions, DEBUG_SLICE_TRACK_KIND} from '../../common/actions';
+import {Disposable} from '../../base/disposable';
+import {Actions} from '../../common/actions';
import {EngineProxy} from '../../common/engine';
+import {SCROLLING_TRACK_GROUP} from '../../common/state';
import {globals} from '../../frontend/globals';
import {
NamedSliceTrackTypes,
} from '../../frontend/named_slice_track';
-import {NewTrackArgs} from '../../frontend/track';
-import {TrackButton, TrackButtonAttrs} from '../../frontend/track_panel';
+import {TrackButton} from '../../frontend/track_panel';
+import {PrimaryTrackSortKey, TrackContext} from '../../public';
import {
CustomSqlDetailsPanelConfig,
CustomSqlTableDefConfig,
CustomSqlTableSliceTrack,
} from '../custom_sql_table_slices';
+import {DEBUG_SLICE_TRACK_URI} from '.';
import {ARG_PREFIX} from './add_debug_track_menu';
import {DebugSliceDetailsTab} from './details_tab';
@@ -48,14 +52,18 @@
}
export class DebugTrackV2 extends CustomSqlTableSliceTrack<DebugTrackV2Types> {
- static readonly kind = DEBUG_SLICE_TRACK_KIND;
-
- static create(args: NewTrackArgs) {
- return new DebugTrackV2(args);
+ constructor(engine: EngineProxy, trackKey: string) {
+ super({
+ engine,
+ trackKey,
+ });
}
- constructor(args: NewTrackArgs) {
- super(args);
+ onCreate(ctx: TrackContext): void {
+ // TODO(stevegolton): Validate params before type asserting.
+ // TODO(stevegolton): Avoid just pushing this config up for some base
+ // class to use. Be more explicit.
+ this.config = ctx.params as DebugTrackV2Config;
}
getSqlDataSource(): CustomSqlTableDefConfig {
@@ -74,19 +82,19 @@
};
}
- async initSqlTable(tableName: string): Promise<void> {
- super.initSqlTable(tableName);
+ async onInit(): Promise<Disposable> {
+ return super.onInit();
}
- getTrackShellButtons(): Array<m.Vnode<TrackButtonAttrs>> {
- return [m(TrackButton, {
+ getTrackShellButtons(): m.Children {
+ return m(TrackButton, {
action: () => {
- globals.dispatch(Actions.removeDebugTrack({trackId: this.trackId}));
+ globals.dispatch(Actions.removeTracks({trackKeys: [this.trackKey]}));
},
i: 'close',
tooltip: 'Close',
showButton: true,
- })];
+ });
}
}
@@ -100,7 +108,7 @@
columns: string[];
}
-export async function addDebugTrack(
+export async function addDebugSliceTrack(
engine: EngineProxy,
data: SqlDataSource,
trackName: string,
@@ -140,12 +148,19 @@
from prepared_data
order by ts;`);
- globals.dispatch(Actions.addDebugTrack({
- engineId: engine.engineId,
- name: trackName.trim() || `Debug Track ${debugTrackId}`,
- config: {
- sqlTableName,
- columns: sliceColumns,
- },
- }));
+ const trackKey = uuidv4();
+ globals.dispatchMultiple([
+ Actions.addTrack({
+ key: trackKey,
+ name: trackName.trim() || `Debug Track ${debugTrackId}`,
+ uri: DEBUG_SLICE_TRACK_URI,
+ trackSortKey: PrimaryTrackSortKey.DEBUG_TRACK,
+ trackGroup: SCROLLING_TRACK_GROUP,
+ params: {
+ sqlTableName,
+ columns: sliceColumns,
+ },
+ }),
+ Actions.toggleTrackPinned({trackKey}),
+ ]);
}
diff --git a/ui/src/tracks/expected_frames/index.ts b/ui/src/tracks/expected_frames/index.ts
index b30d31e..4894722 100644
--- a/ui/src/tracks/expected_frames/index.ts
+++ b/ui/src/tracks/expected_frames/index.ts
@@ -12,56 +12,53 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {TrackData} from '../../common/track_data';
+import {BigintMath as BIMath} from '../../base/bigint_math';
+import {Duration, duration, time} from '../../base/time';
+import {
+ LONG,
+ LONG_NULL,
+ NUM,
+ NUM_NULL,
+ STR,
+ STR_NULL,
+} from '../../common/query_result';
+import {
+ SliceData,
+ SliceTrackBase,
+} from '../../frontend/slice_track_base';
+import {
+ EngineProxy,
+ Plugin,
+ PluginContext,
+ PluginContextTrace,
+ PluginDescriptor,
+} from '../../public';
+import {getTrackName} from '../../public/utils';
export const EXPECTED_FRAMES_SLICE_TRACK_KIND = 'ExpectedFramesSliceTrack';
-import {NewTrackArgs, TrackBase} from '../../frontend/track';
-import {ChromeSliceTrack} from '../chrome_slices';
+class SliceTrack extends SliceTrackBase {
+ private maxDur = Duration.ZERO;
-import {LONG, LONG_NULL, NUM, STR} from '../../common/query_result';
-import {duration, time} from '../../base/time';
-import {
- TrackController,
-} from '../../controller/track_controller';
-import {Plugin, PluginContext, PluginDescriptor} from '../../public';
-import {BigintMath as BIMath} from '../../base/bigint_math';
-
-export interface Config {
- maxDepth: number;
- trackIds: number[];
-}
-
-export interface Data extends TrackData {
- // Slices are stored in a columnar fashion. All fields have the same length.
- strings: string[];
- sliceIds: Float64Array;
- starts: BigInt64Array;
- ends: BigInt64Array;
- depths: Uint16Array;
- titles: Uint16Array; // Index in |strings|.
- colors?: Uint16Array; // Index in |strings|.
- isInstant: Uint16Array;
- isIncomplete: Uint16Array;
-}
-
-class ExpectedFramesSliceTrackController extends TrackController<Config, Data> {
- static readonly kind = EXPECTED_FRAMES_SLICE_TRACK_KIND;
- private maxDurNs: duration = 0n;
+ constructor(
+ private engine: EngineProxy, maxDepth: number, trackKey: string,
+ private trackIds: number[], namespace?: string) {
+ super(maxDepth, trackKey, '', namespace);
+ }
async onBoundsChange(start: time, end: time, resolution: duration):
- Promise<Data> {
- if (this.maxDurNs === 0n) {
- const maxDurResult = await this.query(`
+ Promise<SliceData> {
+ if (this.maxDur === Duration.ZERO) {
+ const maxDurResult = await this.engine.query(`
select max(iif(dur = -1, (SELECT end_ts FROM trace_bounds) - ts, dur))
as maxDur
from experimental_slice_layout
- where filter_track_ids = '${this.config.trackIds.join(',')}'
+ where filter_track_ids = '${this.trackIds.join(',')}'
`);
- this.maxDurNs = maxDurResult.firstRow({maxDur: LONG_NULL}).maxDur || 0n;
+ this.maxDur = maxDurResult.firstRow({maxDur: LONG_NULL}).maxDur || 0n;
}
- const queryRes = await this.query(`
+ const queryRes = await this.engine.query(`
SELECT
(ts + ${resolution / 2n}) / ${resolution} * ${resolution} as tsq,
ts,
@@ -73,15 +70,15 @@
dur = -1 as isIncomplete
from experimental_slice_layout
where
- filter_track_ids = '${this.config.trackIds.join(',')}' and
- ts >= ${start - this.maxDurNs} and
+ filter_track_ids = '${this.trackIds.join(',')}' and
+ ts >= ${start - this.maxDur} and
ts <= ${end}
group by tsq, layout_depth
order by tsq, layout_depth
`);
const numRows = queryRes.numRows();
- const slices: Data = {
+ const slices: SliceData = {
start,
end,
resolution,
@@ -139,18 +136,74 @@
}
}
-
-export class ExpectedFramesSliceTrack extends ChromeSliceTrack {
- static readonly kind = EXPECTED_FRAMES_SLICE_TRACK_KIND;
- static create(args: NewTrackArgs): TrackBase {
- return new ExpectedFramesSliceTrack(args);
- }
-}
-
class ExpectedFramesPlugin implements Plugin {
- onActivate(ctx: PluginContext): void {
- ctx.LEGACY_registerTrackController(ExpectedFramesSliceTrackController);
- ctx.LEGACY_registerTrack(ExpectedFramesSliceTrack);
+ onActivate(_ctx: PluginContext): void {}
+
+ async onTraceLoad(ctx: PluginContextTrace): Promise<void> {
+ const {engine} = ctx;
+ const result = await engine.query(`
+ with process_async_tracks as materialized (
+ select
+ process_track.upid as upid,
+ process_track.name as trackName,
+ process.name as processName,
+ process.pid as pid,
+ group_concat(process_track.id) as trackIds,
+ count(1) as trackCount
+ from process_track
+ left join process using(upid)
+ where process_track.name = "Expected Timeline"
+ group by
+ process_track.upid,
+ process_track.name
+ )
+ select
+ t.*,
+ max_layout_depth(t.trackCount, t.trackIds) as maxDepth
+ from process_async_tracks t;
+ `);
+
+ const it = result.iter({
+ upid: NUM,
+ trackName: STR_NULL,
+ trackIds: STR,
+ processName: STR_NULL,
+ pid: NUM_NULL,
+ maxDepth: NUM_NULL,
+ });
+
+ for (; it.valid(); it.next()) {
+ const upid = it.upid;
+ const trackName = it.trackName;
+ const rawTrackIds = it.trackIds;
+ const trackIds = rawTrackIds.split(',').map((v) => Number(v));
+ const processName = it.processName;
+ const pid = it.pid;
+ const maxDepth = it.maxDepth;
+
+ if (maxDepth === null) {
+ // If there are no slices in this track, skip it.
+ continue;
+ }
+
+ const displayName = getTrackName(
+ {name: trackName, upid, pid, processName, kind: 'ExpectedFrames'});
+
+ ctx.registerStaticTrack({
+ uri: `perfetto.ExpectedFrames#${upid}`,
+ displayName,
+ trackIds,
+ kind: EXPECTED_FRAMES_SLICE_TRACK_KIND,
+ track: ({trackKey}) => {
+ return new SliceTrack(
+ engine,
+ maxDepth,
+ trackKey,
+ trackIds,
+ );
+ },
+ });
+ }
}
}
diff --git a/ui/src/tracks/ftrace/index.ts b/ui/src/tracks/ftrace/index.ts
index f2ad696..58b59b0 100644
--- a/ui/src/tracks/ftrace/index.ts
+++ b/ui/src/tracks/ftrace/index.ts
@@ -144,7 +144,7 @@
for (const cpuNum of cpus) {
const uri = `perfetto.FtraceRaw#cpu${cpuNum}`;
- ctx.addTrack({
+ ctx.registerStaticTrack({
uri,
displayName: `Ftrace Track for CPU ${cpuNum}`,
kind: FTRACE_RAW_TRACK_KIND,
diff --git a/ui/src/tracks/heap_profile/index.ts b/ui/src/tracks/heap_profile/index.ts
index 38b19e7..b85827b 100644
--- a/ui/src/tracks/heap_profile/index.ts
+++ b/ui/src/tracks/heap_profile/index.ts
@@ -15,16 +15,25 @@
import {searchSegment} from '../../base/binary_search';
import {duration, Time, time} from '../../base/time';
import {Actions} from '../../common/actions';
-import {LONG, STR} from '../../common/query_result';
+import {LONG, NUM, STR} from '../../common/query_result';
import {ProfileType} from '../../common/state';
+import {
+ TrackAdapter,
+ TrackControllerAdapter,
+ TrackWithControllerAdapter,
+} from '../../common/track_adapter';
import {TrackData} from '../../common/track_data';
import {profileType} from '../../controller/flamegraph_controller';
-import {TrackController} from '../../controller/track_controller';
import {FLAMEGRAPH_HOVERED_COLOR} from '../../frontend/flamegraph';
import {globals} from '../../frontend/globals';
import {TimeScale} from '../../frontend/time_scale';
-import {NewTrackArgs, TrackBase} from '../../frontend/track';
-import {Plugin, PluginContext, PluginDescriptor} from '../../public';
+import {NewTrackArgs} from '../../frontend/track';
+import {
+ Plugin,
+ PluginContext,
+ PluginContextTrace,
+ PluginDescriptor,
+} from '../../public';
export const HEAP_PROFILE_TRACK_KIND = 'HeapProfileTrack';
@@ -37,8 +46,7 @@
upid: number;
}
-class HeapProfileTrackController extends TrackController<Config, Data> {
- static readonly kind = HEAP_PROFILE_TRACK_KIND;
+class HeapProfileTrackController extends TrackControllerAdapter<Config, Data> {
async onBoundsChange(start: time, end: time, resolution: duration):
Promise<Data> {
if (this.config.upid === undefined) {
@@ -88,8 +96,7 @@
const MARGIN_TOP = 4.5;
const RECT_HEIGHT = 30.5;
-class HeapProfileTrack extends TrackBase<Config, Data> {
- static readonly kind = HEAP_PROFILE_TRACK_KIND;
+class HeapProfileTrack extends TrackAdapter<Config, Data> {
static create(args: NewTrackArgs): HeapProfileTrack {
return new HeapProfileTrack(args);
}
@@ -216,9 +223,30 @@
}
class HeapProfilePlugin implements Plugin {
- onActivate(ctx: PluginContext): void {
- ctx.LEGACY_registerTrackController(HeapProfileTrackController);
- ctx.LEGACY_registerTrack(HeapProfileTrack);
+ onActivate(_ctx: PluginContext): void {}
+ async onTraceLoad(ctx: PluginContextTrace): Promise<void> {
+ const result = await ctx.engine.query(`
+ select distinct(upid) from heap_profile_allocation
+ union
+ select distinct(upid) from heap_graph_object
+ `);
+ for (const it = result.iter({upid: NUM}); it.valid(); it.next()) {
+ const upid = it.upid;
+ ctx.registerStaticTrack({
+ uri: `perfetto.HeapProfile#${upid}`,
+ displayName: 'Heap Profile',
+ kind: HEAP_PROFILE_TRACK_KIND,
+ upid,
+ track: ({trackKey}) => {
+ return new TrackWithControllerAdapter(
+ ctx.engine,
+ trackKey,
+ {upid},
+ HeapProfileTrack,
+ HeapProfileTrackController);
+ },
+ });
+ }
}
}
diff --git a/ui/src/tracks/null_track/index.ts b/ui/src/tracks/null_track/index.ts
index a007185..1b2bb24 100644
--- a/ui/src/tracks/null_track/index.ts
+++ b/ui/src/tracks/null_track/index.ts
@@ -13,15 +13,19 @@
// limitations under the License.
import {NewTrackArgs, TrackBase} from '../../frontend/track';
-import {Plugin, PluginContext, PluginDescriptor} from '../../public';
+import {
+ Plugin,
+ PluginContext,
+ PluginContextTrace,
+ PluginDescriptor,
+} from '../../public';
+export const NULL_TRACK_URI = 'perfetto.NullTrack';
export const NULL_TRACK_KIND = 'NullTrack';
export class NullTrack extends TrackBase {
- static readonly kind = NULL_TRACK_KIND;
constructor(args: NewTrackArgs) {
super(args);
- this.frontendOnly = true;
}
static create(args: NewTrackArgs): NullTrack {
@@ -36,8 +40,21 @@
}
class NullTrackPlugin implements Plugin {
- onActivate(ctx: PluginContext): void {
- ctx.LEGACY_registerTrack(NullTrack);
+ onActivate(_ctx: PluginContext): void {}
+
+ async onTraceLoad(ctx: PluginContextTrace): Promise<void> {
+ // TODO(stevegolton): This is not the right way to handle blank tracks,
+ // instead we should probably just render some blank element at render time
+ // if no track uri is supplied.
+ ctx.registerStaticTrack({
+ uri: NULL_TRACK_URI,
+ displayName: 'Null Track',
+ kind: NULL_TRACK_KIND,
+ track: ({trackKey}) => NullTrack.create({
+ engine: ctx.engine,
+ trackKey,
+ }),
+ });
}
}
diff --git a/ui/src/tracks/perf_samples_profile/index.ts b/ui/src/tracks/perf_samples_profile/index.ts
index b6e624a..330637c 100644
--- a/ui/src/tracks/perf_samples_profile/index.ts
+++ b/ui/src/tracks/perf_samples_profile/index.ts
@@ -15,15 +15,24 @@
import {searchSegment} from '../../base/binary_search';
import {duration, Time, time} from '../../base/time';
import {Actions} from '../../common/actions';
-import {LONG} from '../../common/query_result';
+import {LONG, NUM} from '../../common/query_result';
import {ProfileType} from '../../common/state';
+import {
+ TrackAdapter,
+ TrackControllerAdapter,
+ TrackWithControllerAdapter,
+} from '../../common/track_adapter';
import {TrackData} from '../../common/track_data';
-import {TrackController} from '../../controller/track_controller';
import {FLAMEGRAPH_HOVERED_COLOR} from '../../frontend/flamegraph';
import {globals} from '../../frontend/globals';
import {TimeScale} from '../../frontend/time_scale';
-import {NewTrackArgs, TrackBase} from '../../frontend/track';
-import {Plugin, PluginContext, PluginDescriptor} from '../../public';
+import {NewTrackArgs} from '../../frontend/track';
+import {
+ Plugin,
+ PluginContext,
+ PluginContextTrace,
+ PluginDescriptor,
+} from '../../public';
export const PERF_SAMPLES_PROFILE_TRACK_KIND = 'PerfSamplesProfileTrack';
@@ -35,8 +44,8 @@
upid: number;
}
-class PerfSamplesProfileTrackController extends TrackController<Config, Data> {
- static readonly kind = PERF_SAMPLES_PROFILE_TRACK_KIND;
+class PerfSamplesProfileTrackController extends
+ TrackControllerAdapter<Config, Data> {
async onBoundsChange(start: time, end: time, resolution: duration):
Promise<Data> {
if (this.config.upid === undefined) {
@@ -77,8 +86,7 @@
const MARGIN_TOP = 4.5;
const RECT_HEIGHT = 30.5;
-class PerfSamplesProfileTrack extends TrackBase<Config, Data> {
- static readonly kind = PERF_SAMPLES_PROFILE_TRACK_KIND;
+class PerfSamplesProfileTrack extends TrackAdapter<Config, Data> {
static create(args: NewTrackArgs): PerfSamplesProfileTrack {
return new PerfSamplesProfileTrack(args);
}
@@ -209,9 +217,32 @@
}
class PerfSamplesProfilePlugin implements Plugin {
- onActivate(ctx: PluginContext): void {
- ctx.LEGACY_registerTrackController(PerfSamplesProfileTrackController);
- ctx.LEGACY_registerTrack(PerfSamplesProfileTrack);
+ onActivate(_ctx: PluginContext): void {}
+
+ async onTraceLoad(ctx: PluginContextTrace): Promise<void> {
+ const result = await ctx.engine.query(`
+ select distinct upid, pid
+ from perf_sample join thread using (utid) join process using (upid)
+ where callsite_id is not null
+ `);
+ for (const it = result.iter({upid: NUM, pid: NUM}); it.valid(); it.next()) {
+ const upid = it.upid;
+ const pid = it.pid;
+ ctx.registerStaticTrack({
+ uri: `perfetto.PerfSamplesProfile#${upid}`,
+ displayName: `Callstacks ${pid}`,
+ kind: PERF_SAMPLES_PROFILE_TRACK_KIND,
+ upid,
+ track: ({trackKey}) => {
+ return new TrackWithControllerAdapter(
+ ctx.engine,
+ trackKey,
+ {upid},
+ PerfSamplesProfileTrack,
+ PerfSamplesProfileTrackController);
+ },
+ });
+ }
}
}
diff --git a/ui/src/tracks/process_summary/index.ts b/ui/src/tracks/process_summary/index.ts
index 24cae70..da73975 100644
--- a/ui/src/tracks/process_summary/index.ts
+++ b/ui/src/tracks/process_summary/index.ts
@@ -217,19 +217,19 @@
utid,
};
- ctx.addTrack({
+ ctx.registerStaticTrack({
uri,
displayName: `${upid === null ? tid : pid} schedule`,
kind: PROCESS_SCHEDULING_TRACK_KIND,
tags: {
isDebuggable,
},
- track: ({trackInstanceId}) => {
+ track: ({trackKey}) => {
return new TrackWithControllerAdapter<
ProcessSchedulingTrackConfig,
ProcessSchedulingTrackData>(
ctx.engine,
- trackInstanceId,
+ trackKey,
config,
ProcessSchedulingTrack,
ProcessSchedulingTrackController);
@@ -242,19 +242,19 @@
utid,
};
- ctx.addTrack({
+ ctx.registerStaticTrack({
uri,
displayName: `${upid === null ? tid : pid} summary`,
kind: PROCESS_SUMMARY_TRACK,
tags: {
isDebuggable,
},
- track: ({trackInstanceId}) => {
+ track: ({trackKey}) => {
return new TrackWithControllerAdapter<
ProcessSummaryTrackConfig,
ProcessSummaryTrackData>(
ctx.engine,
- trackInstanceId,
+ trackKey,
config,
ProcessSummaryTrack,
ProcessSummaryTrackController);
@@ -310,16 +310,16 @@
utid: it.utid,
};
- ctx.addTrack({
+ ctx.registerStaticTrack({
uri: 'perfetto.ProcessSummary#kernel',
displayName: `Kernel thread summary`,
kind: PROCESS_SUMMARY_TRACK,
- track: ({trackInstanceId}) => {
+ track: ({trackKey}) => {
return new TrackWithControllerAdapter<
ProcessSummaryTrackConfig,
ProcessSummaryTrackData>(
ctx.engine,
- trackInstanceId,
+ trackKey,
config,
ProcessSummaryTrack,
ProcessSummaryTrackController);
diff --git a/ui/src/tracks/screenshots/index.ts b/ui/src/tracks/screenshots/index.ts
index cc85c16..5ca8efb 100644
--- a/ui/src/tracks/screenshots/index.ts
+++ b/ui/src/tracks/screenshots/index.ts
@@ -12,8 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {v4 as uuidv4} from 'uuid';
-
import {AddTrackArgs} from '../../common/actions';
import {Engine} from '../../common/engine';
import {
@@ -23,6 +21,7 @@
import {
Plugin,
PluginContext,
+ PluginContextTrace,
PluginDescriptor,
PrimaryTrackSortKey,
} from '../../public';
@@ -36,8 +35,6 @@
ScreenshotTab,
} from './screenshot_panel';
-export {Data} from '../chrome_slices';
-
class ScreenshotsTrack extends CustomSqlTableSliceTrack<NamedSliceTrackTypes> {
static readonly kind = 'dev.perfetto.ScreenshotsTrack';
static create(args: NewTrackArgs): TrackBase {
@@ -66,6 +63,7 @@
tracksToAdd: AddTrackArgs[],
};
+// TODO(stevegolton): Use suggestTrack().
export async function decideTracks(engine: Engine):
Promise<DecideTracksResult> {
const result: DecideTracksResult = {
@@ -75,20 +73,28 @@
await engine.query(`INCLUDE PERFETTO MODULE android.screenshots`);
result.tracksToAdd.push({
- id: uuidv4(),
- engineId: engine.id,
- kind: ScreenshotsTrack.kind,
- trackSortKey: PrimaryTrackSortKey.ASYNC_SLICE_TRACK,
+ uri: 'perfetto.Screenshots',
name: 'Screenshots',
- config: {},
- trackGroup: undefined,
+ trackSortKey: PrimaryTrackSortKey.ASYNC_SLICE_TRACK,
});
return result;
}
class ScreenshotsPlugin implements Plugin {
- onActivate(ctx: PluginContext): void {
- ctx.LEGACY_registerTrack(ScreenshotsTrack);
+ onActivate(_ctx: PluginContext): void {}
+
+ async onTraceLoad(ctx: PluginContextTrace): Promise<void> {
+ ctx.registerStaticTrack({
+ uri: 'perfetto.Screenshots',
+ displayName: 'Screenshots',
+ kind: ScreenshotsTrack.kind,
+ track: ({trackKey}) => {
+ return new ScreenshotsTrack({
+ engine: ctx.engine,
+ trackKey,
+ });
+ },
+ });
}
}
diff --git a/ui/src/tracks/thread_state/index.ts b/ui/src/tracks/thread_state/index.ts
index 807f8f9..e6bbc84 100644
--- a/ui/src/tracks/thread_state/index.ts
+++ b/ui/src/tracks/thread_state/index.ts
@@ -21,17 +21,31 @@
import {colorForState} from '../../common/colorizer';
import {LONG, NUM, NUM_NULL, STR_NULL} from '../../common/query_result';
import {translateState} from '../../common/thread_state';
+import {
+ TrackAdapter,
+ TrackControllerAdapter,
+ TrackWithControllerAdapter,
+} from '../../common/track_adapter';
import {TrackData} from '../../common/track_data';
-import {TrackController} from '../../controller/track_controller';
import {checkerboardExcept} from '../../frontend/checkerboard';
import {globals} from '../../frontend/globals';
-import {NewTrackArgs, TrackBase} from '../../frontend/track';
-import {Plugin, PluginContext, PluginDescriptor} from '../../public';
+import {NewTrackArgs} from '../../frontend/track';
+import {
+ Plugin,
+ PluginContext,
+ PluginContextTrace,
+ PluginDescriptor,
+} from '../../public';
+import {getTrackName} from '../../public/utils';
+import {
+ ThreadStateTrack as ThreadStateTrackV2,
+} from './thread_state_v2';
export const THREAD_STATE_TRACK_KIND = 'ThreadStateTrack';
+export const THREAD_STATE_TRACK_V2_KIND = 'ThreadStateTrackV2';
-export interface Data extends TrackData {
+interface Data extends TrackData {
strings: string[];
ids: Float64Array;
starts: BigInt64Array;
@@ -40,13 +54,11 @@
state: Uint16Array; // Index into |strings|.
}
-export interface Config {
+interface Config {
utid: number;
}
-class ThreadStateTrackController extends TrackController<Config, Data> {
- static readonly kind = THREAD_STATE_TRACK_KIND;
-
+class ThreadStateTrackController extends TrackControllerAdapter<Config, Data> {
private maxDurNs: duration = 0n;
async onSetup() {
@@ -162,8 +174,7 @@
const RECT_HEIGHT = 12;
const EXCESS_WIDTH = 10;
-class ThreadStateTrack extends TrackBase<Config, Data> {
- static readonly kind = THREAD_STATE_TRACK_KIND;
+class ThreadStateTrack extends TrackAdapter<Config, Data> {
static create(args: NewTrackArgs): ThreadStateTrack {
return new ThreadStateTrack(args);
}
@@ -278,15 +289,76 @@
if (index === -1) return false;
const id = data.ids[index];
globals.makeSelection(
- Actions.selectThreadState({id, trackId: this.trackState.id}));
+ Actions.selectThreadState({id, trackKey: this.trackKey}));
return true;
}
}
+
class ThreadState implements Plugin {
- onActivate(ctx: PluginContext): void {
- ctx.LEGACY_registerTrack(ThreadStateTrack);
- ctx.LEGACY_registerTrackController(ThreadStateTrackController);
+ onActivate(_ctx: PluginContext): void {}
+
+ async onTraceLoad(ctx: PluginContextTrace): Promise<void> {
+ const {engine} = ctx;
+ const result = await engine.query(`
+ select
+ utid,
+ upid,
+ tid,
+ pid,
+ thread.name as threadName
+ from
+ thread_state
+ left join thread using(utid)
+ left join process using(upid)
+ where utid != 0
+ group by utid`);
+
+ const it = result.iter({
+ utid: NUM,
+ upid: NUM_NULL,
+ tid: NUM_NULL,
+ pid: NUM_NULL,
+ threadName: STR_NULL,
+ });
+ for (; it.valid(); it.next()) {
+ const utid = it.utid;
+ const upid = it.upid;
+ const tid = it.tid;
+ const threadName = it.threadName;
+ const displayName =
+ getTrackName({utid, tid, threadName, kind: THREAD_STATE_TRACK_KIND});
+
+ ctx.registerStaticTrack({
+ uri: `perfetto.ThreadState#${upid}.${utid}`,
+ displayName,
+ kind: THREAD_STATE_TRACK_KIND,
+ utid: utid,
+ track: ({trackKey}) => {
+ return new TrackWithControllerAdapter<Config, Data>(
+ ctx.engine,
+ trackKey,
+ {utid},
+ ThreadStateTrack,
+ ThreadStateTrackController);
+ },
+ });
+
+ ctx.registerStaticTrack({
+ uri: `perfetto.ThreadState#${utid}.v2`,
+ displayName,
+ kind: THREAD_STATE_TRACK_V2_KIND,
+ utid,
+ track: ({trackKey}) => {
+ const track = ThreadStateTrackV2.create({
+ engine: ctx.engine,
+ trackKey,
+ });
+ track.config = {utid};
+ return track;
+ },
+ });
+ }
}
}
diff --git a/ui/src/tracks/thread_state_v2/index.ts b/ui/src/tracks/thread_state/thread_state_track_v2.ts
similarity index 82%
copy from ui/src/tracks/thread_state_v2/index.ts
copy to ui/src/tracks/thread_state/thread_state_track_v2.ts
index 9c465b6..e84505d 100644
--- a/ui/src/tracks/thread_state_v2/index.ts
+++ b/ui/src/tracks/thread_state/thread_state_track_v2.ts
@@ -1,4 +1,4 @@
-// Copyright (C) 2023 The Android Open Source Project
+// Copyright (C) 2021 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.
@@ -29,15 +29,14 @@
SliceLayout,
} from '../../frontend/slice_layout';
import {NewTrackArgs} from '../../frontend/track';
-import {Plugin, PluginContext, PluginDescriptor} from '../../public';
export const THREAD_STATE_ROW = {
...BASE_SLICE_ROW,
state: STR,
ioWait: NUM_NULL,
};
-export type ThreadStateRow = typeof THREAD_STATE_ROW;
+export type ThreadStateRow = typeof THREAD_STATE_ROW;
export interface ThreadStateTrackConfig {
utid: number;
@@ -48,10 +47,7 @@
config: ThreadStateTrackConfig;
}
-export const THREAD_STATE_TRACK_V2_KIND = 'ThreadStateTrackV2';
-
export class ThreadStateTrack extends BaseSliceTrack<ThreadStateTrackTypes> {
- static readonly kind = THREAD_STATE_TRACK_V2_KIND;
static create(args: NewTrackArgs) {
return new ThreadStateTrack(args);
}
@@ -67,10 +63,9 @@
return THREAD_STATE_ROW;
}
- async initSqlTable(tableName: string): Promise<void> {
+ getSqlSource(): string {
// Do not display states 'x' and 'S' (dead & sleeping).
const sql = `
- create view ${tableName} as
select
id,
ts,
@@ -85,7 +80,7 @@
state != 'x' and
state != 'S'
`;
- await this.engine.query(sql);
+ return sql;
}
rowToSlice(row: ThreadStateTrackTypes['row']):
@@ -115,7 +110,7 @@
onSliceClick(args: OnSliceClickArgs<ThreadStateTrackTypes['slice']>) {
globals.makeSelection(Actions.selectThreadState({
id: args.slice.id,
- trackId: this.trackId,
+ trackKey: this.trackKey,
}));
}
@@ -123,14 +118,3 @@
return selection.kind === 'THREAD_STATE';
}
}
-
-class ThreadStateTrackV2 implements Plugin {
- onActivate(ctx: PluginContext): void {
- ctx.LEGACY_registerTrack(ThreadStateTrack);
- }
-}
-
-export const plugin: PluginDescriptor = {
- pluginId: 'perfetto.ThreadStateTrackV2',
- plugin: ThreadStateTrackV2,
-};
diff --git a/ui/src/tracks/thread_state_v2/index.ts b/ui/src/tracks/thread_state/thread_state_v2.ts
similarity index 85%
rename from ui/src/tracks/thread_state_v2/index.ts
rename to ui/src/tracks/thread_state/thread_state_v2.ts
index 9c465b6..d5e0fa5 100644
--- a/ui/src/tracks/thread_state_v2/index.ts
+++ b/ui/src/tracks/thread_state/thread_state_v2.ts
@@ -29,7 +29,6 @@
SliceLayout,
} from '../../frontend/slice_layout';
import {NewTrackArgs} from '../../frontend/track';
-import {Plugin, PluginContext, PluginDescriptor} from '../../public';
export const THREAD_STATE_ROW = {
...BASE_SLICE_ROW,
@@ -51,7 +50,6 @@
export const THREAD_STATE_TRACK_V2_KIND = 'ThreadStateTrackV2';
export class ThreadStateTrack extends BaseSliceTrack<ThreadStateTrackTypes> {
- static readonly kind = THREAD_STATE_TRACK_V2_KIND;
static create(args: NewTrackArgs) {
return new ThreadStateTrack(args);
}
@@ -67,10 +65,9 @@
return THREAD_STATE_ROW;
}
- async initSqlTable(tableName: string): Promise<void> {
+ getSqlSource(): string {
// Do not display states 'x' and 'S' (dead & sleeping).
- const sql = `
- create view ${tableName} as
+ return `
select
id,
ts,
@@ -85,7 +82,6 @@
state != 'x' and
state != 'S'
`;
- await this.engine.query(sql);
}
rowToSlice(row: ThreadStateTrackTypes['row']):
@@ -115,7 +111,7 @@
onSliceClick(args: OnSliceClickArgs<ThreadStateTrackTypes['slice']>) {
globals.makeSelection(Actions.selectThreadState({
id: args.slice.id,
- trackId: this.trackId,
+ trackKey: this.trackKey,
}));
}
@@ -123,14 +119,3 @@
return selection.kind === 'THREAD_STATE';
}
}
-
-class ThreadStateTrackV2 implements Plugin {
- onActivate(ctx: PluginContext): void {
- ctx.LEGACY_registerTrack(ThreadStateTrack);
- }
-}
-
-export const plugin: PluginDescriptor = {
- pluginId: 'perfetto.ThreadStateTrackV2',
- plugin: ThreadStateTrackV2,
-};
diff --git a/ui/src/tracks/visualised_args/index.ts b/ui/src/tracks/visualised_args/index.ts
index 3385bf9..0111078 100644
--- a/ui/src/tracks/visualised_args/index.ts
+++ b/ui/src/tracks/visualised_args/index.ts
@@ -12,63 +12,121 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+// import {NewTrackArgs, Track} from '../../frontend/track';
+// import {TrackButton, TrackButtonAttrs} from '../../frontend/track_panel';
import m from 'mithril';
+import {v4 as uuidv4} from 'uuid';
import {Actions} from '../../common/actions';
import {globals} from '../../frontend/globals';
-import {NewTrackArgs, TrackBase} from '../../frontend/track';
-import {TrackButton, TrackButtonAttrs} from '../../frontend/track_panel';
-import {Plugin, PluginContext, PluginDescriptor} from '../../public';
+import {TrackButton} from '../../frontend/track_panel';
import {
- ChromeSliceTrack,
- ChromeSliceTrackController,
- Config as ChromeSliceConfig,
-} from '../chrome_slices';
+ EngineProxy,
+ Plugin,
+ PluginContext,
+ PluginContextTrace,
+ PluginDescriptor,
+ TrackContext,
+} from '../../public';
+import {ChromeSliceTrack} from '../chrome_slices';
-export {Data} from '../chrome_slices';
+export const VISUALISED_ARGS_SLICE_TRACK_URI = 'perfetto.VisualisedArgs';
-export const VISUALISED_ARGS_SLICE_TRACK_KIND = 'VisualisedArgsTrack';
-
-export interface Config extends ChromeSliceConfig {
+export interface VisualisedArgsState {
argName: string;
-}
-
-// The controller for arg visualisation is exactly the same as the controller
-// for Chrome slices. All customisation is done on the frontend.
-class VisualisedArgsTrackController extends ChromeSliceTrackController {
- static readonly kind = VISUALISED_ARGS_SLICE_TRACK_KIND;
+ maxDepth: number;
+ trackId: number;
}
export class VisualisedArgsTrack extends ChromeSliceTrack {
- static readonly kind = VISUALISED_ARGS_SLICE_TRACK_KIND;
- static create(args: NewTrackArgs): TrackBase {
- return new VisualisedArgsTrack(args);
+ private helperViewName: string;
+
+ constructor(
+ engine: EngineProxy, maxDepth: number, trackKey: string, trackId: number,
+ private argName: string) {
+ const uuid = uuidv4();
+ const namespace = `__arg_visualisation_helper_${argName}_${uuid}`;
+ const escapedNamespace = namespace.replace(/[^a-zA-Z]/g, '_');
+ super(engine, maxDepth, trackKey, trackId, escapedNamespace);
+ this.helperViewName = `${escapedNamespace}_slice`;
+ }
+
+ async onCreate(_ctx: TrackContext): Promise<void> {
+ // Create the helper view - just one which is relevant to this slice
+ await this.engine.query(`
+ create view ${this.helperViewName} as
+ with slice_with_arg as (
+ select
+ slice.id,
+ slice.track_id,
+ slice.ts,
+ slice.dur,
+ slice.thread_dur,
+ NULL as cat,
+ args.display_value as name
+ from slice
+ join args using (arg_set_id)
+ where args.key='${this.argName}'
+ )
+ select
+ *,
+ (select count()
+ from ancestor_slice(s1.id) s2
+ join slice_with_arg s3 on s2.id=s3.id
+ ) as depth
+ from slice_with_arg s1
+ order by id;
+ `);
+ }
+
+ async onDestroy(): Promise<void> {
+ this.engine.query(`drop view ${this.helperViewName}`);
}
getFont() {
return 'italic 11px Roboto';
}
- getTrackShellButtons(): Array<m.Vnode<TrackButtonAttrs>> {
- const config = this.config as Config;
- const buttons: Array<m.Vnode<TrackButtonAttrs>> = [];
- buttons.push(m(TrackButton, {
+ getTrackShellButtons(): m.Children {
+ return m(TrackButton, {
action: () => {
- globals.dispatch(
- Actions.removeVisualisedArg({argName: config.argName}));
+ // This behavior differs to the original behavior a little.
+ // Originally, hitting the close button on a single track removed ALL
+ // tracks with this argName, whereas this one only closes the single
+ // track.
+ // This will be easily fixable once we transition to using dynamic
+ // tracks instead of this "initial state" approach to add these tracks.
+ globals.dispatch(Actions.removeTracks({trackKeys: [this.trackKey]}));
},
i: 'close',
tooltip: 'Close',
showButton: true,
- }));
- return buttons;
+ });
}
}
class VisualisedArgsPlugin implements Plugin {
- onActivate(ctx: PluginContext): void {
- ctx.LEGACY_registerTrackController(VisualisedArgsTrackController);
- ctx.LEGACY_registerTrack(VisualisedArgsTrack);
+ onActivate(_ctx: PluginContext): void {}
+
+ async onTraceLoad(ctx: PluginContextTrace): Promise<void> {
+ ctx.registerTrack({
+ uri: VISUALISED_ARGS_SLICE_TRACK_URI,
+ tags: {
+ metric: true, // TODO(stevegolton): Is this track really a metric?
+ },
+ track: (trackCtx) => {
+ // TODO(stevegolton): Validate params properly. Note, this is no
+ // worse than the situation we had before with track config.
+ const params = trackCtx.params as VisualisedArgsState;
+ return new VisualisedArgsTrack(
+ ctx.engine,
+ params.maxDepth,
+ trackCtx.trackKey,
+ params.trackId,
+ params.argName,
+ );
+ },
+ });
}
}
diff --git a/ui/src/widgets/editor.ts b/ui/src/widgets/editor.ts
index 3bb02dd..5b26daa 100644
--- a/ui/src/widgets/editor.ts
+++ b/ui/src/widgets/editor.ts
@@ -23,6 +23,10 @@
// Initial state for the editor.
initialText?: string;
+ // Changing generation is used to force resetting of the editor state
+ // to the current value of initialText.
+ generation?: number;
+
// Callback for the Ctrl/Cmd + Enter key binding.
onExecute?: (text: string) => void;
@@ -32,6 +36,7 @@
export class Editor implements m.ClassComponent<EditorAttrs> {
private editorView?: EditorView;
+ private generation?: number;
oncreate({dom, attrs}: m.CVnodeDOM<EditorAttrs>) {
const keymaps = [indentWithTab];
@@ -69,6 +74,8 @@
};
}
+ this.generation = attrs.generation;
+
this.editorView = new EditorView({
doc: attrs.initialText ?? '',
extensions: [
@@ -81,6 +88,17 @@
});
}
+ onupdate({attrs}: m.CVnodeDOM<EditorAttrs>): void {
+ const {initialText, generation} = attrs;
+ const editorView = this.editorView;
+ if (editorView && this.generation !== generation) {
+ const state = editorView.state;
+ editorView.dispatch(state.update(
+ {changes: {from: 0, to: state.doc.length, insert: initialText}}));
+ this.generation = generation;
+ }
+ }
+
onremove(): void {
if (this.editorView) {
this.editorView.destroy();
@@ -89,8 +107,6 @@
}
view({}: m.Vnode<EditorAttrs, this>): void|m.Children {
- return m(
- '.pf-editor',
- );
+ return m('.pf-editor');
}
}
diff --git a/ui/src/widgets/tree.ts b/ui/src/widgets/tree.ts
index e046a35..034bf7c 100644
--- a/ui/src/widgets/tree.ts
+++ b/ui/src/widgets/tree.ts
@@ -59,6 +59,8 @@
// Whether this node is collapsed or not.
// If omitted, collapsed state 'uncontrolled' - i.e. controlled internally.
collapsed?: boolean;
+ // Whether the node should start collapsed or not, default: false.
+ startsCollapsed?: boolean;
loading?: boolean;
showCaret?: boolean;
// Optional icon to show to the left of the text.
@@ -69,7 +71,12 @@
}
export class TreeNode implements m.ClassComponent<TreeNodeAttrs> {
- private collapsed = false;
+ private collapsed;
+
+ constructor({attrs}: m.CVnode<TreeNodeAttrs>) {
+ this.collapsed = attrs.startsCollapsed ?? false;
+ }
+
view(vnode: m.CVnode<TreeNodeAttrs>): m.Children {
const {children, attrs, attrs: {left, onCollapseChanged = () => {}}} =
vnode;