Merge "Fix jank metric - HWC release uses a different fence than GPU completion"
diff --git a/Android.bp b/Android.bp
index eeed817..771b599 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1968,14 +1968,16 @@
         ":perfetto_src_trace_processor_db_db",
         ":perfetto_src_trace_processor_dynamic_dynamic",
         ":perfetto_src_trace_processor_export_json",
-        ":perfetto_src_trace_processor_ftrace_descriptors",
         ":perfetto_src_trace_processor_importers_android_bugreport_android_bugreport",
         ":perfetto_src_trace_processor_importers_common_common",
         ":perfetto_src_trace_processor_importers_common_parser_types",
         ":perfetto_src_trace_processor_importers_common_trace_parser_hdr",
+        ":perfetto_src_trace_processor_importers_ftrace_descriptors",
         ":perfetto_src_trace_processor_importers_fuchsia_fuchsia_record",
-        ":perfetto_src_trace_processor_importers_importers_full",
+        ":perfetto_src_trace_processor_importers_full",
         ":perfetto_src_trace_processor_importers_memory_tracker_graph_processor",
+        ":perfetto_src_trace_processor_importers_minimal",
+        ":perfetto_src_trace_processor_importers_ninja_ninja",
         ":perfetto_src_trace_processor_importers_proto_full",
         ":perfetto_src_trace_processor_importers_proto_minimal",
         ":perfetto_src_trace_processor_importers_proto_packet_sequence_state_generation_hdr",
@@ -9103,14 +9105,6 @@
     ],
 }
 
-// GN: //src/trace_processor:ftrace_descriptors
-filegroup {
-    name: "perfetto_src_trace_processor_ftrace_descriptors",
-    srcs: [
-        "src/trace_processor/importers/ftrace/ftrace_descriptors.cc",
-    ],
-}
-
 // GN: //src/trace_processor:gen_cc_test_messages_descriptor
 genrule {
     name: "perfetto_src_trace_processor_gen_cc_test_messages_descriptor",
@@ -9188,6 +9182,14 @@
     ],
 }
 
+// GN: //src/trace_processor/importers:ftrace_descriptors
+filegroup {
+    name: "perfetto_src_trace_processor_importers_ftrace_descriptors",
+    srcs: [
+        "src/trace_processor/importers/ftrace/ftrace_descriptors.cc",
+    ],
+}
+
 // GN: //src/trace_processor/importers/fuchsia:fuchsia_record
 filegroup {
     name: "perfetto_src_trace_processor_importers_fuchsia_fuchsia_record",
@@ -9196,6 +9198,51 @@
     ],
 }
 
+// GN: //src/trace_processor/importers:full
+filegroup {
+    name: "perfetto_src_trace_processor_importers_full",
+    srcs: [
+        "src/trace_processor/importers/additional_modules.cc",
+        "src/trace_processor/importers/ftrace/binder_tracker.cc",
+        "src/trace_processor/importers/ftrace/drm_tracker.cc",
+        "src/trace_processor/importers/ftrace/ftrace_module_impl.cc",
+        "src/trace_processor/importers/ftrace/ftrace_parser.cc",
+        "src/trace_processor/importers/ftrace/ftrace_tokenizer.cc",
+        "src/trace_processor/importers/ftrace/iostat_tracker.cc",
+        "src/trace_processor/importers/ftrace/rss_stat_tracker.cc",
+        "src/trace_processor/importers/ftrace/sched_event_tracker.cc",
+        "src/trace_processor/importers/ftrace/thread_state_tracker.cc",
+        "src/trace_processor/importers/ftrace/v4l2_tracker.cc",
+        "src/trace_processor/importers/ftrace/virtio_video_tracker.cc",
+        "src/trace_processor/importers/fuchsia/fuchsia_trace_parser.cc",
+        "src/trace_processor/importers/fuchsia/fuchsia_trace_tokenizer.cc",
+        "src/trace_processor/importers/fuchsia/fuchsia_trace_utils.cc",
+        "src/trace_processor/importers/gzip/gzip_trace_parser.cc",
+        "src/trace_processor/importers/i2c/i2c_tracker.cc",
+        "src/trace_processor/importers/json/json_trace_parser.cc",
+        "src/trace_processor/importers/json/json_trace_tokenizer.cc",
+        "src/trace_processor/importers/proto/android_camera_event_module.cc",
+        "src/trace_processor/importers/proto/android_probes_module.cc",
+        "src/trace_processor/importers/proto/android_probes_parser.cc",
+        "src/trace_processor/importers/proto/android_probes_tracker.cc",
+        "src/trace_processor/importers/proto/content_analyzer.cc",
+        "src/trace_processor/importers/proto/frame_timeline_event_parser.cc",
+        "src/trace_processor/importers/proto/gpu_event_parser.cc",
+        "src/trace_processor/importers/proto/graphics_event_module.cc",
+        "src/trace_processor/importers/proto/graphics_frame_event_parser.cc",
+        "src/trace_processor/importers/proto/heap_graph_module.cc",
+        "src/trace_processor/importers/proto/system_probes_module.cc",
+        "src/trace_processor/importers/proto/system_probes_parser.cc",
+        "src/trace_processor/importers/proto/translation_table_module.cc",
+        "src/trace_processor/importers/proto/vulkan_memory_tracker.cc",
+        "src/trace_processor/importers/syscalls/syscall_tracker.cc",
+        "src/trace_processor/importers/systrace/systrace_line_parser.cc",
+        "src/trace_processor/importers/systrace/systrace_line_tokenizer.cc",
+        "src/trace_processor/importers/systrace/systrace_parser.cc",
+        "src/trace_processor/importers/systrace/systrace_trace_parser.cc",
+    ],
+}
+
 // GN: //src/trace_processor/importers:gen_cc_chrome_track_event_descriptor
 genrule {
     name: "perfetto_src_trace_processor_importers_gen_cc_chrome_track_event_descriptor",
@@ -9256,49 +9303,6 @@
     ],
 }
 
-// GN: //src/trace_processor/importers:importers_full
-filegroup {
-    name: "perfetto_src_trace_processor_importers_importers_full",
-    srcs: [
-        "src/trace_processor/importers/additional_modules.cc",
-        "src/trace_processor/importers/ftrace/binder_tracker.cc",
-        "src/trace_processor/importers/ftrace/drm_tracker.cc",
-        "src/trace_processor/importers/ftrace/ftrace_module_impl.cc",
-        "src/trace_processor/importers/ftrace/ftrace_parser.cc",
-        "src/trace_processor/importers/ftrace/ftrace_tokenizer.cc",
-        "src/trace_processor/importers/ftrace/iostat_tracker.cc",
-        "src/trace_processor/importers/ftrace/rss_stat_tracker.cc",
-        "src/trace_processor/importers/ftrace/sched_event_tracker.cc",
-        "src/trace_processor/importers/ftrace/thread_state_tracker.cc",
-        "src/trace_processor/importers/ftrace/v4l2_tracker.cc",
-        "src/trace_processor/importers/ftrace/virtio_video_tracker.cc",
-        "src/trace_processor/importers/fuchsia/fuchsia_trace_parser.cc",
-        "src/trace_processor/importers/fuchsia/fuchsia_trace_tokenizer.cc",
-        "src/trace_processor/importers/fuchsia/fuchsia_trace_utils.cc",
-        "src/trace_processor/importers/gzip/gzip_trace_parser.cc",
-        "src/trace_processor/importers/i2c/i2c_tracker.cc",
-        "src/trace_processor/importers/json/json_trace_parser.cc",
-        "src/trace_processor/importers/json/json_trace_tokenizer.cc",
-        "src/trace_processor/importers/proto/android_probes_module.cc",
-        "src/trace_processor/importers/proto/android_probes_parser.cc",
-        "src/trace_processor/importers/proto/android_probes_tracker.cc",
-        "src/trace_processor/importers/proto/content_analyzer.cc",
-        "src/trace_processor/importers/proto/frame_timeline_event_parser.cc",
-        "src/trace_processor/importers/proto/gpu_event_parser.cc",
-        "src/trace_processor/importers/proto/graphics_event_module.cc",
-        "src/trace_processor/importers/proto/graphics_frame_event_parser.cc",
-        "src/trace_processor/importers/proto/heap_graph_module.cc",
-        "src/trace_processor/importers/proto/system_probes_module.cc",
-        "src/trace_processor/importers/proto/system_probes_parser.cc",
-        "src/trace_processor/importers/proto/vulkan_memory_tracker.cc",
-        "src/trace_processor/importers/syscalls/syscall_tracker.cc",
-        "src/trace_processor/importers/systrace/systrace_line_parser.cc",
-        "src/trace_processor/importers/systrace/systrace_line_tokenizer.cc",
-        "src/trace_processor/importers/systrace/systrace_parser.cc",
-        "src/trace_processor/importers/systrace/systrace_trace_parser.cc",
-    ],
-}
-
 // GN: //src/trace_processor/importers/memory_tracker:graph_processor
 filegroup {
     name: "perfetto_src_trace_processor_importers_memory_tracker_graph_processor",
@@ -9311,6 +9315,40 @@
     ],
 }
 
+// GN: //src/trace_processor/importers:minimal
+filegroup {
+    name: "perfetto_src_trace_processor_importers_minimal",
+    srcs: [
+        "src/trace_processor/importers/default_modules.cc",
+        "src/trace_processor/importers/ftrace/ftrace_module.cc",
+        "src/trace_processor/importers/json/json_utils.cc",
+        "src/trace_processor/importers/proto/chrome_system_probes_module.cc",
+        "src/trace_processor/importers/proto/chrome_system_probes_parser.cc",
+        "src/trace_processor/importers/proto/memory_tracker_snapshot_module.cc",
+        "src/trace_processor/importers/proto/memory_tracker_snapshot_parser.cc",
+        "src/trace_processor/importers/proto/metadata_module.cc",
+        "src/trace_processor/importers/proto/metadata_tracker.cc",
+        "src/trace_processor/importers/proto/perf_sample_tracker.cc",
+        "src/trace_processor/importers/proto/profile_module.cc",
+        "src/trace_processor/importers/proto/profile_packet_utils.cc",
+        "src/trace_processor/importers/proto/proto_trace_parser.cc",
+        "src/trace_processor/importers/proto/proto_trace_reader.cc",
+        "src/trace_processor/importers/proto/proto_trace_tokenizer.cc",
+        "src/trace_processor/importers/proto/track_event_module.cc",
+        "src/trace_processor/importers/proto/track_event_parser.cc",
+        "src/trace_processor/importers/proto/track_event_tokenizer.cc",
+        "src/trace_processor/importers/proto/track_event_tracker.cc",
+    ],
+}
+
+// GN: //src/trace_processor/importers/ninja:ninja
+filegroup {
+    name: "perfetto_src_trace_processor_importers_ninja_ninja",
+    srcs: [
+        "src/trace_processor/importers/ninja/ninja_log_parser.cc",
+    ],
+}
+
 // GN: //src/trace_processor/importers/proto:full
 filegroup {
     name: "perfetto_src_trace_processor_importers_proto_full",
@@ -9370,6 +9408,26 @@
     name: "perfetto_src_trace_processor_importers_systrace_systrace_line",
 }
 
+// GN: //src/trace_processor/importers:unittests
+filegroup {
+    name: "perfetto_src_trace_processor_importers_unittests",
+    srcs: [
+        "src/trace_processor/importers/ftrace/binder_tracker_unittest.cc",
+        "src/trace_processor/importers/ftrace/sched_event_tracker_unittest.cc",
+        "src/trace_processor/importers/ftrace/thread_state_tracker_unittest.cc",
+        "src/trace_processor/importers/fuchsia/fuchsia_parser_unittest.cc",
+        "src/trace_processor/importers/fuchsia/fuchsia_trace_utils_unittest.cc",
+        "src/trace_processor/importers/memory_tracker/graph_processor_unittest.cc",
+        "src/trace_processor/importers/memory_tracker/graph_unittest.cc",
+        "src/trace_processor/importers/memory_tracker/raw_process_memory_node_unittest.cc",
+        "src/trace_processor/importers/proto/async_track_set_tracker_unittest.cc",
+        "src/trace_processor/importers/proto/perf_sample_tracker_unittest.cc",
+        "src/trace_processor/importers/proto/proto_trace_parser_unittest.cc",
+        "src/trace_processor/importers/syscalls/syscall_tracker_unittest.cc",
+        "src/trace_processor/importers/systrace/systrace_parser_unittest.cc",
+    ],
+}
+
 // GN: //src/trace_processor:lib
 filegroup {
     name: "perfetto_src_trace_processor_lib",
@@ -9727,28 +9785,6 @@
     name: "perfetto_src_trace_processor_storage_minimal",
     srcs: [
         "src/trace_processor/forwarding_trace_parser.cc",
-        "src/trace_processor/importers/default_modules.cc",
-        "src/trace_processor/importers/ftrace/ftrace_module.cc",
-        "src/trace_processor/importers/json/json_utils.cc",
-        "src/trace_processor/importers/ninja/ninja_log_parser.cc",
-        "src/trace_processor/importers/proto/android_camera_event_module.cc",
-        "src/trace_processor/importers/proto/chrome_system_probes_module.cc",
-        "src/trace_processor/importers/proto/chrome_system_probes_parser.cc",
-        "src/trace_processor/importers/proto/memory_tracker_snapshot_module.cc",
-        "src/trace_processor/importers/proto/memory_tracker_snapshot_parser.cc",
-        "src/trace_processor/importers/proto/metadata_module.cc",
-        "src/trace_processor/importers/proto/metadata_tracker.cc",
-        "src/trace_processor/importers/proto/perf_sample_tracker.cc",
-        "src/trace_processor/importers/proto/profile_module.cc",
-        "src/trace_processor/importers/proto/profile_packet_utils.cc",
-        "src/trace_processor/importers/proto/proto_trace_parser.cc",
-        "src/trace_processor/importers/proto/proto_trace_reader.cc",
-        "src/trace_processor/importers/proto/proto_trace_tokenizer.cc",
-        "src/trace_processor/importers/proto/track_event_module.cc",
-        "src/trace_processor/importers/proto/track_event_parser.cc",
-        "src/trace_processor/importers/proto/track_event_tokenizer.cc",
-        "src/trace_processor/importers/proto/track_event_tracker.cc",
-        "src/trace_processor/importers/proto/translation_table_module.cc",
         "src/trace_processor/trace_blob.cc",
         "src/trace_processor/trace_processor_context.cc",
         "src/trace_processor/trace_processor_storage.cc",
@@ -9781,6 +9817,15 @@
     ],
 }
 
