Merge "Reland "Make the mapping between panels information and VDOM elements explicit""
diff --git a/Android.bp b/Android.bp
index 5bf2da2..3c5e89b 100644
--- a/Android.bp
+++ b/Android.bp
@@ -4204,6 +4204,7 @@
         "protos/perfetto/trace/ftrace/net.proto",
         "protos/perfetto/trace/ftrace/oom.proto",
         "protos/perfetto/trace/ftrace/power.proto",
+        "protos/perfetto/trace/ftrace/printk.proto",
         "protos/perfetto/trace/ftrace/raw_syscalls.proto",
         "protos/perfetto/trace/ftrace/regulator.proto",
         "protos/perfetto/trace/ftrace/sched.proto",
@@ -4430,6 +4431,7 @@
         "protos/perfetto/trace/ftrace/net.proto",
         "protos/perfetto/trace/ftrace/oom.proto",
         "protos/perfetto/trace/ftrace/power.proto",
+        "protos/perfetto/trace/ftrace/printk.proto",
         "protos/perfetto/trace/ftrace/raw_syscalls.proto",
         "protos/perfetto/trace/ftrace/regulator.proto",
         "protos/perfetto/trace/ftrace/sched.proto",
@@ -4489,6 +4491,7 @@
         "external/perfetto/protos/perfetto/trace/ftrace/net.gen.cc",
         "external/perfetto/protos/perfetto/trace/ftrace/oom.gen.cc",
         "external/perfetto/protos/perfetto/trace/ftrace/power.gen.cc",
+        "external/perfetto/protos/perfetto/trace/ftrace/printk.gen.cc",
         "external/perfetto/protos/perfetto/trace/ftrace/raw_syscalls.gen.cc",
         "external/perfetto/protos/perfetto/trace/ftrace/regulator.gen.cc",
         "external/perfetto/protos/perfetto/trace/ftrace/sched.gen.cc",
@@ -4548,6 +4551,7 @@
         "protos/perfetto/trace/ftrace/net.proto",
         "protos/perfetto/trace/ftrace/oom.proto",
         "protos/perfetto/trace/ftrace/power.proto",
+        "protos/perfetto/trace/ftrace/printk.proto",
         "protos/perfetto/trace/ftrace/raw_syscalls.proto",
         "protos/perfetto/trace/ftrace/regulator.proto",
         "protos/perfetto/trace/ftrace/sched.proto",
@@ -4607,6 +4611,7 @@
         "external/perfetto/protos/perfetto/trace/ftrace/net.gen.h",
         "external/perfetto/protos/perfetto/trace/ftrace/oom.gen.h",
         "external/perfetto/protos/perfetto/trace/ftrace/power.gen.h",
+        "external/perfetto/protos/perfetto/trace/ftrace/printk.gen.h",
         "external/perfetto/protos/perfetto/trace/ftrace/raw_syscalls.gen.h",
         "external/perfetto/protos/perfetto/trace/ftrace/regulator.gen.h",
         "external/perfetto/protos/perfetto/trace/ftrace/sched.gen.h",
@@ -4670,6 +4675,7 @@
         "protos/perfetto/trace/ftrace/net.proto",
         "protos/perfetto/trace/ftrace/oom.proto",
         "protos/perfetto/trace/ftrace/power.proto",
+        "protos/perfetto/trace/ftrace/printk.proto",
         "protos/perfetto/trace/ftrace/raw_syscalls.proto",
         "protos/perfetto/trace/ftrace/regulator.proto",
         "protos/perfetto/trace/ftrace/sched.proto",
@@ -4728,6 +4734,7 @@
         "external/perfetto/protos/perfetto/trace/ftrace/net.pb.cc",
         "external/perfetto/protos/perfetto/trace/ftrace/oom.pb.cc",
         "external/perfetto/protos/perfetto/trace/ftrace/power.pb.cc",
+        "external/perfetto/protos/perfetto/trace/ftrace/printk.pb.cc",
         "external/perfetto/protos/perfetto/trace/ftrace/raw_syscalls.pb.cc",
         "external/perfetto/protos/perfetto/trace/ftrace/regulator.pb.cc",
         "external/perfetto/protos/perfetto/trace/ftrace/sched.pb.cc",
@@ -4787,6 +4794,7 @@
         "protos/perfetto/trace/ftrace/net.proto",
         "protos/perfetto/trace/ftrace/oom.proto",
         "protos/perfetto/trace/ftrace/power.proto",
+        "protos/perfetto/trace/ftrace/printk.proto",
         "protos/perfetto/trace/ftrace/raw_syscalls.proto",
         "protos/perfetto/trace/ftrace/regulator.proto",
         "protos/perfetto/trace/ftrace/sched.proto",
@@ -4845,6 +4853,7 @@
         "external/perfetto/protos/perfetto/trace/ftrace/net.pb.h",
         "external/perfetto/protos/perfetto/trace/ftrace/oom.pb.h",
         "external/perfetto/protos/perfetto/trace/ftrace/power.pb.h",
+        "external/perfetto/protos/perfetto/trace/ftrace/printk.pb.h",
         "external/perfetto/protos/perfetto/trace/ftrace/raw_syscalls.pb.h",
         "external/perfetto/protos/perfetto/trace/ftrace/regulator.pb.h",
         "external/perfetto/protos/perfetto/trace/ftrace/sched.pb.h",
@@ -4908,6 +4917,7 @@
         "protos/perfetto/trace/ftrace/net.proto",
         "protos/perfetto/trace/ftrace/oom.proto",
         "protos/perfetto/trace/ftrace/power.proto",
+        "protos/perfetto/trace/ftrace/printk.proto",
         "protos/perfetto/trace/ftrace/raw_syscalls.proto",
         "protos/perfetto/trace/ftrace/regulator.proto",
         "protos/perfetto/trace/ftrace/sched.proto",
@@ -4967,6 +4977,7 @@
         "external/perfetto/protos/perfetto/trace/ftrace/net.pbzero.cc",
         "external/perfetto/protos/perfetto/trace/ftrace/oom.pbzero.cc",
         "external/perfetto/protos/perfetto/trace/ftrace/power.pbzero.cc",
+        "external/perfetto/protos/perfetto/trace/ftrace/printk.pbzero.cc",
         "external/perfetto/protos/perfetto/trace/ftrace/raw_syscalls.pbzero.cc",
         "external/perfetto/protos/perfetto/trace/ftrace/regulator.pbzero.cc",
         "external/perfetto/protos/perfetto/trace/ftrace/sched.pbzero.cc",
@@ -5026,6 +5037,7 @@
         "protos/perfetto/trace/ftrace/net.proto",
         "protos/perfetto/trace/ftrace/oom.proto",
         "protos/perfetto/trace/ftrace/power.proto",
+        "protos/perfetto/trace/ftrace/printk.proto",
         "protos/perfetto/trace/ftrace/raw_syscalls.proto",
         "protos/perfetto/trace/ftrace/regulator.proto",
         "protos/perfetto/trace/ftrace/sched.proto",
@@ -5085,6 +5097,7 @@
         "external/perfetto/protos/perfetto/trace/ftrace/net.pbzero.h",
         "external/perfetto/protos/perfetto/trace/ftrace/oom.pbzero.h",
         "external/perfetto/protos/perfetto/trace/ftrace/power.pbzero.h",
+        "external/perfetto/protos/perfetto/trace/ftrace/printk.pbzero.h",
         "external/perfetto/protos/perfetto/trace/ftrace/raw_syscalls.pbzero.h",
         "external/perfetto/protos/perfetto/trace/ftrace/regulator.pbzero.h",
         "external/perfetto/protos/perfetto/trace/ftrace/sched.pbzero.h",
@@ -8385,6 +8398,7 @@
         "src/trace_processor/metrics/sql/android/startup/launches.sql",
         "src/trace_processor/metrics/sql/android/startup/launches_maxsdk28.sql",
         "src/trace_processor/metrics/sql/android/startup/launches_minsdk29.sql",
+        "src/trace_processor/metrics/sql/android/startup/launches_minsdk33.sql",
         "src/trace_processor/metrics/sql/android/thread_counter_span_view.sql",
         "src/trace_processor/metrics/sql/android/unsymbolized_frames.sql",
         "src/trace_processor/metrics/sql/chrome/actual_power_by_category.sql",
@@ -9417,6 +9431,174 @@
     ],
 }
 
