Update perfetto to 97c9ad19b7fe469a70307fe5556d9751a2db806d

Bug: 400487815
Test: ./gradlew benchmark:benchmark-macro:cC

Change-Id: I61960733527bb15ffc593ab68e29f0320bdc65f5
diff --git a/generate_perfetto_binaries.py b/generate_perfetto_binaries.py
index e244dfa..d257e6d 100755
--- a/generate_perfetto_binaries.py
+++ b/generate_perfetto_binaries.py
@@ -59,6 +59,7 @@
     'protos/perfetto/common/descriptor.proto',
     'protos/perfetto/metrics/perfetto_merged_metrics.proto',
     'protos/perfetto/trace_processor/metatrace_categories.proto',
+    'protos/perfetto/perfetto_sql/structured_query.proto',
 )
 
 ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
diff --git a/protos/perfetto/metrics/perfetto_merged_metrics.proto b/protos/perfetto/metrics/perfetto_merged_metrics.proto
index e2fc3a3..9ec44ed 100644
--- a/protos/perfetto/metrics/perfetto_merged_metrics.proto
+++ b/protos/perfetto/metrics/perfetto_merged_metrics.proto
@@ -120,9 +120,12 @@
   // Process name. Usually, cmdline or <package_name>(:<custom_name>)?.
   optional string name = 1;
 
-  // User id under which this process runs.
+  // App uid under which this process runs.
   optional int64 uid = 2;
 
+  // Android user-id running this process (applicable to multi-user android)
+  optional int64 android_user_id = 10;
+
   // Package metadata from Android package list.
   message Package {
     optional string package_name = 1;
@@ -176,6 +179,50 @@
 
 // End of protos/perfetto/metrics/android/android_blocking_calls_cuj_metric.proto
 
+// Begin of protos/perfetto/metrics/android/android_blocking_call_per_frame.proto
+
+// Blocking call per frame on the main thread.
+message AndroidBlockingCallPerFrame {
+    // Name of the blocking call
+    optional string name = 1;
+    // Maximal duration within a frame.
+    optional int64 max_dur_per_frame_ms = 2;
+    // Maximal duration within a frame in nanoseconds
+    optional int64 max_dur_per_frame_ns = 3;
+    // Mean duration within the CUJ
+    optional int64 mean_dur_per_frame_ms = 4;
+    // Mean duration within the CUJ in nanoseconds
+    optional int64 mean_dur_per_frame_ns = 5;
+    // Max count in a frame
+    optional int64 max_cnt_per_frame = 6;
+    // Mean count in a frame
+    optional double mean_cnt_per_frame = 7;
+}
+
+// End of protos/perfetto/metrics/android/android_blocking_call_per_frame.proto
+
+// Begin of protos/perfetto/metrics/android/android_blocking_calls_cuj_per_frame_metric.proto
+
+// Blocking calls per frame inside Android jank CUJs. Shows count and duration for each.
+message AndroidCujBlockingCallsPerFrameMetric {
+  repeated Cuj cuj = 1;
+
+  message Cuj {
+
+    // Name of the CUJ, extracted from the CUJ jank trace marker.
+    // For example SHADE_EXPAND_COLLAPSE from J<SHADE_EXPAND_COLLAPSE>.
+    optional string name = 1;
+
+    optional AndroidProcessMetadata process = 2;
+
+    // List of blocking calls on the process UI thread.
+    // Aggregation is done by CUJ name.
+    repeated AndroidBlockingCallPerFrame blocking_calls = 3;
+  }
+}
+
+// End of protos/perfetto/metrics/android/android_blocking_calls_cuj_per_frame_metric.proto
+
 // Begin of protos/perfetto/metrics/android/android_blocking_calls_unagg.proto
 
 // All blocking calls for a trace. Shows count and total duration for each.
@@ -337,9 +384,14 @@
     optional int64 tid = 18;
     // monotonic duration of event.
     optional int64 gc_monotonic_dur = 19;
+    // Details about the process (uid, version, etc)
+    optional AndroidProcessMetadata process = 20;
+    // The number of GCs in this event. Namely 1.
+    optional int64 gc_count = 21;
   }
   repeated GarbageCollectionEvent gc_events = 1;
 }