+// GN: //src/trace_processor:top_level_unittests
+filegroup {
+    name: "perfetto_src_trace_processor_top_level_unittests",
+    srcs: [
+        "src/trace_processor/forwarding_trace_parser_unittest.cc",
+        "src/trace_processor/ref_counted_unittest.cc",
+    ],
+}
+
 // GN: //src/trace_processor/types:types
 filegroup {
     name: "perfetto_src_trace_processor_types_types",
@@ -9803,23 +9848,6 @@
 // GN: //src/trace_processor:unittests
 filegroup {
     name: "perfetto_src_trace_processor_unittests",
-    srcs: [
-        "src/trace_processor/forwarding_trace_parser_unittest.cc",
-        "src/trace_processor/importers/ftrace/binder_tracker_unittest.cc",
-        "src/trace_processor/importers/ftrace/sched_event_tracker_unittest.cc",
-        "src/trace_processor/importers/ftrace/thread_state_tracker_unittest.cc",
-        "src/trace_processor/importers/fuchsia/fuchsia_parser_unittest.cc",
-        "src/trace_processor/importers/fuchsia/fuchsia_trace_utils_unittest.cc",
-        "src/trace_processor/importers/memory_tracker/graph_processor_unittest.cc",
-        "src/trace_processor/importers/memory_tracker/graph_unittest.cc",
-        "src/trace_processor/importers/memory_tracker/raw_process_memory_node_unittest.cc",
-        "src/trace_processor/importers/proto/async_track_set_tracker_unittest.cc",
-        "src/trace_processor/importers/proto/perf_sample_tracker_unittest.cc",
-        "src/trace_processor/importers/proto/proto_trace_parser_unittest.cc",
-        "src/trace_processor/importers/syscalls/syscall_tracker_unittest.cc",
-        "src/trace_processor/importers/systrace/systrace_parser_unittest.cc",
-        "src/trace_processor/ref_counted_unittest.cc",
-    ],
 }
 
 // GN: //src/trace_processor/util:descriptors
@@ -11223,21 +11251,24 @@
         ":perfetto_src_trace_processor_dynamic_dynamic",
         ":perfetto_src_trace_processor_dynamic_unittests",
         ":perfetto_src_trace_processor_export_json",
-        ":perfetto_src_trace_processor_ftrace_descriptors",
         ":perfetto_src_trace_processor_importers_android_bugreport_android_bugreport",
         ":perfetto_src_trace_processor_importers_android_bugreport_unittests",
         ":perfetto_src_trace_processor_importers_common_common",
         ":perfetto_src_trace_processor_importers_common_parser_types",
         ":perfetto_src_trace_processor_importers_common_trace_parser_hdr",
         ":perfetto_src_trace_processor_importers_common_unittests",
+        ":perfetto_src_trace_processor_importers_ftrace_descriptors",
         ":perfetto_src_trace_processor_importers_fuchsia_fuchsia_record",
-        ":perfetto_src_trace_processor_importers_importers_full",
+        ":perfetto_src_trace_processor_importers_full",
         ":perfetto_src_trace_processor_importers_memory_tracker_graph_processor",
+        ":perfetto_src_trace_processor_importers_minimal",
+        ":perfetto_src_trace_processor_importers_ninja_ninja",
         ":perfetto_src_trace_processor_importers_proto_full",
         ":perfetto_src_trace_processor_importers_proto_minimal",
         ":perfetto_src_trace_processor_importers_proto_packet_sequence_state_generation_hdr",
         ":perfetto_src_trace_processor_importers_proto_unittests",
         ":perfetto_src_trace_processor_importers_systrace_systrace_line",
+        ":perfetto_src_trace_processor_importers_unittests",
         ":perfetto_src_trace_processor_lib",
         ":perfetto_src_trace_processor_metatrace",
         ":perfetto_src_trace_processor_metrics_metrics",
@@ -11255,6 +11286,7 @@
         ":perfetto_src_trace_processor_storage_storage",
         ":perfetto_src_trace_processor_tables_tables",
         ":perfetto_src_trace_processor_tables_unittests",
+        ":perfetto_src_trace_processor_top_level_unittests",
         ":perfetto_src_trace_processor_types_types",
         ":perfetto_src_trace_processor_types_unittests",
         ":perfetto_src_trace_processor_unittests",
@@ -11872,14 +11904,16 @@
         ":perfetto_src_trace_processor_db_db",
         ":perfetto_src_trace_processor_dynamic_dynamic",
         ":perfetto_src_trace_processor_export_json",
-        ":perfetto_src_trace_processor_ftrace_descriptors",
         ":perfetto_src_trace_processor_importers_android_bugreport_android_bugreport",
         ":perfetto_src_trace_processor_importers_common_common",
         ":perfetto_src_trace_processor_importers_common_parser_types",
         ":perfetto_src_trace_processor_importers_common_trace_parser_hdr",
+        ":perfetto_src_trace_processor_importers_ftrace_descriptors",
         ":perfetto_src_trace_processor_importers_fuchsia_fuchsia_record",
-        ":perfetto_src_trace_processor_importers_importers_full",
+        ":perfetto_src_trace_processor_importers_full",
         ":perfetto_src_trace_processor_importers_memory_tracker_graph_processor",
+        ":perfetto_src_trace_processor_importers_minimal",
+        ":perfetto_src_trace_processor_importers_ninja_ninja",
         ":perfetto_src_trace_processor_importers_proto_full",
         ":perfetto_src_trace_processor_importers_proto_minimal",
         ":perfetto_src_trace_processor_importers_proto_packet_sequence_state_generation_hdr",
@@ -12070,14 +12104,16 @@
         ":perfetto_src_trace_processor_db_db",
         ":perfetto_src_trace_processor_dynamic_dynamic",
         ":perfetto_src_trace_processor_export_json",
-        ":perfetto_src_trace_processor_ftrace_descriptors",
         ":perfetto_src_trace_processor_importers_android_bugreport_android_bugreport",
         ":perfetto_src_trace_processor_importers_common_common",
         ":perfetto_src_trace_processor_importers_common_parser_types",
         ":perfetto_src_trace_processor_importers_common_trace_parser_hdr",
+        ":perfetto_src_trace_processor_importers_ftrace_descriptors",
         ":perfetto_src_trace_processor_importers_fuchsia_fuchsia_record",
-        ":perfetto_src_trace_processor_importers_importers_full",
+        ":perfetto_src_trace_processor_importers_full",
         ":perfetto_src_trace_processor_importers_memory_tracker_graph_processor",
+        ":perfetto_src_trace_processor_importers_minimal",
+        ":perfetto_src_trace_processor_importers_ninja_ninja",
         ":perfetto_src_trace_processor_importers_proto_full",
         ":perfetto_src_trace_processor_importers_proto_minimal",
         ":perfetto_src_trace_processor_importers_proto_packet_sequence_state_generation_hdr",
diff --git a/BUILD b/BUILD
index 23e2d94..b44ab50 100644
--- a/BUILD
+++ b/BUILD
@@ -1160,6 +1160,15 @@
     ],
 )
 
+# GN target: //src/trace_processor/importers/ninja:ninja
+perfetto_filegroup(
+    name = "src_trace_processor_importers_ninja_ninja",
+    srcs = [
+        "src/trace_processor/importers/ninja/ninja_log_parser.cc",
+        "src/trace_processor/importers/ninja/ninja_log_parser.h",
+    ],
+)
+
 # GN target: //src/trace_processor/importers/proto:full
 perfetto_filegroup(
     name = "src_trace_processor_importers_proto_full",
@@ -1221,6 +1230,97 @@
     ],
 )
 
+# GN target: //src/trace_processor/importers:ftrace_descriptors
+perfetto_filegroup(
+    name = "src_trace_processor_importers_ftrace_descriptors",
+    srcs = [
+        "src/trace_processor/importers/ftrace/ftrace_descriptors.cc",
+        "src/trace_processor/importers/ftrace/ftrace_descriptors.h",
+    ],
+)
+
+# GN target: //src/trace_processor/importers:full
+perfetto_filegroup(
+    name = "src_trace_processor_importers_full",
+    srcs = [
+        "src/trace_processor/importers/additional_modules.cc",
+        "src/trace_processor/importers/additional_modules.h",
+        "src/trace_processor/importers/ftrace/binder_tracker.cc",
+        "src/trace_processor/importers/ftrace/binder_tracker.h",
+        "src/trace_processor/importers/ftrace/drm_tracker.cc",
+        "src/trace_processor/importers/ftrace/drm_tracker.h",
+        "src/trace_processor/importers/ftrace/ftrace_module_impl.cc",
+        "src/trace_processor/importers/ftrace/ftrace_module_impl.h",
+        "src/trace_processor/importers/ftrace/ftrace_parser.cc",
+        "src/trace_processor/importers/ftrace/ftrace_parser.h",
+        "src/trace_processor/importers/ftrace/ftrace_tokenizer.cc",
+        "src/trace_processor/importers/ftrace/ftrace_tokenizer.h",
+        "src/trace_processor/importers/ftrace/iostat_tracker.cc",
+        "src/trace_processor/importers/ftrace/iostat_tracker.h",
+        "src/trace_processor/importers/ftrace/rss_stat_tracker.cc",
+        "src/trace_processor/importers/ftrace/rss_stat_tracker.h",
+        "src/trace_processor/importers/ftrace/sched_event_tracker.cc",
+        "src/trace_processor/importers/ftrace/sched_event_tracker.h",
+        "src/trace_processor/importers/ftrace/thread_state_tracker.cc",
+        "src/trace_processor/importers/ftrace/thread_state_tracker.h",
+        "src/trace_processor/importers/ftrace/v4l2_tracker.cc",
+        "src/trace_processor/importers/ftrace/v4l2_tracker.h",
+        "src/trace_processor/importers/ftrace/virtio_video_tracker.cc",
+        "src/trace_processor/importers/ftrace/virtio_video_tracker.h",
+        "src/trace_processor/importers/fuchsia/fuchsia_trace_parser.cc",
+        "src/trace_processor/importers/fuchsia/fuchsia_trace_parser.h",
+        "src/trace_processor/importers/fuchsia/fuchsia_trace_tokenizer.cc",
+        "src/trace_processor/importers/fuchsia/fuchsia_trace_tokenizer.h",
+        "src/trace_processor/importers/fuchsia/fuchsia_trace_utils.cc",
+        "src/trace_processor/importers/gzip/gzip_trace_parser.cc",
+        "src/trace_processor/importers/gzip/gzip_trace_parser.h",
+        "src/trace_processor/importers/i2c/i2c_tracker.cc",
+        "src/trace_processor/importers/i2c/i2c_tracker.h",
+        "src/trace_processor/importers/json/json_trace_parser.cc",
+        "src/trace_processor/importers/json/json_trace_parser.h",
+        "src/trace_processor/importers/json/json_trace_tokenizer.cc",
+        "src/trace_processor/importers/json/json_trace_tokenizer.h",
+        "src/trace_processor/importers/proto/android_camera_event_module.cc",
+        "src/trace_processor/importers/proto/android_camera_event_module.h",
+        "src/trace_processor/importers/proto/android_probes_module.cc",
+        "src/trace_processor/importers/proto/android_probes_module.h",
+        "src/trace_processor/importers/proto/android_probes_parser.cc",
+        "src/trace_processor/importers/proto/android_probes_parser.h",
+        "src/trace_processor/importers/proto/android_probes_tracker.cc",
+        "src/trace_processor/importers/proto/android_probes_tracker.h",
+        "src/trace_processor/importers/proto/content_analyzer.cc",
+        "src/trace_processor/importers/proto/content_analyzer.h",
+        "src/trace_processor/importers/proto/frame_timeline_event_parser.cc",
+        "src/trace_processor/importers/proto/frame_timeline_event_parser.h",
+        "src/trace_processor/importers/proto/gpu_event_parser.cc",
+        "src/trace_processor/importers/proto/gpu_event_parser.h",
+        "src/trace_processor/importers/proto/graphics_event_module.cc",
+        "src/trace_processor/importers/proto/graphics_event_module.h",
+        "src/trace_processor/importers/proto/graphics_frame_event_parser.cc",
+        "src/trace_processor/importers/proto/graphics_frame_event_parser.h",
+        "src/trace_processor/importers/proto/heap_graph_module.cc",
+        "src/trace_processor/importers/proto/heap_graph_module.h",
+        "src/trace_processor/importers/proto/system_probes_module.cc",
+        "src/trace_processor/importers/proto/system_probes_module.h",
+        "src/trace_processor/importers/proto/system_probes_parser.cc",
+        "src/trace_processor/importers/proto/system_probes_parser.h",
+        "src/trace_processor/importers/proto/translation_table_module.cc",
+        "src/trace_processor/importers/proto/translation_table_module.h",
+        "src/trace_processor/importers/proto/vulkan_memory_tracker.cc",
+        "src/trace_processor/importers/proto/vulkan_memory_tracker.h",
+        "src/trace_processor/importers/syscalls/syscall_tracker.cc",
+        "src/trace_processor/importers/syscalls/syscall_tracker.h",
+        "src/trace_processor/importers/systrace/systrace_line_parser.cc",
+        "src/trace_processor/importers/systrace/systrace_line_parser.h",
+        "src/trace_processor/importers/systrace/systrace_line_tokenizer.cc",
+        "src/trace_processor/importers/systrace/systrace_line_tokenizer.h",
+        "src/trace_processor/importers/systrace/systrace_parser.cc",
+        "src/trace_processor/importers/systrace/systrace_parser.h",
+        "src/trace_processor/importers/systrace/systrace_trace_parser.cc",
+        "src/trace_processor/importers/systrace/systrace_trace_parser.h",
+    ],
+)
+
 # GN target: //src/trace_processor/importers:gen_cc_chrome_track_event_descriptor
 perfetto_cc_proto_descriptor(
     name = "src_trace_processor_importers_gen_cc_chrome_track_event_descriptor",
@@ -1265,80 +1365,50 @@
     ],
 )
 