+// GN: [//protos/perfetto/trace:non_minimal_source_set, //protos/perfetto/trace:minimal_source_set]
+java_library {
+    name: "perfetto_trace_java_protos",
+    srcs: [
+        "protos/perfetto/common/android_energy_consumer_descriptor.proto",
+        "protos/perfetto/common/android_log_constants.proto",
+        "protos/perfetto/common/builtin_clock.proto",
+        "protos/perfetto/common/commit_data_request.proto",
+        "protos/perfetto/common/data_source_descriptor.proto",
+        "protos/perfetto/common/descriptor.proto",
+        "protos/perfetto/common/ftrace_descriptor.proto",
+        "protos/perfetto/common/gpu_counter_descriptor.proto",
+        "protos/perfetto/common/interceptor_descriptor.proto",
+        "protos/perfetto/common/observable_events.proto",
+        "protos/perfetto/common/perf_events.proto",
+        "protos/perfetto/common/sys_stats_counters.proto",
+        "protos/perfetto/common/trace_stats.proto",
+        "protos/perfetto/common/tracing_service_capabilities.proto",
+        "protos/perfetto/common/tracing_service_state.proto",
+        "protos/perfetto/common/track_event_descriptor.proto",
+        "protos/perfetto/config/android/android_log_config.proto",
+        "protos/perfetto/config/android/android_polled_state_config.proto",
+        "protos/perfetto/config/android/packages_list_config.proto",
+        "protos/perfetto/config/chrome/chrome_config.proto",
+        "protos/perfetto/config/data_source_config.proto",
+        "protos/perfetto/config/ftrace/ftrace_config.proto",
+        "protos/perfetto/config/gpu/gpu_counter_config.proto",
+        "protos/perfetto/config/gpu/vulkan_memory_config.proto",
+        "protos/perfetto/config/inode_file/inode_file_config.proto",
+        "protos/perfetto/config/interceptor_config.proto",
+        "protos/perfetto/config/interceptors/console_config.proto",
+        "protos/perfetto/config/power/android_power_config.proto",
+        "protos/perfetto/config/process_stats/process_stats_config.proto",
+        "protos/perfetto/config/profiling/heapprofd_config.proto",
+        "protos/perfetto/config/profiling/java_hprof_config.proto",
+        "protos/perfetto/config/profiling/perf_event_config.proto",
+        "protos/perfetto/config/stress_test_config.proto",
+        "protos/perfetto/config/sys_stats/sys_stats_config.proto",
+        "protos/perfetto/config/test_config.proto",
+        "protos/perfetto/config/trace_config.proto",
+        "protos/perfetto/config/track_event/track_event_config.proto",
+        "protos/perfetto/trace/android/android_log.proto",
+        "protos/perfetto/trace/android/camera_event.proto",
+        "protos/perfetto/trace/android/frame_timeline_event.proto",
+        "protos/perfetto/trace/android/gpu_mem_event.proto",
+        "protos/perfetto/trace/android/graphics_frame_event.proto",
+        "protos/perfetto/trace/android/initial_display_state.proto",
+        "protos/perfetto/trace/android/packages_list.proto",
+        "protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto",
+        "protos/perfetto/trace/chrome/chrome_metadata.proto",
+        "protos/perfetto/trace/chrome/chrome_trace_event.proto",
+        "protos/perfetto/trace/clock_snapshot.proto",
+        "protos/perfetto/trace/extension_descriptor.proto",
+        "protos/perfetto/trace/filesystem/inode_file_map.proto",
+        "protos/perfetto/trace/ftrace/binder.proto",
+        "protos/perfetto/trace/ftrace/block.proto",
+        "protos/perfetto/trace/ftrace/cgroup.proto",
+        "protos/perfetto/trace/ftrace/clk.proto",
+        "protos/perfetto/trace/ftrace/compaction.proto",
+        "protos/perfetto/trace/ftrace/cpuhp.proto",
+        "protos/perfetto/trace/ftrace/cros_ec.proto",
+        "protos/perfetto/trace/ftrace/dmabuf_heap.proto",
+        "protos/perfetto/trace/ftrace/dpu.proto",
+        "protos/perfetto/trace/ftrace/ext4.proto",
+        "protos/perfetto/trace/ftrace/f2fs.proto",
+        "protos/perfetto/trace/ftrace/fastrpc.proto",
+        "protos/perfetto/trace/ftrace/fence.proto",
+        "protos/perfetto/trace/ftrace/filemap.proto",
+        "protos/perfetto/trace/ftrace/ftrace.proto",
+        "protos/perfetto/trace/ftrace/ftrace_event.proto",
+        "protos/perfetto/trace/ftrace/ftrace_event_bundle.proto",
+        "protos/perfetto/trace/ftrace/ftrace_stats.proto",
+        "protos/perfetto/trace/ftrace/g2d.proto",
+        "protos/perfetto/trace/ftrace/generic.proto",
+        "protos/perfetto/trace/ftrace/gpu_mem.proto",
+        "protos/perfetto/trace/ftrace/i2c.proto",
+        "protos/perfetto/trace/ftrace/ion.proto",
+        "protos/perfetto/trace/ftrace/ipi.proto",
+        "protos/perfetto/trace/ftrace/irq.proto",
+        "protos/perfetto/trace/ftrace/kmem.proto",
+        "protos/perfetto/trace/ftrace/kvm.proto",
+        "protos/perfetto/trace/ftrace/lowmemorykiller.proto",
+        "protos/perfetto/trace/ftrace/mali.proto",
+        "protos/perfetto/trace/ftrace/mdss.proto",
+        "protos/perfetto/trace/ftrace/mm_event.proto",
+        "protos/perfetto/trace/ftrace/net.proto",
+        "protos/perfetto/trace/ftrace/oom.proto",
+        "protos/perfetto/trace/ftrace/power.proto",
+        "protos/perfetto/trace/ftrace/printk.proto",
+        "protos/perfetto/trace/ftrace/raw_syscalls.proto",
+        "protos/perfetto/trace/ftrace/regulator.proto",
+        "protos/perfetto/trace/ftrace/sched.proto",
+        "protos/perfetto/trace/ftrace/scm.proto",
+        "protos/perfetto/trace/ftrace/sde.proto",
+        "protos/perfetto/trace/ftrace/signal.proto",
+        "protos/perfetto/trace/ftrace/skb.proto",
+        "protos/perfetto/trace/ftrace/sock.proto",
+        "protos/perfetto/trace/ftrace/sync.proto",
+        "protos/perfetto/trace/ftrace/synthetic.proto",
+        "protos/perfetto/trace/ftrace/systrace.proto",
+        "protos/perfetto/trace/ftrace/task.proto",
+        "protos/perfetto/trace/ftrace/tcp.proto",
+        "protos/perfetto/trace/ftrace/test_bundle_wrapper.proto",
+        "protos/perfetto/trace/ftrace/thermal.proto",
+        "protos/perfetto/trace/ftrace/ufs.proto",
+        "protos/perfetto/trace/ftrace/vmscan.proto",
+        "protos/perfetto/trace/ftrace/workqueue.proto",
+        "protos/perfetto/trace/gpu/gpu_counter_event.proto",
+        "protos/perfetto/trace/gpu/gpu_log.proto",
+        "protos/perfetto/trace/gpu/gpu_render_stage_event.proto",
+        "protos/perfetto/trace/gpu/vulkan_api_event.proto",
+        "protos/perfetto/trace/gpu/vulkan_memory_event.proto",
+        "protos/perfetto/trace/interned_data/interned_data.proto",
+        "protos/perfetto/trace/memory_graph.proto",
+        "protos/perfetto/trace/perfetto/perfetto_metatrace.proto",
+        "protos/perfetto/trace/perfetto/tracing_service_event.proto",
+        "protos/perfetto/trace/power/android_energy_estimation_breakdown.proto",
+        "protos/perfetto/trace/power/battery_counters.proto",
+        "protos/perfetto/trace/power/power_rails.proto",
+        "protos/perfetto/trace/profiling/deobfuscation.proto",
+        "protos/perfetto/trace/profiling/heap_graph.proto",
+        "protos/perfetto/trace/profiling/profile_common.proto",
+        "protos/perfetto/trace/profiling/profile_packet.proto",
+        "protos/perfetto/trace/profiling/smaps.proto",
+        "protos/perfetto/trace/ps/process_stats.proto",
+        "protos/perfetto/trace/ps/process_tree.proto",
+        "protos/perfetto/trace/sys_stats/sys_stats.proto",
+        "protos/perfetto/trace/system_info.proto",
+        "protos/perfetto/trace/system_info/cpu_info.proto",
+        "protos/perfetto/trace/test_event.proto",
+        "protos/perfetto/trace/test_extensions.proto",
+        "protos/perfetto/trace/trace.proto",
+        "protos/perfetto/trace/trace_packet.proto",
+        "protos/perfetto/trace/trace_packet_defaults.proto",
+        "protos/perfetto/trace/track_event/chrome_application_state_info.proto",
+        "protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.proto",
+        "protos/perfetto/trace/track_event/chrome_content_settings_event_info.proto",
+        "protos/perfetto/trace/track_event/chrome_frame_reporter.proto",
+        "protos/perfetto/trace/track_event/chrome_histogram_sample.proto",
+        "protos/perfetto/trace/track_event/chrome_keyed_service.proto",
+        "protos/perfetto/trace/track_event/chrome_latency_info.proto",
+        "protos/perfetto/trace/track_event/chrome_legacy_ipc.proto",
+        "protos/perfetto/trace/track_event/chrome_message_pump.proto",
+        "protos/perfetto/trace/track_event/chrome_mojo_event_info.proto",
+        "protos/perfetto/trace/track_event/chrome_process_descriptor.proto",
+        "protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.proto",
+        "protos/perfetto/trace/track_event/chrome_thread_descriptor.proto",
+        "protos/perfetto/trace/track_event/chrome_user_event.proto",
+        "protos/perfetto/trace/track_event/chrome_window_handle_event_info.proto",
+        "protos/perfetto/trace/track_event/counter_descriptor.proto",
+        "protos/perfetto/trace/track_event/debug_annotation.proto",
+        "protos/perfetto/trace/track_event/log_message.proto",
+        "protos/perfetto/trace/track_event/process_descriptor.proto",
+        "protos/perfetto/trace/track_event/source_location.proto",
+        "protos/perfetto/trace/track_event/task_execution.proto",
+        "protos/perfetto/trace/track_event/thread_descriptor.proto",
+        "protos/perfetto/trace/track_event/track_descriptor.proto",
+        "protos/perfetto/trace/track_event/track_event.proto",
+        "protos/perfetto/trace/translation/translation_table.proto",
+        "protos/perfetto/trace/trigger.proto",
+        "protos/perfetto/trace/ui_state.proto",
+    ],
+    proto: {
+        type: "lite",
+        canonical_path_from_root: false,
+    },
+}
+
 // GN: //protos/perfetto/trace:perfetto_trace_protos
 cc_library_static {
     name: "perfetto_trace_protos",
@@ -10616,18 +10798,6 @@
     ],
 }
 
-// TODO(b/225381015): add fix to include all the trace protos.
-java_library {
-    name: "perfetto_trace_java_protos",
-    proto: {
-        type: "lite",
-        canonical_path_from_root: false,
-    },
-    srcs: [
-        "protos/perfetto/common/*.proto",
-    ]
-}
-
 // This sample target shows how to use the perfetto client API from within the
 // Android tree.
 cc_binary {
diff --git a/Android.bp.extras b/Android.bp.extras
index 35e8368..d6deb97 100644
--- a/Android.bp.extras
+++ b/Android.bp.extras
@@ -20,18 +20,6 @@
     ],
 }
 
-// TODO(b/225381015): add fix to include all the trace protos.
-java_library {
-    name: "perfetto_trace_java_protos",
-    proto: {
-        type: "lite",
-        canonical_path_from_root: false,
-    },
-    srcs: [
-        "protos/perfetto/common/*.proto",
-    ]
-}
-
 // This sample target shows how to use the perfetto client API from within the
 // Android tree.
 cc_binary {
diff --git a/BUILD b/BUILD
index 8870bbd..43e1649 100644
--- a/BUILD
+++ b/BUILD
@@ -1109,6 +1109,7 @@
         "src/trace_processor/metrics/sql/android/startup/launches.sql",
         "src/trace_processor/metrics/sql/android/startup/launches_maxsdk28.sql",
         "src/trace_processor/metrics/sql/android/startup/launches_minsdk29.sql",
+        "src/trace_processor/metrics/sql/android/startup/launches_minsdk33.sql",
         "src/trace_processor/metrics/sql/android/thread_counter_span_view.sql",
         "src/trace_processor/metrics/sql/android/unsymbolized_frames.sql",
         "src/trace_processor/metrics/sql/chrome/actual_power_by_category.sql",
@@ -1353,6 +1354,8 @@
         ":include_perfetto_ext_base_base",
         ":include_perfetto_ext_trace_processor_demangle",
     ],