+
 // End of protos/perfetto/metrics/android/android_garbage_collection_unagg_metric.proto
 
 // Begin of protos/perfetto/metrics/android/app_process_starts_metric.proto
@@ -474,6 +526,101 @@
 
 // End of protos/perfetto/metrics/android/android_frame_timeline_metric.proto
 
+// Begin of protos/perfetto/metrics/android/android_garbage_collection_stats.proto
+
+message AndroidGarbageCollectionStats {
+  message ProcessStats {
+    // The process the stats are associated with.
+    optional AndroidProcessMetadata process = 1;
+    // Megabyte-seconds of heap size across the device, used in the calculation
+    // of heap_size_mb.
+    optional double heap_size_mbs = 2;
+    // Total size of heap allocations across the device on average, in MB.
+    optional double heap_size_mb = 3;
+    // Total number of bytes allocated over the course of the trace.
+    optional double heap_allocated_mb = 4;
+    // Overall rate of heap allocations in MB per second. This gives a sense of
+    // how much allocation activity is going on during the trace.
+    optional double heap_allocation_rate = 5;
+    // Megabyte-seconds of live heap for processes that had GC events.
+    optional double heap_live_mbs = 6;
+    // Megabyte-seconds of total heap for processes that had GC events.
+    optional double heap_total_mbs = 7;
+    // Overall heap utilization. This gives a sense of how aggressive GC is
+    // during this trace.
+    optional double heap_utilization = 8;
+    // CPU time spent running GC. Used in the calculation of gc_running_rate.
+    optional int64 gc_running_dur = 9;
+    // CPU time spent running GC, as a fraction of the duration of the trace.
+    // This gives a sense of the battery cost of GC.
+    optional double gc_running_rate = 10;
+    // A measure of how efficient GC is with respect to cpu, independent of how
+    // aggressively GC is tuned. Larger values indicate more efficient GC, so
+    // larger is better.
+    optional double gc_running_efficiency = 11;
+    // Time GC is running during app startup. Used in the calculation of
+    // gc_during_android_startup_rate.
+    optional int64 gc_during_android_startup_dur = 12;
+    // Time GC is running during app startup, as a fraction of startup time in
+    // the trace. This gives a sense of how much potential interference there
+    // is between GC and application startup.
+    optional double gc_during_android_startup_rate = 13;
+    // A measure of how efficient GC is with regards to gc during application
+    // startup, independent of how aggressively GC is tuned. Larger values
+    // indicate more efficient GC, so larger is better.
+    optional double gc_during_android_startup_efficiency = 14;
+  }
+
+  // The start of the window of time that the stats cover in the trace.
+  optional int64 ts = 1;
+  // The duration of the window of time that the stats cover in the trace.
+  optional int64 dur = 2;
+  // Megabyte-seconds of heap size across the device, used in the calculation
+  // of heap_size_mb.
+  optional double heap_size_mbs = 3;
+  // Total size of heap allocations across the device on average, in MB.
+  optional double heap_size_mb = 4;
+  // Total number of bytes allocated over the course of the trace.
+  optional double heap_allocated_mb = 5;
+  // Overall rate of heap allocations in MB per second. This gives a sense of
+  // how much allocation activity is going on during the trace.
+  optional double heap_allocation_rate = 6;
+  // Megabyte-seconds of live heap for processes that had GC events.
+  optional double heap_live_mbs = 7;
+  // Megabyte-seconds of total heap for processes that had GC events.
+  optional double heap_total_mbs = 8;
+  // Overall heap utilization. This gives a sense of how aggressive GC is
+  // during this trace.
+  optional double heap_utilization = 9;
+  // CPU time spent running GC. Used in the calculation of gc_running_rate.
+  optional int64 gc_running_dur = 10;
+  // CPU time spent running GC, as a fraction of the duration of the trace.
+  // This gives a sense of the battery cost of GC.
+  optional double gc_running_rate = 11;
+  // A measure of how efficient GC is with respect to cpu, independent of how
+  // aggressively GC is tuned. Larger values indicate more efficient GC, so
+  // larger is better.
+  optional double gc_running_efficiency = 12;
+  // Time GC is running during app startup. Used in the calculation of
+  // gc_during_android_startup_rate.
+  optional int64 gc_during_android_startup_dur = 13;
+  // Total startup time in the trace, used to normalize the
+  // gc_during_android_startup_rate.
+  optional int64 total_android_startup_dur = 14;
+  // Time GC is running during app startup, as a fraction of startup time in
+  // the trace. This gives a sense of how much potential interference there
+  // is between GC and application startup.
+  optional double gc_during_android_startup_rate = 15;
+  // A measure of how efficient GC is with regards to gc during application
+  // startup, independent of how aggressively GC is tuned. Larger values
+  // indicate more efficient GC, so larger is better.
+  optional double gc_during_android_startup_efficiency = 16;
+  // Per-process stats.
+  repeated ProcessStats processes = 17;
+}
+
+// End of protos/perfetto/metrics/android/android_garbage_collection_stats.proto
+
 // Begin of protos/perfetto/metrics/android/android_oom_adjuster_metric.proto
 
 message AndroidOomAdjusterMetric {
@@ -599,6 +746,7 @@
     optional float capacity_percent = 3;
     optional double current_ua = 4;
     optional double current_avg_ua = 5;
+    optional double voltage_uv = 6;
   }
 
   message BatteryAggregates {
@@ -616,8 +764,8 @@
     optional int64 sleep_screen_doze_ns = 8;
     // Average power over the duration of the trace.
     optional double avg_power_mw = 9;
-    // Energy usage estimate in joules.
-    optional double energy_usage_estimate = 10;
+    // Average power from charge difference at the start and end of the trace.
+    optional double avg_power_from_charge_diff_mw = 10;
   }
 
   // Period of time during the trace that the device went to sleep completely.