-# GN target: //src/trace_processor/importers:importers_full
+# GN target: //src/trace_processor/importers:minimal
 perfetto_filegroup(
-    name = "src_trace_processor_importers_importers_full",
+    name = "src_trace_processor_importers_minimal",
     srcs = [
-        "src/trace_processor/importers/additional_modules.cc",
-        "src/trace_processor/importers/additional_modules.h",
-        "src/trace_processor/importers/ftrace/binder_tracker.cc",
-        "src/trace_processor/importers/ftrace/binder_tracker.h",
-        "src/trace_processor/importers/ftrace/drm_tracker.cc",
-        "src/trace_processor/importers/ftrace/drm_tracker.h",
-        "src/trace_processor/importers/ftrace/ftrace_module_impl.cc",
-        "src/trace_processor/importers/ftrace/ftrace_module_impl.h",
-        "src/trace_processor/importers/ftrace/ftrace_parser.cc",
-        "src/trace_processor/importers/ftrace/ftrace_parser.h",
-        "src/trace_processor/importers/ftrace/ftrace_tokenizer.cc",
-        "src/trace_processor/importers/ftrace/ftrace_tokenizer.h",
-        "src/trace_processor/importers/ftrace/iostat_tracker.cc",
-        "src/trace_processor/importers/ftrace/iostat_tracker.h",
-        "src/trace_processor/importers/ftrace/rss_stat_tracker.cc",
-        "src/trace_processor/importers/ftrace/rss_stat_tracker.h",
-        "src/trace_processor/importers/ftrace/sched_event_tracker.cc",
-        "src/trace_processor/importers/ftrace/sched_event_tracker.h",
-        "src/trace_processor/importers/ftrace/thread_state_tracker.cc",
-        "src/trace_processor/importers/ftrace/thread_state_tracker.h",
-        "src/trace_processor/importers/ftrace/v4l2_tracker.cc",
-        "src/trace_processor/importers/ftrace/v4l2_tracker.h",
-        "src/trace_processor/importers/ftrace/virtio_video_tracker.cc",
-        "src/trace_processor/importers/ftrace/virtio_video_tracker.h",
-        "src/trace_processor/importers/fuchsia/fuchsia_trace_parser.cc",
-        "src/trace_processor/importers/fuchsia/fuchsia_trace_parser.h",
-        "src/trace_processor/importers/fuchsia/fuchsia_trace_tokenizer.cc",
-        "src/trace_processor/importers/fuchsia/fuchsia_trace_tokenizer.h",
-        "src/trace_processor/importers/fuchsia/fuchsia_trace_utils.cc",
-        "src/trace_processor/importers/gzip/gzip_trace_parser.cc",
-        "src/trace_processor/importers/gzip/gzip_trace_parser.h",
-        "src/trace_processor/importers/i2c/i2c_tracker.cc",
-        "src/trace_processor/importers/i2c/i2c_tracker.h",
-        "src/trace_processor/importers/json/json_trace_parser.cc",
-        "src/trace_processor/importers/json/json_trace_parser.h",
-        "src/trace_processor/importers/json/json_trace_tokenizer.cc",
-        "src/trace_processor/importers/json/json_trace_tokenizer.h",
-        "src/trace_processor/importers/proto/android_probes_module.cc",
-        "src/trace_processor/importers/proto/android_probes_module.h",
-        "src/trace_processor/importers/proto/android_probes_parser.cc",
-        "src/trace_processor/importers/proto/android_probes_parser.h",
-        "src/trace_processor/importers/proto/android_probes_tracker.cc",
-        "src/trace_processor/importers/proto/android_probes_tracker.h",
-        "src/trace_processor/importers/proto/content_analyzer.cc",
-        "src/trace_processor/importers/proto/content_analyzer.h",
-        "src/trace_processor/importers/proto/frame_timeline_event_parser.cc",
-        "src/trace_processor/importers/proto/frame_timeline_event_parser.h",
-        "src/trace_processor/importers/proto/gpu_event_parser.cc",
-        "src/trace_processor/importers/proto/gpu_event_parser.h",
-        "src/trace_processor/importers/proto/graphics_event_module.cc",
-        "src/trace_processor/importers/proto/graphics_event_module.h",
-        "src/trace_processor/importers/proto/graphics_frame_event_parser.cc",
-        "src/trace_processor/importers/proto/graphics_frame_event_parser.h",
-        "src/trace_processor/importers/proto/heap_graph_module.cc",
-        "src/trace_processor/importers/proto/heap_graph_module.h",
-        "src/trace_processor/importers/proto/system_probes_module.cc",
-        "src/trace_processor/importers/proto/system_probes_module.h",
-        "src/trace_processor/importers/proto/system_probes_parser.cc",
-        "src/trace_processor/importers/proto/system_probes_parser.h",
-        "src/trace_processor/importers/proto/vulkan_memory_tracker.cc",
-        "src/trace_processor/importers/proto/vulkan_memory_tracker.h",
-        "src/trace_processor/importers/syscalls/syscall_tracker.cc",
-        "src/trace_processor/importers/systrace/systrace_line_parser.cc",
-        "src/trace_processor/importers/systrace/systrace_line_parser.h",
-        "src/trace_processor/importers/systrace/systrace_line_tokenizer.cc",
-        "src/trace_processor/importers/systrace/systrace_line_tokenizer.h",
-        "src/trace_processor/importers/systrace/systrace_parser.cc",
-        "src/trace_processor/importers/systrace/systrace_parser.h",
-        "src/trace_processor/importers/systrace/systrace_trace_parser.cc",
-        "src/trace_processor/importers/systrace/systrace_trace_parser.h",
+        "src/trace_processor/importers/default_modules.cc",
+        "src/trace_processor/importers/default_modules.h",
+        "src/trace_processor/importers/ftrace/ftrace_module.cc",
+        "src/trace_processor/importers/ftrace/ftrace_module.h",
+        "src/trace_processor/importers/fuchsia/fuchsia_trace_utils.h",
+        "src/trace_processor/importers/json/json_utils.cc",
+        "src/trace_processor/importers/json/json_utils.h",
+        "src/trace_processor/importers/proto/chrome_system_probes_module.cc",
+        "src/trace_processor/importers/proto/chrome_system_probes_module.h",
+        "src/trace_processor/importers/proto/chrome_system_probes_parser.cc",
+        "src/trace_processor/importers/proto/chrome_system_probes_parser.h",
+        "src/trace_processor/importers/proto/memory_tracker_snapshot_module.cc",
+        "src/trace_processor/importers/proto/memory_tracker_snapshot_module.h",
+        "src/trace_processor/importers/proto/memory_tracker_snapshot_parser.cc",
+        "src/trace_processor/importers/proto/memory_tracker_snapshot_parser.h",
+        "src/trace_processor/importers/proto/metadata_module.cc",
+        "src/trace_processor/importers/proto/metadata_module.h",
+        "src/trace_processor/importers/proto/metadata_tracker.cc",
+        "src/trace_processor/importers/proto/metadata_tracker.h",
+        "src/trace_processor/importers/proto/perf_sample_tracker.cc",
+        "src/trace_processor/importers/proto/perf_sample_tracker.h",
+        "src/trace_processor/importers/proto/profile_module.cc",
+        "src/trace_processor/importers/proto/profile_module.h",
+        "src/trace_processor/importers/proto/profile_packet_utils.cc",
+        "src/trace_processor/importers/proto/profile_packet_utils.h",
+        "src/trace_processor/importers/proto/proto_incremental_state.h",
+        "src/trace_processor/importers/proto/proto_trace_parser.cc",
+        "src/trace_processor/importers/proto/proto_trace_parser.h",
+        "src/trace_processor/importers/proto/proto_trace_reader.cc",
+        "src/trace_processor/importers/proto/proto_trace_reader.h",
+        "src/trace_processor/importers/proto/proto_trace_tokenizer.cc",
+        "src/trace_processor/importers/proto/proto_trace_tokenizer.h",
+        "src/trace_processor/importers/proto/track_event_module.cc",
+        "src/trace_processor/importers/proto/track_event_module.h",
+        "src/trace_processor/importers/proto/track_event_parser.cc",
+        "src/trace_processor/importers/proto/track_event_parser.h",
+        "src/trace_processor/importers/proto/track_event_tokenizer.cc",
+        "src/trace_processor/importers/proto/track_event_tokenizer.h",
+        "src/trace_processor/importers/proto/track_event_tracker.cc",
+        "src/trace_processor/importers/proto/track_event_tracker.h",
     ],
 )
 
@@ -1917,15 +1987,6 @@
     ],
 )
 
