aboutsummaryrefslogtreecommitdiff
path: root/protos/perfetto/config/trace_config.proto
blob: 4fe3ea974b5c14da792bb30f473c57680e173b11 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

syntax = "proto2";

package perfetto.protos;

import "protos/perfetto/common/builtin_clock.proto";
import "protos/perfetto/config/data_source_config.proto";

// The overall config that is used when starting a new tracing session through
// ProducerPort::StartTracing().
// It contains the general config for the logging buffer(s) and the configs for
// all the data source being enabled.
//
// Next id: 38.
message TraceConfig {
  message BufferConfig {
    optional uint32 size_kb = 1;

    // |page_size|, now deprecated.
    reserved 2;

    // |optimize_for|, now deprecated.
    reserved 3;

    enum FillPolicy {
      UNSPECIFIED = 0;

      // Default behavior. The buffer operates as a conventional ring buffer.
      // If the writer is faster than the reader (or if the reader reads only
      // after tracing is stopped) newly written packets will overwrite old
      // packets.
      RING_BUFFER = 1;

      // Behaves like RING_BUFFER as long as there is space in the buffer or
      // the reader catches up with the writer. As soon as the writer hits
      // an unread chunk, it stops accepting new data in the buffer.
      DISCARD = 2;
    }
    optional FillPolicy fill_policy = 4;
  }
  repeated BufferConfig buffers = 1;

  message DataSource {
    // Filters and data-source specific config. It contains also the unique name
    // of the data source, the one passed in the  DataSourceDescriptor when they
    // register on the service.
    optional protos.DataSourceConfig config = 1;

    // Optional. If multiple producers (~processes) expose the same data source
    // and either |producer_name_filter| or |producer_name_regex_filter| is set,
    // the data source is enabled only for producers whose names match any of
    // the filters.
    // |producer_name_filter| has to be an exact match, while
    // |producer_name_regex_filter| is a regular expression.
    // This allows to enable a data source only for specific processes.
    // The "repeated" fields have OR semantics: specifying a filter ["foo",
    // "bar"] will enable data sources on both "foo" and "bar" (if they exist).
    repeated string producer_name_filter = 2;
    repeated string producer_name_regex_filter = 3;
  }
  repeated DataSource data_sources = 2;

  // Config for disabling builtin data sources in the tracing service.
  message BuiltinDataSource {
    // Disable emitting clock timestamps into the trace.
    optional bool disable_clock_snapshotting = 1;

    // Disable echoing the original trace config in the trace.
    optional bool disable_trace_config = 2;

    // Disable emitting system info (build fingerprint, cpuinfo, etc).
    optional bool disable_system_info = 3;

    // Disable emitting events for data-source state changes (e.g. the marker
    // for all data sources having ACKed the start of the trace).
    optional bool disable_service_events = 4;

    // The authoritative clock domain for the trace. Defaults to BOOTTIME. See
    // also ClockSnapshot's primary_trace_clock. The configured value is written
    // into the trace as part of the ClockSnapshots emitted by the service.
    // Trace processor will attempt to translate packet/event timestamps from
    // various data sources (and their chosen clock domains) to this domain
    // during import. Added in Android R.
    optional BuiltinClock primary_trace_clock = 5;

    // Time interval in between snapshotting of sync markers, clock snapshots,
    // stats, and other periodic service-emitted events. Note that the service
    // only keeps track of the first and the most recent snapshot until
    // ReadBuffers() is called.
    optional uint32 snapshot_interval_ms = 6;

    // Hints to the service that a suspend-aware (i.e. counting time in suspend)
    // clock should be used for periodic snapshots of service-emitted events.
    // This means, if a snapshot *should* have happened during suspend, it will
    // happen immediately after the device resumes.
    //
    // Choosing a clock like this is done on best-effort basis; not all
    // platforms (e.g. Windows) expose a clock which can be used for periodic
    // tasks counting suspend. If such a clock is not available, the service
    // falls back to the best-available alternative.
    //
    // Introduced in Android S.
    // TODO(lalitm): deprecate this in T and make this the default if nothing
    // crashes in S.
    optional bool prefer_suspend_clock_for_snapshot = 7;

    // Disables the reporting of per-trace-writer histograms in TraceStats.
    optional bool disable_chunk_usage_histograms = 8;
  }
  optional BuiltinDataSource builtin_data_sources = 20;

  // If specified, the trace will be stopped |duration_ms| after starting.
  // This does *not* count the time the system is suspended, so we will run
  // for duration_ms of system activity, not wall time.
  //
  // However in case of traces with triggers, see
  // TriggerConfig.trigger_timeout_ms instead.
  optional uint32 duration_ms = 3;

  // If true, tries to use CLOCK_BOOTTIME for duration_ms rather than
  // CLOCK_MONOTONIC (which doesn't count time in suspend). Supported only on
  // Linux/Android, no-op on other platforms. This is used when dealing with
  // long (e.g. 24h) traces, where suspend can inflate them to weeks of
  // wall-time, making them more likely to hit device reboots (and hence loss).
  // This option also changes consistently the semantic of
  // TrigerConfig.stop_delay_ms.
  optional bool prefer_suspend_clock_for_duration = 36;

  // This is set when --dropbox is passed to the Perfetto command line client
  // and enables guardrails that limit resource usage for traces requested
  // by statsd.
  optional bool enable_extra_guardrails = 4;

  enum LockdownModeOperation {
    LOCKDOWN_UNCHANGED = 0;
    LOCKDOWN_CLEAR = 1;
    LOCKDOWN_SET = 2;
  }
  // Reject producers that are not running under the same UID as the tracing
  // service.
  optional LockdownModeOperation lockdown_mode = 5;

  message ProducerConfig {
    // Identifies the producer for which this config is for.
    optional string producer_name = 1;

    // Specifies the preferred size of the shared memory buffer. If the size is
    // larger than the max size, the max will be used. If it is smaller than
    // the page size or doesn't fit pages evenly into it, it will fall back to
    // the size specified by the producer or finally the default shared memory
    // size.
    optional uint32 shm_size_kb = 2;

    // Specifies the preferred size of each page in the shared memory buffer.
    // Must be an integer multiple of 4K.
    optional uint32 page_size_kb = 3;
  }

  repeated ProducerConfig producers = 6;

  // Contains statsd-specific metadata about an alert associated with the trace.
  message StatsdMetadata {
    // The identifier of the alert which triggered this trace.
    optional int64 triggering_alert_id = 1;
    // The uid which registered the triggering configuration with statsd.
    optional int32 triggering_config_uid = 2;
    // The identifier of the config which triggered the alert.
    optional int64 triggering_config_id = 3;
    // The identifier of the subscription which triggered this trace.
    optional int64 triggering_subscription_id = 4;
  }

  // Statsd-specific metadata.
  optional StatsdMetadata statsd_metadata = 7;

  // When true && |output_path| is empty, the EnableTracing() request must
  // provide a file descriptor. The service will then periodically read packets
  // out of the trace buffer and store it into the passed file.
  // If |output_path| is not empty no fd should be passed, the service
  // will create a new file and write into that (see comment below).
  optional bool write_into_file = 8;

  // This must point to a non-existing file. If the file exists the service
  // will NOT overwrite and will fail instead as a security precaution.
  // On Android, when this is used with the system traced, the path must be
  // within /data/misc/perfetto-traces/ or the trace will fail.
  // This option has been introduced in Android R. Before R write_into_file
  // can be used only with the "pass a file descriptor over IPC" mode.
  optional string output_path = 29;

  // Optional. If non-zero tunes the write period. A min value of 100ms is
  // enforced (i.e. smaller values are ignored).
  optional uint32 file_write_period_ms = 9;

  // Optional. When non zero the periodic write stops once at most X bytes
  // have been written into the file. Tracing is disabled when this limit is
  // reached, even if |duration_ms| has not been reached yet.
  optional uint64 max_file_size_bytes = 10;

  // Contains flags which override the default values of the guardrails inside
  // Perfetto.
  message GuardrailOverrides {
    // Override the default limit (in bytes) for uploading data to server within
    // a 24 hour period.
    // On R-, this override only affected userdebug builds. Since S, it also
    // affects user builds.
    optional uint64 max_upload_per_day_bytes = 1;

    // Overrides the guardrail for maximum trace buffer size.
    // Available on U+
    optional uint32 max_tracing_buffer_size_kb = 2;
  }
  optional GuardrailOverrides guardrail_overrides = 11;

  // When true, data sources are not started until an explicit call to
  // StartTracing() on the consumer port. This is to support early
  // initialization and fast trace triggering. This can be used only when the
  // Consumer explicitly triggers the StartTracing() method.
  // This should not be used in a remote trace config via statsd, doing so will
  // result in a hung trace session.
  optional bool deferred_start = 12;

  // When set, it periodically issues a Flush() to all data source, forcing them
  // to commit their data into the tracing service. This can be used for
  // quasi-real-time streaming mode and to guarantee some partial ordering of
  // events in the trace in windows of X ms.
  optional uint32 flush_period_ms = 13;

  // Wait for this long for producers to acknowledge flush requests.
  // Default 5s.
  optional uint32 flush_timeout_ms = 14;

  // Wait for this long for producers to acknowledge stop requests.
  // Default 5s.
  optional uint32 data_source_stop_timeout_ms = 23;

  // |disable_clock_snapshotting| moved.
  reserved 15;

  // Android-only. If set, sends an intent to the Traceur system app when the
  // trace ends to notify it about the trace readiness.
  optional bool notify_traceur = 16;

  // Android-only. If set to a value > 0, marks the trace session as a candidate
  // for being attached to a bugreport. This field effectively acts as a z-index
  // for bugreports. When Android's dumpstate runs perfetto
  // --save-for-bugreport, traced will pick the tracing session with the highest
  // score (score <= 0 is ignored), will steal its contents, save the trace into
  // a known path and stop prematurely.
  // This field was introduced in Android S.
  optional int32 bugreport_score = 30;

  // Triggers allow producers to start or stop the tracing session when an event
  // occurs.
  //
  // For example if we are tracing probabilistically, most traces will be
  // uninteresting. Triggers allow us to keep only the interesting ones such as
  // those traces during which the device temperature reached a certain
  // threshold. In this case the producer can activate a trigger to keep
  // (STOP_TRACING) the trace, otherwise it can also begin a trace
  // (START_TRACING) because it knows something is about to happen.
  message TriggerConfig {
    enum TriggerMode {
      UNSPECIFIED = 0;

      // When this mode is chosen, data sources are not started until one of the
      // |triggers| are received. This supports early initialization and fast
      // starting of the tracing system. On triggering, the session will then
      // record for |stop_delay_ms|. However if no trigger is seen
      // after |trigger_timeout_ms| the session will be stopped and no data will
      // be returned.
      START_TRACING = 1;

      // When this mode is chosen, the session will be started via the normal
      // EnableTracing() & StartTracing(). If no trigger is ever seen
      // the session will be stopped after |trigger_timeout_ms| and no data will
      // be returned. However if triggered the trace will stop after
      // |stop_delay_ms| and any data in the buffer will be returned to the
      // consumer.
      STOP_TRACING = 2;

      // When this mode is chosen, this causes a snapshot of the current tracing
      // session to be created after |stop_delay_ms| while the current tracing
      // session continues undisturbed (% an extra flush). This mode can be
      // used only when the tracing session is handled by the "perfetto" cmdline
      // client (which is true in 90% of cases). Part of the business logic
      // necessary for this behavior, and ensuing file handling, lives in
      // perfetto_cmd.cc . On other consumers, this causes only a notification
      // of the trigger through a CloneTriggerHit ObservableEvent. The custom
      // consumer is supposed to call CloneSession() itself after the event.
      // Use use_clone_snapshot_if_available=true when targeting older versions
      // of perfetto.
      CLONE_SNAPSHOT = 3;

      // NOTE: CLONE_SNAPSHOT should be used only when we targeting Android U+
      // (14+) / Perfetto v34+. A bug in older versions of the tracing service
      // might cause indefinitely long tracing sessions (see b/274931668).
    }
    optional TriggerMode trigger_mode = 1;

    // This flag is really a workaround for b/274931668. This is needed only
    // when deploying configs to different versions of the tracing service.
    // When this is set to true this has the same effect of setting trigger_mode
    // to CLONE_SNAPSHOT on newer versions of the service. This boolean has been
    // introduced to allow to have configs that use CLONE_SNAPSHOT on newer
    // versions of Android and fall back to STOP_TRACING on older versions where
    // CLONE_SNAPSHOT did not exist.
    // When using this flag, trigger_mode must be set to STOP_TRACING.
    optional bool use_clone_snapshot_if_available = 4;

    message Trigger {
      // The producer must specify this name to activate the trigger.
      optional string name = 1;

      // An std::regex that will match the producer that can activate this
      // trigger. This is optional. If unset any producers can activate this
      // trigger.
      optional string producer_name_regex = 2;

      // After a trigger is received either in START_TRACING or STOP_TRACING
      // mode then the trace will end |stop_delay_ms| after triggering.
      // In CLONE_SNAPSHOT mode, this is the delay between the trigger and the
      // snapshot.
      // If |prefer_suspend_clock_for_duration| is set, the duration will be
      // based on wall-clock, counting also time in suspend.
      optional uint32 stop_delay_ms = 3;

      // Limits the number of traces this trigger can start/stop in a rolling
      // 24 hour window. If this field is unset or zero, no limit is applied and
      // activiation of this trigger *always* starts/stops the trace.
      optional uint32 max_per_24_h = 4;

      // A value between 0 and 1 which encodes the probability of skipping a
      // trigger with this name. This is useful for reducing the probability
      // of high-frequency triggers from dominating trace finaization. If this
      // field is unset or zero, the trigger will *never* be skipped. If this
      // field is greater than or equal to 1, this trigger will *always* be
      // skipped i.e. it will be as if this trigger was never included in the
      // first place.
      // This probability check is applied *before* any other limits. For
      // example, if |max_per_24_h| is also set, first we will check if the
      // probability bar is met and only then will we check the |max_per_24_h|
      // limit.
      optional double skip_probability = 5;
    }
    // A list of triggers which are related to this configuration. If ANY
    // trigger is seen then an action will be performed based on |trigger_mode|.
    repeated Trigger triggers = 2;

    // Required and must be positive if a TriggerConfig is specified. This is
    // how long this TraceConfig should wait for a trigger to arrive. After this
    // period of time if no trigger is seen the TracingSession will be cleaned
    // up.
    optional uint32 trigger_timeout_ms = 3;
  }
  optional TriggerConfig trigger_config = 17;

  // When this is non-empty the perfetto command line tool will ignore the rest
  // of this TraceConfig and instead connect to the perfetto service as a
  // producer and send these triggers, potentially stopping or starting traces
  // that were previous configured to use a TriggerConfig.
  repeated string activate_triggers = 18;

  // Configuration for trace contents that reference earlier trace data. For
  // example, a data source might intern strings, and emit packets containing
  // {interned id : string} pairs. Future packets from that data source can then
  // use the interned ids instead of duplicating the raw string contents. The
  // trace parser will then need to use that interning table to fully interpret
  // the rest of the trace.
  message IncrementalStateConfig {
    // If nonzero, notify eligible data sources to clear their incremental state
    // periodically, with the given period. The notification is sent only to
    // data sources that have |handles_incremental_state_clear| set in their
    // DataSourceDescriptor. The notification requests that the data source
    // stops referring to past trace contents. This is particularly useful when
    // tracing in ring buffer mode, where it is not exceptional to overwrite old
    // trace data.
    //
    // Warning: this time-based global clearing is likely to be removed in the
    // future, to be replaced with a smarter way of sending the notifications
    // only when necessary.
    optional uint32 clear_period_ms = 1;
  }
  optional IncrementalStateConfig incremental_state_config = 21;

  // Additional guardrail used by the Perfetto command line client.
  // On user builds when --dropbox is set perfetto will refuse to trace unless
  // this is also set.
  // Added in Q.
  optional bool allow_user_build_tracing = 19;

  // If set the tracing service will ensure there is at most one tracing session
  // with this key.
  optional string unique_session_name = 22;

  // Compress trace with the given method. Best effort.
  enum CompressionType {
    COMPRESSION_TYPE_UNSPECIFIED = 0;
    COMPRESSION_TYPE_DEFLATE = 1;
  }
  optional CompressionType compression_type = 24;

  // Use the legacy codepath that compresses from perfetto_cmd.cc instead of
  // using the new codepath that compresses from tracing_service_impl.cc. This
  // will be removed in the future.
  optional bool compress_from_cli = 37;

  // Android-only. Not for general use. If set, saves the trace into an
  // incident. This field is read by perfetto_cmd, rather than the tracing
  // service. This field must be set when passing the --upload flag to
  // perfetto_cmd.
  message IncidentReportConfig {
    // In this message, either:
    //  * all of |destination_package|, |destination_class| and |privacy_level|
    //    must be set.
    //  * |skip_incidentd| must be explicitly set to true.

    optional string destination_package = 1;
    optional string destination_class = 2;
    // Level of filtering in the requested incident. See |Destination| in
    // frameworks/base/core/proto/android/privacy.proto.
    optional int32 privacy_level = 3;

    // If true, then skips saving the trace to incidentd.
    //
    // This flag is useful in testing (e.g. Perfetto-statsd integration tests)
    // or when we explicitly don't want traces to go to incidentd even when they
    // usually would (e.g. configs deployed using statsd but only used for
    // inclusion in bugreports using |bugreport_score|).
    //
    // The motivation for having this flag, instead of just not setting
    // |incident_report_config|, is prevent accidents where
    // |incident_report_config| is omitted by mistake.
    optional bool skip_incidentd = 5;

    // If true, do not write the trace into dropbox (i.e. incident only).
    // Otherwise, write to both dropbox and incident.
    // TODO(lalitm): remove this field as we no longer use Dropbox.
    optional bool skip_dropbox = 4 [deprecated = true];
  }
  optional IncidentReportConfig incident_report_config = 25;

  enum StatsdLogging {
    STATSD_LOGGING_UNSPECIFIED = 0;
    STATSD_LOGGING_ENABLED = 1;
    STATSD_LOGGING_DISABLED = 2;
  }

  // Android-only. Not for general use. If specified, sets the logging to statsd
  // of guardrails and checkpoints in the tracing service. perfetto_cmd sets
  // this to enabled (if not explicitly set in the config) when specifying
  // --upload.
  optional StatsdLogging statsd_logging = 31;

  // DEPRECATED. Was trace_uuid, use trace_uuid_msb and trace_uuid_lsb instead.
  reserved 26;

  // An identifier clients can use to tie this trace to other logging.
  // DEPRECATED as per v32. See TracePacket.trace_uuid for the authoritative
  // Trace UUID. If this field is set, the tracing service will respect the
  // requested UUID (i.e. TracePacket.trace_uuid == this field) but only if
  // gap-less snapshotting is not used.
  optional int64 trace_uuid_msb = 27 [deprecated = true];
  optional int64 trace_uuid_lsb = 28 [deprecated = true];

  // When set applies a post-filter to the trace contents using the filter
  // provided. The filter is applied at ReadBuffers() time and works both in the
  // case of IPC readback and write_into_file. This filter can be generated
  // using `tools/proto_filter -s schema.proto -F filter_out.bytes` or
  // `-T filter_out.escaped_string` (for .pbtx). See go/trace-filtering for
  // design.
  //
  // Introduced in Android S, but it was broken (b/195065199). Reintroduced in
  // Android T with a different field number.
  message TraceFilter {
    optional bytes bytecode = 1;
  }
  // old field number for trace_filter
  reserved 32;
  optional TraceFilter trace_filter = 33;

  // Android-only. Not for general use. If set, reports the trace to the
  // Android framework. This field is read by perfetto_cmd, rather than the
  // tracing service. This field must be set when passing the --upload flag to
  // perfetto_cmd.
  message AndroidReportConfig {
    // In this message, either:
    //  * |reporter_service_package| and |reporter_service_class| must be set.
    //  * |skip_reporting| must be explicitly set to true.

    optional string reporter_service_package = 1;
    optional string reporter_service_class = 2;

    // If true, then skips reporting the trace to Android framework.
    //
    // This flag is useful in testing (e.g. Perfetto-statsd integration tests)
    // or when we explicitly don't want to report traces to the framework even
    // when they usually would (e.g. configs deployed using statsd but only
    // used for inclusion in bugreports using |bugreport_score|).
    //
    // The motivation for having this flag, instead of just not setting
    // |framework_report_config|, is prevent accidents where
    // |framework_report_config| is omitted by mistake.
    optional bool skip_report = 3;

    // If true, will direct the Android framework to read the data in trace
    // file and pass it to the reporter class over a pipe instead of passing
    // the file descriptor directly.
    //
    // This flag is needed because the Android test framework does not
    // currently support priv-app helper apps (in terms of SELinux) and we
    // really don't want to add an allow rule for untrusted_app to receive
    // trace fds.
    //
    // Because of this, we instead will direct the framework to create a new
    // pipe and pass this to the reporter process instead. As the pipe is
    // created by the framework, we won't have any problems with SELinux
    // (system_server is already allowed to pass pipe fds, even
    // to untrusted apps).
    //
    // As the name suggests this option *MUST* only be used for testing.
    // Note that the framework will reject (and drop) files which are too
    // large both for simplicity and to be minimize the amount of data we
    // pass to a non-priv app (note that the framework will still check
    // manifest permissions even though SELinux permissions are worked around).
    optional bool use_pipe_in_framework_for_testing = 4;
  }
  optional AndroidReportConfig android_report_config = 34;

  // If set, delays the start of tracing by a random duration. The duration is
  // chosen from a uniform distribution between the specified minimum and
  // maximum.
  // Note: this delay is implemented by perfetto_cmd *not* by traced so will
  // not work if you communicate with traced directly over the consumer API.
  // Introduced in Android T.
  message CmdTraceStartDelay {
    optional uint32 min_delay_ms = 1;
    optional uint32 max_delay_ms = 2;
  }
  optional CmdTraceStartDelay cmd_trace_start_delay = 35;
}