+    deps = [
+    ] + PERFETTO_CONFIG.deps.llvm_demangle,
     linkstatic = True,
 )
 
@@ -2178,6 +2181,45 @@
     ],
 )
 
+# GN target: [//protos/perfetto/metrics/chrome:source_set]
+perfetto_proto_library(
+    name = "chrome_metrics_proto",
+    visibility = PERFETTO_CONFIG.public_visibility,
+    deps = [
+        ":protos_perfetto_metrics_android_protos",
+        ":protos_perfetto_metrics_chrome_protos",
+        ":protos_perfetto_metrics_custom_options_protos",
+        ":protos_perfetto_metrics_protos",
+    ],
+)
+
+# GN target: [//protos/perfetto/metrics/chrome:source_set]
+perfetto_cc_proto_library(
+    name = "chrome_metrics_cc_proto",
+    visibility = PERFETTO_CONFIG.public_visibility,
+    deps = [
+        ":chrome_metrics_proto",
+    ],
+)
+
+# GN target: [//protos/perfetto/metrics/chrome:source_set]
+perfetto_java_proto_library(
+    name = "chrome_metrics_java_proto",
+    visibility = PERFETTO_CONFIG.public_visibility,
+    deps = [
+        ":chrome_metrics_proto",
+    ],
+)
+
+# GN target: [//protos/perfetto/metrics/chrome:source_set]
+perfetto_java_lite_proto_library(
+    name = "chrome_metrics_java_proto_lite",
+    visibility = PERFETTO_CONFIG.public_visibility,
+    deps = [
+        ":chrome_metrics_proto",
+    ],
+)
+
 # GN target: //protos/perfetto/common:cpp
 perfetto_cc_protocpp_library(
     name = "protos_perfetto_common_cpp",
@@ -2920,6 +2962,7 @@
         "protos/perfetto/trace/ftrace/net.proto",
         "protos/perfetto/trace/ftrace/oom.proto",
         "protos/perfetto/trace/ftrace/power.proto",
+        "protos/perfetto/trace/ftrace/printk.proto",
         "protos/perfetto/trace/ftrace/raw_syscalls.proto",
         "protos/perfetto/trace/ftrace/regulator.proto",
         "protos/perfetto/trace/ftrace/sched.proto",
diff --git a/CHANGELOG b/CHANGELOG
index 955527a..382f468 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -8,6 +8,9 @@
       message.
   Trace Processor:
     * Added prebuilts for mac-arm64.
+    * Changed LIKE comparisions to be case-insenstive. This reverts the change
+      introduced in v22. GLOB should be used where case senstive searches are
+      desired; built-in metrics continue to require the use of GLOB.
     * Added an optional dependency from trace processor onto a subset of
       sources from llvm-project for function name demangling. Bazel embedders
       might need to update their PERFETTO_CONFIG in perfetto_cfg.bzl to opt in
diff --git a/include/perfetto/base/build_configs/bazel/perfetto_build_flags.h b/include/perfetto/base/build_configs/bazel/perfetto_build_flags.h
index 53c423e..e0958d4 100644
--- a/include/perfetto/base/build_configs/bazel/perfetto_build_flags.h
+++ b/include/perfetto/base/build_configs/bazel/perfetto_build_flags.h
@@ -44,7 +44,7 @@
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_HEAPPROFD() (0)
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_STDERR_CRASH_DUMP() (0)
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_X64_CPU_OPT() (0)
-#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_LLVM_DEMANGLE() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_LLVM_DEMANGLE() (1)
 
 // clang-format on
 #endif  // GEN_BUILD_CONFIG_PERFETTO_BUILD_FLAGS_H_
diff --git a/include/perfetto/tracing/event_context.h b/include/perfetto/tracing/event_context.h
index f1b77d6..b376c5a 100644
--- a/include/perfetto/tracing/event_context.h
+++ b/include/perfetto/tracing/event_context.h
@@ -56,6 +56,10 @@
 
   ~EventContext();
 
+  internal::TrackEventIncrementalState* GetIncrementalState() const {
+    return incremental_state_;
+  }
+
   // Get a TrackEvent message to write typed arguments to.
   //
   // event() is a template method to allow callers to specify a subclass of
diff --git a/include/perfetto/tracing/internal/track_event_data_source.h b/include/perfetto/tracing/internal/track_event_data_source.h
index 93f2428..4f083a8 100644
--- a/include/perfetto/tracing/internal/track_event_data_source.h
+++ b/include/perfetto/tracing/internal/track_event_data_source.h
@@ -338,7 +338,19 @@
         instances, category, /*name=*/nullptr, type, track, timestamp,
         [&](EventContext event_ctx) {
           if (std::is_integral<ValueType>::value) {
-            event_ctx.event()->set_counter_value(static_cast<int64_t>(value));
+            int64_t value_int64 = static_cast<int64_t>(value);
+            if (track.is_incremental()) {
+              TrackEventIncrementalState* incr_state =
+                  event_ctx.GetIncrementalState();
+              PERFETTO_DCHECK(incr_state != nullptr);
+              auto prv_value =
+                  incr_state->last_counter_value_per_track[track.uuid];
+              event_ctx.event()->set_counter_value(value_int64 - prv_value);
+              prv_value = value_int64;
+              incr_state->last_counter_value_per_track[track.uuid] = prv_value;
+            } else {
+              event_ctx.event()->set_counter_value(value_int64);
+            }
           } else {
             event_ctx.event()->set_double_counter_value(
                 static_cast<double>(value));
diff --git a/include/perfetto/tracing/internal/track_event_internal.h b/include/perfetto/tracing/internal/track_event_internal.h
index 5e0665c..97e8ebc 100644
--- a/include/perfetto/tracing/internal/track_event_internal.h
+++ b/include/perfetto/tracing/internal/track_event_internal.h
@@ -150,6 +150,11 @@
   // ClockSnapshot. The increment between this timestamp and the current trace
   // time (GetTimeNs) is a value in kClockIdIncremental's domain.
   uint64_t last_timestamp_ns = 0;
+
+  // The latest known counter values that was used in a TracePacket for each
+  // counter track. The key (uint64_t) is the uuid of counter track.
+  // The value is used for delta encoding of counter values.
+  std::unordered_map<uint64_t, int64_t> last_counter_value_per_track;
 };
 
 // The backend portion of the track event trace point implemention. Outlined to
diff --git a/include/perfetto/tracing/internal/track_event_macros.h b/include/perfetto/tracing/internal/track_event_macros.h
index a901524..05dd5af 100644
--- a/include/perfetto/tracing/internal/track_event_macros.h
+++ b/include/perfetto/tracing/internal/track_event_macros.h
@@ -89,10 +89,11 @@
 // Defines the TrackEvent data source for the current track event namespace.
 // `virtual ~TrackEvent` is added to avoid `-Wweak-vtables` warning.
 // Learn more : aosp/2019906
-#define PERFETTO_INTERNAL_DECLARE_TRACK_EVENT_DATA_SOURCE()              \
-  struct TrackEvent : public ::perfetto::internal::TrackEventDataSource< \
-                          TrackEvent, &internal::kCategoryRegistry> {    \
-    virtual ~TrackEvent();                                               \
+#define PERFETTO_INTERNAL_DECLARE_TRACK_EVENT_DATA_SOURCE() \
+  struct PERFETTO_COMPONENT_EXPORT TrackEvent               \
+      : public ::perfetto::internal::TrackEventDataSource<  \
+            TrackEvent, &internal::kCategoryRegistry> {     \
+    virtual ~TrackEvent();                                  \
   }
 
 #define PERFETTO_INTERNAL_DEFINE_TRACK_EVENT_DATA_SOURCE() \
diff --git a/include/perfetto/tracing/track.h b/include/perfetto/tracing/track.h
index 3a84364..1ddb85e 100644
--- a/include/perfetto/tracing/track.h
+++ b/include/perfetto/tracing/track.h
@@ -258,6 +258,13 @@
                         unit_multiplier_, is_incremental_);
   }
 
+  constexpr CounterTrack set_is_incremental(bool is_incremental = true) const {
+    return CounterTrack(uuid, parent_uuid, name_, category_, unit_, unit_name_,
+                        unit_multiplier_, is_incremental);
+  }
+
+  constexpr bool is_incremental() const { return is_incremental_; }
+
   void Serialize(protos::pbzero::TrackDescriptor*) const;
   protos::gen::TrackDescriptor Serialize() const;
 
@@ -278,19 +285,12 @@
         unit_multiplier_(unit_multiplier),
         is_incremental_(is_incremental) {}
 
-  // TODO(skyostil): Expose incremental counters once we decide how to manage
-  // their incremental state.
-  constexpr CounterTrack set_is_incremental(bool is_incremental = true) const {
-    return CounterTrack(uuid, parent_uuid, name_, category_, unit_, unit_name_,
-                        unit_multiplier_, is_incremental);
-  }
-
   const char* const name_;
   const char* const category_;
   Unit unit_ = perfetto::protos::pbzero::CounterDescriptor::UNIT_UNSPECIFIED;
   const char* const unit_name_ = nullptr;
   int64_t unit_multiplier_ = 1;
-  bool is_incremental_ = false;
+  const bool is_incremental_ = false;
 };
 
 namespace internal {
diff --git a/protos/perfetto/trace/ftrace/all_protos.gni b/protos/perfetto/trace/ftrace/all_protos.gni
index 9330b8d..a51a05f 100644
--- a/protos/perfetto/trace/ftrace/all_protos.gni
+++ b/protos/perfetto/trace/ftrace/all_protos.gni
@@ -50,6 +50,7 @@
   "net.proto",
   "oom.proto",
   "power.proto",
+  "printk.proto",
   "raw_syscalls.proto",
   "regulator.proto",
   "sched.proto",
diff --git a/protos/perfetto/trace/ftrace/ftrace_event.proto b/protos/perfetto/trace/ftrace/ftrace_event.proto
index e917203..b58950f 100644
--- a/protos/perfetto/trace/ftrace/ftrace_event.proto
+++ b/protos/perfetto/trace/ftrace/ftrace_event.proto
@@ -50,6 +50,7 @@
 import "protos/perfetto/trace/ftrace/net.proto";
 import "protos/perfetto/trace/ftrace/oom.proto";
 import "protos/perfetto/trace/ftrace/power.proto";
+import "protos/perfetto/trace/ftrace/printk.proto";
 import "protos/perfetto/trace/ftrace/raw_syscalls.proto";
 import "protos/perfetto/trace/ftrace/regulator.proto";
 import "protos/perfetto/trace/ftrace/sched.proto";
@@ -504,5 +505,6 @@
     WakeupSourceDeactivateFtraceEvent wakeup_source_deactivate = 405;
     UfshcdCommandFtraceEvent ufshcd_command = 406;
     UfshcdClkGatingFtraceEvent ufshcd_clk_gating = 407;
+    ConsoleFtraceEvent console = 408;
   }
 }