-# GN target: //src/trace_processor:ftrace_descriptors
-perfetto_filegroup(
-    name = "src_trace_processor_ftrace_descriptors",
-    srcs = [
-        "src/trace_processor/importers/ftrace/ftrace_descriptors.cc",
-        "src/trace_processor/importers/ftrace/ftrace_descriptors.h",
-    ],
-)
-
 # GN target: //src/trace_processor:lib
 perfetto_filegroup(
     name = "src_trace_processor_lib",
@@ -1956,53 +2017,6 @@
     srcs = [
         "src/trace_processor/forwarding_trace_parser.cc",
         "src/trace_processor/forwarding_trace_parser.h",
-        "src/trace_processor/importers/default_modules.cc",
-        "src/trace_processor/importers/default_modules.h",
-        "src/trace_processor/importers/ftrace/ftrace_module.cc",
-        "src/trace_processor/importers/ftrace/ftrace_module.h",
-        "src/trace_processor/importers/fuchsia/fuchsia_trace_utils.h",
-        "src/trace_processor/importers/json/json_utils.cc",
-        "src/trace_processor/importers/json/json_utils.h",
-        "src/trace_processor/importers/ninja/ninja_log_parser.cc",
-        "src/trace_processor/importers/ninja/ninja_log_parser.h",
-        "src/trace_processor/importers/proto/android_camera_event_module.cc",
-        "src/trace_processor/importers/proto/android_camera_event_module.h",
-        "src/trace_processor/importers/proto/chrome_system_probes_module.cc",
-        "src/trace_processor/importers/proto/chrome_system_probes_module.h",
-        "src/trace_processor/importers/proto/chrome_system_probes_parser.cc",
-        "src/trace_processor/importers/proto/chrome_system_probes_parser.h",
-        "src/trace_processor/importers/proto/memory_tracker_snapshot_module.cc",
-        "src/trace_processor/importers/proto/memory_tracker_snapshot_module.h",
-        "src/trace_processor/importers/proto/memory_tracker_snapshot_parser.cc",
-        "src/trace_processor/importers/proto/memory_tracker_snapshot_parser.h",
-        "src/trace_processor/importers/proto/metadata_module.cc",
-        "src/trace_processor/importers/proto/metadata_module.h",
-        "src/trace_processor/importers/proto/metadata_tracker.cc",
-        "src/trace_processor/importers/proto/metadata_tracker.h",
-        "src/trace_processor/importers/proto/perf_sample_tracker.cc",
-        "src/trace_processor/importers/proto/perf_sample_tracker.h",
-        "src/trace_processor/importers/proto/profile_module.cc",
-        "src/trace_processor/importers/proto/profile_module.h",
-        "src/trace_processor/importers/proto/profile_packet_utils.cc",
-        "src/trace_processor/importers/proto/profile_packet_utils.h",
-        "src/trace_processor/importers/proto/proto_incremental_state.h",
-        "src/trace_processor/importers/proto/proto_trace_parser.cc",
-        "src/trace_processor/importers/proto/proto_trace_parser.h",
-        "src/trace_processor/importers/proto/proto_trace_reader.cc",
-        "src/trace_processor/importers/proto/proto_trace_reader.h",
-        "src/trace_processor/importers/proto/proto_trace_tokenizer.cc",
-        "src/trace_processor/importers/proto/proto_trace_tokenizer.h",
-        "src/trace_processor/importers/proto/track_event_module.cc",
-        "src/trace_processor/importers/proto/track_event_module.h",
-        "src/trace_processor/importers/proto/track_event_parser.cc",
-        "src/trace_processor/importers/proto/track_event_parser.h",
-        "src/trace_processor/importers/proto/track_event_tokenizer.cc",
-        "src/trace_processor/importers/proto/track_event_tokenizer.h",
-        "src/trace_processor/importers/proto/track_event_tracker.cc",
-        "src/trace_processor/importers/proto/track_event_tracker.h",
-        "src/trace_processor/importers/proto/translation_table_module.cc",
-        "src/trace_processor/importers/proto/translation_table_module.h",
-        "src/trace_processor/importers/syscalls/syscall_tracker.h",
         "src/trace_processor/trace_blob.cc",
         "src/trace_processor/trace_processor_context.cc",
         "src/trace_processor/trace_processor_storage.cc",
@@ -4388,14 +4402,16 @@
         ":src_trace_processor_db_db",
         ":src_trace_processor_dynamic_dynamic",
         ":src_trace_processor_export_json",
-        ":src_trace_processor_ftrace_descriptors",
         ":src_trace_processor_importers_android_bugreport_android_bugreport",
         ":src_trace_processor_importers_common_common",
         ":src_trace_processor_importers_common_parser_types",
         ":src_trace_processor_importers_common_trace_parser_hdr",
+        ":src_trace_processor_importers_ftrace_descriptors",
         ":src_trace_processor_importers_fuchsia_fuchsia_record",
-        ":src_trace_processor_importers_importers_full",
+        ":src_trace_processor_importers_full",
         ":src_trace_processor_importers_memory_tracker_graph_processor",
+        ":src_trace_processor_importers_minimal",
+        ":src_trace_processor_importers_ninja_ninja",
         ":src_trace_processor_importers_proto_full",
         ":src_trace_processor_importers_proto_minimal",
         ":src_trace_processor_importers_proto_packet_sequence_state_generation_hdr",
@@ -4522,14 +4538,16 @@
         ":src_trace_processor_db_db",
         ":src_trace_processor_dynamic_dynamic",
         ":src_trace_processor_export_json",
-        ":src_trace_processor_ftrace_descriptors",
         ":src_trace_processor_importers_android_bugreport_android_bugreport",
         ":src_trace_processor_importers_common_common",
         ":src_trace_processor_importers_common_parser_types",
         ":src_trace_processor_importers_common_trace_parser_hdr",
+        ":src_trace_processor_importers_ftrace_descriptors",
         ":src_trace_processor_importers_fuchsia_fuchsia_record",
-        ":src_trace_processor_importers_importers_full",
+        ":src_trace_processor_importers_full",
         ":src_trace_processor_importers_memory_tracker_graph_processor",
+        ":src_trace_processor_importers_minimal",
+        ":src_trace_processor_importers_ninja_ninja",
         ":src_trace_processor_importers_proto_full",
         ":src_trace_processor_importers_proto_minimal",
         ":src_trace_processor_importers_proto_packet_sequence_state_generation_hdr",
@@ -4715,14 +4733,16 @@
         ":src_trace_processor_db_db",
         ":src_trace_processor_dynamic_dynamic",
         ":src_trace_processor_export_json",
-        ":src_trace_processor_ftrace_descriptors",
         ":src_trace_processor_importers_android_bugreport_android_bugreport",
         ":src_trace_processor_importers_common_common",
         ":src_trace_processor_importers_common_parser_types",
         ":src_trace_processor_importers_common_trace_parser_hdr",
+        ":src_trace_processor_importers_ftrace_descriptors",
         ":src_trace_processor_importers_fuchsia_fuchsia_record",
-        ":src_trace_processor_importers_importers_full",
+        ":src_trace_processor_importers_full",
         ":src_trace_processor_importers_memory_tracker_graph_processor",
+        ":src_trace_processor_importers_minimal",
+        ":src_trace_processor_importers_ninja_ninja",
         ":src_trace_processor_importers_proto_full",
         ":src_trace_processor_importers_proto_minimal",
         ":src_trace_processor_importers_proto_packet_sequence_state_generation_hdr",
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index 7fb79c0..528f2df 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -275,7 +275,7 @@
 
   def file_filter(x):
     return input_api.FilterSourceFile(
-        x, files_to_check=['src/trace_processor/stdlib/.*[.]sql&', tool])
+        x, files_to_check=['src/trace_processor/stdlib/.*[.]sql$', tool])
 
   if not input_api.AffectedSourceFiles(file_filter):
     return []
diff --git a/docs/concepts/config.md b/docs/concepts/config.md
index 33e94b7..c4326e6 100644
--- a/docs/concepts/config.md
+++ b/docs/concepts/config.md
@@ -94,13 +94,13 @@
 owned by the tracing service. It looks as follows:
 
 ```protobuf
-// Buffer #0
+# Buffer #0
 buffers {
   size_kb: 4096
   fill_policy: RING_BUFFER
 }
 
-// Buffer #1
+# Buffer #1
 buffers {
   size_kb: 8192
   fill_policy: DISCARD
@@ -160,7 +160,7 @@
 data_sources {
   config {
     name: "linux.ftrace"
-    target_buffer: 0       // <-- This goes into buffer 0.
+    target_buffer: 0       # <-- This goes into buffer 0.
     ftrace_config { ... }
   }
 }
@@ -168,7 +168,7 @@
 data_sources: {
   config {
       name: "linux.sys_stats"
-      target_buffer: 1     // <-- This goes into buffer 1.
+      target_buffer: 1     # <-- This goes into buffer 1.
       sys_stats_config { ... }
   }
 }
@@ -176,7 +176,7 @@
 data_sources: {
   config {
     name: "android.heapprofd"
-    target_buffer: 1       // <-- This goes into buffer 1 as well.
+    target_buffer: 1       # <-- This goes into buffer 1 as well.
     heapprofd_config { ... }
   }
 }
diff --git a/docs/data-sources/cpu-freq.md b/docs/data-sources/cpu-freq.md
index 5f67b24..7185c74 100644
--- a/docs/data-sources/cpu-freq.md
+++ b/docs/data-sources/cpu-freq.md
@@ -121,7 +121,7 @@
 ### TraceConfig
 
 ```protobuf
-// Event-driven recording of frequency and idle state changes.
+# Event-driven recording of frequency and idle state changes.
 data_sources: {
     config {
         name: "linux.ftrace"
@@ -133,7 +133,7 @@
     }
 }
 
-// Polling the current cpu frequency.
+# Polling the current cpu frequency.
 data_sources: {
     config {
         name: "linux.sys_stats"
@@ -143,7 +143,7 @@
     }
 }
 
-// Reporting the list of available frequency for each CPU.
+# Reporting the list of available frequency for each CPU.
 data_sources {
     config {
         name: "linux.system_info"
diff --git a/src/base/unix_socket_unittest.cc b/src/base/unix_socket_unittest.cc
index a803fa8..c902033 100644
--- a/src/base/unix_socket_unittest.cc
+++ b/src/base/unix_socket_unittest.cc
@@ -430,7 +430,8 @@
   // Try listening on a random port. Some ports might be taken by other syste
   // services. Do a bunch of attempts on different ports before giving up.
   do {
-    sprintf(host_and_port, "127.0.0.1:%d", 10000 + (rand() % 10000));
+    base::SprintfTrunc(host_and_port, sizeof(host_and_port), "127.0.0.1:%d",
+                       10000 + (rand() % 10000));
     srv = UnixSocket::Listen(host_and_port, &event_listener_, &task_runner_,
                              SockFamily::kInet, SockType::kStream);
   } while ((!srv || !srv->is_listening()) && attempt++ < 10);
diff --git a/src/kallsyms/kernel_symbol_map_unittest.cc b/src/kallsyms/kernel_symbol_map_unittest.cc
index 9cecdda..b0ac1d4 100644
--- a/src/kallsyms/kernel_symbol_map_unittest.cc
+++ b/src/kallsyms/kernel_symbol_map_unittest.cc
@@ -21,6 +21,7 @@
 #include <unordered_map>
 
 #include "perfetto/ext/base/file_utils.h"
+#include "perfetto/ext/base/string_utils.h"
 #include "perfetto/ext/base/string_view.h"
 #include "perfetto/ext/base/temp_file.h"
 
@@ -143,10 +144,9 @@
     for (size_t i = 0; i < sym_name_len; i++)
       sym_name[i] = kCharset[rng() % strlen(kCharset)];
     sym_name[sym_name_len] = '\0';
-    char line[kNameMax + 40];
-    sprintf(line, "%" PRIx64 " t %s\n", addr, sym_name);
+    base::StackString<128> line("%" PRIx64 " t %s\n", addr, sym_name);
     symbols[addr] = sym_name;
-    fake_kallsyms += line;
+    fake_kallsyms += line.ToStdString();
   }
   base::TempFile tmp = base::TempFile::Create();
   base::WriteAll(tmp.fd(), fake_kallsyms.data(), fake_kallsyms.size());
diff --git a/src/perfetto_cmd/perfetto_cmd_android.cc b/src/perfetto_cmd/perfetto_cmd_android.cc
index c1fa07b..b03493f 100644
--- a/src/perfetto_cmd/perfetto_cmd_android.cc
+++ b/src/perfetto_cmd/perfetto_cmd_android.cc
@@ -118,13 +118,13 @@
 // errors.
 void PerfettoCmd::SaveOutputToIncidentTraceOrCrash() {
   LogUploadEvent(PerfettoStatsdAtom::kUploadIncidentBegin);
-  char kIncidentTracePath[256];
-  sprintf(kIncidentTracePath, "%s/incident-trace", kStateDir);
+  base::StackString<256> kIncidentTracePath("%s/incident-trace", kStateDir);
 
-  char kTempIncidentTracePath[256];
-  sprintf(kTempIncidentTracePath, "%s.temp", kIncidentTracePath);
+  base::StackString<256> kTempIncidentTracePath("%s.temp",
+                                                kIncidentTracePath.c_str());
 
-  PERFETTO_CHECK(unlink(kTempIncidentTracePath) == 0 || errno == ENOENT);
+  PERFETTO_CHECK(unlink(kTempIncidentTracePath.c_str()) == 0 ||
+                 errno == ENOENT);
 
   // TODO(b/155024256) These should not be necessary (we flush when destroying
   // packet writer and sendfile should ignore file offset) however they should
@@ -133,8 +133,8 @@
   PERFETTO_CHECK(fseek(*trace_out_stream_, 0, SEEK_SET) == 0);
 
   // SELinux constrains the set of readers.
-  base::ScopedFile staging_fd =
-      base::OpenFile(kTempIncidentTracePath, O_CREAT | O_EXCL | O_RDWR, 0666);
+  base::ScopedFile staging_fd = base::OpenFile(kTempIncidentTracePath.c_str(),
+                                               O_CREAT | O_EXCL | O_RDWR, 0666);
   PERFETTO_CHECK(staging_fd);
 
   int fd = fileno(*trace_out_stream_);
@@ -169,7 +169,8 @@
   }
 
   staging_fd.reset();
-  PERFETTO_CHECK(rename(kTempIncidentTracePath, kIncidentTracePath) == 0);
+  PERFETTO_CHECK(
+      rename(kTempIncidentTracePath.c_str(), kIncidentTracePath.c_str()) == 0);
   // Note: not calling fsync(2), as we're not interested in the file being
   // consistent in case of a crash.
   LogUploadEvent(PerfettoStatsdAtom::kUploadIncidentSuccess);
diff --git a/src/profiling/symbolizer/local_symbolizer.cc b/src/profiling/symbolizer/local_symbolizer.cc
index 1fe4dbd..e37cee7 100644
--- a/src/profiling/symbolizer/local_symbolizer.cc
+++ b/src/profiling/symbolizer/local_symbolizer.cc
@@ -475,9 +475,9 @@
     const std::string& binary,
     uint64_t address) {
   std::vector<SymbolizedFrame> result;
-  char buffer[1024];
-  int size = sprintf(buffer, "\"%s\" 0x%" PRIx64 "\n", binary.c_str(), address);
-  if (subprocess_.Write(buffer, static_cast<size_t>(size)) < 0) {
+  base::StackString<1024> buffer("\"%s\" 0x%" PRIx64 "\n", binary.c_str(),
+                                 address);
+  if (subprocess_.Write(buffer.c_str(), buffer.len()) < 0) {
     PERFETTO_ELOG("Failed to write to llvm-symbolizer.");
     return result;
   }
diff --git a/src/protozero/filtering/filter_util.cc b/src/protozero/filtering/filter_util.cc
index 01a0bb4..209ea95 100644
--- a/src/protozero/filtering/filter_util.cc
+++ b/src/protozero/filtering/filter_util.cc
@@ -85,8 +85,7 @@
 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
   // If the path is absolute, maps "C:/" -> "C:/" (without hardcoding 'C').
   if (proto_file.size() > 3 && proto_file[1] == ':') {
-    char win_drive[4];
-    sprintf(win_drive, "%c:/", proto_file[0]);
+    char win_drive[4]{proto_file[0], ':', '/', '\0'};
     dst.MapPath(win_drive, win_drive);
   }
 #endif
diff --git a/src/trace_processor/BUILD.gn b/src/trace_processor/BUILD.gn
index 12d484a..c605029 100644
--- a/src/trace_processor/BUILD.gn
+++ b/src/trace_processor/BUILD.gn
@@ -80,69 +80,10 @@
   }
 }
 
-source_set("ftrace_descriptors") {
-  sources = [
-    "importers/ftrace/ftrace_descriptors.cc",
-    "importers/ftrace/ftrace_descriptors.h",
-  ]
-  deps = [
-    "../../gn:default_deps",
-    "../../include/perfetto/ext/base:base",
-    "../protozero",
-  ]
-}
-
 source_set("storage_minimal") {
   sources = [
     "forwarding_trace_parser.cc",
     "forwarding_trace_parser.h",
-    "importers/default_modules.cc",
-    "importers/default_modules.h",
-    "importers/ftrace/ftrace_module.cc",
-    "importers/ftrace/ftrace_module.h",
-    "importers/fuchsia/fuchsia_trace_utils.h",
-    "importers/json/json_utils.cc",
-    "importers/json/json_utils.h",
-    "importers/ninja/ninja_log_parser.cc",
-    "importers/ninja/ninja_log_parser.h",
-    "importers/proto/android_camera_event_module.cc",
-    "importers/proto/android_camera_event_module.h",
-    "importers/proto/chrome_system_probes_module.cc",
-    "importers/proto/chrome_system_probes_module.h",
-    "importers/proto/chrome_system_probes_parser.cc",
-    "importers/proto/chrome_system_probes_parser.h",
-    "importers/proto/memory_tracker_snapshot_module.cc",
-    "importers/proto/memory_tracker_snapshot_module.h",
-    "importers/proto/memory_tracker_snapshot_parser.cc",
-    "importers/proto/memory_tracker_snapshot_parser.h",
-    "importers/proto/metadata_module.cc",
-    "importers/proto/metadata_module.h",
-    "importers/proto/metadata_tracker.cc",
-    "importers/proto/metadata_tracker.h",
-    "importers/proto/perf_sample_tracker.cc",
-    "importers/proto/perf_sample_tracker.h",
-    "importers/proto/profile_module.cc",
-    "importers/proto/profile_module.h",
-    "importers/proto/profile_packet_utils.cc",
-    "importers/proto/profile_packet_utils.h",
-    "importers/proto/proto_incremental_state.h",
-    "importers/proto/proto_trace_parser.cc",
-    "importers/proto/proto_trace_parser.h",
-    "importers/proto/proto_trace_reader.cc",
-    "importers/proto/proto_trace_reader.h",
-    "importers/proto/proto_trace_tokenizer.cc",
-    "importers/proto/proto_trace_tokenizer.h",
-    "importers/proto/track_event_module.cc",
-    "importers/proto/track_event_module.h",
-    "importers/proto/track_event_parser.cc",
-    "importers/proto/track_event_parser.h",
-    "importers/proto/track_event_tokenizer.cc",
-    "importers/proto/track_event_tokenizer.h",
-    "importers/proto/track_event_tracker.cc",
-    "importers/proto/track_event_tracker.h",
-    "importers/proto/translation_table_module.cc",
-    "importers/proto/translation_table_module.h",
-    "importers/syscalls/syscall_tracker.h",
     "trace_blob.cc",
     "trace_processor_context.cc",
     "trace_processor_storage.cc",
@@ -157,6 +98,7 @@
     "containers",
     "importers:gen_cc_chrome_track_event_descriptor",
     "importers:gen_cc_track_event_descriptor",
+    "importers:minimal",
     "importers/common",
     "importers/common:parser_types",
     "importers/fuchsia:fuchsia_record",
@@ -167,7 +109,6 @@
     "storage",
     "tables",
     "types",
-    "util",
     "util:descriptors",
     "util:gzip",
     "util:proto_to_args_parser",
@@ -176,21 +117,6 @@
   ]
   public_deps = [
     "../../include/perfetto/trace_processor:storage",
-    "../../protos/perfetto/common:zero",
-    "../../protos/perfetto/config:zero",
-    "../../protos/perfetto/trace:zero",
-    "../../protos/perfetto/trace/android:zero",
-    "../../protos/perfetto/trace/chrome:zero",
-    "../../protos/perfetto/trace/ftrace:zero",
-    "../../protos/perfetto/trace/interned_data:zero",
-    "../../protos/perfetto/trace/perfetto:zero",
-    "../../protos/perfetto/trace/power:zero",
-    "../../protos/perfetto/trace/profiling:zero",
-    "../../protos/perfetto/trace/ps:zero",
-    "../../protos/perfetto/trace/sys_stats:zero",
-    "../../protos/perfetto/trace/system_info:zero",
-    "../../protos/perfetto/trace/track_event:zero",
-    "../../protos/perfetto/trace/translation:zero",
     "../../src/kernel_utils:syscall_table",
   ]
 
@@ -209,6 +135,7 @@
     ":storage_minimal",
     "../../gn:default_deps",
     "../base",
+    "importers:minimal",
     "storage",
     "types",
   ]
@@ -234,14 +161,18 @@
     deps = [
       ":metatrace",
       "../../gn:default_deps",
-      "../../protos/perfetto/trace/ftrace:zero",
+      "../../protos/perfetto/common:zero",
+      "../../protos/perfetto/trace:zero",
+      "../../protos/perfetto/trace/perfetto:zero",
       "../base",
       "../protozero",
       "db",
       "dynamic",
-      "importers:importers_full",
+      "importers:full",
+      "importers:minimal",
       "importers/android_bugreport",
       "importers/common",
+      "importers/ninja",
       "metrics",
       "sqlite",
       "sqlite/functions",
@@ -301,98 +232,64 @@
   }
 }  # if (enable_perfetto_trace_processor_sqlite)
 