@@ -852,14 +1000,29 @@
 
   // profile details in messages
   message Detail {
-    // function thread
-    optional string thread_name = 1;
+    // was thread_name
+    reserved 1;
     // total time
     optional int64 total_cpu_ns = 2;
     // CPU time ( time 'Running' on cpu)
     optional int64 running_cpu_ns = 3;
-    // CPU cycles
-    optional int64 cpu_cycles = 4;
+    // avg running time for the trace duration
+    optional int64 avg_running_cpu_ns = 9;
+    // Total CPU cycles
+    optional int64 total_cpu_cycles = 4;
+    // avg CPU cycles per call
+    optional int64 avg_cpu_cycles = 8;
+    // avg time for this slice type
+    optional int64 avg_time_ns = 5;
+    optional int32 count = 6;
+    message Latency {
+      optional int64 max_us = 1;
+      optional int64 min_us = 2;
+      optional int64 avg_us = 3;
+      optional int64 agg_us = 4;
+      optional uint32 count = 5;
+    }
+    optional Latency self = 7;
   }
 
   // These are traces and could indicate framework queue latency
@@ -870,10 +1033,15 @@
   message CodecFunction {
     // codec string
     optional string codec_string = 1;
-    // process_name
-    optional string process_name = 2;
-    // details
-    optional Detail detail = 3;
+    message Process {
+      optional string name = 1;
+      message Thread {
+        optional string name = 1;
+        optional Detail detail = 2;
+      }
+      optional Thread thread = 2;
+    }
+    optional Process process = 2;
   }
 
   // This message can indicate overall cpu