diff --git a/protos/perfetto/trace/ftrace/printk.proto b/protos/perfetto/trace/ftrace/printk.proto
new file mode 100644
index 0000000..45261e6
--- /dev/null
+++ b/protos/perfetto/trace/ftrace/printk.proto
@@ -0,0 +1,10 @@
+// Autogenerated by:
+// ../../tools/ftrace_proto_gen/ftrace_proto_gen.cc
+// Do not edit.
+
+syntax = "proto2";
+package perfetto.protos;
+
+message ConsoleFtraceEvent {
+  optional string msg = 1;
+}
diff --git a/protos/perfetto/trace/perfetto_trace.proto b/protos/perfetto/trace/perfetto_trace.proto
index 27c0af2..7bee482 100644
--- a/protos/perfetto/trace/perfetto_trace.proto
+++ b/protos/perfetto/trace/perfetto_trace.proto
@@ -5559,6 +5559,14 @@
 
 // End of protos/perfetto/trace/ftrace/power.proto
 
+// Begin of protos/perfetto/trace/ftrace/printk.proto
+
+message ConsoleFtraceEvent {
+  optional string msg = 1;
+}
+
+// End of protos/perfetto/trace/ftrace/printk.proto
+
 // Begin of protos/perfetto/trace/ftrace/raw_syscalls.proto
 
 message SysEnterFtraceEvent {
@@ -6378,6 +6386,7 @@
     WakeupSourceDeactivateFtraceEvent wakeup_source_deactivate = 405;
     UfshcdCommandFtraceEvent ufshcd_command = 406;
     UfshcdClkGatingFtraceEvent ufshcd_clk_gating = 407;
+    ConsoleFtraceEvent console = 408;
   }
 }
 
diff --git a/protos/third_party/chromium/chrome_track_event.proto b/protos/third_party/chromium/chrome_track_event.proto
index c30f4cd..debe2a7 100644
--- a/protos/third_party/chromium/chrome_track_event.proto
+++ b/protos/third_party/chromium/chrome_track_event.proto
@@ -581,6 +581,7 @@
     NO_RESPONSE_HEAD = 52;
     ACTIVATION_NAVIGATION_DISALLOWED_FOR_BUG_1234857 = 53;
     ERROR_DOCUMENT = 54;
+    FENCED_FRAMES_EMBEDDER = 55;
   }
 
   optional BackForwardCacheNotRestoredReason