-perfetto_unittest_source_set("unittests") {
+perfetto_unittest_source_set("top_level_unittests") {
   testonly = true
+
   sources = [
     "forwarding_trace_parser_unittest.cc",
-    "importers/ftrace/binder_tracker_unittest.cc",
-    "importers/ftrace/sched_event_tracker_unittest.cc",
-    "importers/ftrace/thread_state_tracker_unittest.cc",
-    "importers/fuchsia/fuchsia_parser_unittest.cc",
-    "importers/fuchsia/fuchsia_trace_utils_unittest.cc",
-    "importers/memory_tracker/graph_processor_unittest.cc",
-    "importers/memory_tracker/graph_unittest.cc",
-    "importers/memory_tracker/raw_process_memory_node_unittest.cc",
-    "importers/proto/async_track_set_tracker_unittest.cc",
-    "importers/proto/perf_sample_tracker_unittest.cc",
-    "importers/proto/proto_trace_parser_unittest.cc",
-    "importers/syscalls/syscall_tracker_unittest.cc",
-    "importers/systrace/systrace_parser_unittest.cc",
     "ref_counted_unittest.cc",
   ]
   deps = [
-    ":gen_cc_test_messages_descriptor",
+    ":storage_minimal",
     "../../gn:default_deps",
     "../../gn:gtest_and_gmock",
-    "../../protos/perfetto/common:cpp",
-    "../../protos/perfetto/common:zero",
-    "../../protos/perfetto/trace:cpp",
-    "../../protos/perfetto/trace:minimal_zero",
-    "../../protos/perfetto/trace:zero",
-    "../../protos/perfetto/trace/android:zero",
-    "../../protos/perfetto/trace/chrome:zero",
-    "../../protos/perfetto/trace/ftrace:zero",
-    "../../protos/perfetto/trace/gpu:zero",
-    "../../protos/perfetto/trace/interned_data:zero",
-    "../../protos/perfetto/trace/profiling:cpp",
-    "../../protos/perfetto/trace/ps:zero",
-    "../../protos/perfetto/trace/sys_stats:zero",
-    "../../protos/perfetto/trace/track_event:zero",
-    "../base",
-    "../protozero",
-    "../protozero:testing_messages_zero",
-    "containers",
+    "../../include/perfetto/trace_processor",
+  ]
+
+  if (enable_perfetto_trace_processor_json && !is_win) {
+    # export_json_unittest.cc uses base::TempFile, which is not supported on
+    # windows.
+    sources += [ "export_json_unittest.cc" ]
+    deps += [
+      ":export_json",
+      "../../gn:jsoncpp",
+      "containers",
+      "importers:minimal",
+      "importers/common",
+      "storage",
+      "types",
+    ]
+  }
+}
+
+perfetto_unittest_source_set("unittests") {
+  testonly = true
+
+  # Do not add sources to this target: use top_level_unittests
+  # instead. This us really just a grouping
+  deps = [
+    ":top_level_unittests",
     "containers:unittests",
     "db:unittests",
-    "dynamic",
-    "importers:importers_full",
+    "importers:unittests",
     "importers/android_bugreport:unittests",
-    "importers/common",
-    "importers/common:parser_types",
     "importers/common:unittests",
-    "importers/memory_tracker:graph_processor",
-    "importers/proto:minimal",
     "importers/proto:unittests",
     "rpc:unittests",
-    "sorter",
     "sorter:unittests",
     "sqlite/functions:unittests",
-    "storage",
     "tables:unittests",
-    "types",
     "types:unittests",
     "util:descriptors",
     "util:unittests",
-    "views",
     "views:unittests",
   ]
-
   if (enable_perfetto_trace_processor_sqlite) {
     deps += [
-      ":lib",
-      "../../gn:sqlite",
       "dynamic:unittests",
       "sqlite:unittests",
     ]
   }
-
-  if (enable_perfetto_trace_processor_json) {
-    sources += [
-      "importers/json/json_trace_tokenizer_unittest.cc",
-      "importers/json/json_utils_unittest.cc",
-    ]
-    deps += [ "../../gn:jsoncpp" ]
-
-    if (!is_win) {
-      # export_json_unittest.cc uses base::TempFile, which is not supported on
-      # windows.
-      sources += [ "export_json_unittest.cc" ]
-      deps += [
-        ":export_json",
-        "../../include/perfetto/ext/trace_processor:export_json",
-      ]
-    }
-  }
 }
 
 perfetto_cc_proto_descriptor("gen_cc_test_messages_descriptor") {
@@ -448,6 +345,6 @@
   deps = [
     "../../gn:default_deps",
     "../base",
-    "importers:importers_full",
+    "importers:full",
   ]
 }
diff --git a/src/trace_processor/db/table.cc b/src/trace_processor/db/table.cc
index c582789..4346377 100644
--- a/src/trace_processor/db/table.cc
+++ b/src/trace_processor/db/table.cc
@@ -37,14 +37,14 @@
 }
 
 Table Table::Copy() const {
-  Table table = CopyExceptRowMaps();
+  Table table = CopyExceptOverlays();
   for (const ColumnStorageOverlay& overlay : overlays_) {
     table.overlays_.emplace_back(overlay.Copy());
   }
   return table;
 }
 