@@ -881,16 +1049,22 @@
   message CpuUsage {
     // name of process using codec framework
     optional string process_name = 1;
-    // name of the codec thread
-    optional string thread_name = 2;
+    message ThreadInfo {
+      // name of the codec thread
+      optional string name = 1;
+      message Details {
+        // total cpu usage of the codec thread
+        optional int64 thread_cpu_ns = 1;
+        // can be number of codec framework thread
+        optional uint32 num_threads = 2;
+        // core type data info used by codec thread
+        repeated AndroidCpuMetric.CoreTypeData core_data = 3;
+      }
+      optional Details info = 2;
+    }
+    optional ThreadInfo thread = 2;
     // was thread_cpu_us
     reserved 3;
-    // total cpu usage of the codec thread
-    optional int64 thread_cpu_ns = 6;
-    // can be number of codec framework thread
-    optional uint32 num_threads = 4;
-    // core type data info used by codec thread
-    repeated AndroidCpuMetric.CoreTypeData core_data = 5;
   }
 
   // Rail details
@@ -922,7 +1096,6 @@
   repeated CpuUsage cpu_usage = 1;
   repeated CodecFunction codec_function = 2;
   optional Energy energy = 3;
-
 }
 
 // End of protos/perfetto/metrics/android/codec_metrics.proto