diff --git a/src/trace_processor/importers/ftrace/ftrace_parser.cc b/src/trace_processor/importers/ftrace/ftrace_parser.cc
index f83aede..862f21d 100644
--- a/src/trace_processor/importers/ftrace/ftrace_parser.cc
+++ b/src/trace_processor/importers/ftrace/ftrace_parser.cc
@@ -2020,7 +2020,8 @@
                                       protozero::ConstBytes blob) {
   protos::pbzero::UfshcdCommandFtraceEvent::Decoder evt(blob.data, blob.size);
   uint32_t num = evt.doorbell() > 0 ?
-      static_cast<uint32_t>(PERFETTO_POPCOUNT(evt.doorbell())) : 1;
+      static_cast<uint32_t>(PERFETTO_POPCOUNT(evt.doorbell())) :
+      (evt.str_t() == 1 ? 0 : 1);
 
   TrackId track = context_->track_tracker->InternGlobalCounterTrack(
       ufs_command_count_id_);
diff --git a/src/trace_processor/importers/json/json_trace_parser.cc b/src/trace_processor/importers/json/json_trace_parser.cc
index 91cac7a..600c4f0 100644
--- a/src/trace_processor/importers/json/json_trace_parser.cc
+++ b/src/trace_processor/importers/json/json_trace_parser.cc
@@ -302,16 +302,14 @@
       break;
     }
     case 'M': {  // Metadata events (process and thread names).
-      if (strcmp(value["name"].asCString(), "thread_name") == 0 &&
-          !value["args"]["name"].empty()) {
+      if (name == "thread_name" && !value["args"]["name"].empty()) {
         const char* thread_name = value["args"]["name"].asCString();
         auto thread_name_id = context_->storage->InternString(thread_name);
         procs->UpdateThreadName(tid, thread_name_id,
                                 ThreadNamePriority::kOther);
         break;
       }
-      if (strcmp(value["name"].asCString(), "process_name") == 0 &&
-          !value["args"]["name"].empty()) {
+      if (name == "process_name" && !value["args"]["name"].empty()) {
         const char* proc_name = value["args"]["name"].asCString();
         procs->SetProcessMetadata(pid, base::nullopt, proc_name,
                                   base::StringView());
diff --git a/src/trace_processor/metrics/sql/BUILD.gn b/src/trace_processor/metrics/sql/BUILD.gn
index 5c07ca1..0ec76e6 100644
--- a/src/trace_processor/metrics/sql/BUILD.gn
+++ b/src/trace_processor/metrics/sql/BUILD.gn
@@ -79,6 +79,7 @@
   "android/unsymbolized_frames.sql",
   "android/startup/launches_maxsdk28.sql",
   "android/startup/launches_minsdk29.sql",
+  "android/startup/launches_minsdk33.sql",
   "android/startup/launches.sql",
   "android/startup/hsc.sql",
   "chrome/actual_power_by_category.sql",
diff --git a/src/trace_processor/metrics/sql/android/startup/launches.sql b/src/trace_processor/metrics/sql/android/startup/launches.sql
index 999ba6e..60c1cab 100644
--- a/src/trace_processor/metrics/sql/android/startup/launches.sql
+++ b/src/trace_processor/metrics/sql/android/startup/launches.sql
@@ -30,25 +30,31 @@
 AND (process.name IS NULL OR process.name = 'system_server');
 
 SELECT CREATE_FUNCTION(
-  'ANDROID_SDK_LEVEL()',
-  'INT', "
-    SELECT int_value
-    FROM metadata
-    WHERE name = 'android_sdk_version'
-  ");
-
-SELECT CREATE_FUNCTION(
-  'METRICS_LOGGER_SLICE_COUNT()',
+  'SLICE_COUNT(slice_glob STRING)',
   'INT',
-  "SELECT COUNT(1) FROM slice WHERE name GLOB 'MetricsLogger:*'"
+  'SELECT COUNT(1) FROM slice WHERE name GLOB $slice_glob'
+);
+
+-- All activity launches in the trace, keyed by ID.
+-- Populated by different scripts depending on the platform version / contents.
+-- See android/startup/launches*.sql
+DROP TABLE IF EXISTS launches;
+CREATE TABLE launches(
+  id INTEGER PRIMARY KEY,
+  ts BIG INT,
+  ts_end BIG INT,
+  dur BIG INT,
+  package STRING
 );
 
 -- Note: on Q, we didn't have Android fingerprints but we *did*
 -- have ActivityMetricsLogger events so we will use this approach
 -- if we see any such events.
 SELECT CASE
-  WHEN (ANDROID_SDK_LEVEL() >= 29 OR METRICS_LOGGER_SLICE_COUNT() > 0)
-  THEN RUN_METRIC('android/startup/launches_minsdk29.sql')
+  WHEN SLICE_COUNT('launchingActivity#*:*') > 0
+    THEN RUN_METRIC('android/startup/launches_minsdk33.sql')
+  WHEN SLICE_COUNT('MetricsLogger:*') > 0
+    THEN RUN_METRIC('android/startup/launches_minsdk29.sql')
   ELSE RUN_METRIC('android/startup/launches_maxsdk28.sql')
 END;
 
diff --git a/src/trace_processor/metrics/sql/android/startup/launches_maxsdk28.sql b/src/trace_processor/metrics/sql/android/startup/launches_maxsdk28.sql
index 8753da1..35c797e 100644
--- a/src/trace_processor/metrics/sql/android/startup/launches_maxsdk28.sql
+++ b/src/trace_processor/metrics/sql/android/startup/launches_maxsdk28.sql
@@ -14,23 +14,15 @@
 -- limitations under the License.
 --
 
--- All activity launches in the trace, keyed by ID.
-DROP TABLE IF EXISTS launches;
-CREATE TABLE launches(
-  id INTEGER PRIMARY KEY,
-  ts BIG INT,
-  ts_end BIG INT,
-  dur BIG INT,
-  package STRING
-);
-
 -- Cold/warm starts emitted launching slices on API level 28-.
-INSERT INTO launches(ts, ts_end, dur, package)
+INSERT INTO launches(id, ts, ts_end, dur, package)
 SELECT
+  ROW_NUMBER() OVER(ORDER BY ts) AS id,
   launching_events.ts AS ts,
   launching_events.ts_end AS ts_end,
   launching_events.ts_end - launching_events.ts AS dur,
   package_name AS package
-FROM launching_events;
+FROM launching_events
+ORDER BY ts;
 
 -- TODO(lalitm): add handling of hot starts using frame timings.
diff --git a/src/trace_processor/metrics/sql/android/startup/launches_minsdk29.sql b/src/trace_processor/metrics/sql/android/startup/launches_minsdk29.sql
index 1f4c0f7..e5631bf 100644
--- a/src/trace_processor/metrics/sql/android/startup/launches_minsdk29.sql
+++ b/src/trace_processor/metrics/sql/android/startup/launches_minsdk29.sql
@@ -53,23 +53,14 @@
 SELECT ts FROM slice
 WHERE name = 'MetricsLogger:launchObserverNotifyActivityLaunchFinished';
 
--- All activity launches in the trace, keyed by ID.
-DROP TABLE IF EXISTS launches;
-CREATE TABLE launches(
-  ts BIG INT,
-  ts_end BIG INT,
-  dur BIG INT,
-  id INT,
-  package STRING);
-
 -- Use the starting event package name. The finish event package name
 -- is not reliable in the case of failed launches.
-INSERT INTO launches
+INSERT INTO launches(id, ts, ts_end, dur, package)
 SELECT
+  lpart.id AS id,
   lpart.ts AS ts,
   launching_events.ts_end AS ts_end,
   launching_events.ts_end - lpart.ts AS dur,
-  lpart.id AS id,
   package_name AS package
 FROM launch_partitions AS lpart
 JOIN launching_events ON
diff --git a/src/trace_processor/metrics/sql/android/startup/launches_minsdk33.sql b/src/trace_processor/metrics/sql/android/startup/launches_minsdk33.sql
new file mode 100644
index 0000000..f3773bb
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/startup/launches_minsdk33.sql
@@ -0,0 +1,47 @@
+--
+-- Copyright 2022 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+--     https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+DROP VIEW IF EXISTS launch_async_events;
+CREATE VIEW launch_async_events AS
+SELECT
+  ts,
+  dur,
+  SUBSTR(name, 19) id
+FROM slice
+WHERE
+  name GLOB 'launchingActivity#*'
+  AND dur != 0
+  AND INSTR(name, ':') = 0;
+
+DROP VIEW IF EXISTS launch_complete_events;
+CREATE VIEW launch_complete_events AS
+SELECT
+  STR_SPLIT(completed, ':completed:', 0) id,
+  STR_SPLIT(completed, ':completed:', 1) package_name
+FROM (
+  SELECT SUBSTR(name, 19) completed
+  FROM slice
+  WHERE dur = 0 AND name GLOB 'launchingActivity#*:completed:*'
+);
+
+INSERT INTO launches(id, ts, ts_end, dur, package)
+SELECT
+  id,
+  ts,
+  ts + dur ts_end,
+  dur,
+  package_name
+FROM launch_async_events JOIN launch_complete_events USING (id);
diff --git a/src/trace_processor/trace_processor_impl.cc b/src/trace_processor/trace_processor_impl.cc
index 9ace9ee..a1660ff 100644
--- a/src/trace_processor/trace_processor_impl.cc
+++ b/src/trace_processor/trace_processor_impl.cc
@@ -108,11 +108,6 @@
   if (error) {
     PERFETTO_FATAL("Error setting pragma temp_store: %s", error);
   }
-  sqlite3_exec(db, "PRAGMA case_sensitive_like = 1", 0, 0, &error);
-  if (error) {
-    PERFETTO_FATAL("Error setting pragma case_sensitive_like: %s", error);
-  }
-
   sqlite3_str_split_init(db);
 // In Android tree builds, we don't have the percentile module.
 // Just don't include it.
diff --git a/src/trace_processor/trace_processor_shell.cc b/src/trace_processor/trace_processor_shell.cc
index 51c9e18..7c90fc5 100644
--- a/src/trace_processor/trace_processor_shell.cc
+++ b/src/trace_processor/trace_processor_shell.cc
@@ -198,7 +198,7 @@
       "where severity IN ('error', 'data_loss') and value > 0");
 
   bool first = true;
-  for (uint32_t rows = 0; it.Next(); rows++) {
+  while (it.Next()) {
     if (first) {
       fprintf(stderr, "Error stats for this trace:\n");
 
@@ -269,7 +269,7 @@
   auto tables_it = g_tp->ExecuteQuery(
       "SELECT name FROM perfetto_tables UNION "
       "SELECT name FROM sqlite_master WHERE type='table'");
-  for (uint32_t rows = 0; tables_it.Next(); rows++) {
+  while (tables_it.Next()) {
     std::string table_name = tables_it.Get(0).string_value;
     PERFETTO_CHECK(!base::Contains(table_name, '\''));
     std::string export_sql = "CREATE TABLE perfetto_export." + table_name +
@@ -290,7 +290,7 @@
   // Export views.
   auto views_it =
       g_tp->ExecuteQuery("SELECT sql FROM sqlite_master WHERE type='view'");
-  for (uint32_t rows = 0; views_it.Next(); rows++) {
+  while (views_it.Next()) {
     std::string sql = views_it.Get(0).string_value;
     // View statements are of the form "CREATE VIEW name AS stmt". We need to
     // rewrite name to point to the exported db.
@@ -523,8 +523,7 @@
   }
   fprintf(output, "\n");
 
-  uint32_t rows;
-  for (rows = 0; has_more; rows++, has_more = it->Next()) {
+  for (; has_more; has_more = it->Next()) {
     for (uint32_t c = 0; c < it->ColumnCount(); c++) {
       if (c > 0)
         fprintf(output, ",");
diff --git a/src/trace_processor/trace_sorter.cc b/src/trace_processor/trace_sorter.cc
index a3907dd..766508f 100644
--- a/src/trace_processor/trace_sorter.cc
+++ b/src/trace_processor/trace_sorter.cc
@@ -81,8 +81,7 @@
 // time in a profiler.
 void TraceSorter::SortAndExtractEventsUntilPacket(uint64_t limit_packet_idx) {
   constexpr int64_t kTsMax = std::numeric_limits<int64_t>::max();
-  size_t iterations = 0;
-  for (;; iterations++) {
+  for (;;) {
     size_t min_queue_idx = 0;  // The index of the queue with the min(ts).
 
     // The top-2 min(ts) among all queues.
diff --git a/src/traced/probes/ftrace/event_info.cc b/src/traced/probes/ftrace/event_info.cc
index ae030ab..65012de 100644
--- a/src/traced/probes/ftrace/event_info.cc
+++ b/src/traced/probes/ftrace/event_info.cc
@@ -6648,6 +6648,16 @@
        kUnsetFtraceId,
        405,
        kUnsetSize},
+      {"console",
+       "printk",
+       {
+           {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+            "msg", 1, ProtoSchemaType::kString,
+            TranslationStrategy::kInvalidTranslationStrategy},
+       },
+       kUnsetFtraceId,
+       408,
+       kUnsetSize},
       {"sys_enter",
        "raw_syscalls",
        {
diff --git a/src/tracing/core/tracing_service_impl.cc b/src/tracing/core/tracing_service_impl.cc
index f9da779..807b955 100644
--- a/src/tracing/core/tracing_service_impl.cc
+++ b/src/tracing/core/tracing_service_impl.cc
@@ -1963,13 +1963,11 @@
 
   // Queue the IPCs to producers with active data sources that opted in.
   std::map<ProducerID, std::vector<DataSourceInstanceID>> clear_map;
-  int ds_clear_count = 0;
   for (const auto& kv : tracing_session->data_source_instances) {
     ProducerID producer_id = kv.first;
     const DataSourceInstance& data_source = kv.second;
     if (data_source.handles_incremental_state_clear) {
       clear_map[producer_id].push_back(data_source.instance_id);
-      ++ds_clear_count;
     }
   }
 
diff --git a/src/tracing/test/api_integrationtest.cc b/src/tracing/test/api_integrationtest.cc
index dda24f1..f42fdd9 100644
--- a/src/tracing/test/api_integrationtest.cc
+++ b/src/tracing/test/api_integrationtest.cc
@@ -4753,6 +4753,70 @@
 }
 #endif  // PERFETTO_BUILDFLAG(PERFETTO_COMPILER_CLANG)
 
+TEST_P(PerfettoApiTest, CountersDeltaEncoding) {
+  auto* tracing_session = NewTraceWithCategories({"cat"});
+  tracing_session->get()->StartBlocking();
+
+  // Describe a counter track.
+  perfetto::CounterTrack track1 =
+      perfetto::CounterTrack("Framerate1", "fps1").set_is_incremental(true);
+  // Global tracks can be constructed at build time.
+  constexpr perfetto::CounterTrack track2 =
+      perfetto::CounterTrack::Global("Framerate2", "fps2")
+          .set_is_incremental(true);
+  perfetto::CounterTrack track3 = perfetto::CounterTrack("Framerate3", "fps3");
+
+  TRACE_COUNTER("cat", track1, 120);
+  TRACE_COUNTER("cat", track2, 1000);
+  TRACE_COUNTER("cat", track3, 10009);
+
+  TRACE_COUNTER("cat", track1, 10);
+  TRACE_COUNTER("cat", track1, 1200);
+  TRACE_COUNTER("cat", track1, 34);
+
+  TRACE_COUNTER("cat", track3, 975);
+  TRACE_COUNTER("cat", track2, 449);
+  TRACE_COUNTER("cat", track2, 2);
+
+  TRACE_COUNTER("cat", track3, 1091);
+  TRACE_COUNTER("cat", track3, 110);
+  TRACE_COUNTER("cat", track3, 1081);
+
+  TRACE_COUNTER("cat", track1, 98);
+  TRACE_COUNTER("cat", track2, 1084);
+
+  perfetto::TrackEvent::Flush();
+
+  tracing_session->get()->StopBlocking();
+  std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
+  perfetto::protos::gen::Trace trace;
+  ASSERT_TRUE(trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
+  std::unordered_map<uint64_t, std::string> counter_names;
+  // Map(Counter name -> counter values)
+  std::unordered_map<std::string, std::vector<int64_t>> values;
+  for (const auto& packet : trace.packet()) {
+    if (packet.has_track_descriptor()) {
+      auto& desc = packet.track_descriptor();
+      if (!desc.has_counter())
+        continue;
+      counter_names[desc.uuid()] = desc.name();
+      EXPECT_EQ((desc.name() != "Framerate3"), desc.counter().is_incremental());
+    }
+    if (packet.has_track_event()) {
+      auto event = packet.track_event();
+      EXPECT_EQ(perfetto::protos::gen::TrackEvent_Type_TYPE_COUNTER,
+                event.type());
+      auto& counter_name = counter_names.at(event.track_uuid());
+      values[counter_name].push_back(event.counter_value());
+    }
+  }
+  ASSERT_EQ(3u, values.size());
+  using IntVector = std::vector<int64_t>;
+  EXPECT_EQ((IntVector{120, -110, 1190, -1166, 64}), values.at("Framerate1"));
+  EXPECT_EQ((IntVector{1000, -551, -447, 1082}), values.at("Framerate2"));
+  EXPECT_EQ((IntVector{10009, 975, 1091, 110, 1081}), values.at("Framerate3"));
+}
+
 TEST_P(PerfettoApiTest, Counters) {
   auto* tracing_session = NewTraceWithCategories({"cat"});
   tracing_session->get()->StartBlocking();
diff --git a/test/data/ui-screenshots/ui-chrome_rendering_desktop_select_slice_with_flows.png.sha256 b/test/data/ui-screenshots/ui-chrome_rendering_desktop_select_slice_with_flows.png.sha256
index 05d079d..f0ab323 100644
--- a/test/data/ui-screenshots/ui-chrome_rendering_desktop_select_slice_with_flows.png.sha256
+++ b/test/data/ui-screenshots/ui-chrome_rendering_desktop_select_slice_with_flows.png.sha256
@@ -1 +1 @@
-7d48f3051376161df84deda47c3b03e37e6ca2bc01e4bdb3be3095738b27da37
\ No newline at end of file
+bc8fec10f063913f573a4c9a677df01956e5e902f6d6a0fdc0debaf0b2003158
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_navigate_navigate_back_and_forward.png.sha256 b/test/data/ui-screenshots/ui-routing_navigate_navigate_back_and_forward.png.sha256
index 2d762f9..b48e6b7 100644
--- a/test/data/ui-screenshots/ui-routing_navigate_navigate_back_and_forward.png.sha256
+++ b/test/data/ui-screenshots/ui-routing_navigate_navigate_back_and_forward.png.sha256
@@ -1 +1 @@
-25c8506f82ae41dc34b382cf619300e5907a2a9798bef94c60fc45a654c90a3d
\ No newline at end of file
+bb6094a29a504093b63964c472145be75b7ad010848fe49fd74ac805d3add788
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_open_invalid_trace_from_blank_page.png.sha256 b/test/data/ui-screenshots/ui-routing_open_invalid_trace_from_blank_page.png.sha256
index ce4aadf..d7c7cb9 100644
--- a/test/data/ui-screenshots/ui-routing_open_invalid_trace_from_blank_page.png.sha256
+++ b/test/data/ui-screenshots/ui-routing_open_invalid_trace_from_blank_page.png.sha256
@@ -1 +1 @@
-72e9695470c9067005bca54fcdee310feaeed23d58d6bf4c2e575748a992027e
\ No newline at end of file
+14e436dda252119dbe75bbe7233e8b62ade69e27bbad311181927c097adb86d0
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_invalid_trace.png.sha256 b/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_invalid_trace.png.sha256
index 3c99db9..b5f3a52 100644
--- a/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_invalid_trace.png.sha256
+++ b/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_invalid_trace.png.sha256
@@ -1 +1 @@
-9425ea9f775ab88ebd9d0f47946c0835191a7d4579da40d04f20c9db9d288e95
\ No newline at end of file
+77ead2d35348d988d3938b88fc66f0731f494fb77f2165d3fbddca7f37df97f6
\ No newline at end of file
diff --git a/test/synth_common.py b/test/synth_common.py
index 92d8e3f..be52735 100644
--- a/test/synth_common.py
+++ b/test/synth_common.py
@@ -187,6 +187,9 @@
   def add_atrace_async_end(self, ts, tid, pid, buf):
     self.add_print(ts, tid, 'F|{}|{}|0'.format(pid, buf))
 
+  def add_atrace_instant(self, ts, tid, pid, buf):
+    self.add_print(ts, tid, 'I|{}|{}'.format(pid, buf))
+
   def add_process(self, pid, ppid, cmdline, uid=None):
     process = self.packet.process_tree.processes.add()
     process.pid = pid
diff --git a/test/trace_processor/startup/android_startup_minsdk33.out b/test/trace_processor/startup/android_startup_minsdk33.out
new file mode 100644
index 0000000..e7022b5
--- /dev/null
+++ b/test/trace_processor/startup/android_startup_minsdk33.out
@@ -0,0 +1,25 @@
+android_startup {
+  startup {
+    startup_id: 1
+    package_name: "com.google.android.calendar"
+    zygote_new_process: false
+    to_first_frame {
+      dur_ns: 100
+      main_thread_by_task_state {
+        running_dur_ns: 0
+        runnable_dur_ns: 0
+        uninterruptible_sleep_dur_ns: 0
+        interruptible_sleep_dur_ns: 0
+      }
+      other_processes_spawned_count: 0
+      dur_ms: 0.0001
+      mcycles_by_core_type {
+      }
+    }
+    activity_hosting_process_count: 0
+    event_timestamps {
+      intent_received: 110
+      first_frame: 210
+    }
+  }
+}
diff --git a/test/trace_processor/startup/android_startup_minsdk33.py b/test/trace_processor/startup/android_startup_minsdk33.py
new file mode 100644
index 0000000..dddc503
--- /dev/null
+++ b/test/trace_processor/startup/android_startup_minsdk33.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python3
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from os import sys, path
+
+import synth_common
+
+trace = synth_common.create_trace()
+trace.add_packet()
+trace.add_process(1, 0, 'init')
+trace.add_process(2, 1, 'system_server')
+trace.add_process(3, 1, 'com.google.android.calendar', 10001)
+
+trace.add_package_list(
+    ts=1, name='com.google.android.calendar', uid=10001, version_code=123)
+
+trace.add_ftrace_packet(cpu=0)
+trace.add_atrace_async_begin(ts=110, tid=2, pid=2, buf='launchingActivity#1')
+trace.add_atrace_async_end(ts=210, tid=2, pid=2, buf='launchingActivity#1')
+trace.add_atrace_instant(
+    ts=211,
+    tid=2,
+    pid=2,
+    buf='launchingActivity#1:completed:com.google.android.calendar')
+
+sys.stdout.buffer.write(trace.trace.SerializeToString())
diff --git a/test/trace_processor/startup/index b/test/trace_processor/startup/index
index 1780fa8..ee6003e 100644
--- a/test/trace_processor/startup/index
+++ b/test/trace_processor/startup/index
@@ -2,6 +2,7 @@
 
 # Startup metric tests.
 android_startup.py android_startup android_startup.out
+android_startup_minsdk33.py android_startup android_startup_minsdk33.out
 android_startup_breakdown.py android_startup android_startup_breakdown.out
 android_startup_process_track.py android_startup android_startup_process_track.out
 android_startup_attribution.py android_startup android_startup_attribution.out
diff --git a/tools/ftrace_proto_gen/event_list b/tools/ftrace_proto_gen/event_list
index 11bd455..9189c95 100644
--- a/tools/ftrace_proto_gen/event_list
+++ b/tools/ftrace_proto_gen/event_list
@@ -402,3 +402,4 @@
 power/wakeup_source_deactivate
 ufs/ufshcd_command
 ufs/ufshcd_clk_gating
+printk/console
diff --git a/tools/gen_android_bp b/tools/gen_android_bp
index a3e829f..11e5bea 100755
--- a/tools/gen_android_bp
+++ b/tools/gen_android_bp
@@ -104,6 +104,14 @@
     '//:libperfetto_client_experimental',
 ]
 
+# Proto target groups which will be made public.
+proto_groups = {
+    'trace': [
+        '//protos/perfetto/trace:non_minimal_source_set',
+        '//protos/perfetto/trace:minimal_source_set'
+    ],
+}
+
 # All module names are prefixed with this string to avoid collisions.
 module_prefix = 'perfetto_'
 
@@ -217,9 +225,8 @@
     'traced_probes': [('required', {
         'libperfetto_android_internal', 'trigger_perfetto', 'traced_perf',
         'mm_events'
-    }), ],
-    'libperfetto_android_internal': [
-        ('static_libs', {'libhealthhalutils'}), ],
+    }),],
+    'libperfetto_android_internal': [('static_libs', {'libhealthhalutils'}),],
     'trace_processor_shell': [
         ('strip', {
             'all': True
@@ -290,7 +297,7 @@
     module.static_libs.add('libbase')
     module.static_libs.add('liblzma')
     module.static_libs.add('libdexfile_support')
-    module.runtime_libs.add('libdexfile') # libdexfile_support dependency
+    module.runtime_libs.add('libdexfile')  # libdexfile_support dependency
 
 
 def enable_libunwind(module):
@@ -386,6 +393,12 @@
 def write_blueprint_key_value(output, name, value, sort=True):
   """Writes a Blueprint key-value pair to the output"""
 
+  if isinstance(value, bool):
+    if value:
+      output.append('    %s: true,' % name)
+    else:
+      output.append('    %s: false,' % name)
+    return
   if not value:
     return
   if isinstance(value, set):
@@ -396,9 +409,6 @@
       output.append('        "%s",' % item)
     output.append('    ],')
     return
-  if isinstance(value, bool):
-    output.append('    %s: true,' % name)
-    return
   if isinstance(value, Target):
     value.to_string(output)
     return
@@ -487,6 +497,7 @@
     self.data = set()
     self.apex_available = set()
     self.min_sdk_version = None
+    self.proto = dict()
     # The genrule_XXX below are properties that must to be propagated back
     # on the module(s) that depend on the genrule.
     self.genrule_headers = set()
@@ -509,8 +520,10 @@
     self._output_field(output, 'runtime_libs')
     self._output_field(output, 'tools')
     self._output_field(output, 'cmd', sort=False)
-    self._output_field(output, 'host_supported')
-    self._output_field(output, 'vendor_available')
+    if self.host_supported:
+      self._output_field(output, 'host_supported')
+    if self.vendor_available:
+      self._output_field(output, 'vendor_available')
     self._output_field(output, 'init_rc')
     self._output_field(output, 'out')
     self._output_field(output, 'export_include_dirs')
@@ -532,6 +545,7 @@
     self._output_field(output, 'test_suites')
     self._output_field(output, 'test_config')
     self._output_field(output, 'stubs')
+    self._output_field(output, 'proto')
 
     target_out = []
     self._output_field(target_out, 'android')
@@ -553,7 +567,8 @@
       output.append('    target: {')
       output.append('        android: {')
       output.append('            lto: {')
-      output.append('                thin: %s,' % 'true' if self.lto else 'false')
+      output.append('                thin: %s,' %
+                    'true' if self.lto else 'false')
       output.append('            },')
       output.append('        },')
       output.append('    },')
@@ -671,18 +686,12 @@
 
     # Recursively extract the .proto files of all the dependencies and
     # add them to srcs.
-    target_queue = collections.deque([target.name])
-    seen_targets = set()
-    while target_queue:
-      dep = target_queue.popleft()
-      if dep in seen_targets:
-        continue
-      seen_targets.add(dep)
-
+    descriptor_module.srcs.update(
+        gn_utils.label_to_path(src) for src in target.sources)
+    for dep in target.transitive_proto_deps:
       current_target = gn.get_target(dep)
       descriptor_module.srcs.update(
           gn_utils.label_to_path(src) for src in current_target.sources)
-      target_queue.extend(current_target.proto_deps)
 
     return descriptor_module
 
@@ -804,6 +813,25 @@
   return module
 
 
+def create_proto_group_modules(blueprint, gn, module_name, target_names):
+  # TODO(lalitm): today, we're only adding a Java lite module because that's
+  # the only one used in practice. In the future, if we need other target types
+  # (e.g. C++, Java full etc.) add them here.
+  bp_module_name = label_to_module_name(module_name) + '_java_protos'
+  module = Module('java_library', bp_module_name, bp_module_name)
+  module.comment = f'''GN: [{', '.join(target_names)}]'''
+  module.proto = {'type': 'lite', 'canonical_path_from_root': False}
+
+  for name in target_names:
+    target = gn.get_target(name)
+    module.srcs.update(gn_utils.label_to_path(src) for src in target.sources)
+    for dep_label in target.transitive_proto_deps:
+      dep = gn.get_target(dep_label)
+      module.srcs.update(gn_utils.label_to_path(src) for src in dep.sources)
+
+  blueprint.add_module(module)
+
+
 def _get_cflags(target):
   cflags = {flag for flag in target.cflags if re.match(cflag_allowlist, flag)}
   cflags |= set("-D%s" % define
@@ -914,7 +942,8 @@
                   (type(add_val), key))
 
   # dep_name is an unmangled GN target name (e.g. //foo:bar(toolchain)).
-  for dep_name in target.deps | target.source_set_deps | target.proto_deps:
+  all_deps = target.deps | target.source_set_deps | target.transitive_proto_deps
+  for dep_name in all_deps:
     # If the dependency refers to a library which we can replace with an
     # Android equivalent, stop recursing and patch the dependency in.
     # Don't recurse into //buildtools, builtin_deps are intercepted at
@@ -993,7 +1022,6 @@
   defaults.lto = True
 
   blueprint.add_module(defaults)
-  gn = gn_utils.GnParser(desc)
   for target in targets:
     create_modules_from_target(blueprint, gn, target)
   return blueprint
@@ -1044,6 +1072,10 @@
   # for target_name in default_targets:
   # checker = gn_utils.ODRChecker(gn, target_name)
 
+  # Add any proto groups to the blueprint.
+  for l_name, t_names in proto_groups.items():
+    create_proto_group_modules(blueprint, gn, l_name, t_names)
+
   output = [
       """// Copyright (C) 2017 The Android Open Source Project
 //
diff --git a/tools/gen_bazel b/tools/gen_bazel
index c911be4..76f1b6e 100755
--- a/tools/gen_bazel
+++ b/tools/gen_bazel
@@ -46,7 +46,7 @@
     'enable_perfetto_heapprofd=false',
     'enable_perfetto_traced_perf=false',
     'perfetto_force_dcheck="off"',
-    'enable_perfetto_llvm_demangle=false',
+    'enable_perfetto_llvm_demangle=true',
 ])
 
 # Default targets to translate to the blueprint file.
@@ -78,19 +78,14 @@
 
 # Proto target groups which will be made public.
 proto_groups = {
-  'config': [
-    '//protos/perfetto/config:source_set'
-  ],
-  'trace': [
-    '//protos/perfetto/trace:non_minimal_source_set',
-    '//protos/perfetto/trace:minimal_source_set'
-  ],
-  'metrics': [
-    '//protos/perfetto/metrics:source_set',
-  ],
-  'chromium': [
-    '//protos/third_party/chromium:source_set',
-  ],
+    'config': ['//protos/perfetto/config:source_set'],
+    'trace': [
+        '//protos/perfetto/trace:non_minimal_source_set',
+        '//protos/perfetto/trace:minimal_source_set'
+    ],
+    'metrics': ['//protos/perfetto/metrics:source_set',],
+    'chromium': ['//protos/third_party/chromium:source_set',],
+    'chrome_metrics': ['//protos/perfetto/metrics/chrome:source_set',],
 }
 
 # Path for the protobuf sources in the standalone build.
@@ -115,9 +110,7 @@
     ],
     '//gn:zlib': ['PERFETTO_CONFIG.deps.zlib'],
     '//gn:llvm_demangle': ['PERFETTO_CONFIG.deps.llvm_demangle'],
-    '//src/trace_processor:demangle': [
-        'PERFETTO_CONFIG.deps.demangle_wrapper'
-    ],
+    '//src/trace_processor:demangle': ['PERFETTO_CONFIG.deps.demangle_wrapper'],
     '//src/trace_processor/metrics/sql:gen_amalgamated_sql_metrics': [[
         ':cc_amalgamated_sql_metrics'
     ]],
@@ -283,8 +276,10 @@
     assert (all(x.startswith('//') for x in target.sources))
     assert (all(x.endswith('.proto') for x in target.sources))
     sources_label.srcs = sorted([x[2:] for x in target.sources])  # Strip //.
-    sources_label.deps = sorted(
-        [':' + get_bazel_proto_sources_label(x) for x in target.proto_deps])
+    sources_label.deps = sorted([
+        ':' + get_bazel_proto_sources_label(x)
+        for x in target.transitive_proto_deps
+    ])
 
     # In Bazel, proto_paths are not a supported concept becauase strong
     # dependency checking is enabled. Instead, we need to depend on the target
@@ -299,12 +294,11 @@
 
     sources_label.visibility = ['PERFETTO_CONFIG.proto_library_visibility']
 
-    sources_label.exports = sorted([
-      ':' + get_bazel_proto_sources_label(d) for d in target.proto_exports
-    ])
+    sources_label.exports = sorted(
+        [':' + get_bazel_proto_sources_label(d) for d in target.proto_exports])
     return sources_label
 
-  # For all other types of plugins, we need to generate 
+  # For all other types of plugins, we need to generate
   if target.proto_plugin == 'proto':
     plugin_label_type = 'perfetto_cc_proto_library'
   elif target.proto_plugin == 'protozero':
@@ -328,7 +322,7 @@
   # common.gen.{cc,h}.
   if target.proto_plugin in ('cppgen', 'ipc', 'protozero'):
     plugin_label.deps += [
-        ':' + get_bazel_label_name(x) for x in target.proto_deps
+        ':' + get_bazel_label_name(x) for x in target.transitive_proto_deps
     ]
 
   # Add any dependencies on source_set targets (i.e. targets containing proto
@@ -337,7 +331,7 @@
   # implicit.
   if target.proto_plugin == 'descriptor':
     plugin_label.deps += [
-      ':' + get_bazel_proto_sources_label(x) for x in target.proto_deps
+        ':' + get_bazel_proto_sources_label(x) for x in target.proto_deps
     ]
   else:
     plugin_label.deps += [':' + sources_label_name]
@@ -354,40 +348,35 @@
   # Get a recursive list of the proto_library targets rooted here which
   # have src.
   deps_set = set()
-  def recursive_deps(name, deps_set):
-    target = gn.get_target(name)
-    deps_set.add(target.name)
-    for name in target.proto_deps:
-      recursive_deps(name, deps_set)
-
-  for n in target_names:
-    recursive_deps(n, deps_set)
-
-  deps_list = sorted(list(deps_set))
-  comment = f'''[{', '.join(target_names)}]'''
+  for target_name in target_names:
+    target = gn.get_target(target_name)
+    for dep_name in target.transitive_proto_deps:
+      deps_set.add(dep_name)
+    deps_set.add(target_name)
 
   # First, create a root source set target which references all the child
   # source set targets. We publish this as well as depending on this in all
   # subsequent targets.
   sources_label = BazelLabel(name + '_proto', 'perfetto_proto_library')
   sources_label.deps = [
-    ':' + get_bazel_proto_sources_label(name) for name in deps_set
+      ':' + get_bazel_proto_sources_label(name)
+      for name in sorted(list(deps_set))
   ]
   sources_label.visibility = PUBLIC_VISIBILITY
-  sources_label.comment = comment
+  sources_label.comment = f'''[{', '.join(target_names)}]'''
 
   # Next we create a cc proto target depending on the source set target.
   cc_label = BazelLabel(name + '_cc_proto', 'perfetto_cc_proto_library')
   cc_label.deps = [':' + sources_label.name]
   cc_label.visibility = PUBLIC_VISIBILITY
-  cc_label.comment = comment
+  cc_label.comment = sources_label.comment
 
   # Next we create a java proto target depending on the source set
   # target.
   java_label = BazelLabel(name + '_java_proto', 'perfetto_java_proto_library')
   java_label.deps = [':' + sources_label.name]
   java_label.visibility = PUBLIC_VISIBILITY
-  java_label.comment = comment
+  java_label.comment = sources_label.comment
 
   # Finally we create a java lite proto target depending on the source
   # set target.
@@ -395,7 +384,7 @@
   java_lite_label = BazelLabel(lite_name, 'perfetto_java_lite_proto_library')
   java_lite_label.deps = [':' + sources_label.name]
   java_lite_label.visibility = PUBLIC_VISIBILITY
-  java_lite_label.comment = comment
+  java_lite_label.comment = sources_label.comment
 
   return [sources_label, cc_label, java_label, java_lite_label]
 
@@ -466,7 +455,9 @@
         label.external_deps += external_deps[dep]
       else:
         label.deps += [':' + get_bazel_label_name(dep)]
-    label.deps += [':' + get_bazel_label_name(x) for x in gn_target.proto_deps]
+    label.deps += [
+        ':' + get_bazel_label_name(x) for x in gn_target.transitive_proto_deps
+    ]
 
   # All items starting with : need to be sorted to the end of the list.
   # However, Python makes specifying a comparator function hard so cheat
@@ -580,8 +571,8 @@
 
   # Generate targets for the transitive set of proto targets.
   labels = [
-    l for target in sorted(itervalues(gn.proto_libs))
-    for l in gen_target(target)
+      l for target in sorted(itervalues(gn.proto_libs))
+      for l in gen_target(target)
   ]
   res += ''.join(str(x) for x in sorted(labels))
 
diff --git a/tools/gn_utils.py b/tools/gn_utils.py
index 771d16e..0b9a9d3 100644
--- a/tools/gn_utils.py
+++ b/tools/gn_utils.py
@@ -245,7 +245,8 @@
     for ssdep in target.source_set_deps:
       name_and_path = '%s (via %s)' % (target_name, path)
       self.source_sets[ssdep].add(name_and_path)
-    deps = set(target.deps).union(target.proto_deps) - self.deps_visited
+    deps = set(target.deps).union(
+        target.transitive_proto_deps) - self.deps_visited
     for dep_name in deps:
       dep = self.gn.get_target(dep_name)
       if dep.type == 'executable':
@@ -332,7 +333,8 @@
       self.include_dirs = set()
       self.ldflags = set()
       self.source_set_deps = set()  # Transitive set of source_set deps.
-      self.proto_deps = set()  # Transitive set of protobuf deps.
+      self.proto_deps = set()
+      self.transitive_proto_deps = set()
 
       # Deps on //gn:xxx have this flag set to True. These dependencies
       # are special because they pull third_party code from buildtools/.
@@ -358,7 +360,8 @@
 
     def update(self, other):
       for key in ('cflags', 'defines', 'deps', 'include_dirs', 'ldflags',
-                  'source_set_deps', 'proto_deps', 'libs', 'proto_paths'):
+                  'source_set_deps', 'proto_deps', 'transitive_proto_deps',
+                  'libs', 'proto_paths'):
         self.__dict__[key].update(other.__dict__.get(key, []))
 
   def __init__(self, gn_desc):
@@ -443,11 +446,9 @@
         target.deps.add(dep_name)
       elif dep.type == 'proto_library':
         target.proto_deps.add(dep_name)
+        target.transitive_proto_deps.add(dep_name)
         target.proto_paths.update(dep.proto_paths)
-
-        # Don't bubble deps for action targets
-        if target.type != 'action' and proto_target_type != 'descriptor':
-          target.proto_deps.update(dep.proto_deps)  # Bubble up deps.
+        target.transitive_proto_deps.update(dep.transitive_proto_deps)
       elif dep.type == 'source_set':
         target.source_set_deps.add(dep_name)
         target.update(dep)  # Bubble up source set's cflags/ldflags etc.
diff --git a/ui/release/channels.json b/ui/release/channels.json
index 156f53f..68d1252 100644
--- a/ui/release/channels.json
+++ b/ui/release/channels.json
@@ -2,11 +2,11 @@
   "channels": [
     {
       "name": "stable",
-      "rev": "b574f45ca4f3ae63100c9868a65f9381b0d16c82"
+      "rev": "525b3b84e74e372dd33969edd2f43dbb7080b23c"
     },
     {
       "name": "canary",
-      "rev": "6c78846fe39842faac064421b1e1c745a14c516a"
+      "rev": "cb50f88f8a45ca4d8feef0f1abf639573b471331"
     },
     {
       "name": "autopush",
diff --git a/ui/src/common/feature_flags.ts b/ui/src/common/feature_flags.ts
index 8803969..1dfb28e 100644
--- a/ui/src/common/feature_flags.ts
+++ b/ui/src/common/feature_flags.ts
@@ -232,5 +232,5 @@
   id: 'perfSampleFlamegraph',
   name: 'Perf Sample Flamegraph',
   description: 'Show flamegraph generated by a perf sample.',
-  defaultValue: false
+  defaultValue: true
 });
diff --git a/ui/src/controller/trace_controller.ts b/ui/src/controller/trace_controller.ts
index ee193fa..da74947 100644
--- a/ui/src/controller/trace_controller.ts
+++ b/ui/src/controller/trace_controller.ts
@@ -111,6 +111,7 @@
   'android_jank',
   'android_camera',
   'chrome_dropped_frames',
+  'chrome_long_latency',
   'trace_metadata',
   'android_trusty_workqueues',
 ];
diff --git a/ui/src/frontend/base_slice_track.ts b/ui/src/frontend/base_slice_track.ts
index 55eed50..0b11366 100644
--- a/ui/src/frontend/base_slice_track.ts
+++ b/ui/src/frontend/base_slice_track.ts
@@ -109,6 +109,12 @@
   private computedSliceHeight = 0;
   private computedRowSpacing = 0;
 
+  // True if this track (and any views tables it might have created) has been
+  // destroyed. This is unfortunately error prone (since we must manually check
+  // this between each query).
+  // TODO(hjd): Replace once we have cancellable query sequences.
+  private isDestroyed = false;
+
   // TODO(hjd): Remove when updating selection.
   // We shouldn't know here about CHROME_SLICE. Maybe should be set by
   // whatever deals with that. Dunno the namespace of selection is weird. For
@@ -357,6 +363,12 @@
     }  // if (howSlice)
   }
 
+  onDestroy() {
+    super.onDestroy();
+    this.isDestroyed = true;
+    this.engine.query(`DROP VIEW IF EXISTS ${this.tableName}`);
+  }
+
   // This method figures out if the visible window is outside the bounds of
   // the cached data and if so issues new queries (i.e. sorta subsumes the
   // onBoundsChange).
@@ -366,16 +378,14 @@
     if (this.sqlState === 'UNINITIALIZED') {
       this.sqlState = 'INITIALIZING';
 
-      // TODO(hjd): we need an onDestroy. Right now if you contract and expand a
-      // track group this will crash, because the 2nd time we create the track
-      // we end up re-issuing the CREATE VIEW table_name.
-      // Right now this DROP VIEW is a hack, because it: (1) assumes that
-      // tableName is a VIEW and not a TABLE; (2) assume the impl track didn't
-      // create any other TABLE/VIEW (which happens to be true right now but
-      // might now be in future).
-      await this.engine.query(`DROP VIEW IF EXISTS ${this.tableName}`);
+      if (this.isDestroyed) {
+        return;
+      }
       await this.initSqlTable(this.tableName);
 
+      if (this.isDestroyed) {
+        return;
+      }
       const queryRes = await this.engine.query(`select
           ifnull(max(dur), 0) as maxDur, count(1) as rowCount
           from ${this.tableName}`);
@@ -424,6 +434,9 @@
     // - Materialize the unfinished slices one off.
     // - Avoid the union if we know we don't have any -1 slices.
     // - Maybe we don't need the union at all and can deal in TS?
+    if (this.isDestroyed) {
+      return;
+    }
     const queryRes = await this.engine.query(`
     with q1 as (
       select
diff --git a/ui/src/frontend/chrome_slice_panel.ts b/ui/src/frontend/chrome_slice_panel.ts
index 477e20d..76f0920 100644
--- a/ui/src/frontend/chrome_slice_panel.ts
+++ b/ui/src/frontend/chrome_slice_panel.ts
@@ -187,9 +187,15 @@
           'Duration', this.computeDuration(sliceInfo.ts, sliceInfo.dur));
       if (sliceInfo.thread_ts !== undefined &&
           sliceInfo.thread_dur !== undefined) {
+        // If we have valid thread duration, also display a percentage of
+        // |thread_dur| compared to |dur|.
+        const threadDurFractionSuffix = sliceInfo.thread_dur === -1 ?
+            '' :
+            ` (${(sliceInfo.thread_dur / sliceInfo.dur * 100).toFixed(2)}%)`;
         builder.add(
             'Thread duration',
-            this.computeDuration(sliceInfo.thread_ts, sliceInfo.thread_dur));
+            this.computeDuration(sliceInfo.thread_ts, sliceInfo.thread_dur) +
+                threadDurFractionSuffix);
       }
 
       for (const [key, value] of this.getProcessThreadDetails(sliceInfo)) {
diff --git a/ui/src/frontend/details_panel.ts b/ui/src/frontend/details_panel.ts
index e9773e9..30f536e 100644
--- a/ui/src/frontend/details_panel.ts
+++ b/ui/src/frontend/details_panel.ts
@@ -46,7 +46,7 @@
 const UP_ICON = 'keyboard_arrow_up';
 const DOWN_ICON = 'keyboard_arrow_down';
 const DRAG_HANDLE_HEIGHT_PX = 28;
-const DEFAULT_DETAILS_HEIGHT_PX = 230 + DRAG_HANDLE_HEIGHT_PX;
+const DEFAULT_DETAILS_HEIGHT_PX = 280 + DRAG_HANDLE_HEIGHT_PX;
 
 function getFullScreenHeight() {
   const panelContainer =
@@ -332,9 +332,10 @@
       detailsPanels.push({
         key: 'pivot_table_redux',
         name: 'Pivot Table',
-        vnode:
-            m(PivotTableRedux,
-              {selectionArea: globals.state.pivotTableRedux.selectionArea})
+        vnode: m(PivotTableRedux, {
+          key: 'pivot_table_redux',
+          selectionArea: globals.state.pivotTableRedux.selectionArea
+        })
       });
     }
 
@@ -379,7 +380,7 @@
       detailsPanels.push({
         key: 'selected_flows',
         name: 'Flow Events',
-        vnode: m(FlowEventsAreaSelectedPanel)
+        vnode: m(FlowEventsAreaSelectedPanel, {key: 'flow_events_area'})
       });
     }
 
diff --git a/ui/src/frontend/slice_panel.ts b/ui/src/frontend/slice_panel.ts
index a1b3428..1f649c6 100644
--- a/ui/src/frontend/slice_panel.ts
+++ b/ui/src/frontend/slice_panel.ts
@@ -26,10 +26,8 @@
 
   protected getProcessThreadDetails(sliceInfo: SliceDetails) {
     return new Map<string, string|undefined>([
-      ['Thread ID', sliceInfo.tid ? String(sliceInfo.tid) : undefined],
-      ['Thread name', sliceInfo.threadName],
-      ['Process ID', sliceInfo.pid ? String(sliceInfo.pid) : undefined],
-      ['Process name', sliceInfo.processName],
+      ['Thread', `${sliceInfo.threadName} ${sliceInfo.tid}`],
+      ['Process', `${sliceInfo.processName} ${sliceInfo.pid}`],
       ['User ID', sliceInfo.uid ? String(sliceInfo.uid) : undefined],
       ['Package name', sliceInfo.packageName],
       [
@@ -38,4 +36,4 @@
       ]
     ]);
   }
-}
\ No newline at end of file
+}
diff --git a/ui/src/frontend/track.ts b/ui/src/frontend/track.ts
index 5cd1e9b..0c5716a 100644
--- a/ui/src/frontend/track.ts
+++ b/ui/src/frontend/track.ts
@@ -77,6 +77,10 @@
     this.lastTrackState = assertExists(globals.state.tracks[this.trackId]);
   }
 
+  // Last call the track will receive. Called just before the last reference to
+  // this object is removed.
+  onDestroy() {}
+
   protected abstract renderCanvas(ctx: CanvasRenderingContext2D): void;
 
   protected get trackState(): TrackState {
diff --git a/ui/src/frontend/track_group_panel.ts b/ui/src/frontend/track_group_panel.ts
index e5f6631..7f0b4e9 100644
--- a/ui/src/frontend/track_group_panel.ts
+++ b/ui/src/frontend/track_group_panel.ts
@@ -172,6 +172,13 @@
     }
   }
 
+  onremove() {
+    if (this.summaryTrack !== undefined) {
+      this.summaryTrack.onDestroy();
+      this.summaryTrack = undefined;
+    }
+  }
+
   highlightIfTrackSelected(ctx: CanvasRenderingContext2D, size: PanelSize) {
     const localState = globals.frontendLocalState;
     const selection = globals.state.currentSelection;
diff --git a/ui/src/frontend/track_panel.ts b/ui/src/frontend/track_panel.ts
index a916e93..e479628 100644
--- a/ui/src/frontend/track_panel.ts
+++ b/ui/src/frontend/track_panel.ts
@@ -326,6 +326,13 @@
     }
   }
 
+  onremove() {
+    if (this.track !== undefined) {
+      this.track.onDestroy();
+      this.track = undefined;
+    }
+  }
+
   highlightIfTrackSelected(ctx: CanvasRenderingContext2D, size: PanelSize) {
     const localState = globals.frontendLocalState;
     const selection = globals.state.currentSelection;