-Table Table::CopyExceptRowMaps() const {
+Table Table::CopyExceptOverlays() const {
   Table table(string_pool_);
   table.row_count_ = row_count_;
   for (const Column& col : columns_) {
@@ -113,7 +113,7 @@
 
   // Return a copy of this table with the RowMaps using the computed ordered
   // RowMap.
-  Table table = CopyExceptRowMaps();
+  Table table = CopyExceptOverlays();
   RowMap rm(std::move(idx));
   for (const ColumnStorageOverlay& overlay : overlays_) {
     table.overlays_.emplace_back(overlay.SelectRows(rm));
diff --git a/src/trace_processor/db/table.h b/src/trace_processor/db/table.h
index af697a6..21962bf 100644
--- a/src/trace_processor/db/table.h
+++ b/src/trace_processor/db/table.h
@@ -127,7 +127,7 @@
   // Note: the RowMap should not reorder this table; this is guaranteed if the
   // passed RowMap is generated using |FilterToRowMap|.
   Table Apply(RowMap rm) const {
-    Table table = CopyExceptRowMaps();
+    Table table = CopyExceptOverlays();
     table.row_count_ = rm.size();
     table.overlays_.reserve(overlays_.size());
     for (const ColumnStorageOverlay& map : overlays_) {
@@ -227,7 +227,7 @@
   friend class Column;
   friend class View;
 
-  Table CopyExceptRowMaps() const;
+  Table CopyExceptOverlays() const;
 };
 
 }  // namespace trace_processor
diff --git a/src/trace_processor/forwarding_trace_parser.cc b/src/trace_processor/forwarding_trace_parser.cc
index d8ce547..0cccce2 100644
--- a/src/trace_processor/forwarding_trace_parser.cc
+++ b/src/trace_processor/forwarding_trace_parser.cc
@@ -19,7 +19,6 @@
 #include "perfetto/base/logging.h"
 #include "perfetto/ext/base/string_utils.h"
 #include "src/trace_processor/importers/common/process_tracker.h"
-#include "src/trace_processor/importers/ninja/ninja_log_parser.h"
 #include "src/trace_processor/importers/proto/proto_trace_parser.h"
 #include "src/trace_processor/importers/proto/proto_trace_reader.h"
 #include "src/trace_processor/sorter/trace_sorter.h"
@@ -101,8 +100,11 @@
       }
       case kNinjaLogTraceType: {
         PERFETTO_DLOG("Ninja log detected");
-        reader_.reset(new NinjaLogParser(context_));
-        break;
+        if (context_->ninja_log_parser) {
+          reader_ = std::move(context_->ninja_log_parser);
+          break;
+        }
+        return util::ErrStatus("Ninja support is disabled");
       }
       case kFuchsiaTraceType: {
         PERFETTO_DLOG("Fuchsia trace detected");
diff --git a/src/trace_processor/importers/BUILD.gn b/src/trace_processor/importers/BUILD.gn
index e03a203..1374bf1 100644
--- a/src/trace_processor/importers/BUILD.gn
+++ b/src/trace_processor/importers/BUILD.gn
@@ -13,8 +13,90 @@
 # limitations under the License.
 
 import("../../../gn/perfetto_cc_proto_descriptor.gni")
+import("../../../gn/test.gni")
 
-source_set("importers_full") {
+source_set("minimal") {
+  sources = [
+    "default_modules.cc",
+    "default_modules.h",
+    "ftrace/ftrace_module.cc",
+    "ftrace/ftrace_module.h",
+    "fuchsia/fuchsia_trace_utils.h",
+    "json/json_utils.cc",
+    "json/json_utils.h",
+    "proto/chrome_system_probes_module.cc",
+    "proto/chrome_system_probes_module.h",
+    "proto/chrome_system_probes_parser.cc",
+    "proto/chrome_system_probes_parser.h",
+    "proto/memory_tracker_snapshot_module.cc",
+    "proto/memory_tracker_snapshot_module.h",
+    "proto/memory_tracker_snapshot_parser.cc",
+    "proto/memory_tracker_snapshot_parser.h",
+    "proto/metadata_module.cc",
+    "proto/metadata_module.h",
+    "proto/metadata_tracker.cc",
+    "proto/metadata_tracker.h",
+    "proto/perf_sample_tracker.cc",
+    "proto/perf_sample_tracker.h",
+    "proto/profile_module.cc",
+    "proto/profile_module.h",
+    "proto/profile_packet_utils.cc",
+    "proto/profile_packet_utils.h",
+    "proto/proto_incremental_state.h",
+    "proto/proto_trace_parser.cc",
+    "proto/proto_trace_parser.h",
+    "proto/proto_trace_reader.cc",
+    "proto/proto_trace_reader.h",
+    "proto/proto_trace_tokenizer.cc",
+    "proto/proto_trace_tokenizer.h",
+    "proto/track_event_module.cc",
+    "proto/track_event_module.h",
+    "proto/track_event_parser.cc",
+    "proto/track_event_parser.h",
+    "proto/track_event_tokenizer.cc",
+    "proto/track_event_tokenizer.h",
+    "proto/track_event_tracker.cc",
+    "proto/track_event_tracker.h",
+  ]
+  deps = [
+    "../../../gn:default_deps",
+    "../../../protos/perfetto/common:zero",
+    "../../../protos/perfetto/config:zero",
+    "../../../protos/perfetto/trace:zero",
+    "../../../protos/perfetto/trace/android:zero",
+    "../../../protos/perfetto/trace/chrome:zero",
+    "../../../protos/perfetto/trace/ftrace:zero",
+    "../../../protos/perfetto/trace/interned_data:zero",
+    "../../../protos/perfetto/trace/perfetto:zero",
+    "../../../protos/perfetto/trace/power:zero",
+    "../../../protos/perfetto/trace/profiling:zero",
+    "../../../protos/perfetto/trace/ps:zero",
+    "../../../protos/perfetto/trace/sys_stats:zero",
+    "../../../protos/perfetto/trace/system_info:zero",
+    "../../../protos/perfetto/trace/track_event:zero",
+    "../../../protos/perfetto/trace/translation:zero",
+    "../../protozero",
+    "../containers",
+    "../sorter",
+    "../storage",
+    "../tables",
+    "../types",
+    "../util",
+    "../util:gzip",
+    "../util:proto_to_args_parser",
+    "../util:stack_traces_util",
+    "common",
+    "common:parser_types",
+    "fuchsia:fuchsia_record",
+    "memory_tracker:graph_processor",
+    "proto:minimal",
+  ]
+  if (enable_perfetto_trace_processor_json) {
+    deps += [ "../../../gn:jsoncpp" ]
+  }
+}
+
+source_set("full") {
   sources = [
     "additional_modules.cc",
     "additional_modules.h",
@@ -53,6 +135,8 @@
     "json/json_trace_parser.h",
     "json/json_trace_tokenizer.cc",
     "json/json_trace_tokenizer.h",
+    "proto/android_camera_event_module.cc",
+    "proto/android_camera_event_module.h",
     "proto/android_probes_module.cc",
     "proto/android_probes_module.h",
     "proto/android_probes_parser.cc",
@@ -75,9 +159,12 @@
     "proto/system_probes_module.h",
     "proto/system_probes_parser.cc",
     "proto/system_probes_parser.h",
+    "proto/translation_table_module.cc",
+    "proto/translation_table_module.h",
     "proto/vulkan_memory_tracker.cc",
     "proto/vulkan_memory_tracker.h",
     "syscalls/syscall_tracker.cc",
+    "syscalls/syscall_tracker.h",
     "systrace/systrace_line_parser.cc",
     "systrace/systrace_line_parser.h",
     "systrace/systrace_line_tokenizer.cc",
@@ -89,16 +176,27 @@
   ]
   public_deps = [ "../:storage_minimal" ]
   deps = [
+    ":ftrace_descriptors",
     ":gen_cc_trace_descriptor",
-    "../:ftrace_descriptors",
+    ":minimal",
+    "../../../gn:default_deps",
     "../../../include/perfetto/ext/base:base",
     "../../../include/perfetto/ext/traced:sys_stats_counters",
     "../../../protos/perfetto/common:zero",
+    "../../../protos/perfetto/config:zero",
     "../../../protos/perfetto/trace:zero",
     "../../../protos/perfetto/trace/android:zero",
+    "../../../protos/perfetto/trace/ftrace:zero",
     "../../../protos/perfetto/trace/gpu:zero",
     "../../../protos/perfetto/trace/interned_data:zero",
+    "../../../protos/perfetto/trace/power:zero",
+    "../../../protos/perfetto/trace/profiling:zero",
+    "../../../protos/perfetto/trace/ps:zero",
+    "../../../protos/perfetto/trace/sys_stats:zero",
+    "../../../protos/perfetto/trace/system_info:zero",
+    "../../../protos/perfetto/trace/translation:zero",
     "../../protozero",
+    "../containers",
     "../sorter",
     "../storage",
     "../tables",
@@ -120,6 +218,18 @@
   }
 }
 
+source_set("ftrace_descriptors") {
+  sources = [
+    "ftrace/ftrace_descriptors.cc",
+    "ftrace/ftrace_descriptors.h",
+  ]
+  deps = [
+    "../../../gn:default_deps",
+    "../../../include/perfetto/ext/base:base",
+    "../../protozero",
+  ]
+}
+
 perfetto_cc_proto_descriptor("gen_cc_config_descriptor") {
   descriptor_name = "config.descriptor"
   descriptor_target = "../../../protos/perfetto/config:descriptor"
@@ -139,3 +249,65 @@
   descriptor_name = "trace.descriptor"
   descriptor_target = "../../../protos/perfetto/trace:descriptor"
 }
+
+perfetto_unittest_source_set("unittests") {
+  testonly = true
+  sources = [
+    "ftrace/binder_tracker_unittest.cc",
+    "ftrace/sched_event_tracker_unittest.cc",
+    "ftrace/thread_state_tracker_unittest.cc",
+    "fuchsia/fuchsia_parser_unittest.cc",
+    "fuchsia/fuchsia_trace_utils_unittest.cc",
+    "memory_tracker/graph_processor_unittest.cc",
+    "memory_tracker/graph_unittest.cc",
+    "memory_tracker/raw_process_memory_node_unittest.cc",
+    "proto/async_track_set_tracker_unittest.cc",
+    "proto/perf_sample_tracker_unittest.cc",
+    "proto/proto_trace_parser_unittest.cc",
+    "syscalls/syscall_tracker_unittest.cc",
+    "systrace/systrace_parser_unittest.cc",
+  ]
+  deps = [
+    ":full",
+    ":minimal",
+    "..:gen_cc_test_messages_descriptor",
+    "../../../gn:default_deps",
+    "../../../gn:gtest_and_gmock",
+    "../../../protos/perfetto/common:cpp",
+    "../../../protos/perfetto/common:zero",
+    "../../../protos/perfetto/config:zero",
+    "../../../protos/perfetto/trace:cpp",
+    "../../../protos/perfetto/trace:minimal_zero",
+    "../../../protos/perfetto/trace:zero",
+    "../../../protos/perfetto/trace/android:zero",
+    "../../../protos/perfetto/trace/chrome:zero",
+    "../../../protos/perfetto/trace/ftrace:zero",
+    "../../../protos/perfetto/trace/gpu:zero",
+    "../../../protos/perfetto/trace/interned_data:zero",
+    "../../../protos/perfetto/trace/profiling:cpp",
+    "../../../protos/perfetto/trace/profiling:zero",
+    "../../../protos/perfetto/trace/ps:zero",
+    "../../../protos/perfetto/trace/sys_stats:zero",
+    "../../../protos/perfetto/trace/track_event:zero",
+    "../../base",
+    "../../protozero",
+    "../../protozero:testing_messages_zero",
+    "../sorter",
+    "../storage",
+    "../types",
+    "../util",
+    "../util:descriptors",
+    "../util:proto_to_args_parser",
+    "common",
+    "memory_tracker:graph_processor",
+    "proto:minimal",
+  ]
+
+  if (enable_perfetto_trace_processor_json) {
+    sources += [
+      "json/json_trace_tokenizer_unittest.cc",
+      "json/json_utils_unittest.cc",
+    ]
+    deps += [ "../../../gn:jsoncpp" ]
+  }
+}
diff --git a/src/trace_processor/importers/additional_modules.cc b/src/trace_processor/importers/additional_modules.cc
index b531a22..825cf21 100644
--- a/src/trace_processor/importers/additional_modules.cc
+++ b/src/trace_processor/importers/additional_modules.cc
@@ -16,6 +16,7 @@
 
 #include "src/trace_processor/importers/additional_modules.h"
 #include "src/trace_processor/importers/ftrace/ftrace_module_impl.h"
+#include "src/trace_processor/importers/proto/android_camera_event_module.h"
 #include "src/trace_processor/importers/proto/android_probes_module.h"
 #include "src/trace_processor/importers/proto/content_analyzer.h"
 #include "src/trace_processor/importers/proto/graphics_event_module.h"
@@ -34,6 +35,8 @@
   context->modules.emplace_back(new SystemProbesModule(context));
   context->modules.emplace_back(new TranslationTableModule(context));
   context->modules.emplace_back(new StatsdModule(context));
+  context->modules.emplace_back(new AndroidCameraEventModule(context));
+
   if (context->config.analyze_trace_proto_content) {
     context->modules.emplace_back(new ContentAnalyzerModule(context));
   }
diff --git a/src/trace_processor/importers/default_modules.cc b/src/trace_processor/importers/default_modules.cc
index 51c73cd..5fbc40c 100644
--- a/src/trace_processor/importers/default_modules.cc
+++ b/src/trace_processor/importers/default_modules.cc
@@ -16,7 +16,6 @@
 
 #include "src/trace_processor/importers/default_modules.h"
 #include "src/trace_processor/importers/ftrace/ftrace_module.h"
-#include "src/trace_processor/importers/proto/android_camera_event_module.h"
 #include "src/trace_processor/importers/proto/chrome_system_probes_module.h"
 #include "src/trace_processor/importers/proto/memory_tracker_snapshot_module.h"
 #include "src/trace_processor/importers/proto/metadata_module.h"
@@ -41,7 +40,6 @@
   context->modules.emplace_back(new ChromeSystemProbesModule(context));
   context->modules.emplace_back(new ProfileModule(context));
   context->modules.emplace_back(new MetadataModule(context));
-  context->modules.emplace_back(new AndroidCameraEventModule(context));
 }
 
 }  // namespace trace_processor
diff --git a/src/trace_processor/importers/ftrace/ftrace_parser.cc b/src/trace_processor/importers/ftrace/ftrace_parser.cc
index b890d85..9035823 100644
--- a/src/trace_processor/importers/ftrace/ftrace_parser.cc
+++ b/src/trace_processor/importers/ftrace/ftrace_parser.cc
@@ -17,6 +17,7 @@
 #include "src/trace_processor/importers/ftrace/ftrace_parser.h"
 
 #include "perfetto/base/logging.h"
+#include "perfetto/ext/base/string_utils.h"
 #include "perfetto/ext/base/string_writer.h"
 #include "perfetto/protozero/proto_decoder.h"
 #include "src/trace_processor/importers/common/args_tracker.h"
@@ -1760,9 +1761,8 @@
   TrackId track_id = context_->track_tracker->InternThreadTrack(utid);
   protos::pbzero::ScmCallStartFtraceEvent::Decoder evt(blob.data, blob.size);
 
-  char str[64];
-  sprintf(str, "scm id=%#" PRIx64, evt.x0());
-  StringId name_id = context_->storage->InternString(str);
+  base::StackString<64> str("scm id=%#" PRIx64, evt.x0());
+  StringId name_id = context_->storage->InternString(str.string_view());
   context_->slice_tracker->Begin(timestamp, track_id, kNullStringId, name_id);
 }
 
@@ -2231,9 +2231,9 @@
     skaddr_to_stream_[evt.skaddr()] = ++num_of_tcp_stream_;
   }
   uint32_t stream = skaddr_to_stream_[evt.skaddr()];
-  char stream_str[64];
-  sprintf(stream_str, "TCP stream#%" PRIu32 "", stream);
-  StringId stream_id = context_->storage->InternString(stream_str);
+  base::StackString<64> stream_str("TCP stream#%" PRIu32 "", stream);
+  StringId stream_id =
+      context_->storage->InternString(stream_str.string_view());
 
   StringId slice_name_id;
   if (evt.newstate() == TCP_SYN_SENT) {
diff --git a/src/trace_processor/importers/ninja/BUILD.gn b/src/trace_processor/importers/ninja/BUILD.gn
new file mode 100644
index 0000000..f64cf41
--- /dev/null
+++ b/src/trace_processor/importers/ninja/BUILD.gn
@@ -0,0 +1,26 @@
+# 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.
+
+source_set("ninja") {
+  sources = [
+    "ninja_log_parser.cc",
+    "ninja_log_parser.h",
+  ]
+  deps = [
+    "../../../../gn:default_deps",
+    "../../importers/common",
+    "../../sorter",
+    "../../storage",
+  ]
+}
diff --git a/src/trace_processor/importers/proto/proto_trace_parser.cc b/src/trace_processor/importers/proto/proto_trace_parser.cc
index ec6d2a7..0503cfa 100644
--- a/src/trace_processor/importers/proto/proto_trace_parser.cc
+++ b/src/trace_processor/importers/proto/proto_trace_parser.cc
@@ -23,6 +23,7 @@
 
 #include "perfetto/base/logging.h"
 #include "perfetto/ext/base/metatrace_events.h"
+#include "perfetto/ext/base/string_utils.h"
 #include "perfetto/ext/base/string_view.h"
 #include "perfetto/ext/base/string_writer.h"
 #include "perfetto/ext/base/uuid.h"
@@ -322,7 +323,6 @@
 
   StringId cat_id = metatrace_id_;
   StringId name_id = kNullStringId;
-  char fallback[64];
 
   for (auto it = event.interned_strings(); it; ++it) {
     protos::pbzero::PerfettoMetatrace::InternedString::Decoder interned_string(
@@ -405,8 +405,8 @@
       if (eid < metatrace::EVENTS_MAX) {
         name_id = context_->storage->InternString(metatrace::kEventNames[eid]);
       } else {
-        sprintf(fallback, "Event %d", eid);
-        name_id = context_->storage->InternString(fallback);
+        base::StackString<64> fallback("Event %d", eid);
+        name_id = context_->storage->InternString(fallback.string_view());
       }
     } else if (event.has_event_name_iid()) {
       name_id = GetMetatraceInternedString(event.event_name_iid());
@@ -424,8 +424,8 @@
         name_id =
             context_->storage->InternString(metatrace::kCounterNames[cid]);
       } else {
-        sprintf(fallback, "Counter %d", cid);
-        name_id = context_->storage->InternString(fallback);
+        base::StackString<64> fallback("Counter %d", cid);
+        name_id = context_->storage->InternString(fallback.string_view());
       }
     } else {
       name_id = context_->storage->InternString(event.counter_name());
diff --git a/src/trace_processor/importers/syscalls/syscall_tracker.cc b/src/trace_processor/importers/syscalls/syscall_tracker.cc
index f092455..37be70e 100644
--- a/src/trace_processor/importers/syscalls/syscall_tracker.cc
+++ b/src/trace_processor/importers/syscalls/syscall_tracker.cc
@@ -20,6 +20,7 @@
 #include <type_traits>
 #include <utility>
 
+#include "perfetto/ext/base/string_utils.h"
 #include "src/kernel_utils/syscall_table.h"
 #include "src/trace_processor/storage/stats.h"
 
@@ -50,9 +51,8 @@
       if (!strcmp(name, "sys_write"))
         sys_write_string_id_ = id;
     } else {
-      char unknown_str[64];
-      sprintf(unknown_str, "sys_%zu", i);
-      id = context_->storage->InternString(unknown_str);
+      base::StackString<64> unknown_str("sys_%zu", i);
+      id = context_->storage->InternString(unknown_str.string_view());
     }
     arch_syscall_to_string_id_[i] = id;
   }
diff --git a/src/trace_processor/rpc/httpd.cc b/src/trace_processor/rpc/httpd.cc
index 3429a28..97bee91 100644
--- a/src/trace_processor/rpc/httpd.cc
+++ b/src/trace_processor/rpc/httpd.cc
@@ -210,15 +210,12 @@
     // rpc.Query() call. No further calls will be made once Query() returns.
     auto on_result_chunk = [&](const uint8_t* buf, size_t len, bool has_more) {
       PERFETTO_DLOG("Sending response chunk, len=%zu eof=%d", len, !has_more);
-      char chunk_hdr[32];
-      auto hdr_len = static_cast<size_t>(sprintf(chunk_hdr, "%zx\r\n", len));
-      conn.SendResponseBody(chunk_hdr, hdr_len);
+      base::StackString<32> chunk_hdr("%zx\r\n", len);
+      conn.SendResponseBody(chunk_hdr.c_str(), chunk_hdr.len());
       conn.SendResponseBody(buf, len);
       conn.SendResponseBody("\r\n", 2);
-      if (!has_more) {
-        hdr_len = static_cast<size_t>(sprintf(chunk_hdr, "0\r\n\r\n"));
-        conn.SendResponseBody(chunk_hdr, hdr_len);
-      }
+      if (!has_more)
+        conn.SendResponseBody("0\r\n\r\n", 5);
     };
     trace_processor_rpc_.Query(
         reinterpret_cast<const uint8_t*>(req.body.data()), req.body.size(),
diff --git a/src/trace_processor/sorter/BUILD.gn b/src/trace_processor/sorter/BUILD.gn
index 53609a5..218d639 100644
--- a/src/trace_processor/sorter/BUILD.gn
+++ b/src/trace_processor/sorter/BUILD.gn
@@ -46,11 +46,11 @@
   ]
   deps = [
     ":sorter",
-    "..:storage_minimal",
     "../../../gn:default_deps",
     "../../../gn:gtest_and_gmock",
     "../../../include/perfetto/trace_processor:storage",
     "../../base",
+    "../importers:minimal",
     "../importers/common:parser_types",
     "../importers/proto:minimal",
     "../types",
diff --git a/src/trace_processor/sqlite/BUILD.gn b/src/trace_processor/sqlite/BUILD.gn
index 98ef4c1..0e63e54 100644
--- a/src/trace_processor/sqlite/BUILD.gn
+++ b/src/trace_processor/sqlite/BUILD.gn
@@ -34,7 +34,6 @@
       "window_operator_table.h",
     ]
     deps = [
-      "..:ftrace_descriptors",
       "..:metatrace",
       "../../../gn:default_deps",
       "../../../gn:sqlite",
@@ -43,6 +42,7 @@
       "../containers",
       "../db",
       "../dynamic",
+      "../importers:ftrace_descriptors",
       "../importers/common",
       "../storage",
       "../types",
diff --git a/src/trace_processor/sqlite/functions/BUILD.gn b/src/trace_processor/sqlite/functions/BUILD.gn
index 6a234bf..aa9a953 100644
--- a/src/trace_processor/sqlite/functions/BUILD.gn
+++ b/src/trace_processor/sqlite/functions/BUILD.gn
@@ -37,7 +37,6 @@
     deps = [
       "../..:demangle",
       "../..:export_json",
-      "../..:ftrace_descriptors",
       "../..:metatrace",
       "../../../../gn:default_deps",
       "../../../../gn:sqlite",
@@ -47,6 +46,7 @@
       "../../containers",
       "../../db",
       "../../dynamic",
+      "../../importers:ftrace_descriptors",
       "../../importers/common",
       "../../storage",
       "../../types",
diff --git a/src/trace_processor/sqlite/sqlite_utils.cc b/src/trace_processor/sqlite/sqlite_utils.cc
index 1a11f04..006e4f9 100644
--- a/src/trace_processor/sqlite/sqlite_utils.cc
+++ b/src/trace_processor/sqlite/sqlite_utils.cc
@@ -139,6 +139,75 @@
   return base::OkStatus();
 }
 
+template <typename T>
+base::Status ExtractFromSqlValueInt(const SqlValue& value,
+                                    base::Optional<T>& out) {
+  if (value.is_null()) {
+    out = base::nullopt;
+    return base::OkStatus();
+  }
+  if (value.type != SqlValue::kLong) {
+    return base::ErrStatus(
+        "value has type %s which does not match the expected type %s",
+        SqliteTypeToFriendlyString(value.type),
+        SqliteTypeToFriendlyString(SqlValue::kLong));
+  }
+
+  int64_t res = value.AsLong();
+  if (res > std::numeric_limits<T>::max() ||
+      res < std::numeric_limits<T>::min()) {
+    return base::ErrStatus("value %ld does not fit inside the range [%ld, %ld]",
+                           static_cast<long>(res),
+                           static_cast<long>(std::numeric_limits<T>::min()),
+                           static_cast<long>(std::numeric_limits<T>::max()));
+  }
+  out = static_cast<T>(res);
+  return base::OkStatus();
+}
+
+base::Status ExtractFromSqlValue(const SqlValue& value,
+                                 base::Optional<int64_t>& out) {
+  return ExtractFromSqlValueInt(value, out);
+}
+base::Status ExtractFromSqlValue(const SqlValue& value,
+                                 base::Optional<int32_t>& out) {
+  return ExtractFromSqlValueInt(value, out);
+}
+base::Status ExtractFromSqlValue(const SqlValue& value,
+                                 base::Optional<uint32_t>& out) {
+  return ExtractFromSqlValueInt(value, out);
+}
+base::Status ExtractFromSqlValue(const SqlValue& value,
+                                 base::Optional<double>& out) {
+  if (value.is_null()) {
+    out = base::nullopt;
+    return base::OkStatus();
+  }
+  if (value.type != SqlValue::kDouble) {
+    return base::ErrStatus(
+        "value has type %s which does not match the expected type %s",
+        SqliteTypeToFriendlyString(value.type),
+        SqliteTypeToFriendlyString(SqlValue::kDouble));
+  }
+  out = value.AsDouble();
+  return base::OkStatus();
+}
+base::Status ExtractFromSqlValue(const SqlValue& value,
+                                 base::Optional<const char*>& out) {
+  if (value.is_null()) {
+    out = base::nullopt;
+    return base::OkStatus();
+  }
+  if (value.type != SqlValue::kString) {
+    return base::ErrStatus(
+        "value has type %s which does not match the expected type %s",
+        SqliteTypeToFriendlyString(value.type),
+        SqliteTypeToFriendlyString(SqlValue::kString));
+  }
+  out = value.AsString();
+  return base::OkStatus();
+}
+
 }  // namespace sqlite_utils
 }  // namespace trace_processor
 }  // namespace perfetto