@@ -2941,8 +3114,9 @@
 
 message AndroidWattsonEstimateInfo {
   optional int32 period_id = 1;
-  optional int64 period_dur = 2;
-  optional AndroidWattsonCpuSubsystemEstimate cpu_subsystem = 3;
+  optional string period_name = 2;
+  optional int64 period_dur = 3;
+  optional AndroidWattsonCpuSubsystemEstimate cpu_subsystem = 4;
 }
 
 message AndroidWattsonCpuSubsystemEstimate {
@@ -3020,19 +3194,34 @@
 
 // End of protos/perfetto/metrics/android/wattson_tasks_attribution.proto
 
+// Begin of protos/perfetto/metrics/common/clone_duration.proto
+
+message CloneDuration {
+  message ByBuffer {
+    optional int32 buffer = 1;
+    optional int64 duration_ns = 2;
+  }
+  repeated ByBuffer by_buffer = 1;
+}
+
+// End of protos/perfetto/metrics/common/clone_duration.proto
+
 // Begin of protos/perfetto/metrics/metrics.proto
 
 // Trace processor metadata
-// Next id: 17
+// Next id: 20
 message TraceMetadata {
   reserved 1;
   optional int64 trace_duration_ns = 2;
   optional string trace_uuid = 3;
   optional string android_build_fingerprint = 4;
   optional string android_device_manufacturer = 16;
+  optional int64 android_profile_boot_classpath = 18;
+  optional int64 android_profile_system_server = 19;
   optional int64 statsd_triggering_subscription_id = 5;
   optional int64 trace_size_bytes = 6;
   repeated string trace_trigger = 7;
+  optional string trace_causal_trigger = 17;
   optional string unique_session_name = 8;
   optional string trace_config_pbtxt = 9;
   optional int64 sched_duration_ns = 10;
@@ -3071,10 +3260,15 @@
   repeated Stat stat = 1;
 }
 
-// Root message for all Perfetto-based metrics.
+// Root message for all Perfetto-based metrics (v1 metrics only).
 //
-// Next id: 75
+// NOTE: the v1 system is "soft" deprecated: no new metrics are allowed but
+// we still fully support any existing metrics written using this system.
+//
+// DO NOT ADD ANY OTHER FIELDS HERE. ADDITION OF NEW v1 METRICS WITH
+// IS NO LONGER ALLOWED. PLEASE USE METRICS v2 INSTEAD.
 message TraceMetrics {
+  // Metrics which were later removed.
   reserved 4, 10, 13, 14, 16, 19;
 
   // Battery counters metric on Android.
@@ -3288,6 +3482,23 @@
   // Android Wattson estimate during markers time window.
   optional AndroidWattsonTimePeriodMetric wattson_markers_rails = 74;
 
+  // Android Wattson estimate during time windows defined by atrace apps.
+  optional AndroidWattsonTimePeriodMetric wattson_atrace_apps_rails = 75;
+
+  // Android GC stats.
+  optional AndroidGarbageCollectionStats android_garbage_collection_stats = 76;
+
+  optional CloneDuration clone_duration = 77;
+
+  // Per-frame blocking calls (e.g. binder calls) during CUJs (important UI
+  // transitions).
+  optional AndroidCujBlockingCallsPerFrameMetric
+      android_blocking_calls_cuj_per_frame_metric = 78;
+
+  // Android Wattson thread attribution during app startups.
+  optional AndroidWattsonTasksAttributionMetric wattson_app_startup_threads =
+      79;
+
   // Android
   // Demo extensions.
   extensions 450 to 499;
@@ -3300,6 +3511,9 @@
 
   // WebView metrics.
   extensions 2001 to 2500;
+
+  // DO NOT ADD ANY OTHER FIELDS HERE. ADDITION OF NEW v1 METRICS IS NO LONGER
+  // ALLOWED. PLEASE USE METRICS v2 INSTEAD.
 }
 
 // End of protos/perfetto/metrics/metrics.proto
diff --git a/protos/perfetto/perfetto_sql/structured_query.proto b/protos/perfetto/perfetto_sql/structured_query.proto
new file mode 100644
index 0000000..13e399e
--- /dev/null
+++ b/protos/perfetto/perfetto_sql/structured_query.proto
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package perfetto.protos;
+
+// Represents a PerfettoSQL query as a protobuf.
+//
+// SQL is amazing for writing interactive queries and human readability and
+// development but it is really bad for machine readability. Specifically, given
+// an SQL query, it's very hard to figure out what the author "intended" from
+// that as the same query can be written in countless different ways. This
+// makes building automated tools which take SQL and represent the data flow
+// visually very difficult to build.
+//
+// The goal of this proto is *not* in any way to replace SQL. In fact that's
+// an explicit *non-goal*. Instead, the idea here is this proto encodes it is a
+// very restricted, well-defined subset of the functionality of SQL that we see
+// a lot of usage of when writing PerfettoSQL queries.
+//
+// Basically, trace analysis has a lot of common "patterns" when it comes to
+// writing queries and this proto aims to have a central place codifying those
+// so all Perfetto tooling can share a common interchange format. Specifically,
+// unlike SQL which is quite optimized for human readability, this proto is more
+// designed for easy machine consumption with a secondary goal to still be
+// pretty easy for humans to read/write/modify in small doses. Note that it
+// *will* be verbose to deal with complex instances of this proto.
+//
+// It will always be easy to go from this proto to PerfettoSQL: trace processor
+// exposes APIs for this. It's also easy to bring SQL directly into the proto
+// world through use of the `Sql` source (see below).
+message PerfettoSqlStructuredQuery {
+  // A table or view acting as the source of the query, possibly living in a
+  // PerfettoSQL module.
+  message Table {
+    // The name of the table or view to query. Required.
+    optional string table_name = 1;
+
+    // The name of the module this table lives in. Optional, does not need to
+    // be specified if the table exists in the global scope (e.g. track table,
+    // slice table, any table/function in the prelude). Required otherwise.
+    optional string module_name = 2;
+
+    // The name of the columns of this table which will be used by this query.
+    // Required.
+    //
+    // Note: specifying this field is *mandatory* at all times. In the future,
+    // this may become option for public tables in the standard library.
+    repeated string column_names = 3;
+  }
+
+  // A set of slices which will act as the source for the query. This is
+  // basically equivalent to doing a query on the "slice" table (+ the
+  // appropriate joins) followed by a filter on various columns.
+  //
+  // This message exists for *pure* human convinience as we expect this pattern
+  // to be very commonly used by users.
+  //
+  // Produces a source with the schema
+  // (id, ts, dur, slice_name, thread_name, process_name, track_name).
+  message SimpleSlices {
+    // Glob for the name of the slices. Optional.
+    optional string slice_name_glob = 1;
+
+    // Glob for the thread name of the slices. Optional.
+    optional string thread_name_glob = 2;
+
+    // Glob for the process name of the slices. Optional.
+    optional string process_name_glob = 3;
+
+    // Glob for the track name of the slices. Optional.
+    optional string track_name_glob = 4;
+  }
+
+  // An arbitrary SQL query to use as the source for the query.
+  message Sql {
+    // The SQL string. Required.
+    //
+    // Note: this string is currently required to be a single well-formed select
+    // statement. This means you cannot use CREATE PERFETTO TABLE/VIEW but *can*
+    // use WITH clauses, UNION and INTERSECT. This restriction may be dropped
+    // in the future.
+    optional string sql = 1;
+
+    // The name of columns which will be returned by the SQL. Required.
+    repeated string column_names = 2;
+
+    // SQL string that has to be run before running the SQL. Supports multi
+    // statement queries. Optional.
+    optional string preamble = 3;
+  }
+
+  // Performs a "time-based" intersection of data from `base` with multiple
+  // sets of intervals.
+  //
+  // Examples:
+  // The best way to understand this operator is through example usecases
+  //  1) Compute the CPU usage during some CUJs:
+  //    * `base` points to a query contain CPU scheduling data.
+  //    * `interval_intersect` points to a query containing the CUJ boundaries.
+  //  2) Compute the memory usage of a process during an app startup
+  //    * `base` points to a query contain the memory usage of that process over
+  //      time.
+  //    * `interval_intersect` points to a structued query containing the app
+  //      startups.
+  //  3) Compute dropped frames during an layout while scrolling
+  //    * `base` points to a strucuted query containing the dropped frames
+  //      over time.
+  //    * `interval_intersect` points to two structured queries: the first
+  //      containing the layout intervals, the second containing the scroll
+  //      intervals.
+  //
+  // Schema:
+  //  1) Every query in `interval_intersect` must have both `ts` and
+  //     `dur` columns. It must also have an `id` column: this is necessary
+  //     because of the current implementation; this may be relaxed in the
+  //     future.
+  //    * Both `ts` and `dur` columns. In this case, the `base` interval
+  //      must overlap with one interval from each of `interval_intersect`
+  //      to be included.
+  //    * `ts` column without `dur` column. In this case, the `base`
+  //      timestamp must lie *between* one interval from each of
+  //      `interval_intersect` to be included.
+  //  3) The query in `base` must also have an `id` column: this is necessary
+  //     because of the current implementation; this may be relaxed in the
+  //     future.
+  //
+  // Handling of `dur`:
+  // The `dur` column is treated specially. It is changed to have the amount of
+  // time for which intervals in `base` overlaps with all structured queries in
+  // `interval_intersect`.
+  //
+  // Overlap with multiple intervals:
+  // If one row in `base` overlaps with *multiple* sets of intervals from each
+  // query in `interval_intersect`, then *multiple* rows will be
+  // produced, one for each sets of overlaps.
+  //
+  // Example in ASCII art:
+  //   base:       [-----------]     [--------]
+  //   ii1 :                [-----------]
+  //   ii2 :      [---------------] [-----]
+  // output:                [--]     [--]
+  message IntervalIntersect {
+    // The base query
+    optional PerfettoSqlStructuredQuery base = 1;
+    repeated PerfettoSqlStructuredQuery interval_intersect = 2;
+  }
+
+  // An opaque id field for the query. The convention is to use underscores
+  // and lower case (foo_bar) but this is not enforced. Optional in the general
+  // case but strongly recommended for good error messages. Required in cases
+  // where this query is used as a "shared" query.
+  optional string id = 1;
+
+  // Represents the "source" of the query which will be translared to an SQL
+  // "FROM" clause. One of the following is required.
+  oneof source {
+    // Source is an SQL table, possible in a PerfettoSQL module.
+    Table table = 2;
+
+    // Source is an arbitrary snippet of SQL.
+    Sql sql = 3;
+
+    // Source is a simple set of slices.
+    SimpleSlices simple_slices = 4;
+
+    // Source is a nested query. Useful for aliasing columns,
+    // filtering etc.
+    PerfettoSqlStructuredQuery inner_query = 5;
+
+    // Source is a nested query with the given id which should be
+    // looked up in some external data structure.
+    //
+    // This field is quite special and cannot be used in all StructuredQuery
+    // contexts. It exists to share some common structured queries between many
+    // other structured queries and is only available in contexts where this is
+    // supported.
+    //
+    // Contexts where this is supported that we are aware of:
+    // 1) Trace-Based Metrics v2
+    //
+    // Please see the documentation of the embedding system for more context.
+    string inner_query_id = 6;
+
+    // Source is an interval intersect operation. See IntervalIntersect
+    // documentation for more information.
+    IntervalIntersect interval_intersect = 7;
+  }
+
+  // Represents a single filter on a column.
+  message Filter {
+    // The column name to be filtered. Required.
+    optional string column_name = 1;
+
+    // The operator to use to perform filtering. Required.
+    enum Operator {
+      UNKNOWN = 0;
+      EQUAL = 1;
+      NOT_EQUAL = 2;
+      LESS_THAN = 3;
+      LESS_THAN_EQUAL = 4;
+      GREATER_THAN = 5;
+      GREATER_THAN_EQUAL = 6;
+      IS_NULL = 8;
+      IS_NOT_NULL = 9;
+
+      // Unix GLOB. Only makes sense for string columns.
+      GLOB = 7;
+    }
+    optional Operator op = 2;
+
+    // The RHS for filtering. All values specified here will be ORed together
+    // allowing easy IN and GLOB IN filtering. If operation is different than
+    // IS_NULL or IS_NOT_NULL, at least one of these fields must be non-empty.
+    // Only the first non-empty field will be considered.
+    repeated string string_rhs = 3;
+    repeated double double_rhs = 4;
+    repeated int64 int64_rhs = 5;
+  }
+
+  // A set of filters which are ANDed together. Optional, can be empty.
+  repeated Filter filters = 8;
+
+  // Represents a GROUP BY + aggregation operation in SQL. Optional.
+  message GroupBy {
+    // The column names to group by. At least one column is required.
+    repeated string column_names = 1;
+
+    // The list of aggregations to perform.
+    message Aggregate {
+      enum Op {
+        UNSPECIFIED = 0;
+        COUNT = 1;
+        SUM = 2;
+        MIN = 3;
+        MAX = 4;
+        MEAN = 5;
+        MEDIAN = 6;
+        DURATION_WEIGHTED_MEAN = 7;
+      }
+
+      optional string column_name = 1;
+      optional Op op = 2;
+      optional string result_column_name = 3;
+    }
+    repeated Aggregate aggregates = 2;
+  }
+  optional GroupBy group_by = 9;
+
+  // Represents the selection of columns from the source. Maps to a SELECT
+  // operation. Optional.
+  //
+  // Depending on whether `group_by` was specified the columns available from
+  // the source will be different:
+  // * if `group_by` is specified, all the columns in `group_by.column_names`
+  //   and `group_by.aggregates.result_column_name` are available.
+  // * if `group_by` is not specified, all columns in the source are eligible.
+  //
+  // If this is *not* specified, all columns from the source will be output.
+  message SelectColumn {
+    // The existing name of the column from the source. Required.
+    optional string column_name = 1;
+
+    // The new name of the column. If not set, the name of the column is
+    // `column_name`. Optional.
+    optional string alias = 2;
+  }
+  repeated SelectColumn select_columns = 10;
+}
diff --git a/protos/perfetto/trace_processor/trace_processor.proto b/protos/perfetto/trace_processor/trace_processor.proto
index bfb2a1f..914d4e0 100644
--- a/protos/perfetto/trace_processor/trace_processor.proto
+++ b/protos/perfetto/trace_processor/trace_processor.proto
@@ -20,6 +20,7 @@
 
 import "protos/perfetto/common/descriptor.proto";
 import "protos/perfetto/trace_processor/metatrace_categories.proto";
+import "protos/perfetto/perfetto_sql/structured_query.proto";
 
 // This file defines the schema for {,un}marshalling arguments and return values
 // when interfacing to the trace processor binary interface.
@@ -106,6 +107,7 @@
     TPM_GET_STATUS = 10;
     TPM_RESET_TRACE_PROCESSOR = 11;
     TPM_REGISTER_SQL_PACKAGE = 13;
+    TPM_ANALYZE_STRUCTURED_QUERY = 14;
   }
 
   oneof type {
@@ -139,6 +141,8 @@
     ResetTraceProcessorArgs reset_trace_processor_args = 107;
     // For TPM_REGISTER_SQL_PACKAGE.
     RegisterSqlPackageArgs register_sql_package_args = 108;
+    // For TPM_ANALYZE_STRUCTURED_QUERY.
+    AnalyzeStructuredQueryArgs analyze_structured_query_args = 109;
 
     // TraceProcessorMethod response args.
     // For TPM_APPEND_TRACE_DATA.
@@ -155,6 +159,10 @@
     StatusResult status = 210;
     // For TPM_REGISTER_SQL_PACKAGE.
     RegisterSqlPackageResult register_sql_package_result = 211;
+    // For TPM_FINALIZE_TRACE_DATA.
+    FinalizeDataResult finalize_data_result = 212;
+    // For TPM_ANALYZE_STRUCTURED_QUERY.
+    AnalyzeStructuredQueryResult analyze_structured_query_result = 213;
   }
 
   // Previously: RawQueryArgs for TPM_QUERY_RAW_DEPRECATED
