Merge "Turn --pid and --name into comma separated lists."
diff --git a/Android.bp b/Android.bp
index 3544957..3a0c475 100644
--- a/Android.bp
+++ b/Android.bp
@@ -757,6 +757,7 @@
   srcs: [
     "protos/perfetto/common/android_log_constants.proto",
     "protos/perfetto/common/commit_data_request.proto",
+    "protos/perfetto/common/descriptor.proto",
     "protos/perfetto/common/observable_events.proto",
     "protos/perfetto/common/sys_stats_counters.proto",
     "protos/perfetto/common/trace_stats.proto",
@@ -768,6 +769,7 @@
   out: [
     "external/perfetto/protos/perfetto/common/android_log_constants.pb.cc",
     "external/perfetto/protos/perfetto/common/commit_data_request.pb.cc",
+    "external/perfetto/protos/perfetto/common/descriptor.pb.cc",
     "external/perfetto/protos/perfetto/common/observable_events.pb.cc",
     "external/perfetto/protos/perfetto/common/sys_stats_counters.pb.cc",
     "external/perfetto/protos/perfetto/common/trace_stats.pb.cc",
@@ -780,6 +782,7 @@
   srcs: [
     "protos/perfetto/common/android_log_constants.proto",
     "protos/perfetto/common/commit_data_request.proto",
+    "protos/perfetto/common/descriptor.proto",
     "protos/perfetto/common/observable_events.proto",
     "protos/perfetto/common/sys_stats_counters.proto",
     "protos/perfetto/common/trace_stats.proto",
@@ -791,6 +794,7 @@
   out: [
     "external/perfetto/protos/perfetto/common/android_log_constants.pb.h",
     "external/perfetto/protos/perfetto/common/commit_data_request.pb.h",
+    "external/perfetto/protos/perfetto/common/descriptor.pb.h",
     "external/perfetto/protos/perfetto/common/observable_events.pb.h",
     "external/perfetto/protos/perfetto/common/sys_stats_counters.pb.h",
     "external/perfetto/protos/perfetto/common/trace_stats.pb.h",
@@ -806,6 +810,7 @@
   srcs: [
     "protos/perfetto/common/android_log_constants.proto",
     "protos/perfetto/common/commit_data_request.proto",
+    "protos/perfetto/common/descriptor.proto",
     "protos/perfetto/common/observable_events.proto",
     "protos/perfetto/common/sys_stats_counters.proto",
     "protos/perfetto/common/trace_stats.proto",
@@ -818,6 +823,7 @@
   out: [
     "external/perfetto/protos/perfetto/common/android_log_constants.pbzero.cc",
     "external/perfetto/protos/perfetto/common/commit_data_request.pbzero.cc",
+    "external/perfetto/protos/perfetto/common/descriptor.pbzero.cc",
     "external/perfetto/protos/perfetto/common/observable_events.pbzero.cc",
     "external/perfetto/protos/perfetto/common/sys_stats_counters.pbzero.cc",
     "external/perfetto/protos/perfetto/common/trace_stats.pbzero.cc",
@@ -830,6 +836,7 @@
   srcs: [
     "protos/perfetto/common/android_log_constants.proto",
     "protos/perfetto/common/commit_data_request.proto",
+    "protos/perfetto/common/descriptor.proto",
     "protos/perfetto/common/observable_events.proto",
     "protos/perfetto/common/sys_stats_counters.proto",
     "protos/perfetto/common/trace_stats.proto",
@@ -842,6 +849,7 @@
   out: [
     "external/perfetto/protos/perfetto/common/android_log_constants.pbzero.h",
     "external/perfetto/protos/perfetto/common/commit_data_request.pbzero.h",
+    "external/perfetto/protos/perfetto/common/descriptor.pbzero.h",
     "external/perfetto/protos/perfetto/common/observable_events.pbzero.h",
     "external/perfetto/protos/perfetto/common/sys_stats_counters.pbzero.h",
     "external/perfetto/protos/perfetto/common/trace_stats.pbzero.h",
@@ -2413,7 +2421,6 @@
 genrule {
   name: "perfetto_src_perfetto_cmd_protos_gen",
   srcs: [
-    "src/perfetto_cmd/descriptor.proto",
     "src/perfetto_cmd/perfetto_cmd_state.proto",
   ],
   tools: [
@@ -2421,7 +2428,6 @@
   ],
   cmd: "mkdir -p $(genDir)/external/perfetto && $(location aprotoc) --cpp_out=$(genDir)/external/perfetto --proto_path=external/perfetto/ $(in)",
   out: [
-    "external/perfetto/src/perfetto_cmd/descriptor.pb.cc",
     "external/perfetto/src/perfetto_cmd/perfetto_cmd_state.pb.cc",
   ],
 }
@@ -2430,7 +2436,6 @@
 genrule {
   name: "perfetto_src_perfetto_cmd_protos_gen_headers",
   srcs: [
-    "src/perfetto_cmd/descriptor.proto",
     "src/perfetto_cmd/perfetto_cmd_state.proto",
   ],
   tools: [
@@ -2438,7 +2443,6 @@
   ],
   cmd: "mkdir -p $(genDir)/external/perfetto && $(location aprotoc) --cpp_out=$(genDir)/external/perfetto --proto_path=external/perfetto/ $(in)",
   out: [
-    "external/perfetto/src/perfetto_cmd/descriptor.pb.h",
     "external/perfetto/src/perfetto_cmd/perfetto_cmd_state.pb.h",
   ],
   export_include_dirs: [
diff --git a/BUILD b/BUILD
index b069279..664c8f4 100644
--- a/BUILD
+++ b/BUILD
@@ -201,6 +201,7 @@
         "src/trace_processor/json_trace_utils.cc",
         "src/trace_processor/json_trace_utils.h",
         "src/trace_processor/metrics/metrics.cc",
+        "src/trace_processor/metrics/metrics.descriptor.h",
         "src/trace_processor/metrics/metrics.h",
         "src/trace_processor/metrics/sql_metrics.h",
         "src/trace_processor/null_term_string_view.h",
@@ -462,6 +463,7 @@
         "src/trace_processor/json_trace_utils.cc",
         "src/trace_processor/json_trace_utils.h",
         "src/trace_processor/metrics/metrics.cc",
+        "src/trace_processor/metrics/metrics.descriptor.h",
         "src/trace_processor/metrics/metrics.h",
         "src/trace_processor/metrics/sql_metrics.h",
         "src/trace_processor/null_term_string_view.h",
@@ -679,6 +681,7 @@
         "src/trace_processor/json_trace_utils.cc",
         "src/trace_processor/json_trace_utils.h",
         "src/trace_processor/metrics/metrics.cc",
+        "src/trace_processor/metrics/metrics.descriptor.h",
         "src/trace_processor/metrics/metrics.h",
         "src/trace_processor/metrics/sql_metrics.h",
         "src/trace_processor/null_term_string_view.h",
@@ -821,3 +824,24 @@
     ],
     main = "tools/gen_merged_sql_metrics.py",
 )
+
+load("//security/fuzzing/blaze:cc_fuzz_target.bzl", "cc_fuzz_target")
+
+cc_fuzz_target(
+    name = "trace_parsing_fuzzer",
+    srcs = ["src/trace_processor/trace_parsing_fuzzer.cc"],
+    componentid = 323270,
+    deps = [
+        ":trace_processor",
+        "//third_party/perfetto/protos:trace_processor_cc_proto",
+    ],
+)
+
+cc_fuzz_target(
+    name = "proto_decoder_fuzzer",
+    srcs = ["src/protozero/proto_decoder_fuzzer.cc"],
+    componentid = 323270,
+    deps = [
+        ":trace_processor",
+    ],
+)
diff --git a/BUILD.extras b/BUILD.extras
index cda25fb..d18d9a2 100644
--- a/BUILD.extras
+++ b/BUILD.extras
@@ -17,3 +17,24 @@
     ],
     main = "tools/gen_merged_sql_metrics.py",
 )
+
+load("//security/fuzzing/blaze:cc_fuzz_target.bzl", "cc_fuzz_target")
+
+cc_fuzz_target(
+    name = "trace_parsing_fuzzer",
+    srcs = ["src/trace_processor/trace_parsing_fuzzer.cc"],
+    componentid = 323270,
+    deps = [
+        ":trace_processor",
+        "//third_party/perfetto/protos:trace_processor_cc_proto",
+    ],
+)
+
+cc_fuzz_target(
+    name = "proto_decoder_fuzzer",
+    srcs = ["src/protozero/proto_decoder_fuzzer.cc"],
+    componentid = 323270,
+    deps = [
+        ":trace_processor",
+    ],
+)
diff --git a/include/perfetto/base/paged_memory.h b/include/perfetto/base/paged_memory.h
index ea2aaae..f994ea5 100644
--- a/include/perfetto/base/paged_memory.h
+++ b/include/perfetto/base/paged_memory.h
@@ -78,6 +78,7 @@
 
   inline void* Get() const noexcept { return p_; }
   inline bool IsValid() const noexcept { return !!p_; }
+  inline size_t size() const noexcept { return size_; }
 
  private:
   PagedMemory(char* p, size_t size);
diff --git a/include/perfetto/base/thread_task_runner.h b/include/perfetto/base/thread_task_runner.h
index 7992eeb..db49a61 100644
--- a/include/perfetto/base/thread_task_runner.h
+++ b/include/perfetto/base/thread_task_runner.h
@@ -50,7 +50,7 @@
   //
   // Warning: do not call Quit() on the returned runner pointer, the termination
   // should be handled exclusively by this class' destructor.
-  UnixTaskRunner* get() { return task_runner_; }
+  UnixTaskRunner* get() const { return task_runner_; }
 
  private:
   ThreadTaskRunner();
diff --git a/include/perfetto/trace_processor/basic_types.h b/include/perfetto/trace_processor/basic_types.h
index 32ca2cd..82e417e 100644
--- a/include/perfetto/trace_processor/basic_types.h
+++ b/include/perfetto/trace_processor/basic_types.h
@@ -17,9 +17,12 @@
 #ifndef INCLUDE_PERFETTO_TRACE_PROCESSOR_BASIC_TYPES_H_
 #define INCLUDE_PERFETTO_TRACE_PROCESSOR_BASIC_TYPES_H_
 
+#include <stdarg.h>
 #include <stdint.h>
+#include <string>
 
 #include "perfetto/base/logging.h"
+#include "perfetto/base/optional.h"
 
 namespace perfetto {
 namespace trace_processor {
@@ -54,6 +57,61 @@
   Type type = kNull;
 };
 
+// Status and related methods are inside util for consistency with embedders of
+// trace processor.
+namespace util {
+
+// Represents either the success or the failure message of a function.
+// This can used as the return type of functions which would usually return an
+// bool for success or int for errno but also wants to add some string context
+// (ususally for logging).
+class Status {
+ public:
+  Status() = default;
+  explicit Status(std::string error) : message_(std::move(error)) {}
+
+  // Copy operations.
+  Status(const Status&) = default;
+  Status& operator=(const Status&) = default;
+
+  // Move operations. The moved-from state is valid but unspecified.
+  Status(Status&&) noexcept = default;
+  Status& operator=(Status&&) = default;
+
+  bool ok() const { return !message_.has_value(); }
+
+  // Only valid to call when this message has an Err status (i.e. ok() returned
+  // false or operator bool() returned true).
+  const std::string& message() const { return message_.value(); }
+
+  // Only valid to call when this message has an Err status (i.e. ok() returned
+  // false or operator bool() returned true).
+  const char* c_message() const { return message_.value().c_str(); }
+
+ private:
+  base::Optional<std::string> message_;
+};
+
+// Returns a status object which represents the Ok status.
+inline Status OkStatus() {
+  return Status();
+}
+
+// Returns a status object which represents an error with the given message
+// formatted using printf.
+__attribute__((__format__(__printf__, 1, 2))) inline Status ErrStatus(
+    const char* format,
+    ...) {
+  va_list ap;
+  va_start(ap, format);
+
+  char buffer[1024];
+  vsnprintf(buffer, sizeof(buffer), format, ap);
+  return Status(std::string(buffer));
+}
+
+}  // namespace util
+
 }  // namespace trace_processor
 }  // namespace perfetto
 
diff --git a/include/perfetto/trace_processor/trace_processor.h b/include/perfetto/trace_processor/trace_processor.h
index 13be4dd..e52fae7 100644
--- a/include/perfetto/trace_processor/trace_processor.h
+++ b/include/perfetto/trace_processor/trace_processor.h
@@ -65,10 +65,8 @@
     // even before calling |Next()|.
     uint32_t ColumnCount();
 
-    // Returns the error (if any) from the last call to next. If no error
-    // occurred, the returned value will be base::nullopt and implies that
-    // EOF was reached.
-    base::Optional<std::string> GetLastError();
+    // Returns the status of the iterator.
+    util::Status Status();
 
    private:
     std::unique_ptr<IteratorImpl> iterator_;
@@ -82,10 +80,11 @@
   // The entry point to push trace data into the processor. The trace format
   // will be automatically discovered on the first push call. It is possible
   // to make queries between two pushes.
-  // Returns true if parsing has been succeeding so far, false if some
-  // unrecoverable error happened. If this happens, the TraceProcessor will
-  // ignore the following Parse() requests and drop data on the floor.
-  virtual bool Parse(std::unique_ptr<uint8_t[]>, size_t) = 0;
+  // Returns the Ok status if parsing has been succeeding so far, and Error
+  // status if some unrecoverable error happened. If this happens, the
+  // TraceProcessor will ignore the following Parse() requests, drop data on the
+  // floor and return errors forever.
+  virtual util::Status Parse(std::unique_ptr<uint8_t[]>, size_t) = 0;
 
   // When parsing a bounded file (as opposite to streaming from a device) this
   // function should be called when the last chunk of the file has been passed
@@ -101,10 +100,10 @@
   // Computes the given metrics on the loded portion of the trace. If
   // successful, the output argument |metrics_proto| will be filled with the
   // proto-encoded bytes for the message TraceMetrics in
-  // perfetto/metrics/metrics.proto. The return value will be 0 if no error
-  // occured or non-zero otherwise.
-  virtual int ComputeMetric(const std::vector<std::string>& metric_names,
-                            std::vector<uint8_t>* metrics_proto) = 0;
+  // perfetto/metrics/metrics.proto.
+  virtual util::Status ComputeMetric(
+      const std::vector<std::string>& metric_names,
+      std::vector<uint8_t>* metrics_proto) = 0;
 
   // Interrupts the current query. Typically used by Ctrl-C handler.
   virtual void InterruptQuery() = 0;
diff --git a/include/perfetto/tracing/core/heapprofd_config.h b/include/perfetto/tracing/core/heapprofd_config.h
index cd3244c..a1e22cc 100644
--- a/include/perfetto/tracing/core/heapprofd_config.h
+++ b/include/perfetto/tracing/core/heapprofd_config.h
@@ -155,6 +155,12 @@
   bool block_client() const { return block_client_; }
   void set_block_client(bool value) { block_client_ = value; }
 
+  bool no_startup() const { return no_startup_; }
+  void set_no_startup(bool value) { no_startup_ = value; }
+
+  bool no_running() const { return no_running_; }
+  void set_no_running(bool value) { no_running_ = value; }
+
  private:
   uint64_t sampling_interval_bytes_ = {};
   std::vector<std::string> process_cmdline_;
@@ -164,6 +170,8 @@
   ContinuousDumpConfig continuous_dump_config_ = {};
   uint64_t shmem_size_bytes_ = {};
   bool block_client_ = {};
+  bool no_startup_ = {};
+  bool no_running_ = {};
 
   // Allows to preserve unknown protobuf fields for compatibility
   // with future versions of .proto files.
diff --git a/include/perfetto/tracing/core/tracing_service.h b/include/perfetto/tracing/core/tracing_service.h
index c2eb971..3d27698 100644
--- a/include/perfetto/tracing/core/tracing_service.h
+++ b/include/perfetto/tracing/core/tracing_service.h
@@ -45,6 +45,165 @@
 // TODO: for the moment this assumes that all the calls happen on the same
 // thread/sequence. Not sure this will be the case long term in Chrome.
 
+// The API for the Producer port of the Service.
+// Subclassed by:
+// 1. The tracing_service_impl.cc business logic when returning it in response
+//    to the ConnectProducer() method.
+// 2. The transport layer (e.g., src/ipc) when the producer and
+//    the service don't talk locally but via some IPC mechanism.
+class PERFETTO_EXPORT ProducerEndpoint {
+ public:
+  virtual ~ProducerEndpoint();
+
+  // Called by the Producer to (un)register data sources. Data sources are
+  // identified by their name (i.e. DataSourceDescriptor.name)
+  virtual void RegisterDataSource(const DataSourceDescriptor&) = 0;
+  virtual void UnregisterDataSource(const std::string& name) = 0;
+
+  // Associate the trace writer with the given |writer_id| with
+  // |target_buffer|. The service may use this information to retrieve and
+  // copy uncommitted chunks written by the trace writer into its associated
+  // buffer, e.g. when a producer process crashes or when a flush is
+  // necessary.
+  virtual void RegisterTraceWriter(uint32_t writer_id,
+                                   uint32_t target_buffer) = 0;
+
+  // Remove the association of the trace writer previously created via
+  // RegisterTraceWriter.
+  virtual void UnregisterTraceWriter(uint32_t writer_id) = 0;
+
+  // Called by the Producer to signal that some pages in the shared memory
+  // buffer (shared between Service and Producer) have changed.
+  // When the Producer and the Service are hosted in the same process and
+  // hence potentially live on the same task runner, This method must call
+  // TracingServiceImpl's CommitData synchronously, without any PostTask()s,
+  // if on the same thread. This is to avoid a deadlock where the Producer
+  // exhausts its SMB and stalls waiting for the service to catch up with
+  // reads, but the Service never gets to that because it lives on the same
+  // thread.
+  using CommitDataCallback = std::function<void()>;
+  virtual void CommitData(const CommitDataRequest&,
+                          CommitDataCallback callback = {}) = 0;
+
+  virtual SharedMemory* shared_memory() const = 0;
+
+  // Size of shared memory buffer pages. It's always a multiple of 4K.
+  // See shared_memory_abi.h
+  virtual size_t shared_buffer_page_size_kb() const = 0;
+
+  // Creates a trace writer, which allows to create events, handling the
+  // underying shared memory buffer and signalling to the Service. This method
+  // is thread-safe but the returned object is not. A TraceWriter should be
+  // used only from a single thread, or the caller has to handle sequencing
+  // via a mutex or equivalent. This method can only be called if
+  // TracingService::ConnectProducer was called with |in_process=true|.
+  // Args:
+  // |target_buffer| is the target buffer ID where the data produced by the
+  // writer should be stored by the tracing service. This value is passed
+  // upon creation of the data source (StartDataSource()) in the
+  // DataSourceConfig.target_buffer().
+  virtual std::unique_ptr<TraceWriter> CreateTraceWriter(
+      BufferID target_buffer) = 0;
+
+  // If TracingService::ConnectProducer is called with |in_process=true|,
+  // this returns the producer's SharedMemoryArbiter which can be used
+  // to create TraceWriters which is able to directly commit chunks
+  // without going through an IPC layer.
+  virtual SharedMemoryArbiter* GetInProcessShmemArbiter() = 0;
+
+  // Called in response to a Producer::Flush(request_id) call after all data
+  // for the flush request has been committed.
+  virtual void NotifyFlushComplete(FlushRequestID) = 0;
+
+  // Called in response to one or more Producer::StartDataSource(),
+  // if the data source registered setting the flag
+  // DataSourceDescriptor.will_notify_on_start.
+  virtual void NotifyDataSourceStarted(DataSourceInstanceID) = 0;
+
+  // Called in response to one or more Producer::StopDataSource(),
+  // if the data source registered setting the flag
+  // DataSourceDescriptor.will_notify_on_stop.
+  virtual void NotifyDataSourceStopped(DataSourceInstanceID) = 0;
+
+  // This informs the service to activate any of these triggers if any tracing
+  // session was waiting for them.
+  virtual void ActivateTriggers(const std::vector<std::string>&) = 0;
+};  // class ProducerEndpoint.
+
+// The API for the Consumer port of the Service.
+// Subclassed by:
+// 1. The tracing_service_impl.cc business logic when returning it in response
+// to
+//    the ConnectConsumer() method.
+// 2. The transport layer (e.g., src/ipc) when the consumer and
+//    the service don't talk locally but via some IPC mechanism.
+class ConsumerEndpoint {
+ public:
+  virtual ~ConsumerEndpoint();
+
+  // Enables tracing with the given TraceConfig. The ScopedFile argument is
+  // used only when TraceConfig.write_into_file == true.
+  // If TraceConfig.deferred_start == true data sources are configured via
+  // SetupDataSource() but are not started until StartTracing() is called.
+  // This is to support pre-initialization and fast triggering of traces.
+  // The ScopedFile argument is used only when TraceConfig.write_into_file
+  // == true.
+  virtual void EnableTracing(const TraceConfig&,
+                             base::ScopedFile = base::ScopedFile()) = 0;
+
+  // Update the trace config of an existing tracing session; only a subset
+  // of options can be changed mid-session. Currently the only
+  // supported functionality is expanding the list of producer_name_filters()
+  // (or removing the filter entirely) for existing data sources.
+  virtual void ChangeTraceConfig(const TraceConfig&) = 0;
+
+  // Starts all data sources configured in the trace config. This is used only
+  // after calling EnableTracing() with TraceConfig.deferred_start=true.
+  // It's a no-op if called after a regular EnableTracing(), without setting
+  // deferred_start.
+  virtual void StartTracing() = 0;
+
+  virtual void DisableTracing() = 0;
+
+  // Requests all data sources to flush their data immediately and invokes the
+  // passed callback once all of them have acked the flush (in which case
+  // the callback argument |success| will be true) or |timeout_ms| are elapsed
+  // (in which case |success| will be false).
+  // If |timeout_ms| is 0 the TraceConfig's flush_timeout_ms is used, or,
+  // if that one is not set (or is set to 0), kDefaultFlushTimeoutMs (5s) is
+  // used.
+  using FlushCallback = std::function<void(bool /*success*/)>;
+  virtual void Flush(uint32_t timeout_ms, FlushCallback) = 0;
+
+  // Tracing data will be delivered invoking Consumer::OnTraceData().
+  virtual void ReadBuffers() = 0;
+
+  virtual void FreeBuffers() = 0;
+
+  // Will call OnDetach().
+  virtual void Detach(const std::string& key) = 0;
+
+  // Will call OnAttach().
+  virtual void Attach(const std::string& key) = 0;
+
+  // Will call OnTraceStats().
+  virtual void GetTraceStats() = 0;
+
+  enum ObservableEventType : uint32_t {
+    kNone = 0,
+    kDataSourceInstances = 1 << 0
+  };
+
+  // Start or stop observing events of selected types. |enabled_event_types|
+  // specifies the types of events to observe in a bitmask (see
+  // ObservableEventType enum). To disable observing, pass
+  // ObservableEventType::kNone. Will call OnObservableEvents() repeatedly
+  // whenever an event of an enabled ObservableEventType occurs.
+  //
+  // TODO(eseckler): Extend this to support producers & data sources.
+  virtual void ObserveEvents(uint32_t enabled_event_types) = 0;
+};  // class ConsumerEndpoint.
+
 // The public API of the tracing Service business logic.
 //
 // Exposed to:
@@ -57,164 +216,8 @@
 //   The service business logic in src/core/tracing_service_impl.cc.
 class PERFETTO_EXPORT TracingService {
  public:
-  // The API for the Producer port of the Service.
-  // Subclassed by:
-  // 1. The tracing_service_impl.cc business logic when returning it in response
-  //    to the ConnectProducer() method.
-  // 2. The transport layer (e.g., src/ipc) when the producer and
-  //    the service don't talk locally but via some IPC mechanism.
-  class PERFETTO_EXPORT ProducerEndpoint {
-   public:
-    virtual ~ProducerEndpoint();
-
-    // Called by the Producer to (un)register data sources. Data sources are
-    // identified by their name (i.e. DataSourceDescriptor.name)
-    virtual void RegisterDataSource(const DataSourceDescriptor&) = 0;
-    virtual void UnregisterDataSource(const std::string& name) = 0;
-
-    // Associate the trace writer with the given |writer_id| with
-    // |target_buffer|. The service may use this information to retrieve and
-    // copy uncommitted chunks written by the trace writer into its associated
-    // buffer, e.g. when a producer process crashes or when a flush is
-    // necessary.
-    virtual void RegisterTraceWriter(uint32_t writer_id,
-                                     uint32_t target_buffer) = 0;
-
-    // Remove the association of the trace writer previously created via
-    // RegisterTraceWriter.
-    virtual void UnregisterTraceWriter(uint32_t writer_id) = 0;
-
-    // Called by the Producer to signal that some pages in the shared memory
-    // buffer (shared between Service and Producer) have changed.
-    // When the Producer and the Service are hosted in the same process and
-    // hence potentially live on the same task runner, This method must call
-    // TracingServiceImpl's CommitData synchronously, without any PostTask()s,
-    // if on the same thread. This is to avoid a deadlock where the Producer
-    // exhausts its SMB and stalls waiting for the service to catch up with
-    // reads, but the Service never gets to that because it lives on the same
-    // thread.
-    using CommitDataCallback = std::function<void()>;
-    virtual void CommitData(const CommitDataRequest&,
-                            CommitDataCallback callback = {}) = 0;
-
-    virtual SharedMemory* shared_memory() const = 0;
-
-    // Size of shared memory buffer pages. It's always a multiple of 4K.
-    // See shared_memory_abi.h
-    virtual size_t shared_buffer_page_size_kb() const = 0;
-
-    // Creates a trace writer, which allows to create events, handling the
-    // underying shared memory buffer and signalling to the Service. This method
-    // is thread-safe but the returned object is not. A TraceWriter should be
-    // used only from a single thread, or the caller has to handle sequencing
-    // via a mutex or equivalent. This method can only be called if
-    // TracingService::ConnectProducer was called with |in_process=true|.
-    // Args:
-    // |target_buffer| is the target buffer ID where the data produced by the
-    // writer should be stored by the tracing service. This value is passed
-    // upon creation of the data source (StartDataSource()) in the
-    // DataSourceConfig.target_buffer().
-    virtual std::unique_ptr<TraceWriter> CreateTraceWriter(
-        BufferID target_buffer) = 0;
-
-    // If TracingService::ConnectProducer is called with |in_process=true|,
-    // this returns the producer's SharedMemoryArbiter which can be used
-    // to create TraceWriters which is able to directly commit chunks
-    // without going through an IPC layer.
-    virtual SharedMemoryArbiter* GetInProcessShmemArbiter() = 0;
-
-    // Called in response to a Producer::Flush(request_id) call after all data
-    // for the flush request has been committed.
-    virtual void NotifyFlushComplete(FlushRequestID) = 0;
-
-    // Called in response to one or more Producer::StartDataSource(),
-    // if the data source registered setting the flag
-    // DataSourceDescriptor.will_notify_on_start.
-    virtual void NotifyDataSourceStarted(DataSourceInstanceID) = 0;
-
-    // Called in response to one or more Producer::StopDataSource(),
-    // if the data source registered setting the flag
-    // DataSourceDescriptor.will_notify_on_stop.
-    virtual void NotifyDataSourceStopped(DataSourceInstanceID) = 0;
-
-    // This informs the service to activate any of these triggers if any tracing
-    // session was waiting for them.
-    virtual void ActivateTriggers(const std::vector<std::string>&) = 0;
-  };  // class ProducerEndpoint.
-
-  // The API for the Consumer port of the Service.
-  // Subclassed by:
-  // 1. The tracing_service_impl.cc business logic when returning it in response
-  // to
-  //    the ConnectConsumer() method.
-  // 2. The transport layer (e.g., src/ipc) when the consumer and
-  //    the service don't talk locally but via some IPC mechanism.
-  class ConsumerEndpoint {
-   public:
-    virtual ~ConsumerEndpoint();
-
-    // Enables tracing with the given TraceConfig. The ScopedFile argument is
-    // used only when TraceConfig.write_into_file == true.
-    // If TraceConfig.deferred_start == true data sources are configured via
-    // SetupDataSource() but are not started until StartTracing() is called.
-    // This is to support pre-initialization and fast triggering of traces.
-    // The ScopedFile argument is used only when TraceConfig.write_into_file
-    // == true.
-    virtual void EnableTracing(const TraceConfig&,
-                               base::ScopedFile = base::ScopedFile()) = 0;
-
-    // Update the trace config of an existing tracing session; only a subset
-    // of options can be changed mid-session. Currently the only
-    // supported functionality is expanding the list of producer_name_filters()
-    // (or removing the filter entirely) for existing data sources.
-    virtual void ChangeTraceConfig(const TraceConfig&) = 0;
-
-    // Starts all data sources configured in the trace config. This is used only
-    // after calling EnableTracing() with TraceConfig.deferred_start=true.
-    // It's a no-op if called after a regular EnableTracing(), without setting
-    // deferred_start.
-    virtual void StartTracing() = 0;
-
-    virtual void DisableTracing() = 0;
-
-    // Requests all data sources to flush their data immediately and invokes the
-    // passed callback once all of them have acked the flush (in which case
-    // the callback argument |success| will be true) or |timeout_ms| are elapsed
-    // (in which case |success| will be false).
-    // If |timeout_ms| is 0 the TraceConfig's flush_timeout_ms is used, or,
-    // if that one is not set (or is set to 0), kDefaultFlushTimeoutMs (5s) is
-    // used.
-    using FlushCallback = std::function<void(bool /*success*/)>;
-    virtual void Flush(uint32_t timeout_ms, FlushCallback) = 0;
-
-    // Tracing data will be delivered invoking Consumer::OnTraceData().
-    virtual void ReadBuffers() = 0;
-
-    virtual void FreeBuffers() = 0;
-
-    // Will call OnDetach().
-    virtual void Detach(const std::string& key) = 0;
-
-    // Will call OnAttach().
-    virtual void Attach(const std::string& key) = 0;
-
-    // Will call OnTraceStats().
-    virtual void GetTraceStats() = 0;
-
-    enum ObservableEventType : uint32_t {
-      kNone = 0,
-      kDataSourceInstances = 1 << 0
-    };
-
-    // Start or stop observing events of selected types. |enabled_event_types|
-    // specifies the types of events to observe in a bitmask (see
-    // ObservableEventType enum). To disable observing, pass
-    // ObservableEventType::kNone. Will call OnObservableEvents() repeatedly
-    // whenever an event of an enabled ObservableEventType occurs.
-    //
-    // TODO(eseckler): Extend this to support producers & data sources.
-    virtual void ObserveEvents(uint32_t enabled_event_types) = 0;
-  };  // class ConsumerEndpoint.
+  using ProducerEndpoint = perfetto::ProducerEndpoint;
+  using ConsumerEndpoint = perfetto::ConsumerEndpoint;
 
   // Implemented in src/core/tracing_service_impl.cc .
   static std::unique_ptr<TracingService> CreateInstance(
diff --git a/protos/BUILD b/protos/BUILD
index ed2ce1f..bf721d9 100644
--- a/protos/BUILD
+++ b/protos/BUILD
@@ -29,6 +29,7 @@
     srcs = [
         "perfetto/common/android_log_constants.proto",
         "perfetto/common/commit_data_request.proto",
+        "perfetto/common/descriptor.proto",
         "perfetto/common/observable_events.proto",
         "perfetto/common/sys_stats_counters.proto",
         "perfetto/common/trace_stats.proto",
@@ -58,6 +59,7 @@
     srcs = [
         "perfetto/common/android_log_constants.proto",
         "perfetto/common/commit_data_request.proto",
+        "perfetto/common/descriptor.proto",
         "perfetto/common/observable_events.proto",
         "perfetto/common/sys_stats_counters.proto",
         "perfetto/common/trace_stats.proto",
@@ -672,6 +674,33 @@
     ],
 )
 
+# GN target: //protos/perfetto/trace_processor:lite_gen
+proto_library(
+    name = "trace_processor",
+    srcs = [
+        "perfetto/trace_processor/raw_query.proto",
+        "perfetto/trace_processor/sched.proto",
+        "perfetto/trace_processor/trace_processor.proto",
+    ],
+    has_services = 1,
+    cc_api_version = 2,
+    cc_generic_services = 1,
+    visibility = [
+        "//visibility:public",
+    ],
+)
+
+# GN target: //protos/perfetto/trace_processor:lite_gen
+cc_proto_library(
+    name = "trace_processor_cc_proto",
+    visibility = [
+        "//visibility:public",
+    ],
+    deps = [
+        "//third_party/perfetto/protos:trace_processor",
+    ],
+)
+
 # GN target: //protos/perfetto/trace/profiling:lite_gen
 proto_library(
     name = "trace_profiling",
diff --git a/protos/perfetto/common/BUILD.gn b/protos/perfetto/common/BUILD.gn
index a67b42d..36a9b20 100644
--- a/protos/perfetto/common/BUILD.gn
+++ b/protos/perfetto/common/BUILD.gn
@@ -17,8 +17,9 @@
 import("../../../gn/protozero_library.gni")
 
 common_sources = [
-  "commit_data_request.proto",
   "android_log_constants.proto",
+  "commit_data_request.proto",
+  "descriptor.proto",
   "observable_events.proto",
   "sys_stats_counters.proto",
   "trace_stats.proto",
diff --git a/src/perfetto_cmd/descriptor.proto b/protos/perfetto/common/descriptor.proto
similarity index 100%
rename from src/perfetto_cmd/descriptor.proto
rename to protos/perfetto/common/descriptor.proto
diff --git a/protos/perfetto/config/perfetto_config.proto b/protos/perfetto/config/perfetto_config.proto
index 10ad415..d1795f6 100644
--- a/protos/perfetto/config/perfetto_config.proto
+++ b/protos/perfetto/config/perfetto_config.proto
@@ -791,6 +791,17 @@
   // trace. Use with caution as this will significantly slow down the target
   // process.
   optional bool block_client = 9;
+
+  // Do not profile processes from startup, only match already running
+  // processes.
+  //
+  // Can not be set at the same time as no_running.
+  optional bool no_startup = 10;
+
+  // Do not profile running processes. Only match processes on startup.
+  //
+  // Can not be set at the same time as no_startup.
+  optional bool no_running = 11;
 }
 
 // End of protos/perfetto/config/profiling/heapprofd_config.proto
diff --git a/protos/perfetto/config/profiling/heapprofd_config.proto b/protos/perfetto/config/profiling/heapprofd_config.proto
index cc9085f..b71a149 100644
--- a/protos/perfetto/config/profiling/heapprofd_config.proto
+++ b/protos/perfetto/config/profiling/heapprofd_config.proto
@@ -84,4 +84,15 @@
   // trace. Use with caution as this will significantly slow down the target
   // process.
   optional bool block_client = 9;
+
+  // Do not profile processes from startup, only match already running
+  // processes.
+  //
+  // Can not be set at the same time as no_running.
+  optional bool no_startup = 10;
+
+  // Do not profile running processes. Only match processes on startup.
+  //
+  // Can not be set at the same time as no_startup.
+  optional bool no_running = 11;
 }
diff --git a/protos/perfetto/trace/perfetto_trace.proto b/protos/perfetto/trace/perfetto_trace.proto
index 103b8a9..66daa9f 100644
--- a/protos/perfetto/trace/perfetto_trace.proto
+++ b/protos/perfetto/trace/perfetto_trace.proto
@@ -3846,6 +3846,17 @@
   // trace. Use with caution as this will significantly slow down the target
   // process.
   optional bool block_client = 9;
+
+  // Do not profile processes from startup, only match already running
+  // processes.
+  //
+  // Can not be set at the same time as no_running.
+  optional bool no_startup = 10;
+
+  // Do not profile running processes. Only match processes on startup.
+  //
+  // Can not be set at the same time as no_startup.
+  optional bool no_running = 11;
 }
 
 // End of protos/perfetto/config/profiling/heapprofd_config.proto
diff --git a/src/perfetto_cmd/BUILD.gn b/src/perfetto_cmd/BUILD.gn
index 2a5408b..b4ec76c 100644
--- a/src/perfetto_cmd/BUILD.gn
+++ b/src/perfetto_cmd/BUILD.gn
@@ -24,6 +24,7 @@
     ":trigger_producer",
     "../../buildtools:protobuf_lite",
     "../../gn:default_deps",
+    "../../protos/perfetto/common:lite",
     "../../protos/perfetto/config:lite",
     "../base",
     "../protozero",
@@ -84,7 +85,6 @@
   generate_python = false
   deps = []
   sources = [
-    "descriptor.proto",
     "perfetto_cmd_state.proto",
   ]
   proto_in_dir = perfetto_root_path
diff --git a/src/perfetto_cmd/pbtxt_to_pb.cc b/src/perfetto_cmd/pbtxt_to_pb.cc
index 4dc0518..687ae79 100644
--- a/src/perfetto_cmd/pbtxt_to_pb.cc
+++ b/src/perfetto_cmd/pbtxt_to_pb.cc
@@ -22,12 +22,12 @@
 #include "src/perfetto_cmd/pbtxt_to_pb.h"
 
 #include "google/protobuf/io/zero_copy_stream_impl_lite.h"
-#include "src/perfetto_cmd/descriptor.pb.h"
 
 #include "perfetto/base/file_utils.h"
 #include "perfetto/base/logging.h"
 #include "perfetto/base/string_view.h"
 #include "perfetto/base/utils.h"
+#include "perfetto/common/descriptor.pb.h"
 #include "perfetto/protozero/message.h"
 #include "perfetto/protozero/message_handle.h"
 #include "perfetto/protozero/scattered_heap_buffer.h"
diff --git a/src/perfetto_cmd/perfetto_config.descriptor.h b/src/perfetto_cmd/perfetto_config.descriptor.h
index 5148e1e..7d026c2 100644
--- a/src/perfetto_cmd/perfetto_config.descriptor.h
+++ b/src/perfetto_cmd/perfetto_config.descriptor.h
@@ -10,17 +10,17 @@
 // This file was autogenerated by tools/gen_binary_descriptors. Do not edit.
 
 // SHA1(tools/gen_binary_descriptors)
-// e329b1e1e964417db57f83d8ecf081e041923e78
+// 750d7d8f95621b45d4b6430d6f8808087a8702e6
 // SHA1(protos/perfetto/config/perfetto_config.proto)
-// 6ba9704e910146497fefad8eff33f521453acc85
+// 4554d63035935a67ece9ce82e683a119d45aa1f9
 
 // This is the proto PerfettoConfig encoded as a ProtoFileDescriptor to allow
 // for reflection without libprotobuf full/non-lite protos.
 
 namespace perfetto {
 
-constexpr std::array<uint8_t, 10934> kPerfettoConfigDescriptor{
-    {0x0a, 0xb3, 0x55, 0x0a, 0x25, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74,
+constexpr std::array<uint8_t, 10996> kPerfettoConfigDescriptor{
+    {0x0a, 0xf1, 0x55, 0x0a, 0x25, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74,
      0x6f, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x70, 0x65, 0x72,
      0x66, 0x65, 0x74, 0x74, 0x6f, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
      0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x70, 0x65, 0x72, 0x66,
@@ -571,7 +571,7 @@
      0x12, 0x12, 0x0a, 0x0e, 0x4c, 0x4f, 0x43, 0x4b, 0x44, 0x4f, 0x57, 0x4e,
      0x5f, 0x43, 0x4c, 0x45, 0x41, 0x52, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c,
      0x4c, 0x4f, 0x43, 0x4b, 0x44, 0x4f, 0x57, 0x4e, 0x5f, 0x53, 0x45, 0x54,
-     0x10, 0x02, 0x4a, 0x04, 0x08, 0x0f, 0x10, 0x10, 0x22, 0xe4, 0x03, 0x0a,
+     0x10, 0x02, 0x4a, 0x04, 0x08, 0x0f, 0x10, 0x10, 0x22, 0xa2, 0x04, 0x0a,
      0x0f, 0x48, 0x65, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x66, 0x64, 0x43, 0x6f,
      0x6e, 0x66, 0x69, 0x67, 0x12, 0x36, 0x0a, 0x17, 0x73, 0x61, 0x6d, 0x70,
      0x6c, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61,
@@ -603,335 +603,340 @@
      0x6d, 0x53, 0x69, 0x7a, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x21,
      0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x63, 0x6c, 0x69, 0x65,
      0x6e, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x62, 0x6c,
-     0x6f, 0x63, 0x6b, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x1a, 0x64, 0x0a,
-     0x14, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x44,
-     0x75, 0x6d, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x22, 0x0a,
-     0x0d, 0x64, 0x75, 0x6d, 0x70, 0x5f, 0x70, 0x68, 0x61, 0x73, 0x65, 0x5f,
-     0x6d, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x64, 0x75,
-     0x6d, 0x70, 0x50, 0x68, 0x61, 0x73, 0x65, 0x4d, 0x73, 0x12, 0x28, 0x0a,
-     0x10, 0x64, 0x75, 0x6d, 0x70, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76,
-     0x61, 0x6c, 0x5f, 0x6d, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52,
-     0x0e, 0x64, 0x75, 0x6d, 0x70, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61,
-     0x6c, 0x4d, 0x73, 0x2a, 0x8e, 0x01, 0x0a, 0x0c, 0x41, 0x6e, 0x64, 0x72,
-     0x6f, 0x69, 0x64, 0x4c, 0x6f, 0x67, 0x49, 0x64, 0x12, 0x0f, 0x0a, 0x0b,
-     0x4c, 0x49, 0x44, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10,
-     0x00, 0x12, 0x0d, 0x0a, 0x09, 0x4c, 0x49, 0x44, 0x5f, 0x52, 0x41, 0x44,
-     0x49, 0x4f, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x4c, 0x49, 0x44, 0x5f,
-     0x45, 0x56, 0x45, 0x4e, 0x54, 0x53, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a,
-     0x4c, 0x49, 0x44, 0x5f, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x10, 0x03,
-     0x12, 0x0d, 0x0a, 0x09, 0x4c, 0x49, 0x44, 0x5f, 0x43, 0x52, 0x41, 0x53,
-     0x48, 0x10, 0x04, 0x12, 0x0d, 0x0a, 0x09, 0x4c, 0x49, 0x44, 0x5f, 0x53,
-     0x54, 0x41, 0x54, 0x53, 0x10, 0x05, 0x12, 0x10, 0x0a, 0x0c, 0x4c, 0x49,
-     0x44, 0x5f, 0x53, 0x45, 0x43, 0x55, 0x52, 0x49, 0x54, 0x59, 0x10, 0x06,
-     0x12, 0x0e, 0x0a, 0x0a, 0x4c, 0x49, 0x44, 0x5f, 0x4b, 0x45, 0x52, 0x4e,
-     0x45, 0x4c, 0x10, 0x07, 0x2a, 0x9b, 0x01, 0x0a, 0x12, 0x41, 0x6e, 0x64,
-     0x72, 0x6f, 0x69, 0x64, 0x4c, 0x6f, 0x67, 0x50, 0x72, 0x69, 0x6f, 0x72,
-     0x69, 0x74, 0x79, 0x12, 0x14, 0x0a, 0x10, 0x50, 0x52, 0x49, 0x4f, 0x5f,
-     0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10,
-     0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x50, 0x52, 0x49, 0x4f, 0x5f, 0x55, 0x4e,
-     0x55, 0x53, 0x45, 0x44, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x50, 0x52,
-     0x49, 0x4f, 0x5f, 0x56, 0x45, 0x52, 0x42, 0x4f, 0x53, 0x45, 0x10, 0x02,
-     0x12, 0x0e, 0x0a, 0x0a, 0x50, 0x52, 0x49, 0x4f, 0x5f, 0x44, 0x45, 0x42,
-     0x55, 0x47, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x50, 0x52, 0x49, 0x4f,
-     0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x04, 0x12, 0x0d, 0x0a, 0x09, 0x50,
-     0x52, 0x49, 0x4f, 0x5f, 0x57, 0x41, 0x52, 0x4e, 0x10, 0x05, 0x12, 0x0e,
-     0x0a, 0x0a, 0x50, 0x52, 0x49, 0x4f, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52,
-     0x10, 0x06, 0x12, 0x0e, 0x0a, 0x0a, 0x50, 0x52, 0x49, 0x4f, 0x5f, 0x46,
-     0x41, 0x54, 0x41, 0x4c, 0x10, 0x07, 0x2a, 0xbf, 0x06, 0x0a, 0x0f, 0x4d,
-     0x65, 0x6d, 0x69, 0x6e, 0x66, 0x6f, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65,
-     0x72, 0x73, 0x12, 0x17, 0x0a, 0x13, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46,
+     0x6f, 0x63, 0x6b, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x1d, 0x0a,
+     0x0a, 0x6e, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x18,
+     0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x6e, 0x6f, 0x53, 0x74, 0x61,
+     0x72, 0x74, 0x75, 0x70, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x6f, 0x5f, 0x72,
+     0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08,
+     0x52, 0x09, 0x6e, 0x6f, 0x52, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x1a,
+     0x64, 0x0a, 0x14, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75,
+     0x73, 0x44, 0x75, 0x6d, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
+     0x22, 0x0a, 0x0d, 0x64, 0x75, 0x6d, 0x70, 0x5f, 0x70, 0x68, 0x61, 0x73,
+     0x65, 0x5f, 0x6d, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b,
+     0x64, 0x75, 0x6d, 0x70, 0x50, 0x68, 0x61, 0x73, 0x65, 0x4d, 0x73, 0x12,
+     0x28, 0x0a, 0x10, 0x64, 0x75, 0x6d, 0x70, 0x5f, 0x69, 0x6e, 0x74, 0x65,
+     0x72, 0x76, 0x61, 0x6c, 0x5f, 0x6d, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28,
+     0x0d, 0x52, 0x0e, 0x64, 0x75, 0x6d, 0x70, 0x49, 0x6e, 0x74, 0x65, 0x72,
+     0x76, 0x61, 0x6c, 0x4d, 0x73, 0x2a, 0x8e, 0x01, 0x0a, 0x0c, 0x41, 0x6e,
+     0x64, 0x72, 0x6f, 0x69, 0x64, 0x4c, 0x6f, 0x67, 0x49, 0x64, 0x12, 0x0f,
+     0x0a, 0x0b, 0x4c, 0x49, 0x44, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c,
+     0x54, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x4c, 0x49, 0x44, 0x5f, 0x52,
+     0x41, 0x44, 0x49, 0x4f, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x4c, 0x49,
+     0x44, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x53, 0x10, 0x02, 0x12, 0x0e,
+     0x0a, 0x0a, 0x4c, 0x49, 0x44, 0x5f, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d,
+     0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x4c, 0x49, 0x44, 0x5f, 0x43, 0x52,
+     0x41, 0x53, 0x48, 0x10, 0x04, 0x12, 0x0d, 0x0a, 0x09, 0x4c, 0x49, 0x44,
+     0x5f, 0x53, 0x54, 0x41, 0x54, 0x53, 0x10, 0x05, 0x12, 0x10, 0x0a, 0x0c,
+     0x4c, 0x49, 0x44, 0x5f, 0x53, 0x45, 0x43, 0x55, 0x52, 0x49, 0x54, 0x59,
+     0x10, 0x06, 0x12, 0x0e, 0x0a, 0x0a, 0x4c, 0x49, 0x44, 0x5f, 0x4b, 0x45,
+     0x52, 0x4e, 0x45, 0x4c, 0x10, 0x07, 0x2a, 0x9b, 0x01, 0x0a, 0x12, 0x41,
+     0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x4c, 0x6f, 0x67, 0x50, 0x72, 0x69,
+     0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x14, 0x0a, 0x10, 0x50, 0x52, 0x49,
      0x4f, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45,
-     0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x45, 0x4d, 0x49, 0x4e,
-     0x46, 0x4f, 0x5f, 0x4d, 0x45, 0x4d, 0x5f, 0x54, 0x4f, 0x54, 0x41, 0x4c,
-     0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46,
-     0x4f, 0x5f, 0x4d, 0x45, 0x4d, 0x5f, 0x46, 0x52, 0x45, 0x45, 0x10, 0x02,
-     0x12, 0x19, 0x0a, 0x15, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f,
-     0x4d, 0x45, 0x4d, 0x5f, 0x41, 0x56, 0x41, 0x49, 0x4c, 0x41, 0x42, 0x4c,
-     0x45, 0x10, 0x03, 0x12, 0x13, 0x0a, 0x0f, 0x4d, 0x45, 0x4d, 0x49, 0x4e,
-     0x46, 0x4f, 0x5f, 0x42, 0x55, 0x46, 0x46, 0x45, 0x52, 0x53, 0x10, 0x04,
-     0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f,
-     0x43, 0x41, 0x43, 0x48, 0x45, 0x44, 0x10, 0x05, 0x12, 0x17, 0x0a, 0x13,
-     0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x53, 0x57, 0x41, 0x50,
-     0x5f, 0x43, 0x41, 0x43, 0x48, 0x45, 0x44, 0x10, 0x06, 0x12, 0x12, 0x0a,
-     0x0e, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x41, 0x43, 0x54,
-     0x49, 0x56, 0x45, 0x10, 0x07, 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x45, 0x4d,
-     0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56,
-     0x45, 0x10, 0x08, 0x12, 0x17, 0x0a, 0x13, 0x4d, 0x45, 0x4d, 0x49, 0x4e,
-     0x46, 0x4f, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x41, 0x4e,
-     0x4f, 0x4e, 0x10, 0x09, 0x12, 0x19, 0x0a, 0x15, 0x4d, 0x45, 0x4d, 0x49,
-     0x4e, 0x46, 0x4f, 0x5f, 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45,
-     0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x10, 0x0a, 0x12, 0x17, 0x0a, 0x13, 0x4d,
-     0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56,
-     0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x0b, 0x12, 0x19, 0x0a, 0x15,
-     0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x49, 0x4e, 0x41, 0x43,
-     0x54, 0x49, 0x56, 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x0c, 0x12,
-     0x17, 0x0a, 0x13, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x55,
-     0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x0d,
-     0x12, 0x13, 0x0a, 0x0f, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f,
-     0x4d, 0x4c, 0x4f, 0x43, 0x4b, 0x45, 0x44, 0x10, 0x0e, 0x12, 0x16, 0x0a,
-     0x12, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x53, 0x57, 0x41,
-     0x50, 0x5f, 0x54, 0x4f, 0x54, 0x41, 0x4c, 0x10, 0x0f, 0x12, 0x15, 0x0a,
-     0x11, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x53, 0x57, 0x41,
-     0x50, 0x5f, 0x46, 0x52, 0x45, 0x45, 0x10, 0x10, 0x12, 0x11, 0x0a, 0x0d,
-     0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x44, 0x49, 0x52, 0x54,
-     0x59, 0x10, 0x11, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x45, 0x4d, 0x49, 0x4e,
-     0x46, 0x4f, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x42, 0x41, 0x43, 0x4b,
-     0x10, 0x12, 0x12, 0x16, 0x0a, 0x12, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46,
-     0x4f, 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x53,
-     0x10, 0x13, 0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46,
-     0x4f, 0x5f, 0x4d, 0x41, 0x50, 0x50, 0x45, 0x44, 0x10, 0x14, 0x12, 0x11,
-     0x0a, 0x0d, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x53, 0x48,
-     0x4d, 0x45, 0x4d, 0x10, 0x15, 0x12, 0x10, 0x0a, 0x0c, 0x4d, 0x45, 0x4d,
-     0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x53, 0x4c, 0x41, 0x42, 0x10, 0x16, 0x12,
-     0x1c, 0x0a, 0x18, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x53,
-     0x4c, 0x41, 0x42, 0x5f, 0x52, 0x45, 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x41,
-     0x42, 0x4c, 0x45, 0x10, 0x17, 0x12, 0x1e, 0x0a, 0x1a, 0x4d, 0x45, 0x4d,
-     0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x53, 0x4c, 0x41, 0x42, 0x5f, 0x55, 0x4e,
-     0x52, 0x45, 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x41, 0x42, 0x4c, 0x45, 0x10,
-     0x18, 0x12, 0x18, 0x0a, 0x14, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f,
-     0x5f, 0x4b, 0x45, 0x52, 0x4e, 0x45, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x43,
-     0x4b, 0x10, 0x19, 0x12, 0x17, 0x0a, 0x13, 0x4d, 0x45, 0x4d, 0x49, 0x4e,
-     0x46, 0x4f, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x5f, 0x54, 0x41, 0x42, 0x4c,
-     0x45, 0x53, 0x10, 0x1a, 0x12, 0x18, 0x0a, 0x14, 0x4d, 0x45, 0x4d, 0x49,
-     0x4e, 0x46, 0x4f, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x5f, 0x4c,
-     0x49, 0x4d, 0x49, 0x54, 0x10, 0x1b, 0x12, 0x17, 0x0a, 0x13, 0x4d, 0x45,
-     0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54,
-     0x45, 0x44, 0x5f, 0x41, 0x53, 0x10, 0x1c, 0x12, 0x19, 0x0a, 0x15, 0x4d,
-     0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x56, 0x4d, 0x41, 0x4c, 0x4c,
-     0x4f, 0x43, 0x5f, 0x54, 0x4f, 0x54, 0x41, 0x4c, 0x10, 0x1d, 0x12, 0x18,
-     0x0a, 0x14, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x56, 0x4d,
-     0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x5f, 0x55, 0x53, 0x45, 0x44, 0x10, 0x1e,
-     0x12, 0x19, 0x0a, 0x15, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f,
-     0x56, 0x4d, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x5f, 0x43, 0x48, 0x55, 0x4e,
-     0x4b, 0x10, 0x1f, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x45, 0x4d, 0x49, 0x4e,
-     0x46, 0x4f, 0x5f, 0x43, 0x4d, 0x41, 0x5f, 0x54, 0x4f, 0x54, 0x41, 0x4c,
-     0x10, 0x20, 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46,
-     0x4f, 0x5f, 0x43, 0x4d, 0x41, 0x5f, 0x46, 0x52, 0x45, 0x45, 0x10, 0x21,
-     0x2a, 0xff, 0x14, 0x0a, 0x0e, 0x56, 0x6d, 0x73, 0x74, 0x61, 0x74, 0x43,
-     0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x12, 0x16, 0x0a, 0x12, 0x56,
-     0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43,
-     0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x14, 0x56,
-     0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x46, 0x52, 0x45,
-     0x45, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x53, 0x10, 0x01, 0x12, 0x19, 0x0a,
-     0x15, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x41,
-     0x4c, 0x4c, 0x4f, 0x43, 0x5f, 0x42, 0x41, 0x54, 0x43, 0x48, 0x10, 0x02,
-     0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e,
-     0x52, 0x5f, 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x41,
-     0x4e, 0x4f, 0x4e, 0x10, 0x03, 0x12, 0x19, 0x0a, 0x15, 0x56, 0x4d, 0x53,
-     0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56,
-     0x45, 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x10, 0x04, 0x12, 0x1b, 0x0a, 0x17,
-     0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x49, 0x4e,
+     0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x50, 0x52, 0x49, 0x4f, 0x5f,
+     0x55, 0x4e, 0x55, 0x53, 0x45, 0x44, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c,
+     0x50, 0x52, 0x49, 0x4f, 0x5f, 0x56, 0x45, 0x52, 0x42, 0x4f, 0x53, 0x45,
+     0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x50, 0x52, 0x49, 0x4f, 0x5f, 0x44,
+     0x45, 0x42, 0x55, 0x47, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x50, 0x52,
+     0x49, 0x4f, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x04, 0x12, 0x0d, 0x0a,
+     0x09, 0x50, 0x52, 0x49, 0x4f, 0x5f, 0x57, 0x41, 0x52, 0x4e, 0x10, 0x05,
+     0x12, 0x0e, 0x0a, 0x0a, 0x50, 0x52, 0x49, 0x4f, 0x5f, 0x45, 0x52, 0x52,
+     0x4f, 0x52, 0x10, 0x06, 0x12, 0x0e, 0x0a, 0x0a, 0x50, 0x52, 0x49, 0x4f,
+     0x5f, 0x46, 0x41, 0x54, 0x41, 0x4c, 0x10, 0x07, 0x2a, 0xbf, 0x06, 0x0a,
+     0x0f, 0x4d, 0x65, 0x6d, 0x69, 0x6e, 0x66, 0x6f, 0x43, 0x6f, 0x75, 0x6e,
+     0x74, 0x65, 0x72, 0x73, 0x12, 0x17, 0x0a, 0x13, 0x4d, 0x45, 0x4d, 0x49,
+     0x4e, 0x46, 0x4f, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46,
+     0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x45, 0x4d,
+     0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x4d, 0x45, 0x4d, 0x5f, 0x54, 0x4f, 0x54,
+     0x41, 0x4c, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x45, 0x4d, 0x49,
+     0x4e, 0x46, 0x4f, 0x5f, 0x4d, 0x45, 0x4d, 0x5f, 0x46, 0x52, 0x45, 0x45,
+     0x10, 0x02, 0x12, 0x19, 0x0a, 0x15, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46,
+     0x4f, 0x5f, 0x4d, 0x45, 0x4d, 0x5f, 0x41, 0x56, 0x41, 0x49, 0x4c, 0x41,
+     0x42, 0x4c, 0x45, 0x10, 0x03, 0x12, 0x13, 0x0a, 0x0f, 0x4d, 0x45, 0x4d,
+     0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x42, 0x55, 0x46, 0x46, 0x45, 0x52, 0x53,
+     0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46,
+     0x4f, 0x5f, 0x43, 0x41, 0x43, 0x48, 0x45, 0x44, 0x10, 0x05, 0x12, 0x17,
+     0x0a, 0x13, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x53, 0x57,
+     0x41, 0x50, 0x5f, 0x43, 0x41, 0x43, 0x48, 0x45, 0x44, 0x10, 0x06, 0x12,
+     0x12, 0x0a, 0x0e, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x41,
+     0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x07, 0x12, 0x14, 0x0a, 0x10, 0x4d,
+     0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x49, 0x4e, 0x41, 0x43, 0x54,
+     0x49, 0x56, 0x45, 0x10, 0x08, 0x12, 0x17, 0x0a, 0x13, 0x4d, 0x45, 0x4d,
+     0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5f,
+     0x41, 0x4e, 0x4f, 0x4e, 0x10, 0x09, 0x12, 0x19, 0x0a, 0x15, 0x4d, 0x45,
+     0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49,
+     0x56, 0x45, 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x10, 0x0a, 0x12, 0x17, 0x0a,
+     0x13, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x41, 0x43, 0x54,
+     0x49, 0x56, 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x0b, 0x12, 0x19,
+     0x0a, 0x15, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x49, 0x4e,
      0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10,
-     0x05, 0x12, 0x19, 0x0a, 0x15, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
-     0x4e, 0x52, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x46, 0x49,
-     0x4c, 0x45, 0x10, 0x06, 0x12, 0x19, 0x0a, 0x15, 0x56, 0x4d, 0x53, 0x54,
-     0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43,
-     0x54, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x07, 0x12, 0x13, 0x0a, 0x0f, 0x56,
-     0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x4d, 0x4c, 0x4f,
-     0x43, 0x4b, 0x10, 0x08, 0x12, 0x18, 0x0a, 0x14, 0x56, 0x4d, 0x53, 0x54,
-     0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x5f, 0x50,
-     0x41, 0x47, 0x45, 0x53, 0x10, 0x09, 0x12, 0x14, 0x0a, 0x10, 0x56, 0x4d,
-     0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x4d, 0x41, 0x50, 0x50,
-     0x45, 0x44, 0x10, 0x0a, 0x12, 0x18, 0x0a, 0x14, 0x56, 0x4d, 0x53, 0x54,
-     0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x5f, 0x50,
-     0x41, 0x47, 0x45, 0x53, 0x10, 0x0b, 0x12, 0x13, 0x0a, 0x0f, 0x56, 0x4d,
-     0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x44, 0x49, 0x52, 0x54,
-     0x59, 0x10, 0x0c, 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4d, 0x53, 0x54, 0x41,
-     0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x42, 0x41,
-     0x43, 0x4b, 0x10, 0x0d, 0x12, 0x1e, 0x0a, 0x1a, 0x56, 0x4d, 0x53, 0x54,
-     0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x53, 0x4c, 0x41, 0x42, 0x5f, 0x52,
-     0x45, 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x0e,
-     0x12, 0x20, 0x0a, 0x1c, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e,
-     0x52, 0x5f, 0x53, 0x4c, 0x41, 0x42, 0x5f, 0x55, 0x4e, 0x52, 0x45, 0x43,
-     0x4c, 0x41, 0x49, 0x4d, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x0f, 0x12, 0x1e,
-     0x0a, 0x1a, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f,
-     0x50, 0x41, 0x47, 0x45, 0x5f, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x50,
-     0x41, 0x47, 0x45, 0x53, 0x10, 0x10, 0x12, 0x1a, 0x0a, 0x16, 0x56, 0x4d,
-     0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x4b, 0x45, 0x52, 0x4e,
-     0x45, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x43, 0x4b, 0x10, 0x11, 0x12, 0x16,
-     0x0a, 0x12, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f,
-     0x4f, 0x56, 0x45, 0x52, 0x48, 0x45, 0x41, 0x44, 0x10, 0x12, 0x12, 0x16,
-     0x0a, 0x12, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f,
-     0x55, 0x4e, 0x53, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x13, 0x12, 0x14,
-     0x0a, 0x10, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f,
-     0x42, 0x4f, 0x55, 0x4e, 0x43, 0x45, 0x10, 0x14, 0x12, 0x1a, 0x0a, 0x16,
-     0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x56, 0x4d,
-     0x53, 0x43, 0x41, 0x4e, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x15,
-     0x12, 0x26, 0x0a, 0x22, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e,
-     0x52, 0x5f, 0x56, 0x4d, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x49, 0x4d, 0x4d,
-     0x45, 0x44, 0x49, 0x41, 0x54, 0x45, 0x5f, 0x52, 0x45, 0x43, 0x4c, 0x41,
-     0x49, 0x4d, 0x10, 0x16, 0x12, 0x1c, 0x0a, 0x18, 0x56, 0x4d, 0x53, 0x54,
-     0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x42,
-     0x41, 0x43, 0x4b, 0x5f, 0x54, 0x45, 0x4d, 0x50, 0x10, 0x17, 0x12, 0x1b,
+     0x0c, 0x12, 0x17, 0x0a, 0x13, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f,
+     0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45,
+     0x10, 0x0d, 0x12, 0x13, 0x0a, 0x0f, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46,
+     0x4f, 0x5f, 0x4d, 0x4c, 0x4f, 0x43, 0x4b, 0x45, 0x44, 0x10, 0x0e, 0x12,
+     0x16, 0x0a, 0x12, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x53,
+     0x57, 0x41, 0x50, 0x5f, 0x54, 0x4f, 0x54, 0x41, 0x4c, 0x10, 0x0f, 0x12,
+     0x15, 0x0a, 0x11, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x53,
+     0x57, 0x41, 0x50, 0x5f, 0x46, 0x52, 0x45, 0x45, 0x10, 0x10, 0x12, 0x11,
+     0x0a, 0x0d, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x44, 0x49,
+     0x52, 0x54, 0x59, 0x10, 0x11, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x45, 0x4d,
+     0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x42, 0x41,
+     0x43, 0x4b, 0x10, 0x12, 0x12, 0x16, 0x0a, 0x12, 0x4d, 0x45, 0x4d, 0x49,
+     0x4e, 0x46, 0x4f, 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x5f, 0x50, 0x41, 0x47,
+     0x45, 0x53, 0x10, 0x13, 0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x45, 0x4d, 0x49,
+     0x4e, 0x46, 0x4f, 0x5f, 0x4d, 0x41, 0x50, 0x50, 0x45, 0x44, 0x10, 0x14,
+     0x12, 0x11, 0x0a, 0x0d, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f,
+     0x53, 0x48, 0x4d, 0x45, 0x4d, 0x10, 0x15, 0x12, 0x10, 0x0a, 0x0c, 0x4d,
+     0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x53, 0x4c, 0x41, 0x42, 0x10,
+     0x16, 0x12, 0x1c, 0x0a, 0x18, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f,
+     0x5f, 0x53, 0x4c, 0x41, 0x42, 0x5f, 0x52, 0x45, 0x43, 0x4c, 0x41, 0x49,
+     0x4d, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x17, 0x12, 0x1e, 0x0a, 0x1a, 0x4d,
+     0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x53, 0x4c, 0x41, 0x42, 0x5f,
+     0x55, 0x4e, 0x52, 0x45, 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x41, 0x42, 0x4c,
+     0x45, 0x10, 0x18, 0x12, 0x18, 0x0a, 0x14, 0x4d, 0x45, 0x4d, 0x49, 0x4e,
+     0x46, 0x4f, 0x5f, 0x4b, 0x45, 0x52, 0x4e, 0x45, 0x4c, 0x5f, 0x53, 0x54,
+     0x41, 0x43, 0x4b, 0x10, 0x19, 0x12, 0x17, 0x0a, 0x13, 0x4d, 0x45, 0x4d,
+     0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x5f, 0x54, 0x41,
+     0x42, 0x4c, 0x45, 0x53, 0x10, 0x1a, 0x12, 0x18, 0x0a, 0x14, 0x4d, 0x45,
+     0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54,
+     0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x10, 0x1b, 0x12, 0x17, 0x0a, 0x13,
+     0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x43, 0x4f, 0x4d, 0x4d,
+     0x49, 0x54, 0x45, 0x44, 0x5f, 0x41, 0x53, 0x10, 0x1c, 0x12, 0x19, 0x0a,
+     0x15, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x56, 0x4d, 0x41,
+     0x4c, 0x4c, 0x4f, 0x43, 0x5f, 0x54, 0x4f, 0x54, 0x41, 0x4c, 0x10, 0x1d,
+     0x12, 0x18, 0x0a, 0x14, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f,
+     0x56, 0x4d, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x5f, 0x55, 0x53, 0x45, 0x44,
+     0x10, 0x1e, 0x12, 0x19, 0x0a, 0x15, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46,
+     0x4f, 0x5f, 0x56, 0x4d, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x5f, 0x43, 0x48,
+     0x55, 0x4e, 0x4b, 0x10, 0x1f, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x45, 0x4d,
+     0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x43, 0x4d, 0x41, 0x5f, 0x54, 0x4f, 0x54,
+     0x41, 0x4c, 0x10, 0x20, 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x45, 0x4d, 0x49,
+     0x4e, 0x46, 0x4f, 0x5f, 0x43, 0x4d, 0x41, 0x5f, 0x46, 0x52, 0x45, 0x45,
+     0x10, 0x21, 0x2a, 0xff, 0x14, 0x0a, 0x0e, 0x56, 0x6d, 0x73, 0x74, 0x61,
+     0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x12, 0x16, 0x0a,
+     0x12, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50,
+     0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x18, 0x0a,
+     0x14, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x46,
+     0x52, 0x45, 0x45, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x53, 0x10, 0x01, 0x12,
+     0x19, 0x0a, 0x15, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52,
+     0x5f, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x5f, 0x42, 0x41, 0x54, 0x43, 0x48,
+     0x10, 0x02, 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
+     0x5f, 0x4e, 0x52, 0x5f, 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45,
+     0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x10, 0x03, 0x12, 0x19, 0x0a, 0x15, 0x56,
+     0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x41, 0x43, 0x54,
+     0x49, 0x56, 0x45, 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x10, 0x04, 0x12, 0x1b,
      0x0a, 0x17, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f,
-     0x49, 0x53, 0x4f, 0x4c, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x41, 0x4e, 0x4f,
-     0x4e, 0x10, 0x18, 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4d, 0x53, 0x54, 0x41,
-     0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x49, 0x53, 0x4f, 0x4c, 0x41, 0x54, 0x45,
-     0x44, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x19, 0x12, 0x13, 0x0a, 0x0f,
-     0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x53, 0x48,
-     0x4d, 0x45, 0x4d, 0x10, 0x1a, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x4d, 0x53,
-     0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x44, 0x49, 0x52, 0x54, 0x49,
-     0x45, 0x44, 0x10, 0x1b, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x4d, 0x53, 0x54,
-     0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x54, 0x45,
-     0x4e, 0x10, 0x1c, 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4d, 0x53, 0x54, 0x41,
-     0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x53, 0x5f, 0x53,
-     0x43, 0x41, 0x4e, 0x4e, 0x45, 0x44, 0x10, 0x1d, 0x12, 0x1d, 0x0a, 0x19,
-     0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x57, 0x4f, 0x52, 0x4b, 0x49,
-     0x4e, 0x47, 0x53, 0x45, 0x54, 0x5f, 0x52, 0x45, 0x46, 0x41, 0x55, 0x4c,
-     0x54, 0x10, 0x1e, 0x12, 0x1e, 0x0a, 0x1a, 0x56, 0x4d, 0x53, 0x54, 0x41,
-     0x54, 0x5f, 0x57, 0x4f, 0x52, 0x4b, 0x49, 0x4e, 0x47, 0x53, 0x45, 0x54,
-     0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x41, 0x54, 0x45, 0x10, 0x1f, 0x12,
-     0x21, 0x0a, 0x1d, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x57, 0x4f,
-     0x52, 0x4b, 0x49, 0x4e, 0x47, 0x53, 0x45, 0x54, 0x5f, 0x4e, 0x4f, 0x44,
-     0x45, 0x52, 0x45, 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x10, 0x20, 0x12, 0x28,
-     0x0a, 0x24, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f,
-     0x41, 0x4e, 0x4f, 0x4e, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x50, 0x41,
-     0x52, 0x45, 0x4e, 0x54, 0x5f, 0x48, 0x55, 0x47, 0x45, 0x50, 0x41, 0x47,
-     0x45, 0x53, 0x10, 0x21, 0x12, 0x16, 0x0a, 0x12, 0x56, 0x4d, 0x53, 0x54,
-     0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x46, 0x52, 0x45, 0x45, 0x5f, 0x43,
-     0x4d, 0x41, 0x10, 0x22, 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4d, 0x53, 0x54,
-     0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x53, 0x57, 0x41, 0x50, 0x43, 0x41,
-     0x43, 0x48, 0x45, 0x10, 0x23, 0x12, 0x1d, 0x0a, 0x19, 0x56, 0x4d, 0x53,
-     0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x44, 0x49, 0x52, 0x54, 0x59,
-     0x5f, 0x54, 0x48, 0x52, 0x45, 0x53, 0x48, 0x4f, 0x4c, 0x44, 0x10, 0x24,
+     0x49, 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x46, 0x49, 0x4c,
+     0x45, 0x10, 0x05, 0x12, 0x19, 0x0a, 0x15, 0x56, 0x4d, 0x53, 0x54, 0x41,
+     0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5f,
+     0x46, 0x49, 0x4c, 0x45, 0x10, 0x06, 0x12, 0x19, 0x0a, 0x15, 0x56, 0x4d,
+     0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x55, 0x4e, 0x45, 0x56,
+     0x49, 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x07, 0x12, 0x13, 0x0a,
+     0x0f, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x4d,
+     0x4c, 0x4f, 0x43, 0x4b, 0x10, 0x08, 0x12, 0x18, 0x0a, 0x14, 0x56, 0x4d,
+     0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x41, 0x4e, 0x4f, 0x4e,
+     0x5f, 0x50, 0x41, 0x47, 0x45, 0x53, 0x10, 0x09, 0x12, 0x14, 0x0a, 0x10,
+     0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x4d, 0x41,
+     0x50, 0x50, 0x45, 0x44, 0x10, 0x0a, 0x12, 0x18, 0x0a, 0x14, 0x56, 0x4d,
+     0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x46, 0x49, 0x4c, 0x45,
+     0x5f, 0x50, 0x41, 0x47, 0x45, 0x53, 0x10, 0x0b, 0x12, 0x13, 0x0a, 0x0f,
+     0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x44, 0x49,
+     0x52, 0x54, 0x59, 0x10, 0x0c, 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4d, 0x53,
+     0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45,
+     0x42, 0x41, 0x43, 0x4b, 0x10, 0x0d, 0x12, 0x1e, 0x0a, 0x1a, 0x56, 0x4d,
+     0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x53, 0x4c, 0x41, 0x42,
+     0x5f, 0x52, 0x45, 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x41, 0x42, 0x4c, 0x45,
+     0x10, 0x0e, 0x12, 0x20, 0x0a, 0x1c, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
+     0x5f, 0x4e, 0x52, 0x5f, 0x53, 0x4c, 0x41, 0x42, 0x5f, 0x55, 0x4e, 0x52,
+     0x45, 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x0f,
+     0x12, 0x1e, 0x0a, 0x1a, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e,
+     0x52, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x5f, 0x54, 0x41, 0x42, 0x4c, 0x45,
+     0x5f, 0x50, 0x41, 0x47, 0x45, 0x53, 0x10, 0x10, 0x12, 0x1a, 0x0a, 0x16,
+     0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x4b, 0x45,
+     0x52, 0x4e, 0x45, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x43, 0x4b, 0x10, 0x11,
+     0x12, 0x16, 0x0a, 0x12, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e,
+     0x52, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x48, 0x45, 0x41, 0x44, 0x10, 0x12,
+     0x12, 0x16, 0x0a, 0x12, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e,
+     0x52, 0x5f, 0x55, 0x4e, 0x53, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x13,
+     0x12, 0x14, 0x0a, 0x10, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e,
+     0x52, 0x5f, 0x42, 0x4f, 0x55, 0x4e, 0x43, 0x45, 0x10, 0x14, 0x12, 0x1a,
+     0x0a, 0x16, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f,
+     0x56, 0x4d, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45,
+     0x10, 0x15, 0x12, 0x26, 0x0a, 0x22, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
+     0x5f, 0x4e, 0x52, 0x5f, 0x56, 0x4d, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x49,
+     0x4d, 0x4d, 0x45, 0x44, 0x49, 0x41, 0x54, 0x45, 0x5f, 0x52, 0x45, 0x43,
+     0x4c, 0x41, 0x49, 0x4d, 0x10, 0x16, 0x12, 0x1c, 0x0a, 0x18, 0x56, 0x4d,
+     0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x57, 0x52, 0x49, 0x54,
+     0x45, 0x42, 0x41, 0x43, 0x4b, 0x5f, 0x54, 0x45, 0x4d, 0x50, 0x10, 0x17,
+     0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e,
+     0x52, 0x5f, 0x49, 0x53, 0x4f, 0x4c, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x41,
+     0x4e, 0x4f, 0x4e, 0x10, 0x18, 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4d, 0x53,
+     0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x49, 0x53, 0x4f, 0x4c, 0x41,
+     0x54, 0x45, 0x44, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x19, 0x12, 0x13,
+     0x0a, 0x0f, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f,
+     0x53, 0x48, 0x4d, 0x45, 0x4d, 0x10, 0x1a, 0x12, 0x15, 0x0a, 0x11, 0x56,
+     0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x44, 0x49, 0x52,
+     0x54, 0x49, 0x45, 0x44, 0x10, 0x1b, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x4d,
+     0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x57, 0x52, 0x49, 0x54,
+     0x54, 0x45, 0x4e, 0x10, 0x1c, 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4d, 0x53,
+     0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x53,
+     0x5f, 0x53, 0x43, 0x41, 0x4e, 0x4e, 0x45, 0x44, 0x10, 0x1d, 0x12, 0x1d,
+     0x0a, 0x19, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x57, 0x4f, 0x52,
+     0x4b, 0x49, 0x4e, 0x47, 0x53, 0x45, 0x54, 0x5f, 0x52, 0x45, 0x46, 0x41,
+     0x55, 0x4c, 0x54, 0x10, 0x1e, 0x12, 0x1e, 0x0a, 0x1a, 0x56, 0x4d, 0x53,
+     0x54, 0x41, 0x54, 0x5f, 0x57, 0x4f, 0x52, 0x4b, 0x49, 0x4e, 0x47, 0x53,
+     0x45, 0x54, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x41, 0x54, 0x45, 0x10,
+     0x1f, 0x12, 0x21, 0x0a, 0x1d, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+     0x57, 0x4f, 0x52, 0x4b, 0x49, 0x4e, 0x47, 0x53, 0x45, 0x54, 0x5f, 0x4e,
+     0x4f, 0x44, 0x45, 0x52, 0x45, 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x10, 0x20,
      0x12, 0x28, 0x0a, 0x24, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e,
-     0x52, 0x5f, 0x44, 0x49, 0x52, 0x54, 0x59, 0x5f, 0x42, 0x41, 0x43, 0x4b,
-     0x47, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x54, 0x48, 0x52, 0x45, 0x53,
-     0x48, 0x4f, 0x4c, 0x44, 0x10, 0x25, 0x12, 0x11, 0x0a, 0x0d, 0x56, 0x4d,
-     0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x50, 0x47, 0x49, 0x4e, 0x10,
-     0x26, 0x12, 0x12, 0x0a, 0x0e, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
-     0x50, 0x47, 0x50, 0x47, 0x4f, 0x55, 0x54, 0x10, 0x27, 0x12, 0x17, 0x0a,
-     0x13, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x50, 0x47,
-     0x4f, 0x55, 0x54, 0x43, 0x4c, 0x45, 0x41, 0x4e, 0x10, 0x28, 0x12, 0x11,
-     0x0a, 0x0d, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x53, 0x57,
-     0x50, 0x49, 0x4e, 0x10, 0x29, 0x12, 0x12, 0x0a, 0x0e, 0x56, 0x4d, 0x53,
-     0x54, 0x41, 0x54, 0x5f, 0x50, 0x53, 0x57, 0x50, 0x4f, 0x55, 0x54, 0x10,
-     0x2a, 0x12, 0x16, 0x0a, 0x12, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
-     0x50, 0x47, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x5f, 0x44, 0x4d, 0x41, 0x10,
-     0x2b, 0x12, 0x19, 0x0a, 0x15, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
-     0x50, 0x47, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x5f, 0x4e, 0x4f, 0x52, 0x4d,
-     0x41, 0x4c, 0x10, 0x2c, 0x12, 0x1a, 0x0a, 0x16, 0x56, 0x4d, 0x53, 0x54,
-     0x41, 0x54, 0x5f, 0x50, 0x47, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x5f, 0x4d,
-     0x4f, 0x56, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x2d, 0x12, 0x11, 0x0a, 0x0d,
-     0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x46, 0x52, 0x45,
-     0x45, 0x10, 0x2e, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x4d, 0x53, 0x54, 0x41,
-     0x54, 0x5f, 0x50, 0x47, 0x41, 0x43, 0x54, 0x49, 0x56, 0x41, 0x54, 0x45,
-     0x10, 0x2f, 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
-     0x5f, 0x50, 0x47, 0x44, 0x45, 0x41, 0x43, 0x54, 0x49, 0x56, 0x41, 0x54,
-     0x45, 0x10, 0x30, 0x12, 0x12, 0x0a, 0x0e, 0x56, 0x4d, 0x53, 0x54, 0x41,
-     0x54, 0x5f, 0x50, 0x47, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x31, 0x12,
-     0x15, 0x0a, 0x11, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47,
-     0x4d, 0x41, 0x4a, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x32, 0x12, 0x17,
-     0x0a, 0x13, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x52,
-     0x45, 0x46, 0x49, 0x4c, 0x4c, 0x5f, 0x44, 0x4d, 0x41, 0x10, 0x33, 0x12,
-     0x1a, 0x0a, 0x16, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47,
-     0x52, 0x45, 0x46, 0x49, 0x4c, 0x4c, 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41,
-     0x4c, 0x10, 0x34, 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4d, 0x53, 0x54, 0x41,
-     0x54, 0x5f, 0x50, 0x47, 0x52, 0x45, 0x46, 0x49, 0x4c, 0x4c, 0x5f, 0x4d,
-     0x4f, 0x56, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x35, 0x12, 0x1d, 0x0a, 0x19,
-     0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x54, 0x45,
-     0x41, 0x4c, 0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f, 0x44, 0x4d,
-     0x41, 0x10, 0x36, 0x12, 0x20, 0x0a, 0x1c, 0x56, 0x4d, 0x53, 0x54, 0x41,
-     0x54, 0x5f, 0x50, 0x47, 0x53, 0x54, 0x45, 0x41, 0x4c, 0x5f, 0x4b, 0x53,
-     0x57, 0x41, 0x50, 0x44, 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10,
-     0x37, 0x12, 0x21, 0x0a, 0x1d, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
-     0x50, 0x47, 0x53, 0x54, 0x45, 0x41, 0x4c, 0x5f, 0x4b, 0x53, 0x57, 0x41,
-     0x50, 0x44, 0x5f, 0x4d, 0x4f, 0x56, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x38,
-     0x12, 0x1d, 0x0a, 0x19, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50,
-     0x47, 0x53, 0x54, 0x45, 0x41, 0x4c, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43,
-     0x54, 0x5f, 0x44, 0x4d, 0x41, 0x10, 0x39, 0x12, 0x20, 0x0a, 0x1c, 0x56,
-     0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x54, 0x45, 0x41,
-     0x4c, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x4e, 0x4f, 0x52,
-     0x4d, 0x41, 0x4c, 0x10, 0x3a, 0x12, 0x21, 0x0a, 0x1d, 0x56, 0x4d, 0x53,
+     0x52, 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53,
+     0x50, 0x41, 0x52, 0x45, 0x4e, 0x54, 0x5f, 0x48, 0x55, 0x47, 0x45, 0x50,
+     0x41, 0x47, 0x45, 0x53, 0x10, 0x21, 0x12, 0x16, 0x0a, 0x12, 0x56, 0x4d,
+     0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x46, 0x52, 0x45, 0x45,
+     0x5f, 0x43, 0x4d, 0x41, 0x10, 0x22, 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4d,
+     0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x53, 0x57, 0x41, 0x50,
+     0x43, 0x41, 0x43, 0x48, 0x45, 0x10, 0x23, 0x12, 0x1d, 0x0a, 0x19, 0x56,
+     0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x44, 0x49, 0x52,
+     0x54, 0x59, 0x5f, 0x54, 0x48, 0x52, 0x45, 0x53, 0x48, 0x4f, 0x4c, 0x44,
+     0x10, 0x24, 0x12, 0x28, 0x0a, 0x24, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
+     0x5f, 0x4e, 0x52, 0x5f, 0x44, 0x49, 0x52, 0x54, 0x59, 0x5f, 0x42, 0x41,
+     0x43, 0x4b, 0x47, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x54, 0x48, 0x52,
+     0x45, 0x53, 0x48, 0x4f, 0x4c, 0x44, 0x10, 0x25, 0x12, 0x11, 0x0a, 0x0d,
+     0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x50, 0x47, 0x49,
+     0x4e, 0x10, 0x26, 0x12, 0x12, 0x0a, 0x0e, 0x56, 0x4d, 0x53, 0x54, 0x41,
+     0x54, 0x5f, 0x50, 0x47, 0x50, 0x47, 0x4f, 0x55, 0x54, 0x10, 0x27, 0x12,
+     0x17, 0x0a, 0x13, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47,
+     0x50, 0x47, 0x4f, 0x55, 0x54, 0x43, 0x4c, 0x45, 0x41, 0x4e, 0x10, 0x28,
+     0x12, 0x11, 0x0a, 0x0d, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50,
+     0x53, 0x57, 0x50, 0x49, 0x4e, 0x10, 0x29, 0x12, 0x12, 0x0a, 0x0e, 0x56,
+     0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x53, 0x57, 0x50, 0x4f, 0x55,
+     0x54, 0x10, 0x2a, 0x12, 0x16, 0x0a, 0x12, 0x56, 0x4d, 0x53, 0x54, 0x41,
+     0x54, 0x5f, 0x50, 0x47, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x5f, 0x44, 0x4d,
+     0x41, 0x10, 0x2b, 0x12, 0x19, 0x0a, 0x15, 0x56, 0x4d, 0x53, 0x54, 0x41,
+     0x54, 0x5f, 0x50, 0x47, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x5f, 0x4e, 0x4f,
+     0x52, 0x4d, 0x41, 0x4c, 0x10, 0x2c, 0x12, 0x1a, 0x0a, 0x16, 0x56, 0x4d,
+     0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x41, 0x4c, 0x4c, 0x4f, 0x43,
+     0x5f, 0x4d, 0x4f, 0x56, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x2d, 0x12, 0x11,
+     0x0a, 0x0d, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x46,
+     0x52, 0x45, 0x45, 0x10, 0x2e, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x4d, 0x53,
+     0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x41, 0x43, 0x54, 0x49, 0x56, 0x41,
+     0x54, 0x45, 0x10, 0x2f, 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4d, 0x53, 0x54,
+     0x41, 0x54, 0x5f, 0x50, 0x47, 0x44, 0x45, 0x41, 0x43, 0x54, 0x49, 0x56,
+     0x41, 0x54, 0x45, 0x10, 0x30, 0x12, 0x12, 0x0a, 0x0e, 0x56, 0x4d, 0x53,
+     0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10,
+     0x31, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+     0x50, 0x47, 0x4d, 0x41, 0x4a, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x32,
+     0x12, 0x17, 0x0a, 0x13, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50,
+     0x47, 0x52, 0x45, 0x46, 0x49, 0x4c, 0x4c, 0x5f, 0x44, 0x4d, 0x41, 0x10,
+     0x33, 0x12, 0x1a, 0x0a, 0x16, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+     0x50, 0x47, 0x52, 0x45, 0x46, 0x49, 0x4c, 0x4c, 0x5f, 0x4e, 0x4f, 0x52,
+     0x4d, 0x41, 0x4c, 0x10, 0x34, 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4d, 0x53,
+     0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x52, 0x45, 0x46, 0x49, 0x4c, 0x4c,
+     0x5f, 0x4d, 0x4f, 0x56, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x35, 0x12, 0x1d,
+     0x0a, 0x19, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53,
+     0x54, 0x45, 0x41, 0x4c, 0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f,
+     0x44, 0x4d, 0x41, 0x10, 0x36, 0x12, 0x20, 0x0a, 0x1c, 0x56, 0x4d, 0x53,
      0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x54, 0x45, 0x41, 0x4c, 0x5f,
-     0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x4d, 0x4f, 0x56, 0x41, 0x42,
-     0x4c, 0x45, 0x10, 0x3b, 0x12, 0x1c, 0x0a, 0x18, 0x56, 0x4d, 0x53, 0x54,
-     0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x4b, 0x53,
-     0x57, 0x41, 0x50, 0x44, 0x5f, 0x44, 0x4d, 0x41, 0x10, 0x3c, 0x12, 0x1f,
-     0x0a, 0x1b, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53,
-     0x43, 0x41, 0x4e, 0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f, 0x4e,
-     0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x3d, 0x12, 0x20, 0x0a, 0x1c, 0x56,
-     0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x43, 0x41, 0x4e,
-     0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f, 0x4d, 0x4f, 0x56, 0x41,
-     0x42, 0x4c, 0x45, 0x10, 0x3e, 0x12, 0x1c, 0x0a, 0x18, 0x56, 0x4d, 0x53,
-     0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x44,
-     0x49, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x44, 0x4d, 0x41, 0x10, 0x3f, 0x12,
-     0x1f, 0x0a, 0x1b, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47,
-     0x53, 0x43, 0x41, 0x4e, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x5f,
-     0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x40, 0x12, 0x20, 0x0a, 0x1c,
-     0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x43, 0x41,
-     0x4e, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x4d, 0x4f, 0x56,
-     0x41, 0x42, 0x4c, 0x45, 0x10, 0x41, 0x12, 0x21, 0x0a, 0x1d, 0x56, 0x4d,
+     0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41,
+     0x4c, 0x10, 0x37, 0x12, 0x21, 0x0a, 0x1d, 0x56, 0x4d, 0x53, 0x54, 0x41,
+     0x54, 0x5f, 0x50, 0x47, 0x53, 0x54, 0x45, 0x41, 0x4c, 0x5f, 0x4b, 0x53,
+     0x57, 0x41, 0x50, 0x44, 0x5f, 0x4d, 0x4f, 0x56, 0x41, 0x42, 0x4c, 0x45,
+     0x10, 0x38, 0x12, 0x1d, 0x0a, 0x19, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
+     0x5f, 0x50, 0x47, 0x53, 0x54, 0x45, 0x41, 0x4c, 0x5f, 0x44, 0x49, 0x52,
+     0x45, 0x43, 0x54, 0x5f, 0x44, 0x4d, 0x41, 0x10, 0x39, 0x12, 0x20, 0x0a,
+     0x1c, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x54,
+     0x45, 0x41, 0x4c, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x4e,
+     0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x3a, 0x12, 0x21, 0x0a, 0x1d, 0x56,
+     0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x54, 0x45, 0x41,
+     0x4c, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x4d, 0x4f, 0x56,
+     0x41, 0x42, 0x4c, 0x45, 0x10, 0x3b, 0x12, 0x1c, 0x0a, 0x18, 0x56, 0x4d,
      0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x43, 0x41, 0x4e, 0x5f,
-     0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x54, 0x48, 0x52, 0x4f, 0x54,
-     0x54, 0x4c, 0x45, 0x10, 0x42, 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4d, 0x53,
-     0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x49, 0x4e, 0x4f, 0x44, 0x45, 0x53,
-     0x54, 0x45, 0x41, 0x4c, 0x10, 0x43, 0x12, 0x18, 0x0a, 0x14, 0x56, 0x4d,
-     0x53, 0x54, 0x41, 0x54, 0x5f, 0x53, 0x4c, 0x41, 0x42, 0x53, 0x5f, 0x53,
-     0x43, 0x41, 0x4e, 0x4e, 0x45, 0x44, 0x10, 0x44, 0x12, 0x1c, 0x0a, 0x18,
-     0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50,
-     0x44, 0x5f, 0x49, 0x4e, 0x4f, 0x44, 0x45, 0x53, 0x54, 0x45, 0x41, 0x4c,
-     0x10, 0x45, 0x12, 0x27, 0x0a, 0x23, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
-     0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f, 0x4c, 0x4f, 0x57, 0x5f,
-     0x57, 0x4d, 0x41, 0x52, 0x4b, 0x5f, 0x48, 0x49, 0x54, 0x5f, 0x51, 0x55,
-     0x49, 0x43, 0x4b, 0x4c, 0x59, 0x10, 0x46, 0x12, 0x28, 0x0a, 0x24, 0x56,
-     0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50, 0x44,
-     0x5f, 0x48, 0x49, 0x47, 0x48, 0x5f, 0x57, 0x4d, 0x41, 0x52, 0x4b, 0x5f,
-     0x48, 0x49, 0x54, 0x5f, 0x51, 0x55, 0x49, 0x43, 0x4b, 0x4c, 0x59, 0x10,
-     0x47, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
-     0x50, 0x41, 0x47, 0x45, 0x4f, 0x55, 0x54, 0x52, 0x55, 0x4e, 0x10, 0x48,
-     0x12, 0x15, 0x0a, 0x11, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x41,
-     0x4c, 0x4c, 0x4f, 0x43, 0x53, 0x54, 0x41, 0x4c, 0x4c, 0x10, 0x49, 0x12,
-     0x14, 0x0a, 0x10, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47,
-     0x52, 0x4f, 0x54, 0x41, 0x54, 0x45, 0x44, 0x10, 0x4a, 0x12, 0x19, 0x0a,
-     0x15, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x44, 0x52, 0x4f, 0x50,
-     0x5f, 0x50, 0x41, 0x47, 0x45, 0x43, 0x41, 0x43, 0x48, 0x45, 0x10, 0x4b,
-     0x12, 0x14, 0x0a, 0x10, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x44,
-     0x52, 0x4f, 0x50, 0x5f, 0x53, 0x4c, 0x41, 0x42, 0x10, 0x4c, 0x12, 0x1c,
-     0x0a, 0x18, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x4d,
-     0x49, 0x47, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45,
-     0x53, 0x53, 0x10, 0x4d, 0x12, 0x19, 0x0a, 0x15, 0x56, 0x4d, 0x53, 0x54,
-     0x41, 0x54, 0x5f, 0x50, 0x47, 0x4d, 0x49, 0x47, 0x52, 0x41, 0x54, 0x45,
-     0x5f, 0x46, 0x41, 0x49, 0x4c, 0x10, 0x4e, 0x12, 0x22, 0x0a, 0x1e, 0x56,
-     0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x43,
-     0x54, 0x5f, 0x4d, 0x49, 0x47, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x43,
-     0x41, 0x4e, 0x4e, 0x45, 0x44, 0x10, 0x4f, 0x12, 0x1f, 0x0a, 0x1b, 0x56,
-     0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x43,
-     0x54, 0x5f, 0x46, 0x52, 0x45, 0x45, 0x5f, 0x53, 0x43, 0x41, 0x4e, 0x4e,
-     0x45, 0x44, 0x10, 0x50, 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4d, 0x53, 0x54,
-     0x41, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x43, 0x54, 0x5f, 0x49,
-     0x53, 0x4f, 0x4c, 0x41, 0x54, 0x45, 0x44, 0x10, 0x51, 0x12, 0x18, 0x0a,
-     0x14, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50,
-     0x41, 0x43, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x4c, 0x4c, 0x10, 0x52, 0x12,
-     0x17, 0x0a, 0x13, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x43, 0x4f,
-     0x4d, 0x50, 0x41, 0x43, 0x54, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x10, 0x53,
-     0x12, 0x1a, 0x0a, 0x16, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x43,
-     0x4f, 0x4d, 0x50, 0x41, 0x43, 0x54, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45,
-     0x53, 0x53, 0x10, 0x54, 0x12, 0x1e, 0x0a, 0x1a, 0x56, 0x4d, 0x53, 0x54,
-     0x41, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x43, 0x54, 0x5f, 0x44,
-     0x41, 0x45, 0x4d, 0x4f, 0x4e, 0x5f, 0x57, 0x41, 0x4b, 0x45, 0x10, 0x55,
-     0x12, 0x21, 0x0a, 0x1d, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x55,
-     0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x50,
-     0x47, 0x53, 0x5f, 0x43, 0x55, 0x4c, 0x4c, 0x45, 0x44, 0x10, 0x56, 0x12,
-     0x22, 0x0a, 0x1e, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x55, 0x4e,
-     0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x50, 0x47,
-     0x53, 0x5f, 0x53, 0x43, 0x41, 0x4e, 0x4e, 0x45, 0x44, 0x10, 0x57, 0x12,
-     0x22, 0x0a, 0x1e, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x55, 0x4e,
-     0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x50, 0x47,
-     0x53, 0x5f, 0x52, 0x45, 0x53, 0x43, 0x55, 0x45, 0x44, 0x10, 0x58, 0x12,
-     0x22, 0x0a, 0x1e, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x55, 0x4e,
-     0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x50, 0x47,
-     0x53, 0x5f, 0x4d, 0x4c, 0x4f, 0x43, 0x4b, 0x45, 0x44, 0x10, 0x59, 0x12,
-     0x24, 0x0a, 0x20, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x55, 0x4e,
-     0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x50, 0x47,
-     0x53, 0x5f, 0x4d, 0x55, 0x4e, 0x4c, 0x4f, 0x43, 0x4b, 0x45, 0x44, 0x10,
-     0x5a, 0x12, 0x22, 0x0a, 0x1e, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+     0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f, 0x44, 0x4d, 0x41, 0x10, 0x3c,
+     0x12, 0x1f, 0x0a, 0x1b, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50,
+     0x47, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50, 0x44,
+     0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x3d, 0x12, 0x20, 0x0a,
+     0x1c, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x43,
+     0x41, 0x4e, 0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f, 0x4d, 0x4f,
+     0x56, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x3e, 0x12, 0x1c, 0x0a, 0x18, 0x56,
+     0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x43, 0x41, 0x4e,
+     0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x44, 0x4d, 0x41, 0x10,
+     0x3f, 0x12, 0x1f, 0x0a, 0x1b, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+     0x50, 0x47, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43,
+     0x54, 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x40, 0x12, 0x20,
+     0x0a, 0x1c, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53,
+     0x43, 0x41, 0x4e, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x4d,
+     0x4f, 0x56, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x41, 0x12, 0x21, 0x0a, 0x1d,
+     0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x43, 0x41,
+     0x4e, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x54, 0x48, 0x52,
+     0x4f, 0x54, 0x54, 0x4c, 0x45, 0x10, 0x42, 0x12, 0x17, 0x0a, 0x13, 0x56,
+     0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x49, 0x4e, 0x4f, 0x44,
+     0x45, 0x53, 0x54, 0x45, 0x41, 0x4c, 0x10, 0x43, 0x12, 0x18, 0x0a, 0x14,
+     0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x53, 0x4c, 0x41, 0x42, 0x53,
+     0x5f, 0x53, 0x43, 0x41, 0x4e, 0x4e, 0x45, 0x44, 0x10, 0x44, 0x12, 0x1c,
+     0x0a, 0x18, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4b, 0x53, 0x57,
+     0x41, 0x50, 0x44, 0x5f, 0x49, 0x4e, 0x4f, 0x44, 0x45, 0x53, 0x54, 0x45,
+     0x41, 0x4c, 0x10, 0x45, 0x12, 0x27, 0x0a, 0x23, 0x56, 0x4d, 0x53, 0x54,
+     0x41, 0x54, 0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f, 0x4c, 0x4f,
+     0x57, 0x5f, 0x57, 0x4d, 0x41, 0x52, 0x4b, 0x5f, 0x48, 0x49, 0x54, 0x5f,
+     0x51, 0x55, 0x49, 0x43, 0x4b, 0x4c, 0x59, 0x10, 0x46, 0x12, 0x28, 0x0a,
+     0x24, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4b, 0x53, 0x57, 0x41,
+     0x50, 0x44, 0x5f, 0x48, 0x49, 0x47, 0x48, 0x5f, 0x57, 0x4d, 0x41, 0x52,
+     0x4b, 0x5f, 0x48, 0x49, 0x54, 0x5f, 0x51, 0x55, 0x49, 0x43, 0x4b, 0x4c,
+     0x59, 0x10, 0x47, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x4d, 0x53, 0x54, 0x41,
+     0x54, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x4f, 0x55, 0x54, 0x52, 0x55, 0x4e,
+     0x10, 0x48, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
+     0x5f, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x53, 0x54, 0x41, 0x4c, 0x4c, 0x10,
+     0x49, 0x12, 0x14, 0x0a, 0x10, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+     0x50, 0x47, 0x52, 0x4f, 0x54, 0x41, 0x54, 0x45, 0x44, 0x10, 0x4a, 0x12,
+     0x19, 0x0a, 0x15, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x44, 0x52,
+     0x4f, 0x50, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x43, 0x41, 0x43, 0x48, 0x45,
+     0x10, 0x4b, 0x12, 0x14, 0x0a, 0x10, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
+     0x5f, 0x44, 0x52, 0x4f, 0x50, 0x5f, 0x53, 0x4c, 0x41, 0x42, 0x10, 0x4c,
+     0x12, 0x1c, 0x0a, 0x18, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50,
+     0x47, 0x4d, 0x49, 0x47, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x55, 0x43,
+     0x43, 0x45, 0x53, 0x53, 0x10, 0x4d, 0x12, 0x19, 0x0a, 0x15, 0x56, 0x4d,
+     0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x4d, 0x49, 0x47, 0x52, 0x41,
+     0x54, 0x45, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x10, 0x4e, 0x12, 0x22, 0x0a,
+     0x1e, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50,
+     0x41, 0x43, 0x54, 0x5f, 0x4d, 0x49, 0x47, 0x52, 0x41, 0x54, 0x45, 0x5f,
+     0x53, 0x43, 0x41, 0x4e, 0x4e, 0x45, 0x44, 0x10, 0x4f, 0x12, 0x1f, 0x0a,
+     0x1b, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50,
+     0x41, 0x43, 0x54, 0x5f, 0x46, 0x52, 0x45, 0x45, 0x5f, 0x53, 0x43, 0x41,
+     0x4e, 0x4e, 0x45, 0x44, 0x10, 0x50, 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4d,
+     0x53, 0x54, 0x41, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x43, 0x54,
+     0x5f, 0x49, 0x53, 0x4f, 0x4c, 0x41, 0x54, 0x45, 0x44, 0x10, 0x51, 0x12,
+     0x18, 0x0a, 0x14, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x43, 0x4f,
+     0x4d, 0x50, 0x41, 0x43, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x4c, 0x4c, 0x10,
+     0x52, 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+     0x43, 0x4f, 0x4d, 0x50, 0x41, 0x43, 0x54, 0x5f, 0x46, 0x41, 0x49, 0x4c,
+     0x10, 0x53, 0x12, 0x1a, 0x0a, 0x16, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
+     0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x43, 0x54, 0x5f, 0x53, 0x55, 0x43,
+     0x43, 0x45, 0x53, 0x53, 0x10, 0x54, 0x12, 0x1e, 0x0a, 0x1a, 0x56, 0x4d,
+     0x53, 0x54, 0x41, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x43, 0x54,
+     0x5f, 0x44, 0x41, 0x45, 0x4d, 0x4f, 0x4e, 0x5f, 0x57, 0x41, 0x4b, 0x45,
+     0x10, 0x55, 0x12, 0x21, 0x0a, 0x1d, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
+     0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45,
+     0x5f, 0x50, 0x47, 0x53, 0x5f, 0x43, 0x55, 0x4c, 0x4c, 0x45, 0x44, 0x10,
+     0x56, 0x12, 0x22, 0x0a, 0x1e, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
      0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x5f,
-     0x50, 0x47, 0x53, 0x5f, 0x43, 0x4c, 0x45, 0x41, 0x52, 0x45, 0x44, 0x10,
-     0x5b, 0x12, 0x23, 0x0a, 0x1f, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+     0x50, 0x47, 0x53, 0x5f, 0x53, 0x43, 0x41, 0x4e, 0x4e, 0x45, 0x44, 0x10,
+     0x57, 0x12, 0x22, 0x0a, 0x1e, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
      0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x5f,
-     0x50, 0x47, 0x53, 0x5f, 0x53, 0x54, 0x52, 0x41, 0x4e, 0x44, 0x45, 0x44,
-     0x10, 0x5c}};
+     0x50, 0x47, 0x53, 0x5f, 0x52, 0x45, 0x53, 0x43, 0x55, 0x45, 0x44, 0x10,
+     0x58, 0x12, 0x22, 0x0a, 0x1e, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+     0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x5f,
+     0x50, 0x47, 0x53, 0x5f, 0x4d, 0x4c, 0x4f, 0x43, 0x4b, 0x45, 0x44, 0x10,
+     0x59, 0x12, 0x24, 0x0a, 0x20, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+     0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x5f,
+     0x50, 0x47, 0x53, 0x5f, 0x4d, 0x55, 0x4e, 0x4c, 0x4f, 0x43, 0x4b, 0x45,
+     0x44, 0x10, 0x5a, 0x12, 0x22, 0x0a, 0x1e, 0x56, 0x4d, 0x53, 0x54, 0x41,
+     0x54, 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c,
+     0x45, 0x5f, 0x50, 0x47, 0x53, 0x5f, 0x43, 0x4c, 0x45, 0x41, 0x52, 0x45,
+     0x44, 0x10, 0x5b, 0x12, 0x23, 0x0a, 0x1f, 0x56, 0x4d, 0x53, 0x54, 0x41,
+     0x54, 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c,
+     0x45, 0x5f, 0x50, 0x47, 0x53, 0x5f, 0x53, 0x54, 0x52, 0x41, 0x4e, 0x44,
+     0x45, 0x44, 0x10, 0x5c}};
 
 }  // namespace perfetto
 
diff --git a/src/profiling/memory/CHANGELOG.md b/src/profiling/memory/CHANGELOG.md
new file mode 100644
index 0000000..403ee98
--- /dev/null
+++ b/src/profiling/memory/CHANGELOG.md
@@ -0,0 +1,8 @@
+# Changes from Android Q
+
+## New features
+* Allow to specify whether profiling should only be done for existing processes
+  or only for newly spawned ones using `no_startup` or `no_running` in
+  `HeapprofdConfig`.
+
+## Bugfixes
diff --git a/src/profiling/memory/heapprofd_producer.cc b/src/profiling/memory/heapprofd_producer.cc
index 60067b2..220af57 100644
--- a/src/profiling/memory/heapprofd_producer.cc
+++ b/src/profiling/memory/heapprofd_producer.cc
@@ -398,6 +398,47 @@
   return false;
 }
 
+void HeapprofdProducer::SetStartupProperties(DataSource* data_source) {
+  const HeapprofdConfig& heapprofd_config = data_source->config;
+  if (heapprofd_config.all())
+    data_source->properties.emplace_back(properties_.SetAll());
+
+  for (std::string cmdline : data_source->normalized_cmdlines)
+    data_source->properties.emplace_back(
+        properties_.SetProperty(std::move(cmdline)));
+}
+
+void HeapprofdProducer::SignalRunningProcesses(DataSource* data_source) {
+  const HeapprofdConfig& heapprofd_config = data_source->config;
+
+  std::set<pid_t> pids;
+  if (heapprofd_config.all())
+    FindAllProfilablePids(&pids);
+  for (uint64_t pid : heapprofd_config.pid())
+    pids.emplace(static_cast<pid_t>(pid));
+
+  if (!data_source->normalized_cmdlines.empty())
+    FindPidsForCmdlines(data_source->normalized_cmdlines, &pids);
+
+  for (auto pid_it = pids.cbegin(); pid_it != pids.cend();) {
+    pid_t pid = *pid_it;
+    if (IsPidProfiled(pid)) {
+      PERFETTO_LOG("Rejecting concurrent session for %" PRIdMAX,
+                   static_cast<intmax_t>(pid));
+      data_source->rejected_pids.emplace(pid);
+      pid_it = pids.erase(pid_it);
+      continue;
+    }
+
+    PERFETTO_DLOG("Sending %d to %d", kHeapprofdSignal, pid);
+    if (kill(pid, kHeapprofdSignal) != 0) {
+      PERFETTO_DPLOG("kill");
+    }
+    ++pid_it;
+  }
+  data_source->signaled_pids = std::move(pids);
+}
+
 void HeapprofdProducer::StartDataSource(DataSourceInstanceID id,
                                         const DataSourceConfig& cfg) {
   PERFETTO_DLOG("Start DataSource");
@@ -418,39 +459,10 @@
   // Central daemon - set system properties for any targets that start later,
   // and signal already-running targets to start the profiling client.
   if (mode_ == HeapprofdMode::kCentral) {
-    if (heapprofd_config.all())
-      data_source.properties.emplace_back(properties_.SetAll());
-
-    for (std::string cmdline : data_source.normalized_cmdlines)
-      data_source.properties.emplace_back(
-          properties_.SetProperty(std::move(cmdline)));
-
-    std::set<pid_t> pids;
-    if (heapprofd_config.all())
-      FindAllProfilablePids(&pids);
-    for (uint64_t pid : heapprofd_config.pid())
-      pids.emplace(static_cast<pid_t>(pid));
-
-    if (!data_source.normalized_cmdlines.empty())
-      FindPidsForCmdlines(data_source.normalized_cmdlines, &pids);
-
-    for (auto pid_it = pids.cbegin(); pid_it != pids.cend();) {
-      pid_t pid = *pid_it;
-      if (IsPidProfiled(pid)) {
-        PERFETTO_LOG("Rejecting concurrent session for %" PRIdMAX,
-                     static_cast<intmax_t>(pid));
-        data_source.rejected_pids.emplace(pid);
-        pid_it = pids.erase(pid_it);
-        continue;
-      }
-
-      PERFETTO_DLOG("Sending %d to %d", kHeapprofdSignal, pid);
-      if (kill(pid, kHeapprofdSignal) != 0) {
-        PERFETTO_DPLOG("kill");
-      }
-      ++pid_it;
-    }
-    data_source.signaled_pids = std::move(pids);
+    if (!heapprofd_config.no_startup())
+      SetStartupProperties(&data_source);
+    if (!heapprofd_config.no_running())
+      SignalRunningProcesses(&data_source);
   }
 
   const auto continuous_dump_config = heapprofd_config.continuous_dump_config();
diff --git a/src/profiling/memory/heapprofd_producer.h b/src/profiling/memory/heapprofd_producer.h
index d100be1..aa2ab81 100644
--- a/src/profiling/memory/heapprofd_producer.h
+++ b/src/profiling/memory/heapprofd_producer.h
@@ -209,6 +209,9 @@
   DataSource* GetDataSourceForProcess(const Process& proc);
   void RecordOtherSourcesAsRejected(DataSource* active_ds, const Process& proc);
 
+  void SetStartupProperties(DataSource* data_source);
+  void SignalRunningProcesses(DataSource* data_source);
+
   // Specific to mode_ == kCentral
   std::unique_ptr<base::UnixSocket> MakeListeningSocket();
 
diff --git a/src/trace_processor/chunked_trace_reader.h b/src/trace_processor/chunked_trace_reader.h
index 26a6cc3..bbf93a2 100644
--- a/src/trace_processor/chunked_trace_reader.h
+++ b/src/trace_processor/chunked_trace_reader.h
@@ -22,6 +22,8 @@
 
 #include <memory>
 
+#include "perfetto/trace_processor/basic_types.h"
+
 namespace perfetto {
 namespace trace_processor {
 
@@ -35,9 +37,7 @@
   // caller to match line/protos boundaries. The parser class has to deal with
   // intermediate buffering lines/protos that span across different chunks.
   // The buffer size is guaranteed to be > 0.
-  // Returns true if the data has been succesfully parsed, false if some
-  // unrecoverable parsing error happened and no more chunks should be pushed.
-  virtual bool Parse(std::unique_ptr<uint8_t[]>, size_t) = 0;
+  virtual util::Status Parse(std::unique_ptr<uint8_t[]>, size_t) = 0;
 };
 
 }  // namespace trace_processor
diff --git a/src/trace_processor/export_json_unittest.cc b/src/trace_processor/export_json_unittest.cc
index 06f6ded..63a0c10 100644
--- a/src/trace_processor/export_json_unittest.cc
+++ b/src/trace_processor/export_json_unittest.cc
@@ -33,8 +33,9 @@
   fseek(input, 0, SEEK_SET);
   const int kBufSize = 1000;
   char buffer[kBufSize];
-  EXPECT_GT(fread(buffer, sizeof(char), kBufSize, input), 0);
-  return std::string(buffer);
+  size_t ret = fread(buffer, sizeof(char), kBufSize, input);
+  EXPECT_GT(ret, 0);
+  return std::string(buffer, ret);
 }
 
 TEST(ExportJsonTest, EmptyStorage) {
diff --git a/src/trace_processor/fuchsia_trace_tokenizer.cc b/src/trace_processor/fuchsia_trace_tokenizer.cc
index 0c4d216..db90da2 100644
--- a/src/trace_processor/fuchsia_trace_tokenizer.cc
+++ b/src/trace_processor/fuchsia_trace_tokenizer.cc
@@ -69,8 +69,8 @@
 
 FuchsiaTraceTokenizer::~FuchsiaTraceTokenizer() = default;
 
-bool FuchsiaTraceTokenizer::Parse(std::unique_ptr<uint8_t[]> data,
-                                  size_t size) {
+util::Status FuchsiaTraceTokenizer::Parse(std::unique_ptr<uint8_t[]> data,
+                                          size_t size) {
   // The relevant internal state is |leftover_bytes_|. Each call to Parse should
   // maintain the following properties, unless a fatal error occurs in which
   // case it should return false and no assumptions should be made about the
@@ -96,7 +96,7 @@
     // record, so just add the new bytes to |leftover_bytes_| and return.
     leftover_bytes_.insert(leftover_bytes_.end(), data.get() + byte_offset,
                            data.get() + size);
-    return true;
+    return util::OkStatus();
   }
   if (leftover_bytes_.size() > 0) {
     // There is a record starting from leftover bytes.
@@ -141,7 +141,7 @@
       // have to leftover_bytes_ and wait for more.
       leftover_bytes_.insert(leftover_bytes_.end(), data.get() + byte_offset,
                              data.get() + byte_offset + size);
-      return true;
+      return util::OkStatus();
     }
   }
 
@@ -157,10 +157,8 @@
     uint32_t record_len_bytes =
         fuchsia_trace_utils::ReadField<uint32_t>(header, 4, 15) *
         sizeof(uint64_t);
-    if (record_len_bytes == 0) {
-      PERFETTO_DLOG("Unexpected record of size 0");
-      return false;
-    }
+    if (record_len_bytes == 0)
+      return util::ErrStatus("Unexpected record of size 0");
 
     if (record_offset + record_len_bytes > size)
       break;
@@ -175,7 +173,7 @@
   leftover_bytes_.insert(leftover_bytes_.end(),
                          full_view.data() + record_offset,
                          full_view.data() + size);
-  return true;
+  return util::OkStatus();
 }
 
 // Most record types are read and recorded in |TraceStorage| here directly.
diff --git a/src/trace_processor/fuchsia_trace_tokenizer.h b/src/trace_processor/fuchsia_trace_tokenizer.h
index 9f5bad9..be2f7cb 100644
--- a/src/trace_processor/fuchsia_trace_tokenizer.h
+++ b/src/trace_processor/fuchsia_trace_tokenizer.h
@@ -35,7 +35,7 @@
   ~FuchsiaTraceTokenizer() override;
 
   // ChunkedTraceReader implementation
-  bool Parse(std::unique_ptr<uint8_t[]>, size_t) override;
+  util::Status Parse(std::unique_ptr<uint8_t[]>, size_t) override;
 
  private:
   struct ProviderInfo {
diff --git a/src/trace_processor/json_trace_tokenizer.cc b/src/trace_processor/json_trace_tokenizer.cc
index f6e3de6..274d908 100644
--- a/src/trace_processor/json_trace_tokenizer.cc
+++ b/src/trace_processor/json_trace_tokenizer.cc
@@ -98,7 +98,8 @@
     : context_(ctx) {}
 JsonTraceTokenizer::~JsonTraceTokenizer() = default;
 
-bool JsonTraceTokenizer::Parse(std::unique_ptr<uint8_t[]> data, size_t size) {
+util::Status JsonTraceTokenizer::Parse(std::unique_ptr<uint8_t[]> data,
+                                       size_t size) {
   buffer_.insert(buffer_.end(), data.get(), data.get() + size);
   const char* buf = buffer_.data();
   const char* next = buf;
@@ -113,10 +114,8 @@
     while (next != end && *next != '[') {
       next++;
     }
-    if (next == end) {
-      PERFETTO_ELOG("Failed to parse: first chunk missing opening [");
-      return false;
-    }
+    if (next == end)
+      return util::ErrStatus("Failed to parse: first chunk missing opening [");
     next++;
   }
 
@@ -126,7 +125,7 @@
     std::unique_ptr<Json::Value> value(new Json::Value());
     const auto res = ReadOneJsonDict(next, end, value.get(), &next);
     if (res == kFatalError)
-      return false;
+      return util::ErrStatus("Encountered fatal error while parsing JSON");
     if (res == kEndOfTrace || res == kNeedsMoreData)
       break;
 
@@ -143,7 +142,7 @@
 
   offset_ += static_cast<uint64_t>(next - buf);
   buffer_.erase(buffer_.begin(), buffer_.begin() + (next - buf));
-  return true;
+  return util::OkStatus();
 }
 
 }  // namespace trace_processor
diff --git a/src/trace_processor/json_trace_tokenizer.h b/src/trace_processor/json_trace_tokenizer.h
index c2c4ab5..499342a 100644
--- a/src/trace_processor/json_trace_tokenizer.h
+++ b/src/trace_processor/json_trace_tokenizer.h
@@ -48,7 +48,7 @@
   ~JsonTraceTokenizer() override;
 
   // ChunkedTraceReader implementation.
-  bool Parse(std::unique_ptr<uint8_t[]>, size_t) override;
+  util::Status Parse(std::unique_ptr<uint8_t[]>, size_t) override;
 
  private:
   TraceProcessorContext* const context_;
diff --git a/src/trace_processor/metrics/BUILD.gn b/src/trace_processor/metrics/BUILD.gn
index 2cc26cb..0ca3908 100644
--- a/src/trace_processor/metrics/BUILD.gn
+++ b/src/trace_processor/metrics/BUILD.gn
@@ -41,6 +41,7 @@
 source_set("lib") {
   sources = [
     "metrics.cc",
+    "metrics.descriptor.h",
     "metrics.h",
   ]
   deps = [
diff --git a/src/trace_processor/metrics/metrics.cc b/src/trace_processor/metrics/metrics.cc
index afb17f4..9de5423 100644
--- a/src/trace_processor/metrics/metrics.cc
+++ b/src/trace_processor/metrics/metrics.cc
@@ -102,10 +102,11 @@
 
     PERFETTO_DLOG("RUN_METRIC: Executing query: %s", buffer.c_str());
     auto it = tp->ExecuteQuery(buffer);
-    if (auto opt_error = it.GetLastError()) {
+    util::Status status = it.Status();
+    if (!status.ok()) {
       char* error =
           sqlite3_mprintf("RUN_METRIC: Error when running file %s: %s",
-                          filename, opt_error->c_str());
+                          filename, status.c_message());
       sqlite3_result_error(ctx, error, -1);
       sqlite3_free(error);
       return;
@@ -117,15 +118,13 @@
   }
 }
 
-int ComputeMetrics(TraceProcessor* tp,
-                   const std::vector<std::string>& metric_names,
-                   std::vector<uint8_t>* metrics_proto) {
+util::Status ComputeMetrics(TraceProcessor* tp,
+                            const std::vector<std::string>& metric_names,
+                            std::vector<uint8_t>* metrics_proto) {
   // TODO(lalitm): stop hardcoding android.mem metric and read the proto
   // descriptor for this logic instead.
-  if (metric_names.size() != 1 || metric_names[0] != "android.mem") {
-    PERFETTO_ELOG("Only android.mem metric is currently supported");
-    return 1;
-  }
+  if (metric_names.size() != 1 || metric_names[0] != "android.mem")
+    return util::ErrStatus("Only android.mem metric is currently supported");
 
   auto queries = base::SplitString(sql_metrics::kAndroidMem, ";\n");
   for (const auto& query : queries) {
@@ -133,10 +132,9 @@
     auto prep_it = tp->ExecuteQuery(query);
     prep_it.Next();
 
-    if (auto opt_error = prep_it.GetLastError()) {
-      PERFETTO_ELOG("SQLite error: %s", opt_error->c_str());
-      return 1;
-    }
+    util::Status status = prep_it.Status();
+    if (!status.ok())
+      return status;
   }
 
   protozero::ScatteredHeapBuffer delegate;
@@ -150,10 +148,10 @@
   // filling to ensure that the code above works.
   auto it = tp->ExecuteQuery("SELECT COUNT(*) from lmk_by_score;");
   auto has_next = it.Next();
-  if (auto opt_error = it.GetLastError()) {
-    PERFETTO_ELOG("SQLite error: %s", opt_error->c_str());
-    return 1;
-  }
+  util::Status status = it.Status();
+  if (!status.ok())
+    return status;
+
   PERFETTO_CHECK(has_next);
   PERFETTO_CHECK(it.Get(0).type == SqlValue::Type::kLong);
 
@@ -176,14 +174,13 @@
     anon->set_max(it.Get(2).AsDouble());
     anon->set_avg(it.Get(3).AsDouble());
   }
-  if (auto opt_error = it.GetLastError()) {
-    PERFETTO_ELOG("SQLite error: %s", opt_error->c_str());
-    return 1;
-  }
+  status = it.Status();
+  if (!status.ok())
+    return status;
 
   metrics.Finalize();
   *metrics_proto = delegate.StitchSlices();
-  return 0;
+  return util::OkStatus();
 }
 
 }  // namespace metrics
diff --git a/src/trace_processor/metrics/metrics.descriptor.h b/src/trace_processor/metrics/metrics.descriptor.h
new file mode 100644
index 0000000..4e70b86
--- /dev/null
+++ b/src/trace_processor/metrics/metrics.descriptor.h
@@ -0,0 +1,208 @@
+
+#ifndef SRC_TRACE_PROCESSOR_METRICS_METRICS_DESCRIPTOR_H_
+#define SRC_TRACE_PROCESSOR_METRICS_METRICS_DESCRIPTOR_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <array>
+
+// This file was autogenerated by tools/gen_binary_descriptors. Do not edit.
+
+// SHA1(tools/gen_binary_descriptors)
+// 750d7d8f95621b45d4b6430d6f8808087a8702e6
+// SHA1(protos/perfetto/metrics/metrics.proto)
+// 3fc743f705a514100577d023096291939c010c6d
+
+// This is the proto Metrics encoded as a ProtoFileDescriptor to allow
+// for reflection without libprotobuf full/non-lite protos.
+
+namespace perfetto {
+
+constexpr std::array<uint8_t, 2179> kMetricsDescriptor{
+    {0x0a, 0xc6, 0x0f, 0x0a, 0x29, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74,
+     0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x61, 0x6e,
+     0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x6d, 0x65, 0x6d, 0x5f, 0x6d, 0x65,
+     0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f,
+     0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f,
+     0x74, 0x6f, 0x73, 0x22, 0x83, 0x0f, 0x0a, 0x13, 0x41, 0x6e, 0x64, 0x72,
+     0x6f, 0x69, 0x64, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x74,
+     0x72, 0x69, 0x63, 0x12, 0x59, 0x0a, 0x0e, 0x73, 0x79, 0x73, 0x74, 0x65,
+     0x6d, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x04, 0x20,
+     0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74,
+     0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e,
+     0x64, 0x72, 0x6f, 0x69, 0x64, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x4d,
+     0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d,
+     0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x0d, 0x73, 0x79, 0x73,
+     0x74, 0x65, 0x6d, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x5c,
+     0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6d, 0x65,
+     0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32,
+     0x33, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70,
+     0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69,
+     0x64, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69,
+     0x63, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4d, 0x65, 0x74,
+     0x72, 0x69, 0x63, 0x73, 0x52, 0x0e, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73,
+     0x73, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x1a, 0xd0, 0x02, 0x0a,
+     0x0d, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x4d, 0x65, 0x74, 0x72, 0x69,
+     0x63, 0x73, 0x12, 0x4b, 0x0a, 0x0a, 0x61, 0x6e, 0x6f, 0x6e, 0x5f, 0x70,
+     0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c,
+     0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72,
+     0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
+     0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63,
+     0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x52, 0x09, 0x61, 0x6e,
+     0x6f, 0x6e, 0x50, 0x61, 0x67, 0x65, 0x73, 0x12, 0x4f, 0x0a, 0x0c, 0x6d,
+     0x6d, 0x61, 0x70, 0x65, 0x64, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x73, 0x18,
+     0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x70, 0x65, 0x72, 0x66,
+     0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e,
+     0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x4d, 0x65, 0x6d, 0x6f, 0x72,
+     0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x43, 0x6f, 0x75, 0x6e,
+     0x74, 0x65, 0x72, 0x52, 0x0b, 0x6d, 0x6d, 0x61, 0x70, 0x65, 0x64, 0x50,
+     0x61, 0x67, 0x65, 0x73, 0x12, 0x52, 0x0a, 0x0b, 0x69, 0x6f, 0x6e, 0x5f,
+     0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28,
+     0x0b, 0x32, 0x31, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f,
+     0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72,
+     0x6f, 0x69, 0x64, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x74,
+     0x72, 0x69, 0x63, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x43, 0x6f, 0x75,
+     0x6e, 0x74, 0x65, 0x72, 0x52, 0x0a, 0x69, 0x6f, 0x6e, 0x42, 0x75, 0x66,
+     0x66, 0x65, 0x72, 0x73, 0x12, 0x47, 0x0a, 0x04, 0x6c, 0x6d, 0x6b, 0x73,
+     0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x70, 0x65, 0x72,
+     0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
+     0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x4d, 0x65, 0x6d, 0x6f,
+     0x72, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x4c, 0x6f, 0x77,
+     0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x4b, 0x69, 0x6c, 0x6c, 0x73, 0x52,
+     0x04, 0x6c, 0x6d, 0x6b, 0x73, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x1a,
+     0xef, 0x01, 0x0a, 0x0e, 0x4c, 0x6f, 0x77, 0x4d, 0x65, 0x6d, 0x6f, 0x72,
+     0x79, 0x4b, 0x69, 0x6c, 0x6c, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f,
+     0x74, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20,
+     0x01, 0x28, 0x05, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x43, 0x6f,
+     0x75, 0x6e, 0x74, 0x12, 0x68, 0x0a, 0x09, 0x62, 0x72, 0x65, 0x61, 0x6b,
+     0x64, 0x6f, 0x77, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x4a,
+     0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72,
+     0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
+     0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63,
+     0x2e, 0x4c, 0x6f, 0x77, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x4b, 0x69,
+     0x6c, 0x6c, 0x73, 0x2e, 0x4c, 0x6f, 0x77, 0x4d, 0x65, 0x6d, 0x6f, 0x72,
+     0x79, 0x4b, 0x69, 0x6c, 0x6c, 0x42, 0x72, 0x65, 0x61, 0x6b, 0x64, 0x6f,
+     0x77, 0x6e, 0x52, 0x09, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x64, 0x6f, 0x77,
+     0x6e, 0x1a, 0x52, 0x0a, 0x16, 0x4c, 0x6f, 0x77, 0x4d, 0x65, 0x6d, 0x6f,
+     0x72, 0x79, 0x4b, 0x69, 0x6c, 0x6c, 0x42, 0x72, 0x65, 0x61, 0x6b, 0x64,
+     0x6f, 0x77, 0x6e, 0x12, 0x22, 0x0a, 0x0d, 0x6f, 0x6f, 0x6d, 0x5f, 0x73,
+     0x63, 0x6f, 0x72, 0x65, 0x5f, 0x61, 0x64, 0x6a, 0x18, 0x01, 0x20, 0x01,
+     0x28, 0x05, 0x52, 0x0b, 0x6f, 0x6f, 0x6d, 0x53, 0x63, 0x6f, 0x72, 0x65,
+     0x41, 0x64, 0x6a, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74,
+     0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e,
+     0x74, 0x1a, 0x88, 0x04, 0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73,
+     0x73, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x21, 0x0a, 0x0c,
+     0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65,
+     0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x63,
+     0x65, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x65, 0x0a, 0x10, 0x6f,
+     0x76, 0x65, 0x72, 0x61, 0x6c, 0x6c, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74,
+     0x65, 0x72, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 0x2e,
+     0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f,
+     0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x4d,
+     0x65, 0x6d, 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e,
+     0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4d, 0x65, 0x6d, 0x6f, 0x72,
+     0x79, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x52, 0x0f, 0x6f,
+     0x76, 0x65, 0x72, 0x61, 0x6c, 0x6c, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65,
+     0x72, 0x73, 0x12, 0x69, 0x0a, 0x09, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x64,
+     0x6f, 0x77, 0x6e, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x4b, 0x2e,
+     0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f,
+     0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x4d,
+     0x65, 0x6d, 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e,
+     0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4d, 0x65, 0x74, 0x72, 0x69,
+     0x63, 0x73, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4d, 0x65,
+     0x74, 0x72, 0x69, 0x63, 0x73, 0x42, 0x72, 0x65, 0x61, 0x6b, 0x64, 0x6f,
+     0x77, 0x6e, 0x52, 0x09, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x64, 0x6f, 0x77,
+     0x6e, 0x12, 0x50, 0x0a, 0x0b, 0x61, 0x6e, 0x6f, 0x6e, 0x5f, 0x67, 0x72,
+     0x6f, 0x77, 0x74, 0x68, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f,
+     0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72,
+     0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
+     0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63,
+     0x2e, 0x53, 0x70, 0x61, 0x6e, 0x47, 0x72, 0x6f, 0x77, 0x74, 0x68, 0x52,
+     0x0a, 0x61, 0x6e, 0x6f, 0x6e, 0x47, 0x72, 0x6f, 0x77, 0x74, 0x68, 0x1a,
+     0xa2, 0x01, 0x0a, 0x17, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4d,
+     0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x42, 0x72, 0x65, 0x61, 0x6b, 0x64,
+     0x6f, 0x77, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x70, 0x72, 0x6f, 0x63, 0x65,
+     0x73, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18,
+     0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x63, 0x65,
+     0x73, 0x73, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x56,
+     0x0a, 0x08, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x18, 0x02,
+     0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65,
+     0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41,
+     0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79,
+     0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65,
+     0x73, 0x73, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x43, 0x6f, 0x75, 0x6e,
+     0x74, 0x65, 0x72, 0x73, 0x52, 0x08, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65,
+     0x72, 0x73, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x2a, 0x04, 0x08, 0x0c,
+     0x10, 0x0d, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x0a, 0x1a, 0xbd, 0x02, 0x0a,
+     0x15, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4d, 0x65, 0x6d, 0x6f,
+     0x72, 0x79, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x12, 0x47,
+     0x0a, 0x08, 0x61, 0x6e, 0x6f, 0x6e, 0x5f, 0x72, 0x73, 0x73, 0x18, 0x01,
+     0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65,
+     0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41,
+     0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79,
+     0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74,
+     0x65, 0x72, 0x52, 0x07, 0x61, 0x6e, 0x6f, 0x6e, 0x52, 0x73, 0x73, 0x12,
+     0x47, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x72, 0x73, 0x73, 0x18,
+     0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x70, 0x65, 0x72, 0x66,
+     0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e,
+     0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x4d, 0x65, 0x6d, 0x6f, 0x72,
+     0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x43, 0x6f, 0x75, 0x6e,
+     0x74, 0x65, 0x72, 0x52, 0x07, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x73, 0x73,
+     0x12, 0x40, 0x0a, 0x04, 0x73, 0x77, 0x61, 0x70, 0x18, 0x03, 0x20, 0x01,
+     0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74,
+     0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64,
+     0x72, 0x6f, 0x69, 0x64, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x4d, 0x65,
+     0x74, 0x72, 0x69, 0x63, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72,
+     0x52, 0x04, 0x73, 0x77, 0x61, 0x70, 0x12, 0x50, 0x0a, 0x0d, 0x61, 0x6e,
+     0x6f, 0x6e, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x73, 0x77, 0x61, 0x70, 0x18,
+     0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x70, 0x65, 0x72, 0x66,
+     0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e,
+     0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x4d, 0x65, 0x6d, 0x6f, 0x72,
+     0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x43, 0x6f, 0x75, 0x6e,
+     0x74, 0x65, 0x72, 0x52, 0x0b, 0x61, 0x6e, 0x6f, 0x6e, 0x41, 0x6e, 0x64,
+     0x53, 0x77, 0x61, 0x70, 0x1a, 0x6a, 0x0a, 0x0c, 0x4e, 0x61, 0x6d, 0x65,
+     0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04,
+     0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
+     0x6e, 0x61, 0x6d, 0x65, 0x12, 0x46, 0x0a, 0x07, 0x63, 0x6f, 0x75, 0x6e,
+     0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e,
+     0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f,
+     0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x4d,
+     0x65, 0x6d, 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e,
+     0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x52, 0x07, 0x63, 0x6f, 0x75,
+     0x6e, 0x74, 0x65, 0x72, 0x1a, 0x3f, 0x0a, 0x07, 0x43, 0x6f, 0x75, 0x6e,
+     0x74, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x69, 0x6e, 0x18, 0x01,
+     0x20, 0x01, 0x28, 0x01, 0x52, 0x03, 0x6d, 0x69, 0x6e, 0x12, 0x10, 0x0a,
+     0x03, 0x6d, 0x61, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x03,
+     0x6d, 0x61, 0x78, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x76, 0x67, 0x18, 0x03,
+     0x20, 0x01, 0x28, 0x01, 0x52, 0x03, 0x61, 0x76, 0x67, 0x1a, 0x76, 0x0a,
+     0x0a, 0x53, 0x70, 0x61, 0x6e, 0x47, 0x72, 0x6f, 0x77, 0x74, 0x68, 0x12,
+     0x1b, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x76, 0x61, 0x6c,
+     0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x08, 0x73, 0x74, 0x61, 0x72,
+     0x74, 0x56, 0x61, 0x6c, 0x12, 0x17, 0x0a, 0x07, 0x65, 0x6e, 0x64, 0x5f,
+     0x76, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x06, 0x65,
+     0x6e, 0x64, 0x56, 0x61, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x75, 0x72,
+     0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52,
+     0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a,
+     0x06, 0x67, 0x72, 0x6f, 0x77, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28,
+     0x01, 0x52, 0x06, 0x67, 0x72, 0x6f, 0x77, 0x74, 0x68, 0x42, 0x02, 0x48,
+     0x03, 0x0a, 0xb7, 0x01, 0x0a, 0x1e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74,
+     0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x6d,
+     0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+     0x12, 0x0f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70,
+     0x72, 0x6f, 0x74, 0x6f, 0x73, 0x1a, 0x29, 0x70, 0x65, 0x72, 0x66, 0x65,
+     0x74, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f,
+     0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x6d, 0x65, 0x6d, 0x5f,
+     0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+     0x22, 0x55, 0x0a, 0x0c, 0x54, 0x72, 0x61, 0x63, 0x65, 0x4d, 0x65, 0x74,
+     0x72, 0x69, 0x63, 0x73, 0x12, 0x45, 0x0a, 0x0b, 0x61, 0x6e, 0x64, 0x72,
+     0x6f, 0x69, 0x64, 0x5f, 0x6d, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28,
+     0x0b, 0x32, 0x24, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f,
+     0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72,
+     0x6f, 0x69, 0x64, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x74,
+     0x72, 0x69, 0x63, 0x52, 0x0a, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
+     0x4d, 0x65, 0x6d, 0x42, 0x02, 0x48, 0x03}};
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACE_PROCESSOR_METRICS_METRICS_DESCRIPTOR_H_
diff --git a/src/trace_processor/metrics/metrics.h b/src/trace_processor/metrics/metrics.h
index 4c85ecb..2183947 100644
--- a/src/trace_processor/metrics/metrics.h
+++ b/src/trace_processor/metrics/metrics.h
@@ -40,9 +40,9 @@
 // This function implements the RUN_METRIC SQL function.
 void RunMetric(sqlite3_context* ctx, int argc, sqlite3_value** argv);
 
-int ComputeMetrics(TraceProcessor* impl,
-                   const std::vector<std::string>& metric_names,
-                   std::vector<uint8_t>* metrics_proto);
+util::Status ComputeMetrics(TraceProcessor* impl,
+                            const std::vector<std::string>& metric_names,
+                            std::vector<uint8_t>* metrics_proto);
 
 }  // namespace metrics
 }  // namespace trace_processor
diff --git a/src/trace_processor/process_table.cc b/src/trace_processor/process_table.cc
index 3d72aa4..6410fe9 100644
--- a/src/trace_processor/process_table.cc
+++ b/src/trace_processor/process_table.cc
@@ -36,8 +36,8 @@
   Table::Register<ProcessTable>(db, storage, "process");
 }
 
-base::Optional<Table::Schema> ProcessTable::Init(int, const char* const*) {
-  return Schema(
+util::Status ProcessTable::Init(int, const char* const*, Schema* schema) {
+  *schema = Schema(
       {
           Table::Column(Column::kUpid, "upid", ColumnType::kInt),
           Table::Column(Column::kName, "name", ColumnType::kString),
@@ -45,6 +45,7 @@
           Table::Column(Column::kStartTs, "start_ts", ColumnType::kLong),
       },
       {Column::kUpid});
+  return util::OkStatus();
 }
 
 std::unique_ptr<Table::Cursor> ProcessTable::CreateCursor() {
diff --git a/src/trace_processor/process_table.h b/src/trace_processor/process_table.h
index 1fc0f0f..2e6fc19 100644
--- a/src/trace_processor/process_table.h
+++ b/src/trace_processor/process_table.h
@@ -54,7 +54,7 @@
   ProcessTable(sqlite3*, const TraceStorage*);
 
   // Table implementation.
-  base::Optional<Table::Schema> Init(int, const char* const*) override;
+  util::Status Init(int, const char* const*, Table::Schema*) override;
   std::unique_ptr<Table::Cursor> CreateCursor() override;
   int BestIndex(const QueryConstraints&, BestIndexInfo*) override;
 
diff --git a/src/trace_processor/proto_trace_tokenizer.cc b/src/trace_processor/proto_trace_tokenizer.cc
index 41e175e..9b71331 100644
--- a/src/trace_processor/proto_trace_tokenizer.cc
+++ b/src/trace_processor/proto_trace_tokenizer.cc
@@ -103,8 +103,8 @@
     : context_(ctx) {}
 ProtoTraceTokenizer::~ProtoTraceTokenizer() = default;
 
-bool ProtoTraceTokenizer::Parse(std::unique_ptr<uint8_t[]> owned_buf,
-                                size_t size) {
+util::Status ProtoTraceTokenizer::Parse(std::unique_ptr<uint8_t[]> owned_buf,
+                                        size_t size) {
   uint8_t* data = &owned_buf[0];
   if (!partial_buf_.empty()) {
     // It takes ~5 bytes for a proto preamble + the varint size.
@@ -113,7 +113,7 @@
       size_t missing_len = std::min(kHeaderBytes - partial_buf_.size(), size);
       partial_buf_.insert(partial_buf_.end(), &data[0], &data[missing_len]);
       if (partial_buf_.size() < kHeaderBytes)
-        return true;
+        return util::OkStatus();
       data += missing_len;
       size -= missing_len;
     }
@@ -129,8 +129,8 @@
     bool parse_failed = next == pos;
     pos = next;
     if (proto_field_tag != kTracePacketTag || field_size == 0 || parse_failed) {
-      PERFETTO_ELOG("Failed parsing a TracePacket from the partial buffer");
-      return false;  // Unrecoverable error, stop parsing.
+      return util::ErrStatus(
+          "Failed parsing a TracePacket from the partial buffer");
     }
 
     // At this point we know how big the TracePacket is.
@@ -157,26 +157,22 @@
       size -= size_missing;
       partial_buf_.clear();
       uint8_t* buf_start = &buf[0];  // Note that buf is std::moved below.
-      bool success = ParseInternal(std::move(buf), buf_start, size_incl_header);
-      if (PERFETTO_UNLIKELY(!success)) {
-        PERFETTO_ELOG(
-            "Failed to parse trace.  Check if the trace is corrupted.");
-        return false;
-      }
+      util::Status status =
+          ParseInternal(std::move(buf), buf_start, size_incl_header);
+      if (PERFETTO_UNLIKELY(!status.ok()))
+        return status;
     } else {
       partial_buf_.insert(partial_buf_.end(), data, &data[size]);
-      return true;
+      return util::OkStatus();
     }
   }
-  bool success = ParseInternal(std::move(owned_buf), data, size);
-  if (!success)
-    PERFETTO_ELOG("Failed to parse trace. Check if the trace is corrupted.");
-  return success;
+  return ParseInternal(std::move(owned_buf), data, size);
 }
 
-bool ProtoTraceTokenizer::ParseInternal(std::unique_ptr<uint8_t[]> owned_buf,
-                                        uint8_t* data,
-                                        size_t size) {
+util::Status ProtoTraceTokenizer::ParseInternal(
+    std::unique_ptr<uint8_t[]> owned_buf,
+    uint8_t* data,
+    size_t size) {
   PERFETTO_DCHECK(data >= &owned_buf[0]);
   const uint8_t* start = &owned_buf[0];
   const size_t data_off = static_cast<size_t>(data - start);
@@ -185,9 +181,10 @@
   protos::pbzero::Trace::Decoder decoder(data, size);
   for (auto it = decoder.packet(); it; ++it) {
     size_t field_offset = whole_buf.offset_of(it->data());
-    bool success = ParsePacket(whole_buf.slice(field_offset, it->size()));
-    if (PERFETTO_UNLIKELY(!success))
-      return false;
+    util::Status status =
+        ParsePacket(whole_buf.slice(field_offset, it->size()));
+    if (PERFETTO_UNLIKELY(!status.ok()))
+      return status;
   }
 
   const size_t bytes_left = decoder.bytes_left();
@@ -196,13 +193,14 @@
     partial_buf_.insert(partial_buf_.end(), &data[decoder.read_offset()],
                         &data[decoder.read_offset() + bytes_left]);
   }
-  return true;
+  return util::OkStatus();
 }
 
-bool ProtoTraceTokenizer::ParsePacket(TraceBlobView packet) {
+util::Status ProtoTraceTokenizer::ParsePacket(TraceBlobView packet) {
   protos::pbzero::TracePacket::Decoder decoder(packet.data(), packet.length());
   if (PERFETTO_UNLIKELY(decoder.bytes_left()))
-    return false;
+    return util::ErrStatus(
+        "Failed to parse proto packet fully; the trace is probably corrupt.");
 
   auto timestamp = decoder.has_timestamp()
                        ? static_cast<int64_t>(decoder.timestamp())
@@ -225,24 +223,24 @@
     auto ftrace_field = decoder.ftrace_events();
     const size_t fld_off = packet.offset_of(ftrace_field.data);
     ParseFtraceBundle(packet.slice(fld_off, ftrace_field.size));
-    return true;
+    return util::OkStatus();
   }
 
   if (decoder.has_track_event()) {
     ParseTrackEventPacket(decoder, std::move(packet));
-    return true;
+    return util::OkStatus();
   }
 
   if (decoder.has_thread_descriptor()) {
     ParseThreadDescriptorPacket(decoder);
-    return true;
+    return util::OkStatus();
   }
 
   // Use parent data and length because we want to parse this again
   // later to get the exact type of the packet.
   context_->sorter->PushTracePacket(timestamp, std::move(packet));
 
-  return true;
+  return util::OkStatus();
 }
 
 void ProtoTraceTokenizer::HandleIncrementalStateCleared(
diff --git a/src/trace_processor/proto_trace_tokenizer.h b/src/trace_processor/proto_trace_tokenizer.h
index 3b68575..918c25a 100644
--- a/src/trace_processor/proto_trace_tokenizer.h
+++ b/src/trace_processor/proto_trace_tokenizer.h
@@ -55,13 +55,13 @@
   ~ProtoTraceTokenizer() override;
 
   // ChunkedTraceReader implementation.
-  bool Parse(std::unique_ptr<uint8_t[]>, size_t size) override;
+  util::Status Parse(std::unique_ptr<uint8_t[]>, size_t size) override;
 
  private:
-  bool ParseInternal(std::unique_ptr<uint8_t[]> owned_buf,
-                     uint8_t* data,
-                     size_t size);
-  bool ParsePacket(TraceBlobView);
+  util::Status ParseInternal(std::unique_ptr<uint8_t[]> owned_buf,
+                             uint8_t* data,
+                             size_t size);
+  util::Status ParsePacket(TraceBlobView);
   void HandleIncrementalStateCleared(
       const protos::pbzero::TracePacket::Decoder& packet_decoder);
   void HandlePreviousPacketDropped(
diff --git a/src/trace_processor/span_join_operator_table.cc b/src/trace_processor/span_join_operator_table.cc
index dcb2b15..c5a7973 100644
--- a/src/trace_processor/span_join_operator_table.cc
+++ b/src/trace_processor/span_join_operator_table.cc
@@ -40,18 +40,17 @@
   return name == kTsColumnName || name == kDurColumnName;
 }
 
-bool HasDuplicateColumns(const std::vector<Table::Column>& cols) {
+base::Optional<std::string> HasDuplicateColumns(
+    const std::vector<Table::Column>& cols) {
   std::set<std::string> names;
   for (const auto& col : cols) {
-    if (names.count(col.name()) > 0) {
-      PERFETTO_ELOG("Column '%s' present in the output schema more than once.",
-                    col.name().c_str());
-      return true;
-    }
+    if (names.count(col.name()) > 0)
+      return col.name();
     names.insert(col.name());
   }
-  return false;
+  return base::nullopt;
 }
+
 }  // namespace
 
 SpanJoinOperatorTable::SpanJoinOperatorTable(sqlite3* db, const TraceStorage*)
@@ -72,57 +71,56 @@
                                          /* requires_args */ true);
 }
 
-base::Optional<Table::Schema> SpanJoinOperatorTable::Init(
-    int argc,
-    const char* const* argv) {
+util::Status SpanJoinOperatorTable::Init(int argc,
+                                         const char* const* argv,
+                                         Schema* schema) {
   // argv[0] - argv[2] are SQLite populated fields which are always present.
-  if (argc < 5) {
-    PERFETTO_ELOG("SPAN JOIN expected at least 2 args, received %d", argc - 3);
-    return base::nullopt;
-  }
+  if (argc < 5)
+    return util::Status("SPAN_JOIN: expected at least 2 args");
 
-  auto maybe_t1_desc = TableDescriptor::Parse(
-      std::string(reinterpret_cast<const char*>(argv[3])));
-  if (!maybe_t1_desc.has_value())
-    return base::nullopt;
-  auto t1_desc = *maybe_t1_desc;
+  TableDescriptor t1_desc;
+  auto status = TableDescriptor::Parse(
+      std::string(reinterpret_cast<const char*>(argv[3])), &t1_desc);
+  if (!status.ok())
+    return status;
 
-  auto maybe_t2_desc = TableDescriptor::Parse(
-      std::string(reinterpret_cast<const char*>(argv[4])));
-  if (!maybe_t2_desc.has_value())
-    return base::nullopt;
-  auto t2_desc = *maybe_t2_desc;
+  TableDescriptor t2_desc;
+  status = TableDescriptor::Parse(
+      std::string(reinterpret_cast<const char*>(argv[4])), &t2_desc);
+  if (!status.ok())
+    return status;
 
+  // Check that the partition columns match between the two tables.
   if (t1_desc.partition_col == t2_desc.partition_col) {
     partitioning_ = t1_desc.IsPartitioned()
                         ? PartitioningType::kSamePartitioning
                         : PartitioningType::kNoPartitioning;
     if (partitioning_ == PartitioningType::kNoPartitioning && IsOuterJoin()) {
-      PERFETTO_ELOG("Outer join not supported for no partition tables");
-      return base::nullopt;
+      return util::ErrStatus(
+          "SPAN_JOIN: Outer join not supported for no partition tables");
     }
   } else if (t1_desc.IsPartitioned() && t2_desc.IsPartitioned()) {
-    PERFETTO_ELOG("Mismatching partitions (%s, %s)",
-                  t1_desc.partition_col.c_str(), t2_desc.partition_col.c_str());
-    return base::nullopt;
+    return util::ErrStatus(
+        "SPAN_JOIN: mismatching partitions between the two tables; "
+        "(partition %s in table %s, partition %s in table %s)",
+        t1_desc.partition_col.c_str(), t1_desc.name.c_str(),
+        t2_desc.partition_col.c_str(), t2_desc.name.c_str());
   } else {
     if (IsOuterJoin()) {
-      PERFETTO_ELOG("Outer join not supported for mixed partitioned tables");
-      return base::nullopt;
+      return util::ErrStatus(
+          "SPAN_JOIN: Outer join not supported for mixed partitioned tables");
     }
     partitioning_ = PartitioningType::kMixedPartitioning;
   }
 
-  auto maybe_t1_defn = CreateTableDefinition(t1_desc, IsOuterJoin());
-  if (!maybe_t1_defn.has_value())
-    return base::nullopt;
-  t1_defn_ = maybe_t1_defn.value();
+  status = CreateTableDefinition(t1_desc, IsOuterJoin(), &t1_defn_);
+  if (!status.ok())
+    return status;
 
-  auto maybe_t2_defn =
-      CreateTableDefinition(t2_desc, IsOuterJoin() || IsLeftJoin());
-  if (!maybe_t2_defn.has_value())
-    return base::nullopt;
-  t2_defn_ = maybe_t2_defn.value();
+  status =
+      CreateTableDefinition(t2_desc, IsOuterJoin() || IsLeftJoin(), &t2_defn_);
+  if (!status.ok())
+    return status;
 
   std::vector<Table::Column> cols;
   // Ensure the shared columns are consistently ordered and are not
@@ -135,13 +133,18 @@
   CreateSchemaColsForDefn(t1_defn_, &cols);
   CreateSchemaColsForDefn(t2_defn_, &cols);
 
-  if (HasDuplicateColumns(cols)) {
-    return base::nullopt;
+  if (auto opt_dupe_col = HasDuplicateColumns(cols)) {
+    return util::ErrStatus(
+        "SPAN_JOIN: column %s present in both tables %s and %s",
+        opt_dupe_col->c_str(), t1_defn_.name().c_str(),
+        t2_defn_.name().c_str());
   }
   std::vector<size_t> primary_keys = {Column::kTimestamp};
   if (partitioning_ != PartitioningType::kNoPartitioning)
     primary_keys.push_back(Column::kPartition);
-  return Schema(cols, primary_keys);
+  *schema = Schema(cols, primary_keys);
+
+  return util::OkStatus();
 }
 
 void SpanJoinOperatorTable::CreateSchemaColsForDefn(
@@ -194,9 +197,17 @@
   return constraints;
 }
 
-base::Optional<SpanJoinOperatorTable::TableDefinition>
-SpanJoinOperatorTable::CreateTableDefinition(const TableDescriptor& desc,
-                                             bool emit_shadow_slices) {
+util::Status SpanJoinOperatorTable::CreateTableDefinition(
+    const TableDescriptor& desc,
+    bool emit_shadow_slices,
+    SpanJoinOperatorTable::TableDefinition* defn) {
+  if (desc.partition_col == kTsColumnName ||
+      desc.partition_col == kDurColumnName) {
+    return util::ErrStatus(
+        "SPAN_JOIN: partition column cannot be any of {ts, dur} for table %s",
+        desc.name.c_str());
+  }
+
   auto cols = sqlite_utils::GetColumnsForTable(db_, desc.name);
 
   uint32_t required_columns_found = 0;
@@ -209,8 +220,9 @@
       ++required_columns_found;
       if (col.type() != Table::ColumnType::kLong &&
           col.type() != Table::ColumnType::kUnknown) {
-        PERFETTO_ELOG("Invalid column type for %s", col.name().c_str());
-        return base::nullopt;
+        return util::ErrStatus(
+            "SPAN_JOIN: Invalid type for column %s in table %s",
+            col.name().c_str(), desc.name.c_str());
       }
     }
 
@@ -223,17 +235,20 @@
     }
   }
   if (required_columns_found != 2) {
-    PERFETTO_ELOG("Required columns not found (found %d)",
-                  required_columns_found);
-    return base::nullopt;
+    return util::ErrStatus(
+        "SPAN_JOIN: Missing one of columns {ts, dur} in table %s",
+        desc.name.c_str());
+  } else if (desc.IsPartitioned() && partition_idx >= cols.size()) {
+    return util::ErrStatus("SPAN_JOIN: Missing partition column %s in table %s",
+                           desc.partition_col.c_str(), desc.name.c_str());
   }
 
   PERFETTO_DCHECK(ts_idx < cols.size());
   PERFETTO_DCHECK(dur_idx < cols.size());
-  PERFETTO_DCHECK(desc.partition_col.empty() || partition_idx < cols.size());
 
-  return TableDefinition(desc.name, desc.partition_col, std::move(cols),
-                         emit_shadow_slices, ts_idx, dur_idx, partition_idx);
+  *defn = TableDefinition(desc.name, desc.partition_col, std::move(cols),
+                          emit_shadow_slices, ts_idx, dur_idx, partition_idx);
+  return util::OkStatus();
 }
 
 std::string SpanJoinOperatorTable::GetNameForGlobalColumnIndex(
@@ -680,33 +695,29 @@
       dur_idx_(dur_idx),
       partition_idx_(partition_idx) {}
 
-base::Optional<SpanJoinOperatorTable::TableDescriptor>
-SpanJoinOperatorTable::TableDescriptor::Parse(
-    const std::string& raw_descriptor) {
+util::Status SpanJoinOperatorTable::TableDescriptor::Parse(
+    const std::string& raw_descriptor,
+    SpanJoinOperatorTable::TableDescriptor* descriptor) {
   // Descriptors have one of the following forms:
   // table_name [PARTITIONED column_name]
 
   // Find the table name.
   base::StringSplitter splitter(raw_descriptor, ' ');
   if (!splitter.Next())
-    return base::nullopt;
+    return util::ErrStatus("SPAN_JOIN: Missing table name");
 
-  TableDescriptor descriptor;
-  descriptor.name = splitter.cur_token();
+  descriptor->name = splitter.cur_token();
   if (!splitter.Next())
-    return std::move(descriptor);
+    return util::OkStatus();
 
-  if (strcasecmp(splitter.cur_token(), "PARTITIONED") != 0) {
-    PERFETTO_ELOG("Invalid SPAN_JOIN token %s", splitter.cur_token());
-    return base::nullopt;
-  }
-  if (!splitter.Next()) {
-    PERFETTO_ELOG("Missing partitioning column");
-    return base::nullopt;
-  }
+  if (strcasecmp(splitter.cur_token(), "PARTITIONED") != 0)
+    return util::ErrStatus("SPAN_JOIN: Invalid token");
 
-  descriptor.partition_col = splitter.cur_token();
-  return std::move(descriptor);
+  if (!splitter.Next())
+    return util::ErrStatus("SPAN_JOIN: Missing partitioning column");
+
+  descriptor->partition_col = splitter.cur_token();
+  return util::OkStatus();
 }
 
 }  // namespace trace_processor
diff --git a/src/trace_processor/span_join_operator_table.h b/src/trace_processor/span_join_operator_table.h
index 6d62d8b..27cc5db 100644
--- a/src/trace_processor/span_join_operator_table.h
+++ b/src/trace_processor/span_join_operator_table.h
@@ -27,6 +27,7 @@
 #include <unordered_map>
 #include <vector>
 
+#include "perfetto/trace_processor/basic_types.h"
 #include "src/trace_processor/scoped_db.h"
 #include "src/trace_processor/table.h"
 
@@ -83,8 +84,8 @@
 
   // Parsed version of a table descriptor.
   struct TableDescriptor {
-    static base::Optional<TableDescriptor> Parse(
-        const std::string& raw_descriptor);
+    static util::Status Parse(const std::string& raw_descriptor,
+                              TableDescriptor* descriptor);
 
     bool IsPartitioned() const { return !partition_col.empty(); }
 
@@ -251,7 +252,7 @@
   static void RegisterTable(sqlite3* db, const TraceStorage* storage);
 
   // Table implementation.
-  base::Optional<Table::Schema> Init(int, const char* const*) override;
+  util::Status Init(int, const char* const*, Table::Schema*) override;
   std::unique_ptr<Table::Cursor> CreateCursor() override;
   int BestIndex(const QueryConstraints& qc, BestIndexInfo* info) override;
 
@@ -270,9 +271,10 @@
                                     : t2_defn_.partition_col();
   }
 
-  base::Optional<TableDefinition> CreateTableDefinition(
+  util::Status CreateTableDefinition(
       const TableDescriptor& desc,
-      bool emit_shadow_slices);
+      bool emit_shadow_slices,
+      SpanJoinOperatorTable::TableDefinition* defn);
 
   std::vector<std::string> ComputeSqlConstraintsForDefinition(
       const TableDefinition& defn,
diff --git a/src/trace_processor/sql_stats_table.cc b/src/trace_processor/sql_stats_table.cc
index 25e4a17..f81ac66 100644
--- a/src/trace_processor/sql_stats_table.cc
+++ b/src/trace_processor/sql_stats_table.cc
@@ -35,8 +35,8 @@
   Table::Register<SqlStatsTable>(db, storage, "sqlstats");
 }
 
-base::Optional<Table::Schema> SqlStatsTable::Init(int, const char* const*) {
-  return Schema(
+util::Status SqlStatsTable::Init(int, const char* const*, Schema* schema) {
+  *schema = Schema(
       {
           Table::Column(Column::kQuery, "query", ColumnType::kString),
           Table::Column(Column::kTimeQueued, "queued", ColumnType::kLong),
@@ -46,6 +46,7 @@
           Table::Column(Column::kTimeEnded, "ended", ColumnType::kLong),
       },
       {Column::kTimeQueued});
+  return util::OkStatus();
 }
 
 std::unique_ptr<Table::Cursor> SqlStatsTable::CreateCursor() {
diff --git a/src/trace_processor/sql_stats_table.h b/src/trace_processor/sql_stats_table.h
index ebbe120..4774a10 100644
--- a/src/trace_processor/sql_stats_table.h
+++ b/src/trace_processor/sql_stats_table.h
@@ -70,7 +70,7 @@
   static void RegisterTable(sqlite3* db, const TraceStorage* storage);
 
   // Table implementation.
-  base::Optional<Table::Schema> Init(int, const char* const*) override;
+  util::Status Init(int, const char* const*, Schema*) override;
   std::unique_ptr<Table::Cursor> CreateCursor() override;
   int BestIndex(const QueryConstraints&, BestIndexInfo*) override;
 
diff --git a/src/trace_processor/stats_table.cc b/src/trace_processor/stats_table.cc
index f43c36a..3397d91 100644
--- a/src/trace_processor/stats_table.cc
+++ b/src/trace_processor/stats_table.cc
@@ -28,8 +28,8 @@
   Table::Register<StatsTable>(db, storage, "stats");
 }
 
-base::Optional<Table::Schema> StatsTable::Init(int, const char* const*) {
-  return Schema(
+util::Status StatsTable::Init(int, const char* const*, Schema* schema) {
+  *schema = Schema(
       {
           Table::Column(Column::kName, "name", ColumnType::kString),
           // Calling a column "index" causes sqlite to silently fail, hence idx.
@@ -39,6 +39,7 @@
           Table::Column(Column::kValue, "value", ColumnType::kLong),
       },
       {Column::kName});
+  return util::OkStatus();
 }
 
 std::unique_ptr<Table::Cursor> StatsTable::CreateCursor() {
diff --git a/src/trace_processor/stats_table.h b/src/trace_processor/stats_table.h
index 9ae2165..83f46ff 100644
--- a/src/trace_processor/stats_table.h
+++ b/src/trace_processor/stats_table.h
@@ -61,7 +61,7 @@
   StatsTable(sqlite3*, const TraceStorage*);
 
   // Table implementation.
-  base::Optional<Table::Schema> Init(int, const char* const*) override;
+  util::Status Init(int, const char* const*, Table::Schema*) override;
   std::unique_ptr<Table::Cursor> CreateCursor() override;
   int BestIndex(const QueryConstraints&, BestIndexInfo*) override;
 
diff --git a/src/trace_processor/storage_table.cc b/src/trace_processor/storage_table.cc
index 7de67a5..821a394 100644
--- a/src/trace_processor/storage_table.cc
+++ b/src/trace_processor/storage_table.cc
@@ -22,9 +22,10 @@
 StorageTable::StorageTable() = default;
 StorageTable::~StorageTable() = default;
 
-base::Optional<Table::Schema> StorageTable::Init(int, const char* const*) {
+util::Status StorageTable::Init(int, const char* const*, Schema* schema) {
   schema_ = CreateStorageSchema();
-  return schema_.ToTableSchema();
+  *schema = schema_.ToTableSchema();
+  return util::OkStatus();
 }
 
 std::unique_ptr<Table::Cursor> StorageTable::CreateCursor() {
diff --git a/src/trace_processor/storage_table.h b/src/trace_processor/storage_table.h
index 3afe5cea..6474748 100644
--- a/src/trace_processor/storage_table.h
+++ b/src/trace_processor/storage_table.h
@@ -52,7 +52,7 @@
   virtual ~StorageTable() override;
 
   // Table implementation.
-  base::Optional<Table::Schema> Init(int, const char* const*) override final;
+  util::Status Init(int, const char* const*, Table::Schema*) override final;
   std::unique_ptr<Table::Cursor> CreateCursor() override;
 
   // Required methods for subclasses to implement.
diff --git a/src/trace_processor/string_table.cc b/src/trace_processor/string_table.cc
index 91d4985..0007296 100644
--- a/src/trace_processor/string_table.cc
+++ b/src/trace_processor/string_table.cc
@@ -36,13 +36,14 @@
   Table::Register<StringTable>(db, storage, "strings");
 }
 
-base::Optional<Table::Schema> StringTable::Init(int, const char* const*) {
-  return Schema(
+util::Status StringTable::Init(int, const char* const*, Schema* schema) {
+  *schema = Schema(
       {
           Table::Column(Column::kStringId, "id", ColumnType::kUint),
           Table::Column(Column::kString, "str", ColumnType::kString),
       },
       {Column::kStringId});
+  return util::OkStatus();
 }
 
 std::unique_ptr<Table::Cursor> StringTable::CreateCursor() {
diff --git a/src/trace_processor/string_table.h b/src/trace_processor/string_table.h
index 9746fdf..56d17a1 100644
--- a/src/trace_processor/string_table.h
+++ b/src/trace_processor/string_table.h
@@ -66,7 +66,7 @@
   static void RegisterTable(sqlite3* db, const TraceStorage* storage);
 
   // Table implementation.
-  base::Optional<Table::Schema> Init(int, const char* const*) override;
+  util::Status Init(int, const char* const*, Schema*) override;
   std::unique_ptr<Table::Cursor> CreateCursor() override;
   int BestIndex(const QueryConstraints&, BestIndexInfo*) override;
 
diff --git a/src/trace_processor/table.h b/src/trace_processor/table.h
index 58c9d18..0405eb9 100644
--- a/src/trace_processor/table.h
+++ b/src/trace_processor/table.h
@@ -25,6 +25,7 @@
 #include <vector>
 
 #include "perfetto/base/optional.h"
+#include "perfetto/trace_processor/basic_types.h"
 #include "src/trace_processor/query_constraints.h"
 
 namespace perfetto {
@@ -175,19 +176,19 @@
     memset(module, 0, sizeof(*module));
 
     auto create_fn = [](sqlite3* xdb, void* arg, int argc,
-                        const char* const* argv, sqlite3_vtab** tab, char**) {
+                        const char* const* argv, sqlite3_vtab** tab,
+                        char** pzErr) {
       const TableDescriptor* xdesc = static_cast<const TableDescriptor*>(arg);
       auto table = xdesc->factory(xdb, xdesc->storage);
       table->name_ = xdesc->name;
 
-      auto opt_schema = table->Init(argc, argv);
-      if (!opt_schema.has_value()) {
-        PERFETTO_ELOG("Failed to create schema (table %s)",
-                      xdesc->name.c_str());
+      Schema schema;
+      util::Status status = table->Init(argc, argv, &schema);
+      if (!status.ok()) {
+        *pzErr = sqlite3_mprintf("%s", status.c_message());
         return SQLITE_ERROR;
       }
 
-      const auto& schema = opt_schema.value();
       auto create_stmt = schema.ToCreateTableStmt();
       PERFETTO_DLOG("Create table statement: %s", create_stmt.c_str());
 
@@ -274,7 +275,7 @@
   }
 
   // Methods to be implemented by derived table classes.
-  virtual base::Optional<Schema> Init(int argc, const char* const* argv) = 0;
+  virtual util::Status Init(int argc, const char* const* argv, Schema*) = 0;
   virtual std::unique_ptr<Cursor> CreateCursor() = 0;
   virtual int BestIndex(const QueryConstraints& qc, BestIndexInfo* info) = 0;
 
diff --git a/src/trace_processor/thread_table.cc b/src/trace_processor/thread_table.cc
index e66f565..a0bb04e 100644
--- a/src/trace_processor/thread_table.cc
+++ b/src/trace_processor/thread_table.cc
@@ -36,8 +36,8 @@
   Table::Register<ThreadTable>(db, storage, "thread");
 }
 
-base::Optional<Table::Schema> ThreadTable::Init(int, const char* const*) {
-  return Schema(
+util::Status ThreadTable::Init(int, const char* const*, Schema* schema) {
+  *schema = Schema(
       {
           Table::Column(Column::kUtid, "utid", ColumnType::kInt),
           Table::Column(Column::kUpid, "upid", ColumnType::kInt),
@@ -46,6 +46,7 @@
           Table::Column(Column::kStartTs, "start_ts", ColumnType::kLong),
       },
       {Column::kUtid});
+  return util::OkStatus();
 }
 
 std::unique_ptr<Table::Cursor> ThreadTable::CreateCursor() {
diff --git a/src/trace_processor/thread_table.h b/src/trace_processor/thread_table.h
index d8ab0b7..4027a62 100644
--- a/src/trace_processor/thread_table.h
+++ b/src/trace_processor/thread_table.h
@@ -62,7 +62,7 @@
   ThreadTable(sqlite3*, const TraceStorage*);
 
   // Table implementation.
-  base::Optional<Table::Schema> Init(int, const char* const*) override;
+  util::Status Init(int, const char* const*, Table::Schema*) override;
   std::unique_ptr<Table::Cursor> CreateCursor() override;
   int BestIndex(const QueryConstraints&, BestIndexInfo*) override;
 
diff --git a/src/trace_processor/trace_database_integrationtest.cc b/src/trace_processor/trace_database_integrationtest.cc
index 698ac94..d6db8bf 100644
--- a/src/trace_processor/trace_database_integrationtest.cc
+++ b/src/trace_processor/trace_database_integrationtest.cc
@@ -35,7 +35,7 @@
       : processor_(TraceProcessor::CreateInstance(Config())) {}
 
  protected:
-  bool LoadTrace(const char* name, int min_chunk_size = 512) {
+  util::Status LoadTrace(const char* name, int min_chunk_size = 512) {
     base::ScopedFstream f(fopen(base::GetTestDataPath(name).c_str(), "rb"));
     std::minstd_rand0 rnd_engine(0);
     std::uniform_int_distribution<> dist(min_chunk_size, 1024);
@@ -43,11 +43,12 @@
       size_t chunk_size = static_cast<size_t>(dist(rnd_engine));
       std::unique_ptr<uint8_t[]> buf(new uint8_t[chunk_size]);
       auto rsize = fread(reinterpret_cast<char*>(buf.get()), 1, chunk_size, *f);
-      if (!processor_->Parse(std::move(buf), rsize))
-        return false;
+      auto status = processor_->Parse(std::move(buf), rsize);
+      if (!status.ok())
+        return status;
     }
     processor_->NotifyEndOfFile();
-    return true;
+    return util::OkStatus();
   }
 
   TraceProcessor::Iterator Query(const std::string& query) {
@@ -59,7 +60,7 @@
 };
 
 TEST_F(TraceProcessorIntegrationTest, AndroidSchedAndPs) {
-  ASSERT_TRUE(LoadTrace("android_sched_and_ps.pb"));
+  ASSERT_TRUE(LoadTrace("android_sched_and_ps.pb").ok());
   auto it = Query(
       "select count(*), max(ts) - min(ts) from sched "
       "where dur != 0 and utid != 0");
@@ -72,7 +73,7 @@
 }
 
 TEST_F(TraceProcessorIntegrationTest, Sfgate) {
-  ASSERT_TRUE(LoadTrace("sfgate.json", strlen("{\"traceEvents\":[")));
+  ASSERT_TRUE(LoadTrace("sfgate.json", strlen("{\"traceEvents\":[")).ok());
   auto it =
       Query("select count(*), max(ts) - min(ts) from slices where utid != 0");
   ASSERT_TRUE(it.Next());
@@ -84,7 +85,8 @@
 }
 
 TEST_F(TraceProcessorIntegrationTest, UnsortedTrace) {
-  ASSERT_TRUE(LoadTrace("unsorted_trace.json", strlen("{\"traceEvents\":[")));
+  ASSERT_TRUE(
+      LoadTrace("unsorted_trace.json", strlen("{\"traceEvents\":[")).ok());
   auto it = Query("select ts, depth from slices order by ts");
   ASSERT_TRUE(it.Next());
   ASSERT_EQ(it.Get(0).type, SqlValue::kLong);
@@ -100,7 +102,7 @@
 }
 
 TEST_F(TraceProcessorIntegrationTest, TraceBounds) {
-  ASSERT_TRUE(LoadTrace("android_sched_and_ps.pb"));
+  ASSERT_TRUE(LoadTrace("android_sched_and_ps.pb").ok());
   auto it = Query("select start_ts, end_ts from trace_bounds");
   ASSERT_TRUE(it.Next());
   ASSERT_EQ(it.Get(0).type, SqlValue::kLong);
@@ -112,7 +114,7 @@
 
 // TODO(hjd): Add trace to test_data.
 TEST_F(TraceProcessorIntegrationTest, DISABLED_AndroidBuildTrace) {
-  ASSERT_TRUE(LoadTrace("android_build_trace.json", strlen("[\n{")));
+  ASSERT_TRUE(LoadTrace("android_build_trace.json", strlen("[\n{")).ok());
 }
 
 }  // namespace
diff --git a/src/trace_processor/trace_parsing_fuzzer.cc b/src/trace_processor/trace_parsing_fuzzer.cc
index 19ef03d..78c76ab 100644
--- a/src/trace_processor/trace_parsing_fuzzer.cc
+++ b/src/trace_processor/trace_parsing_fuzzer.cc
@@ -29,7 +29,8 @@
       TraceProcessor::CreateInstance(Config());
   std::unique_ptr<uint8_t[]> buf(new uint8_t[size]);
   memcpy(buf.get(), data, size);
-  if (!processor->Parse(std::move(buf), size))
+  util::Status status = processor->Parse(std::move(buf), size);
+  if (!status.ok())
     return;
   processor->NotifyEndOfFile();
 }
diff --git a/src/trace_processor/trace_processor.cc b/src/trace_processor/trace_processor.cc
index 80e3b4d..ac1b7c4 100644
--- a/src/trace_processor/trace_processor.cc
+++ b/src/trace_processor/trace_processor.cc
@@ -54,8 +54,8 @@
   return iterator_->ColumnCount();
 }
 
-base::Optional<std::string> TraceProcessor::Iterator::GetLastError() {
-  return iterator_->GetLastError();
+util::Status TraceProcessor::Iterator::Status() {
+  return iterator_->Status();
 }
 
 // static
diff --git a/src/trace_processor/trace_processor_impl.cc b/src/trace_processor/trace_processor_impl.cc
index 57c40ea..cf6e9a7 100644
--- a/src/trace_processor/trace_processor_impl.cc
+++ b/src/trace_processor/trace_processor_impl.cc
@@ -303,11 +303,13 @@
     it->Reset();
 }
 
-bool TraceProcessorImpl::Parse(std::unique_ptr<uint8_t[]> data, size_t size) {
+util::Status TraceProcessorImpl::Parse(std::unique_ptr<uint8_t[]> data,
+                                       size_t size) {
   if (size == 0)
-    return true;
+    return util::OkStatus();
   if (unrecoverable_parse_error_)
-    return false;
+    return util::ErrStatus(
+        "Failed unrecoverably while parsing in a previous Parse call");
 
   // If this is the first Parse() call, guess the trace type and create the
   // appropriate parser.
@@ -349,15 +351,15 @@
         context_.parser.reset(new FuchsiaTraceParser(&context_));
         break;
       case kUnknownTraceType:
-        return false;
+        return util::ErrStatus("Unknown trace type provided");
     }
   }
 
   auto scoped_trace = context_.storage->TraceExecutionTimeIntoStats(
       stats::parse_trace_duration_ns);
-  bool res = context_.chunk_reader->Parse(std::move(data), size);
-  unrecoverable_parse_error_ |= !res;
-  return res;
+  util::Status status = context_.chunk_reader->Parse(std::move(data), size);
+  unrecoverable_parse_error_ |= !status.ok();
+  return status;
 }
 
 void TraceProcessorImpl::NotifyEndOfFile() {
@@ -375,10 +377,10 @@
   sqlite3_stmt* raw_stmt;
   int err = sqlite3_prepare_v2(*db_, sql.c_str(), static_cast<int>(sql.size()),
                                &raw_stmt, nullptr);
-  base::Optional<std::string> error;
+  util::Status status;
   uint32_t col_count = 0;
   if (err != SQLITE_OK) {
-    error = sqlite3_errmsg(*db_);
+    status = util::ErrStatus("%s", sqlite3_errmsg(*db_));
   } else {
     col_count = static_cast<uint32_t>(sqlite3_column_count(raw_stmt));
   }
@@ -389,7 +391,7 @@
                                                               t_start.count());
 
   std::unique_ptr<IteratorImpl> impl(new IteratorImpl(
-      this, *db_, ScopedStmt(raw_stmt), col_count, error, sql_stats_row));
+      this, *db_, ScopedStmt(raw_stmt), col_count, status, sql_stats_row));
   iterators_.emplace_back(impl.get());
   return TraceProcessor::Iterator(std::move(impl));
 }
@@ -401,7 +403,7 @@
   sqlite3_interrupt(db_.get());
 }
 
-int TraceProcessorImpl::ComputeMetric(
+util::Status TraceProcessorImpl::ComputeMetric(
     const std::vector<std::string>& metric_names,
     std::vector<uint8_t>* metrics_proto) {
   return metrics::ComputeMetrics(this, metric_names, metrics_proto);
@@ -411,13 +413,13 @@
                                            sqlite3* db,
                                            ScopedStmt stmt,
                                            uint32_t column_count,
-                                           base::Optional<std::string> error,
+                                           util::Status status,
                                            uint32_t sql_stats_row)
     : trace_processor_(trace_processor),
       db_(db),
       stmt_(std::move(stmt)),
       column_count_(column_count),
-      error_(error),
+      status_(status),
       sql_stats_row_(sql_stats_row) {}
 
 TraceProcessor::IteratorImpl::~IteratorImpl() {
@@ -434,7 +436,8 @@
 }
 
 void TraceProcessor::IteratorImpl::Reset() {
-  *this = IteratorImpl(nullptr, nullptr, ScopedStmt(), 0, base::nullopt, 0);
+  *this = IteratorImpl(nullptr, nullptr, ScopedStmt(), 0,
+                       util::ErrStatus("Trace processor was deleted"), 0);
 }
 
 void TraceProcessor::IteratorImpl::RecordFirstNextInSqlStats() {
diff --git a/src/trace_processor/trace_processor_impl.h b/src/trace_processor/trace_processor_impl.h
index 4dd4856..5aeb58b 100644
--- a/src/trace_processor/trace_processor_impl.h
+++ b/src/trace_processor/trace_processor_impl.h
@@ -51,15 +51,15 @@
 
   ~TraceProcessorImpl() override;
 
-  bool Parse(std::unique_ptr<uint8_t[]>, size_t) override;
+  util::Status Parse(std::unique_ptr<uint8_t[]>, size_t) override;
 
   void NotifyEndOfFile() override;
 
   Iterator ExecuteQuery(const std::string& sql,
                         int64_t time_queued = 0) override;
 
-  int ComputeMetric(const std::vector<std::string>& metric_names,
-                    std::vector<uint8_t>* metrics) override;
+  util::Status ComputeMetric(const std::vector<std::string>& metric_names,
+                             std::vector<uint8_t>* metrics) override;
 
   void InterruptQuery() override;
 
@@ -87,7 +87,7 @@
                sqlite3* db,
                ScopedStmt,
                uint32_t column_count,
-               base::Optional<std::string> error,
+               util::Status,
                uint32_t sql_stats_row);
   ~IteratorImpl();
 
@@ -106,12 +106,12 @@
       called_next_ = true;
     }
 
-    if (PERFETTO_UNLIKELY(error_.has_value()))
+    if (!status_.ok())
       return false;
 
     int ret = sqlite3_step(*stmt_);
     if (PERFETTO_UNLIKELY(ret != SQLITE_ROW && ret != SQLITE_DONE)) {
-      error_ = base::Optional<std::string>(sqlite3_errmsg(db_));
+      status_ = util::ErrStatus("%s", sqlite3_errmsg(db_));
       return false;
     }
     return ret == SQLITE_ROW;
@@ -148,7 +148,7 @@
 
   uint32_t ColumnCount() { return column_count_; }
 
-  base::Optional<std::string> GetLastError() { return error_; }
+  util::Status Status() { return status_; }
 
   // Methods called by TraceProcessorImpl.
   void Reset();
@@ -160,7 +160,7 @@
   sqlite3* db_ = nullptr;
   ScopedStmt stmt_;
   uint32_t column_count_ = 0;
-  base::Optional<std::string> error_;
+  util::Status status_;
 
   uint32_t sql_stats_row_ = 0;
   bool called_next_ = false;
diff --git a/src/trace_processor/trace_processor_shell.cc b/src/trace_processor/trace_processor_shell.cc
index 91b132d..2d0ad66 100644
--- a/src/trace_processor/trace_processor_shell.cc
+++ b/src/trace_processor/trace_processor_shell.cc
@@ -182,8 +182,9 @@
     fprintf(stderr, "\n");
   }
 
-  if (base::Optional<std::string> opt_error = it.GetLastError()) {
-    PERFETTO_ELOG("Error while iterating stats %s", opt_error->c_str());
+  util::Status status = it.Status();
+  if (!status.ok()) {
+    PERFETTO_ELOG("Error while iterating stats %s", status.c_message());
     return false;
   }
   return true;
@@ -206,8 +207,10 @@
   auto attach_it = g_tp->ExecuteQuery(attach_sql);
   bool attach_has_more = attach_it.Next();
   PERFETTO_DCHECK(!attach_has_more);
-  if (base::Optional<std::string> opt_error = attach_it.GetLastError()) {
-    PERFETTO_ELOG("SQLite error: %s", opt_error->c_str());
+
+  util::Status status = attach_it.Status();
+  if (!status.ok()) {
+    PERFETTO_ELOG("SQLite error: %s", status.c_message());
     return 1;
   }
 
@@ -223,21 +226,25 @@
     auto export_it = g_tp->ExecuteQuery(export_sql);
     bool export_has_more = export_it.Next();
     PERFETTO_DCHECK(!export_has_more);
-    if (base::Optional<std::string> opt_error = export_it.GetLastError()) {
-      PERFETTO_ELOG("SQLite error: %s", opt_error->c_str());
+
+    status = export_it.Status();
+    if (!status.ok()) {
+      PERFETTO_ELOG("SQLite error: %s", status.c_message());
       return 1;
     }
   }
-  if (base::Optional<std::string> opt_error = tables_it.GetLastError()) {
-    PERFETTO_ELOG("SQLite error: %s", opt_error->c_str());
+  status = tables_it.Status();
+  if (!status.ok()) {
+    PERFETTO_ELOG("SQLite error: %s", status.c_message());
     return 1;
   }
 
   auto detach_it = g_tp->ExecuteQuery("DETACH DATABASE perfetto_export");
   bool detach_has_more = attach_it.Next();
   PERFETTO_DCHECK(!detach_has_more);
-  if (base::Optional<std::string> opt_error = detach_it.GetLastError()) {
-    PERFETTO_ELOG("SQLite error: %s", opt_error->c_str());
+  status = detach_it.Status();
+  if (!status.ok()) {
+    PERFETTO_ELOG("SQLite error: %s", status.c_message());
     return 1;
   }
   return 0;
@@ -245,9 +252,9 @@
 
 int RunMetrics(const std::vector<std::string>& metric_names) {
   std::vector<uint8_t> metric_result;
-  int res = g_tp->ComputeMetric(metric_names, &metric_result);
-  if (res) {
-    PERFETTO_ELOG("Error when computing metrics");
+  util::Status status = g_tp->ComputeMetric(metric_names, &metric_result);
+  if (!status.ok()) {
+    PERFETTO_ELOG("Error when computing metrics: %s", status.c_message());
     return 1;
   }
   fwrite(metric_result.data(), sizeof(uint8_t), metric_result.size(), stdout);
@@ -300,8 +307,9 @@
     printf("\n");
   }
 
-  if (base::Optional<std::string> opt_error = it->GetLastError()) {
-    PERFETTO_ELOG("SQLite error: %s", opt_error->c_str());
+  util::Status status = it->Status();
+  if (!status.ok()) {
+    PERFETTO_ELOG("SQLite error: %s", status.c_message());
   }
   printf("\nQuery executed in %.3f ms\n\n", (t_end - t_start).count() / 1E6);
 }
@@ -423,8 +431,9 @@
     PERFETTO_ILOG("Executing query: %s", sql_query.c_str());
 
     auto it = g_tp->ExecuteQuery(sql_query);
-    if (base::Optional<std::string> opt_error = it.GetLastError()) {
-      PERFETTO_ELOG("SQLite error: %s", opt_error->c_str());
+    util::Status status = it.Status();
+    if (!status.ok()) {
+      PERFETTO_ELOG("SQLite error: %s", status.c_message());
       is_query_error = true;
       break;
     }
@@ -617,9 +626,11 @@
     PERFETTO_CHECK(aio_read(&cb) == 0);
 
     // Parse the completed buffer while the async read is in-flight.
-    bool success = tp->Parse(std::move(buf), static_cast<size_t>(rsize));
-    if (PERFETTO_UNLIKELY(!success))
+    util::Status status = tp->Parse(std::move(buf), static_cast<size_t>(rsize));
+    if (PERFETTO_UNLIKELY(!status.ok())) {
+      PERFETTO_ELOG("Fatal error while parsing trace: %s", status.c_message());
       return 1;
+    }
   }
   tp->NotifyEndOfFile();
 
diff --git a/src/trace_processor/wasm_bridge.cc b/src/trace_processor/wasm_bridge.cc
index e05a79b..f4b23e0 100644
--- a/src/trace_processor/wasm_bridge.cc
+++ b/src/trace_processor/wasm_bridge.cc
@@ -69,8 +69,14 @@
   // See https://github.com/WebAssembly/design/issues/1162.
   std::unique_ptr<uint8_t[]> buf(new uint8_t[size]);
   memcpy(buf.get(), data, size);
-  g_trace_processor->Parse(std::move(buf), size);
-  g_reply(id, true, "", 0);
+
+  util::Status status = g_trace_processor->Parse(std::move(buf), size);
+  if (status.ok()) {
+    g_reply(id, true, "", 0);
+  } else {
+    PERFETTO_FATAL("Fatal failure while parsing the trace: %s",
+                   status.c_message());
+  }
 }
 
 // We keep the same signature as other methods even though we don't take input
@@ -179,8 +185,9 @@
     }
     result.set_num_records(rows + 1);
   }
-  if (auto opt_error = it.GetLastError()) {
-    result.set_error(*opt_error);
+  util::Status status = it.Status();
+  if (!status.ok()) {
+    result.set_error(status.message());
   }
 
   std::string encoded;
diff --git a/src/trace_processor/window_operator_table.cc b/src/trace_processor/window_operator_table.cc
index 2d22422..b2ce9ef 100644
--- a/src/trace_processor/window_operator_table.cc
+++ b/src/trace_processor/window_operator_table.cc
@@ -32,10 +32,11 @@
   Table::Register<WindowOperatorTable>(db, storage, "window", true);
 }
 
-base::Optional<Table::Schema> WindowOperatorTable::Init(int,
-                                                        const char* const*) {
+util::Status WindowOperatorTable::Init(int,
+                                       const char* const*,
+                                       Schema* schema) {
   const bool kHidden = true;
-  return Schema(
+  *schema = Schema(
       {
           // These are the operator columns:
           Table::Column(Column::kRowId, "rowid", ColumnType::kLong, kHidden),
@@ -51,6 +52,7 @@
           Table::Column(Column::kQuantumTs, "quantum_ts", ColumnType::kLong),
       },
       {Column::kRowId});
+  return util::OkStatus();
 }
 
 std::unique_ptr<Table::Cursor> WindowOperatorTable::CreateCursor() {
diff --git a/src/trace_processor/window_operator_table.h b/src/trace_processor/window_operator_table.h
index fc8f102..e719c1e 100644
--- a/src/trace_processor/window_operator_table.h
+++ b/src/trace_processor/window_operator_table.h
@@ -75,7 +75,7 @@
   WindowOperatorTable(sqlite3*, const TraceStorage*);
 
   // Table implementation.
-  base::Optional<Table::Schema> Init(int, const char* const*) override;
+  util::Status Init(int, const char* const*, Schema* schema) override;
   std::unique_ptr<Table::Cursor> CreateCursor() override;
   int BestIndex(const QueryConstraints&, BestIndexInfo*) override;
   int Update(int, sqlite3_value**, sqlite3_int64*) override;
diff --git a/src/tracing/core/heapprofd_config.cc b/src/tracing/core/heapprofd_config.cc
index ec11d22..80019bf 100644
--- a/src/tracing/core/heapprofd_config.cc
+++ b/src/tracing/core/heapprofd_config.cc
@@ -47,7 +47,9 @@
          (skip_symbol_prefix_ == other.skip_symbol_prefix_) &&
          (continuous_dump_config_ == other.continuous_dump_config_) &&
          (shmem_size_bytes_ == other.shmem_size_bytes_) &&
-         (block_client_ == other.block_client_);
+         (block_client_ == other.block_client_) &&
+         (no_startup_ == other.no_startup_) &&
+         (no_running_ == other.no_running_);
 }
 #pragma GCC diagnostic pop
 
@@ -99,6 +101,14 @@
   static_assert(sizeof(block_client_) == sizeof(proto.block_client()),
                 "size mismatch");
   block_client_ = static_cast<decltype(block_client_)>(proto.block_client());
+
+  static_assert(sizeof(no_startup_) == sizeof(proto.no_startup()),
+                "size mismatch");
+  no_startup_ = static_cast<decltype(no_startup_)>(proto.no_startup());
+
+  static_assert(sizeof(no_running_) == sizeof(proto.no_running()),
+                "size mismatch");
+  no_running_ = static_cast<decltype(no_running_)>(proto.no_running());
   unknown_fields_ = proto.unknown_fields();
 }
 
@@ -145,6 +155,16 @@
                 "size mismatch");
   proto->set_block_client(
       static_cast<decltype(proto->block_client())>(block_client_));
+
+  static_assert(sizeof(no_startup_) == sizeof(proto->no_startup()),
+                "size mismatch");
+  proto->set_no_startup(
+      static_cast<decltype(proto->no_startup())>(no_startup_));
+
+  static_assert(sizeof(no_running_) == sizeof(proto->no_running()),
+                "size mismatch");
+  proto->set_no_running(
+      static_cast<decltype(proto->no_running())>(no_running_));
   *(proto->mutable_unknown_fields()) = unknown_fields_;
 }
 
diff --git a/tools/gen_binary_descriptors b/tools/gen_binary_descriptors
index 1dc600f..b8e700c 100755
--- a/tools/gen_binary_descriptors
+++ b/tools/gen_binary_descriptors
@@ -28,6 +28,8 @@
 SOURCE_TARGET = {
     'protos/perfetto/config/perfetto_config.proto':
             'src/perfetto_cmd/perfetto_config.descriptor.h',
+    'protos/perfetto/metrics/metrics.proto':
+            'src/trace_processor/metrics/metrics.descriptor.h',
 }
 
 ROOT_DIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
@@ -75,8 +77,9 @@
   with tempfile.NamedTemporaryFile() as fdescriptor:
     subprocess.check_call([
         protoc_path,
+        '--include_imports',
         '--proto_path=protos',
-        '-o{}'.format(fdescriptor.name),
+        '--descriptor_set_out={}'.format(fdescriptor.name),
         source,
     ], cwd=ROOT_DIR)
 
diff --git a/tools/gen_build b/tools/gen_build
index d03f8d2..c2b0581 100755
--- a/tools/gen_build
+++ b/tools/gen_build
@@ -64,6 +64,7 @@
   '//tools/trace_to_text:trace_to_text_host(//gn/standalone/toolchain:gcc_like_host)',
   '//protos/perfetto/config:merged_config_gen',
   '//protos/perfetto/trace:merged_trace_gen',
+  '//protos/perfetto/trace_processor:lite_gen',
 ]
 
 # Aliases to add to the BUILD file
diff --git a/tools/trace_to_text/trace_to_systrace.cc b/tools/trace_to_text/trace_to_systrace.cc
index 5e07c05..0b5d793 100644
--- a/tools/trace_to_text/trace_to_systrace.cc
+++ b/tools/trace_to_text/trace_to_systrace.cc
@@ -147,9 +147,9 @@
     }
 
     // Check if we have an error in the iterator and print if so.
-    auto opt_error = iterator.GetLastError();
-    if (opt_error.has_value()) {
-      PERFETTO_ELOG("Error while writing systrace %s", opt_error->c_str());
+    auto status = iterator.Status();
+    if (!status.ok()) {
+      PERFETTO_ELOG("Error while writing systrace %s", status.c_message());
       return false;
     }