diff --git a/src/trace_processor/sqlite/sqlite_utils.h b/src/trace_processor/sqlite/sqlite_utils.h
index 7d6d68f..f09a258 100644
--- a/src/trace_processor/sqlite/sqlite_utils.h
+++ b/src/trace_processor/sqlite/sqlite_utils.h
@@ -211,6 +211,24 @@
   return base::OkStatus();
 }
 
+// Exracts the given type from the SqlValue if |value| can fit
+// in the provided optional. Note that SqlValue::kNull will always
+// succeed and cause base::nullopt to be set.
+//
+// Returns base::ErrStatus if the type does not match or does not
+// fit in the width of the provided optional type (i.e. int64 value
+// not fitting in int32 optional).
+base::Status ExtractFromSqlValue(const SqlValue& value,
+                                 base::Optional<int64_t>&);
+base::Status ExtractFromSqlValue(const SqlValue& value,
+                                 base::Optional<int32_t>&);
+base::Status ExtractFromSqlValue(const SqlValue& value,
+                                 base::Optional<uint32_t>&);
+base::Status ExtractFromSqlValue(const SqlValue& value,
+                                 base::Optional<double>&);
+base::Status ExtractFromSqlValue(const SqlValue& value,
+                                 base::Optional<const char*>&);
+
 // Returns the column names for the table named by |raw_table_name|.
 base::Status GetColumnsForTable(sqlite3* db,
                                 const std::string& raw_table_name,
diff --git a/src/trace_processor/sqlite/sqlite_utils_unittest.cc b/src/trace_processor/sqlite/sqlite_utils_unittest.cc
index 5e30551..b52df66 100644
--- a/src/trace_processor/sqlite/sqlite_utils_unittest.cc
+++ b/src/trace_processor/sqlite/sqlite_utils_unittest.cc
@@ -20,6 +20,8 @@
 
 namespace perfetto {
 namespace trace_processor {
+namespace sqlite_utils {
+
 namespace {
 
 class GetColumnsForTableTest : public ::testing::Test {
@@ -72,6 +74,110 @@
   ASSERT_FALSE(status.ok());
 }
 
+TEST(SqliteUtilsTest, ExtractFromSqlValueInt32) {
+  base::Optional<int32_t> int32;
+
+  static constexpr int64_t kMin = std::numeric_limits<int32_t>::min();
+  static constexpr int64_t kMax = std::numeric_limits<int32_t>::max();
+
+  ASSERT_TRUE(ExtractFromSqlValue(SqlValue::Long(1234), int32).ok());
+  ASSERT_EQ(*int32, 1234);
+
+  ASSERT_TRUE(ExtractFromSqlValue(SqlValue::Long(kMin), int32).ok());
+  ASSERT_EQ(*int32, kMin);
+
+  ASSERT_TRUE(ExtractFromSqlValue(SqlValue::Long(kMax), int32).ok());
+  ASSERT_EQ(*int32, kMax);
+
+  ASSERT_TRUE(ExtractFromSqlValue(SqlValue(), int32).ok());
+  ASSERT_FALSE(int32.has_value());
+
+  ASSERT_FALSE(ExtractFromSqlValue(SqlValue::Long(kMax + 1), int32).ok());
+  ASSERT_FALSE(ExtractFromSqlValue(SqlValue::Double(1.0), int32).ok());
+  ASSERT_FALSE(ExtractFromSqlValue(SqlValue::String("foo"), int32).ok());
+}
+
+TEST(SqliteUtilsTest, ExtractFromSqlValueUint32) {
+  base::Optional<uint32_t> uint32;
+
+  static constexpr int64_t kMin = std::numeric_limits<uint32_t>::min();
+  static constexpr int64_t kMax = std::numeric_limits<uint32_t>::max();
+
+  ASSERT_TRUE(ExtractFromSqlValue(SqlValue::Long(1234), uint32).ok());
+  ASSERT_EQ(*uint32, 1234u);
+
+  ASSERT_TRUE(ExtractFromSqlValue(SqlValue::Long(kMin), uint32).ok());
+  ASSERT_EQ(*uint32, kMin);
+
+  ASSERT_TRUE(ExtractFromSqlValue(SqlValue::Long(kMax), uint32).ok());
+  ASSERT_EQ(*uint32, kMax);
+
+  ASSERT_TRUE(ExtractFromSqlValue(SqlValue(), uint32).ok());
+  ASSERT_FALSE(uint32.has_value());
+
+  ASSERT_FALSE(ExtractFromSqlValue(SqlValue::Long(kMax + 1), uint32).ok());
+  ASSERT_FALSE(ExtractFromSqlValue(SqlValue::Double(1.0), uint32).ok());
+  ASSERT_FALSE(ExtractFromSqlValue(SqlValue::String("foo"), uint32).ok());
+}
+
+TEST(SqliteUtilsTest, ExtractFromSqlValueInt64) {
+  base::Optional<int64_t> int64;
+
+  static constexpr int64_t kMin = std::numeric_limits<int64_t>::min();
+  static constexpr int64_t kMax = std::numeric_limits<int64_t>::max();
+
+  ASSERT_TRUE(ExtractFromSqlValue(SqlValue::Long(1234), int64).ok());
+  ASSERT_EQ(*int64, 1234);
+
+  ASSERT_TRUE(ExtractFromSqlValue(SqlValue::Long(kMin), int64).ok());
+  ASSERT_EQ(*int64, kMin);
+
+  ASSERT_TRUE(ExtractFromSqlValue(SqlValue::Long(kMax), int64).ok());
+  ASSERT_EQ(*int64, kMax);
+
+  ASSERT_TRUE(ExtractFromSqlValue(SqlValue(), int64).ok());
+  ASSERT_FALSE(int64.has_value());
+
+  ASSERT_FALSE(ExtractFromSqlValue(SqlValue::Double(1.0), int64).ok());
+  ASSERT_FALSE(ExtractFromSqlValue(SqlValue::String("foo"), int64).ok());
+}
+
+TEST(SqliteUtilsTest, ExtractFromSqlValueDouble) {
+  base::Optional<double> doub;
+
+  static constexpr double kMin = std::numeric_limits<double>::min();
+  static constexpr double kMax = std::numeric_limits<double>::max();
+
+  ASSERT_TRUE(ExtractFromSqlValue(SqlValue::Double(1234.1), doub).ok());
+  ASSERT_EQ(*doub, 1234.1);
+
+  ASSERT_TRUE(ExtractFromSqlValue(SqlValue::Double(kMin), doub).ok());
+  ASSERT_EQ(*doub, kMin);
+
+  ASSERT_TRUE(ExtractFromSqlValue(SqlValue::Double(kMax), doub).ok());
+  ASSERT_EQ(*doub, kMax);
+
+  ASSERT_TRUE(ExtractFromSqlValue(SqlValue(), doub).ok());
+  ASSERT_FALSE(doub.has_value());
+
+  ASSERT_FALSE(ExtractFromSqlValue(SqlValue::Long(1234), doub).ok());
+  ASSERT_FALSE(ExtractFromSqlValue(SqlValue::String("foo"), doub).ok());
+}
+
+TEST(SqliteUtilsTest, ExtractFromSqlValueString) {
+  base::Optional<const char*> string;
+
+  ASSERT_TRUE(ExtractFromSqlValue(SqlValue::String("foo"), string).ok());
+  ASSERT_STREQ(*string, "foo");
+
+  ASSERT_TRUE(ExtractFromSqlValue(SqlValue(), string).ok());
+  ASSERT_FALSE(string.has_value());
+
+  ASSERT_FALSE(ExtractFromSqlValue(SqlValue::Long(1234), string).ok());
+  ASSERT_FALSE(ExtractFromSqlValue(SqlValue::Double(123.1), string).ok());
+}
+
 }  // namespace
+}  // namespace sqlite_utils
 }  // namespace trace_processor
 }  // namespace perfetto
diff --git a/src/trace_processor/trace_processor_impl.cc b/src/trace_processor/trace_processor_impl.cc
index 37a447a..871eb52 100644
--- a/src/trace_processor/trace_processor_impl.cc
+++ b/src/trace_processor/trace_processor_impl.cc
@@ -49,6 +49,7 @@
 #include "src/trace_processor/importers/gzip/gzip_trace_parser.h"
 #include "src/trace_processor/importers/json/json_trace_parser.h"
 #include "src/trace_processor/importers/json/json_trace_tokenizer.h"
+#include "src/trace_processor/importers/ninja/ninja_log_parser.h"
 #include "src/trace_processor/importers/proto/metadata_tracker.h"
 #include "src/trace_processor/importers/systrace/systrace_trace_parser.h"
 #include "src/trace_processor/iterator_impl.h"
@@ -681,6 +682,8 @@
   context_.fuchsia_trace_tokenizer.reset(new FuchsiaTraceTokenizer(&context_));
   context_.fuchsia_trace_parser.reset(new FuchsiaTraceParser(&context_));
 
+  context_.ninja_log_parser.reset(new NinjaLogParser(&context_));
+
   context_.systrace_trace_parser.reset(new SystraceTraceParser(&context_));
 
   if (util::IsGzipSupported()) {
diff --git a/src/trace_processor/types/trace_processor_context.h b/src/trace_processor/types/trace_processor_context.h
index db5efaf..e28a9d5 100644
--- a/src/trace_processor/types/trace_processor_context.h
+++ b/src/trace_processor/types/trace_processor_context.h
@@ -120,16 +120,17 @@
 
   // These fields are trace readers which will be called by |forwarding_parser|
   // once the format of the trace is discovered. They are placed here as they
-  // are only available in the storage_full target.
+  // are only available in the lib target.
   std::unique_ptr<ChunkedTraceReader> json_trace_tokenizer;
   std::unique_ptr<ChunkedTraceReader> fuchsia_trace_tokenizer;
+  std::unique_ptr<ChunkedTraceReader> ninja_log_parser;
   std::unique_ptr<ChunkedTraceReader> android_bugreport_parser;
   std::unique_ptr<ChunkedTraceReader> systrace_trace_parser;
   std::unique_ptr<ChunkedTraceReader> gzip_trace_parser;
 
   // These fields are trace parsers which will be called by |forwarding_parser|
   // once the format of the trace is discovered. They are placed here as they
-  // are only available in the storage_full target.
+  // are only available in the lib target.
   std::unique_ptr<TraceParser> json_trace_parser;
   std::unique_ptr<TraceParser> fuchsia_trace_parser;
 
diff --git a/src/traceconv/trace_to_json.cc b/src/traceconv/trace_to_json.cc
index 429b4d7..7986f24 100644
--- a/src/traceconv/trace_to_json.cc
+++ b/src/traceconv/trace_to_json.cc
@@ -20,6 +20,7 @@
 
 #include "perfetto/base/logging.h"
 #include "perfetto/ext/base/scoped_file.h"
+#include "perfetto/ext/base/string_utils.h"
 #include "perfetto/ext/base/temp_file.h"
 #include "perfetto/trace_processor/trace_processor.h"
 #include "src/traceconv/utils.h"
@@ -45,9 +46,9 @@
   // Write userspace trace to a temporary file.
   // TODO(eseckler): Support streaming the result out of TP directly instead.
   auto file = base::TempFile::Create();
-  char query[100];
-  sprintf(query, "select export_json(\"%s\")", file.path().c_str());
-  auto it = tp->ExecuteQuery(query);
+  base::StackString<100> query("select export_json(\"%s\")",
+                               file.path().c_str());
+  auto it = tp->ExecuteQuery(query.ToStdString());
 
   if (!it.Next()) {
     auto status = it.Status();
diff --git a/src/traceconv/trace_to_systrace.cc b/src/traceconv/trace_to_systrace.cc
index d89f0d6..6b2f380 100644
--- a/src/traceconv/trace_to_systrace.cc
+++ b/src/traceconv/trace_to_systrace.cc
@@ -27,6 +27,7 @@
 
 #include "perfetto/base/build_config.h"
 #include "perfetto/base/logging.h"
+#include "perfetto/ext/base/string_utils.h"
 #include "perfetto/ext/base/string_writer.h"
 #include "perfetto/ext/base/utils.h"
 #include "perfetto/trace_processor/trace_processor.h"
@@ -247,15 +248,15 @@
 
   // 2. Write the actual events.
   if (truncate_keep == Keep::kEnd && raw_events > max_ftrace_events) {
-    char end_truncate[150];
-    sprintf(end_truncate, "%s limit %d offset %d", kRawEventsQuery,
-            max_ftrace_events, raw_events - max_ftrace_events);
-    if (!q_writer.RunQuery(end_truncate, raw_callback))
+    base::StackString<150> end_truncate("%s limit %d offset %d",
+                                        kRawEventsQuery, max_ftrace_events,
+                                        raw_events - max_ftrace_events);
+    if (!q_writer.RunQuery(end_truncate.ToStdString(), raw_callback))
       return 1;
   } else if (truncate_keep == Keep::kStart) {
-    char start_truncate[150];
-    sprintf(start_truncate, "%s limit %d", kRawEventsQuery, max_ftrace_events);
-    if (!q_writer.RunQuery(start_truncate, raw_callback))
+    base::StackString<150> start_truncate("%s limit %d", kRawEventsQuery,
+                                          max_ftrace_events);
+    if (!q_writer.RunQuery(start_truncate.ToStdString(), raw_callback))
       return 1;
   } else {
     if (!q_writer.RunQuery(kRawEventsQuery, raw_callback))
diff --git a/src/traced/probes/ps/process_stats_data_source_unittest.cc b/src/traced/probes/ps/process_stats_data_source_unittest.cc
index bb12ea7..a68afb9 100644
--- a/src/traced/probes/ps/process_stats_data_source_unittest.cc
+++ b/src/traced/probes/ps/process_stats_data_source_unittest.cc
@@ -19,6 +19,7 @@
 #include <dirent.h>
 
 #include "perfetto/ext/base/file_utils.h"
+#include "perfetto/ext/base/string_utils.h"
 #include "perfetto/ext/base/temp_file.h"
 #include "perfetto/protozero/scattered_heap_buffer.h"
 #include "perfetto/tracing/core/data_source_config.h"
@@ -330,10 +331,9 @@
   const int kPids[] = {1, 2};
   std::vector<std::string> dirs_to_delete;
   for (int pid : kPids) {
-    char path[256];
-    sprintf(path, "%s/%d", fake_proc.path().c_str(), pid);
-    dirs_to_delete.push_back(path);
-    mkdir(path, 0755);
+    base::StackString<256> path("%s/%d", fake_proc.path().c_str(), pid);
+    dirs_to_delete.push_back(path.ToStdString());
+    mkdir(path.c_str(), 0755);
   }
 
   auto checkpoint = task_runner_.CreateCheckpoint("all_done");
@@ -346,13 +346,13 @@
   int iter = 0;
   for (int pid : kPids) {
     EXPECT_CALL(*data_source, ReadProcPidFile(pid, "status"))
-        .WillRepeatedly(Invoke([checkpoint, &iter](int32_t p,
-                                                   const std::string&) {
-          char ret[1024];
-          sprintf(ret, "Name:	pid_10\nVmSize:	 %d kB\nVmRSS:\t%d  kB\n",
+        .WillRepeatedly(
+            Invoke([checkpoint, &iter](int32_t p, const std::string&) {
+              base::StackString<1024> ret(
+                  "Name:	pid_10\nVmSize:	 %d kB\nVmRSS:\t%d  kB\n",
                   p * 100 + iter * 10 + 1, p * 100 + iter * 10 + 2);
-          return std::string(ret);
-        }));
+              return ret.ToStdString();
+            }));
 
     EXPECT_CALL(*data_source, ReadProcPidFile(pid, "oom_score_adj"))
         .WillRepeatedly(Invoke(
@@ -409,9 +409,8 @@
   auto fake_proc = base::TempDir::Create();
   const int kPid = 1;
 
-  char path[256];
-  sprintf(path, "%s/%d", fake_proc.path().c_str(), kPid);
-  mkdir(path, 0755);
+  base::StackString<256> path("%s/%d", fake_proc.path().c_str(), kPid);
+  mkdir(path.c_str(), 0755);
 
   auto checkpoint = task_runner_.CreateCheckpoint("all_done");
 
@@ -423,10 +422,10 @@
   int iter = 0;
   EXPECT_CALL(*data_source, ReadProcPidFile(kPid, "status"))
       .WillRepeatedly(Invoke([checkpoint](int32_t p, const std::string&) {
-        char ret[1024];
-        sprintf(ret, "Name:	pid_10\nVmSize:	 %d kB\nVmRSS:\t%d  kB\n",
-                p * 100 + 1, p * 100 + 2);
-        return std::string(ret);
+        base::StackString<1024> ret(
+            "Name:	pid_10\nVmSize:	 %d kB\nVmRSS:\t%d  kB\n", p * 100 + 1,
+            p * 100 + 2);
+        return ret.ToStdString();
       }));
 
   EXPECT_CALL(*data_source, ReadProcPidFile(kPid, "oom_score_adj"))
@@ -461,7 +460,7 @@
   }
 
   // Cleanup |fake_proc|. TempDir checks that the directory is empty.
-  base::Rmdir(path);
+  base::Rmdir(path.ToStdString());
 }
 
 TEST_F(ProcessStatsDataSourceTest, NamespacedProcess) {
diff --git a/src/traced/probes/sys_stats/sys_stats_data_source_unittest.cc b/src/traced/probes/sys_stats/sys_stats_data_source_unittest.cc
index 611a2f0..bd9eaa2 100644
--- a/src/traced/probes/sys_stats/sys_stats_data_source_unittest.cc
+++ b/src/traced/probes/sys_stats/sys_stats_data_source_unittest.cc
@@ -17,6 +17,7 @@
 #include <unistd.h>
 
 #include "perfetto/ext/base/file_utils.h"
+#include "perfetto/ext/base/string_utils.h"
 #include "perfetto/ext/base/temp_file.h"
 #include "src/base/test/test_task_runner.h"
 #include "src/traced/probes/common/cpu_freq_info_for_testing.h"
@@ -437,14 +438,12 @@
   auto make_devfreq_paths = [&symlinks_to_delete, &dirs_to_delete](
                                 base::TempDir& temp_dir, base::TempDir& sym_dir,
                                 const char* name) {
-    char path[256];
-    sprintf(path, "%s/%s", temp_dir.path().c_str(), name);
-    dirs_to_delete.push_back(path);
-    mkdir(path, 0755);
-    char sym_path[256];
-    sprintf(sym_path, "%s/%s", sym_dir.path().c_str(), name);
-    symlinks_to_delete.push_back(sym_path);
-    symlink(path, sym_path);
+    base::StackString<256> path("%s/%s", temp_dir.path().c_str(), name);
+    dirs_to_delete.push_back(path.ToStdString());
+    mkdir(path.c_str(), 0755);
+    base::StackString<256> sym_path("%s/%s", sym_dir.path().c_str(), name);
+    symlinks_to_delete.push_back(sym_path.ToStdString());
+    symlink(path.c_str(), sym_path.c_str());
   };
   auto fake_devfreq = base::TempDir::Create();
   auto fake_devfreq_symdir = base::TempDir::Create();
diff --git a/src/tracing/test/api_test_support.cc b/src/tracing/test/api_test_support.cc
index 139adf3..064f259 100644
--- a/src/tracing/test/api_test_support.cc
+++ b/src/tracing/test/api_test_support.cc
@@ -19,6 +19,7 @@
 #include "perfetto/base/compiler.h"
 #include "perfetto/base/proc_utils.h"
 #include "perfetto/base/time.h"
+#include "perfetto/ext/base/string_utils.h"
 #include "perfetto/ext/base/temp_file.h"
 #include "src/tracing/internal/tracing_muxer_impl.h"
 
@@ -145,9 +146,8 @@
 TestTempFile CreateTempFile() {
   TestTempFile res{};
 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
-  char temp_file[255]{};
-  sprintf(temp_file, "%s\\perfetto-XXXXXX", getenv("TMP"));
-  PERFETTO_CHECK(_mktemp_s(temp_file, strlen(temp_file) + 1) == 0);
+  base::StackString<255> temp_file("%s\\perfetto-XXXXXX", getenv("TMP"));
+  PERFETTO_CHECK(_mktemp_s(temp_file.c_str(), temp_file.len() + 1) == 0);
   HANDLE handle =
       ::CreateFileA(temp_file, GENERIC_READ | GENERIC_WRITE,
                     FILE_SHARE_DELETE | FILE_SHARE_READ, nullptr, CREATE_ALWAYS,
diff --git a/ui/src/assets/common.scss b/ui/src/assets/common.scss
index 52b7022..c6a3958 100644
--- a/ui/src/assets/common.scss
+++ b/ui/src/assets/common.scss
@@ -211,9 +211,6 @@
     thead td.reorderable-cell {
       cursor: grab;
     }
-    td {
-      height: 25px;
-    }
     .disabled {
       cursor: default;
     }
@@ -793,6 +790,10 @@
     // In regular pivot table cells, avoids wrapping the icon spacer to go on
     // a separate line.
     white-space: pre;
+
+    i.material-icons {
+      font-size: 16px;
+    }
   }
 }
 
diff --git a/ui/src/common/query_utils.ts b/ui/src/common/query_utils.ts
index e071082..0c9a855 100644
--- a/ui/src/common/query_utils.ts
+++ b/ui/src/common/query_utils.ts
@@ -14,21 +14,38 @@
  * limitations under the License.
  */
 
-function replaceUndesiredCharacters(s: string): string {
+enum EscapeFlag {
+  CaseInsensitive = 1,
+  MatchAny = 2,
+}
+
+function escape(s: string, flags?: number): string {
+  flags = flags === undefined ? 0 : flags;
   // See https://www.sqlite.org/lang_expr.html#:~:text=A%20string%20constant
   s = s.replace(/\'/g, '\'\'');
   s = s.replace(/\[/g, '[[]');
+  if (flags & EscapeFlag.CaseInsensitive) {
+    s = s.replace(/[a-zA-Z]/g, (m) => {
+      const lower = m.toLowerCase();
+      const upper = m.toUpperCase();
+      return `[${lower}${upper}]`;
+    });
+  }
   s = s.replace(/\?/g, '[?]');
   s = s.replace(/\*/g, '[*]');
+  if (flags & EscapeFlag.MatchAny) {
+    s = `*${s}*`;
+  }
+  s = `'${s}'`;
   return s;
 }
 
 export function escapeQuery(s: string): string {
-  return `'${replaceUndesiredCharacters(s)}'`;
+  return escape(s);
 }
 
-export function escapeAndExpandQuery(s: string): string {
-  return `'*${replaceUndesiredCharacters(s)}*'`;
+export function escapeSearchQuery(s: string): string {
+  return escape(s, EscapeFlag.CaseInsensitive | EscapeFlag.MatchAny);
 }
 
 export function escapeGlob(s: string): string {
diff --git a/ui/src/common/query_utils_unittest.ts b/ui/src/common/query_utils_unittest.ts
index a61a05a..3ac9869 100644
--- a/ui/src/common/query_utils_unittest.ts
+++ b/ui/src/common/query_utils_unittest.ts
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-import {escapeAndExpandQuery, escapeGlob, escapeQuery} from './query_utils';
+import {escapeGlob, escapeQuery, escapeSearchQuery} from './query_utils';
 
 test('escapeQuery', () => {
   expect(escapeQuery(``)).toEqual(`''`);
@@ -23,12 +23,12 @@
   expect(escapeQuery('[]?')).toEqual(`'[[]][?]'`);
 });
 
-test('escapeAndExpandQuery', () => {
-  expect(escapeAndExpandQuery(``)).toEqual(`'**'`);
-  expect(escapeAndExpandQuery(`hello`)).toEqual(`'*hello*'`);
-  expect(escapeAndExpandQuery('foo\'bar')).toEqual(`'*foo''bar*'`);
-  expect(escapeAndExpandQuery('*_*')).toEqual(`'*[*]_[*]*'`);
-  expect(escapeAndExpandQuery('[]?')).toEqual(`'*[[]][?]*'`);
+test('escapeSearchQuery', () => {
+  expect(escapeSearchQuery(``)).toEqual(`'**'`);
+  expect(escapeSearchQuery(`hello`)).toEqual(`'*[hH][eE][lL][lL][oO]*'`);
+  expect(escapeSearchQuery('a\'b')).toEqual(`'*[aA]''[bB]*'`);
+  expect(escapeSearchQuery('*_*')).toEqual(`'*[*]_[*]*'`);
+  expect(escapeSearchQuery('[]?')).toEqual(`'*[[]][?]*'`);
 });
 
 test('escapeGlob', () => {
diff --git a/ui/src/controller/search_controller.ts b/ui/src/controller/search_controller.ts
index 8ee432c..118570a 100644
--- a/ui/src/controller/search_controller.ts
+++ b/ui/src/controller/search_controller.ts
@@ -15,7 +15,7 @@
 import {sqliteString} from '../base/string_utils';
 import {Engine} from '../common/engine';
 import {NUM, STR} from '../common/query_result';
-import {escapeAndExpandQuery} from '../common/query_utils';
+import {escapeSearchQuery} from '../common/query_utils';
 import {CurrentSearchResults, SearchSummary} from '../common/search_data';
 import {TimeSpan} from '../common/time';
 import {publishSearch, publishSearchResult} from '../frontend/publish';
@@ -146,7 +146,7 @@
       resolution: number): Promise<SearchSummary> {
     const quantumNs = Math.round(resolution * 10 * 1e9);
 
-    const searchLiteral = escapeAndExpandQuery(search);
+    const searchLiteral = escapeSearchQuery(search);
 
     startNs = Math.floor(startNs / quantumNs) * quantumNs;
 
@@ -205,7 +205,7 @@
   }
 
   private async specificSearch(search: string) {
-    const searchLiteral = escapeAndExpandQuery(search);
+    const searchLiteral = escapeSearchQuery(search);
     // TODO(hjd): we should avoid recomputing this every time. This will be
     // easier once the track table has entries for all the tracks.
     const cpuToTrackId = new Map();
diff --git a/ui/src/frontend/pivot_table_redux.ts b/ui/src/frontend/pivot_table_redux.ts
index c2d11e8..5fb1145 100644
--- a/ui/src/frontend/pivot_table_redux.ts
+++ b/ui/src/frontend/pivot_table_redux.ts
@@ -102,11 +102,6 @@
   get pivotState() {
     return globals.state.nonSerializableState.pivotTableRedux;
   }
-  get selectedAggregations() {
-    return globals.state.nonSerializableState.pivotTableRedux
-        .selectedAggregations;
-  }
-
   get constrainToArea() {
     return globals.state.nonSerializableState.pivotTableRedux.constrainToArea;
   }