@@ -356,4 +364,23 @@
 
 message RegisterSqlPackageResult {
   optional string error = 1;
-}
\ No newline at end of file
+}
+
+message FinalizeDataResult {
+  optional string error = 1;
+}
+
+message AnalyzeStructuredQueryArgs {
+  repeated PerfettoSqlStructuredQuery queries = 1;
+}
+
+message AnalyzeStructuredQueryResult {
+  message StructuredQueryResult {
+    optional string sql = 1;
+    optional string textproto = 4;
+    repeated string modules = 2;
+    repeated string preambles = 3;
+  }
+  optional string error = 1;
+  repeated StructuredQueryResult results = 2;
+}
diff --git a/trace_processor_shell/trace_processor_shell_aarch64 b/trace_processor_shell/trace_processor_shell_aarch64
index 50ec968..9839ab4 100644
--- a/trace_processor_shell/trace_processor_shell_aarch64
+++ b/trace_processor_shell/trace_processor_shell_aarch64
Binary files differ
diff --git a/trace_processor_shell/trace_processor_shell_arm b/trace_processor_shell/trace_processor_shell_arm
index 28dc7e1..144a168 100644
--- a/trace_processor_shell/trace_processor_shell_arm
+++ b/trace_processor_shell/trace_processor_shell_arm
Binary files differ
diff --git a/trace_processor_shell/trace_processor_shell_x86 b/trace_processor_shell/trace_processor_shell_x86
index 60d47c2..a12f665 100644
--- a/trace_processor_shell/trace_processor_shell_x86
+++ b/trace_processor_shell/trace_processor_shell_x86
Binary files differ
diff --git a/trace_processor_shell/trace_processor_shell_x86_64 b/trace_processor_shell/trace_processor_shell_x86_64
index 64f4c85..5231683 100644
--- a/trace_processor_shell/trace_processor_shell_x86_64
+++ b/trace_processor_shell/trace_processor_shell_x86_64
Binary files differ
diff --git a/tracebox/tracebox_aarch64 b/tracebox/tracebox_aarch64
index 14fe0ad..d732715 100644
--- a/tracebox/tracebox_aarch64
+++ b/tracebox/tracebox_aarch64
Binary files differ
diff --git a/tracebox/tracebox_arm b/tracebox/tracebox_arm
index 1dfe92f..4c4d834 100644
--- a/tracebox/tracebox_arm
+++ b/tracebox/tracebox_arm
Binary files differ
diff --git a/tracebox/tracebox_x86 b/tracebox/tracebox_x86
index 4c9c846..ea6080c 100644
--- a/tracebox/tracebox_x86
+++ b/tracebox/tracebox_x86
Binary files differ
diff --git a/tracebox/tracebox_x86_64 b/tracebox/tracebox_x86_64
index cc1a7de..bc11431 100644
--- a/tracebox/tracebox_x86_64
+++ b/tracebox/tracebox_x86_64
Binary files differ