Merge changes Ie224e1d2,I1350517d,Ie4b5c91e

* changes:
  perfetto-ui: Add thread state aggregation
  perfetto-ui: Make aggregation controller a base class
  perfetto-ui: Generic aggregation table
diff --git a/Android.bp b/Android.bp
index f89a890..c3b5b80 100644
--- a/Android.bp
+++ b/Android.bp
@@ -6471,6 +6471,7 @@
     "src/traced/probes/ftrace/compact_sched.cc",
     "src/traced/probes/ftrace/cpu_reader.cc",
     "src/traced/probes/ftrace/cpu_stats_parser.cc",
+    "src/traced/probes/ftrace/discover_vendor_tracepoints.cc",
     "src/traced/probes/ftrace/event_info.cc",
     "src/traced/probes/ftrace/event_info_constants.cc",
     "src/traced/probes/ftrace/ftrace_config_muxer.cc",
@@ -6627,6 +6628,7 @@
   srcs: [
     "src/traced/probes/ftrace/cpu_reader_unittest.cc",
     "src/traced/probes/ftrace/cpu_stats_parser_unittest.cc",
+    "src/traced/probes/ftrace/discover_vendor_tracepoints_unittest.cc",
     "src/traced/probes/ftrace/event_info_unittest.cc",
     "src/traced/probes/ftrace/format_parser_unittest.cc",
     "src/traced/probes/ftrace/ftrace_config_muxer_unittest.cc",
diff --git a/BUILD b/BUILD
index 0f6e5b9..c268a11 100644
--- a/BUILD
+++ b/BUILD
@@ -1059,6 +1059,8 @@
         "src/traced/probes/ftrace/cpu_reader.h",
         "src/traced/probes/ftrace/cpu_stats_parser.cc",
         "src/traced/probes/ftrace/cpu_stats_parser.h",
+        "src/traced/probes/ftrace/discover_vendor_tracepoints.cc",
+        "src/traced/probes/ftrace/discover_vendor_tracepoints.h",
         "src/traced/probes/ftrace/event_info.cc",
         "src/traced/probes/ftrace/event_info.h",
         "src/traced/probes/ftrace/event_info_constants.cc",
diff --git a/gn/perfetto.gni b/gn/perfetto.gni
index 3d27339..b2fe750 100644
--- a/gn/perfetto.gni
+++ b/gn/perfetto.gni
@@ -258,6 +258,9 @@
   # Allows to build the UI (TypeScript/ HTML / WASM)
   enable_perfetto_ui =
       perfetto_build_standalone && enable_perfetto_trace_processor_sqlite
+
+  # Skip buildtools dependency checks (needed for ChromeOS).
+  skip_buildtools_check = false
 }
 
 # +---------------------------------------------------------------------------+
diff --git a/gn/perfetto_check_build_deps.gni b/gn/perfetto_check_build_deps.gni
index 481a6c3..a2e5a03 100644
--- a/gn/perfetto_check_build_deps.gni
+++ b/gn/perfetto_check_build_deps.gni
@@ -18,7 +18,7 @@
 # tools/install-build-deps --check-only ${args}.
 # It's used to ensure that deps are current before building.
 template("perfetto_check_build_deps") {
-  if (perfetto_build_standalone) {
+  if (perfetto_build_standalone && !skip_buildtools_check) {
     action(target_name) {
       out_file = "$target_gen_dir/$target_name.check"
       out_file_path = rebase_path(out_file, root_build_dir)
diff --git a/include/perfetto/tracing/internal/track_event_data_source.h b/include/perfetto/tracing/internal/track_event_data_source.h
index bef0382..72fe0a4 100644
--- a/include/perfetto/tracing/internal/track_event_data_source.h
+++ b/include/perfetto/tracing/internal/track_event_data_source.h
@@ -109,6 +109,23 @@
     Base::template Trace([](typename Base::TraceContext ctx) { ctx.Flush(); });
   }
 
+  // Determine if tracing for the given static category is enabled.
+  template <size_t CategoryIndex>
+  static bool IsCategoryEnabled() {
+    return Registry->GetCategoryState(CategoryIndex)
+        ->load(std::memory_order_relaxed);
+  }
+
+  // Determine if tracing for the given dynamic category is enabled.
+  static bool IsDynamicCategoryEnabled(
+      const DynamicCategory& dynamic_category) {
+    bool enabled = false;
+    Base::template Trace([&](typename Base::TraceContext ctx) {
+      enabled = IsDynamicCategoryEnabled(&ctx, dynamic_category);
+    });
+    return enabled;
+  }
+
   // This is the inlined entrypoint for all track event trace points. It tries
   // to be as lightweight as possible in terms of instructions and aims to
   // compile down to an unlikely conditional jump to the actual trace writing
diff --git a/include/perfetto/tracing/internal/track_event_macros.h b/include/perfetto/tracing/internal/track_event_macros.h
index e0ea03c..d7fa92e 100644
--- a/include/perfetto/tracing/internal/track_event_macros.h
+++ b/include/perfetto/tracing/internal/track_event_macros.h
@@ -87,11 +87,9 @@
 // the category hasn't been registered or added to the list of allowed dynamic
 // categories. See PERFETTO_DEFINE_CATEGORIES.
 #define PERFETTO_GET_CATEGORY_INDEX(category)                                  \
-  ::perfetto::internal::TrackEventCategoryRegistry::Validate<                  \
-      ::PERFETTO_TRACK_EVENT_NAMESPACE::internal::kConstExprCategoryRegistry   \
-          .Find(category,                                                      \
-                ::PERFETTO_TRACK_EVENT_NAMESPACE::internal::IsDynamicCategory( \
-                    category))>()
+  ::PERFETTO_TRACK_EVENT_NAMESPACE::internal::kConstExprCategoryRegistry.Find( \
+      category,                                                                \
+      ::PERFETTO_TRACK_EVENT_NAMESPACE::internal::IsDynamicCategory(category))
 
 // Generate a unique variable name with a given prefix.
 #define PERFETTO_INTERNAL_CONCAT2(a, b) a##b
@@ -142,4 +140,11 @@
     }()                                                                       \
   }
 
+#define PERFETTO_INTERNAL_CATEGORY_ENABLED(category)                         \
+  (::PERFETTO_TRACK_EVENT_NAMESPACE::internal::IsDynamicCategory(category)   \
+       ? ::PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent::                      \
+             IsDynamicCategoryEnabled(::perfetto::DynamicCategory(category)) \
+       : ::PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent::IsCategoryEnabled<    \
+             PERFETTO_GET_CATEGORY_INDEX(category)>())
+
 #endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_MACROS_H_
diff --git a/include/perfetto/tracing/track_event.h b/include/perfetto/tracing/track_event.h
index be20e0b..18ea40a 100644
--- a/include/perfetto/tracing/track_event.h
+++ b/include/perfetto/tracing/track_event.h
@@ -219,14 +219,16 @@
   PERFETTO_INTERNAL_SCOPED_TRACK_EVENT(category, name, ##__VA_ARGS__)
 
 // Emit a slice which has zero duration.
-// TODO(skyostil): Add support for process-wide and global instant events.
 #define TRACE_EVENT_INSTANT(category, name, ...)                            \
   PERFETTO_INTERNAL_TRACK_EVENT(                                            \
       category, name, ::perfetto::protos::pbzero::TrackEvent::TYPE_INSTANT, \
       ##__VA_ARGS__)
 
-// TODO(skyostil): Add arguments.
-// TODO(skyostil): Add async events.
+// Efficiently determine if the given static or dynamic trace category or
+// category group is enabled for tracing.
+#define TRACE_EVENT_CATEGORY_ENABLED(category) \
+  PERFETTO_INTERNAL_CATEGORY_ENABLED(category)
+
 // TODO(skyostil): Add flow events.
 // TODO(skyostil): Add counters.
 
diff --git a/include/perfetto/tracing/track_event_category_registry.h b/include/perfetto/tracing/track_event_category_registry.h
index ae58a31..23f423e 100644
--- a/include/perfetto/tracing/track_event_category_registry.h
+++ b/include/perfetto/tracing/track_event_category_registry.h
@@ -234,31 +234,14 @@
   // passed in.
   static constexpr size_t kInvalidCategoryIndex = static_cast<size_t>(-1);
   static constexpr size_t kDynamicCategoryIndex = static_cast<size_t>(-2);
-  constexpr size_t Find(const char* name,
-                        bool is_dynamic,
-                        size_t index = 0) const {
-    return is_dynamic ? kDynamicCategoryIndex
-                      : (index == category_count_)
-                            ? kInvalidCategoryIndex
-                            : StringEq(categories_[index].name, name)
-                                  ? index
-                                  : Find(name, false, index + 1);
+  constexpr size_t Find(const char* name, bool is_dynamic) const {
+    return CheckIsValidCategoryIndex(FindImpl(name, is_dynamic));
   }
 
   constexpr size_t Find(const DynamicCategory&, bool) const {
     return kDynamicCategoryIndex;
   }
 
-  // A helper for validating that a category was registered at compile time or
-  // was in the allowed list of statically defined dynamic categories.
-  template <size_t CategoryIndex>
-  static constexpr size_t Validate() {
-    static_assert(CategoryIndex != kInvalidCategoryIndex,
-                  "A track event used an unknown category. Please add it to "
-                  "PERFETTO_DEFINE_CATEGORIES().");
-    return CategoryIndex;
-  }
-
   constexpr bool ValidateCategories(size_t index = 0) const {
     return (index == category_count_)
                ? true
@@ -269,6 +252,35 @@
 
  private:
   // TODO(skyostil): Make the compile-time routines nicer with C++14.
+  constexpr size_t FindImpl(const char* name,
+                            bool is_dynamic,
+                            size_t index = 0) const {
+    return is_dynamic ? kDynamicCategoryIndex
+                      : (index == category_count_)
+                            ? kInvalidCategoryIndex
+                            : StringEq(categories_[index].name, name)
+                                  ? index
+                                  : FindImpl(name, false, index + 1);
+  }
+
+  // A compile time helper for checking that a category index is valid.
+  static constexpr size_t CheckIsValidCategoryIndex(size_t index) {
+    // Relies on PERFETTO_CHECK() (and the surrounding lambda) being a
+    // non-constexpr function, which will fail the build if the given |index| is
+    // invalid. The funny formatting here is so that clang shows the comment
+    // below as part of the error message.
+    // clang-format off
+    return index != kInvalidCategoryIndex ? index : \
+        /* Invalid category -- add it to PERFETTO_DEFINE_CATEGORIES(). */ [] {
+        PERFETTO_CHECK(
+            false &&
+            "A track event used an unknown category. Please add it to "
+            "PERFETTO_DEFINE_CATEGORIES().");
+        return kInvalidCategoryIndex;
+      }();
+    // clang-format on
+  }
+
   static constexpr bool IsValidCategoryName(const char* name) {
     return (!name || *name == '\"' || *name == '*' || *name == ' ')
                ? false
diff --git a/include/perfetto/tracing/track_event_legacy.h b/include/perfetto/tracing/track_event_legacy.h
index 0e124c3..cae83a5 100644
--- a/include/perfetto/tracing/track_event_legacy.h
+++ b/include/perfetto/tracing/track_event_legacy.h
@@ -1154,12 +1154,9 @@
                                    TRACE_EVENT_FLAG_NONE)
 
 // Macro to efficiently determine if a given category group is enabled.
-#define TRACE_EVENT_CATEGORY_GROUP_ENABLED(category, ret)                      \
-  do {                                                                         \
-    *ret =                                                                     \
-        ::PERFETTO_TRACK_EVENT_NAMESPACE::internal::kConstExprCategoryRegistry \
-            .GetCategoryState(PERFETTO_GET_CATEGORY_INDEX(category))           \
-            ->load(std::memory_order_relaxed);                                 \
+#define TRACE_EVENT_CATEGORY_GROUP_ENABLED(category, ret) \
+  do {                                                    \
+    *ret = TRACE_EVENT_CATEGORY_ENABLED(category);        \
   } while (0)
 
 // Macro to efficiently determine, through polling, if a new trace has begun.
@@ -1194,9 +1191,16 @@
 // the given category or not. A zero value means tracing is disabled and
 // non-zero indicates at least one tracing session for this category is active.
 // Note that callers should not make any assumptions at what each bit represents
-// in the status byte.
+// in the status byte. Does not support dynamic categories.
 #define TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category)                 \
   reinterpret_cast<const uint8_t*>(                                          \
+      [&] {                                                                  \
+        static_assert(                                                       \
+            !::PERFETTO_TRACK_EVENT_NAMESPACE::internal::IsDynamicCategory(  \
+                category),                                                   \
+            "Enabled flag pointers are not supported for dynamic trace "     \
+            "categories.");                                                  \
+      },                                                                     \
       ::PERFETTO_TRACK_EVENT_NAMESPACE::internal::kConstExprCategoryRegistry \
           .GetCategoryState(PERFETTO_GET_CATEGORY_INDEX(category)))
 
diff --git a/protos/perfetto/metrics/android/startup_metric.proto b/protos/perfetto/metrics/android/startup_metric.proto
index d38a598..21e22f0 100644
--- a/protos/perfetto/metrics/android/startup_metric.proto
+++ b/protos/perfetto/metrics/android/startup_metric.proto
@@ -63,6 +63,12 @@
     // The ratio between the cpu time of the activity process
     // to all other processes in the system.
     optional double other_process_to_activity_cpu_ratio = 12;
+
+    optional uint32 to_post_fork = 13;
+    optional uint32 to_activity_thread_main = 14;
+    optional uint32 to_bind_application = 15;
+
+    optional Slice time_post_fork = 16;
   }
 
   // Next id: 7
diff --git a/protos/perfetto/metrics/perfetto_merged_metrics.proto b/protos/perfetto/metrics/perfetto_merged_metrics.proto
index b04a972..a801023 100644
--- a/protos/perfetto/metrics/perfetto_merged_metrics.proto
+++ b/protos/perfetto/metrics/perfetto_merged_metrics.proto
@@ -326,6 +326,12 @@
     // The ratio between the cpu time of the activity process
     // to all other processes in the system.
     optional double other_process_to_activity_cpu_ratio = 12;
+
+    optional uint32 to_post_fork = 13;
+    optional uint32 to_activity_thread_main = 14;
+    optional uint32 to_bind_application = 15;
+
+    optional Slice time_post_fork = 16;
   }
 
   // Next id: 7
diff --git a/protos/perfetto/trace/perfetto_trace.proto b/protos/perfetto/trace/perfetto_trace.proto
index a2ea1d1..aca3208 100644
--- a/protos/perfetto/trace/perfetto_trace.proto
+++ b/protos/perfetto/trace/perfetto_trace.proto
@@ -3411,6 +3411,10 @@
 // Individual performance sampling packet payload. Typically corresponds to a
 // stack sample on a configration-dependent counter overflow.
 // Timestamps are within the root packet (in the CLOCK_BOOTTIME domain).
+// There are three distinct views of this message:
+// * completely processed sample (callstack_iid set)
+// * indication of kernel buffer data loss (kernel_records_lost set)
+// * indication of skipped samples (sample_skipped_reason set)
 message PerfSample {
   optional uint32 cpu = 1;
   optional uint32 pid = 2;
@@ -3424,10 +3428,8 @@
   optional uint64 callstack_iid = 4;
 
   // If set, stack unwinding was incomplete due to an error.
-  // Unset values should be treated as UNWIND_ERROR_NONE. Decoder is responsible
-  // for correctly handling the "unknown on-the-wire values are decoded as the
-  // first enum value" caveat.
-  optional Profiling.StackUnwindError unwind_error = 16;
+  // Unset values should be treated as UNWIND_ERROR_NONE.
+  oneof optional_unwind_error { Profiling.StackUnwindError unwind_error = 16; };
 
   // If set, indicates that this message is not a sample, but rather an
   // indication of data loss in the ring buffer allocated for |cpu|. Such data
@@ -3442,6 +3444,18 @@
   // specific time bounds of that loss (which would require tracking precedessor
   // & successor timestamps, which is not deemed necessary at the moment).
   optional uint64 kernel_records_lost = 17;
+
+  // If set, indicates that the profiler encountered a sample that was relevant,
+  // but was skipped as it was considered to be not unwindable (e.g. the process
+  // no longer exists).
+  enum ProfilerStage {
+    PROFILER_STAGE_UNKNOWN = 0;
+    PROFILER_STAGE_READ = 1;
+    PROFILER_STAGE_UNWIND = 2;
+  }
+  oneof optional_sample_skipped_reason {
+    ProfilerStage sample_skipped_reason = 18;
+  };
 }
 // End of protos/perfetto/trace/profiling/profile_packet.proto
 
diff --git a/protos/perfetto/trace/profiling/profile_packet.proto b/protos/perfetto/trace/profiling/profile_packet.proto
index c1cac95..000b550 100644
--- a/protos/perfetto/trace/profiling/profile_packet.proto
+++ b/protos/perfetto/trace/profiling/profile_packet.proto
@@ -176,6 +176,10 @@
 // Individual performance sampling packet payload. Typically corresponds to a
 // stack sample on a configration-dependent counter overflow.
 // Timestamps are within the root packet (in the CLOCK_BOOTTIME domain).
+// There are three distinct views of this message:
+// * completely processed sample (callstack_iid set)
+// * indication of kernel buffer data loss (kernel_records_lost set)
+// * indication of skipped samples (sample_skipped_reason set)
 message PerfSample {
   optional uint32 cpu = 1;
   optional uint32 pid = 2;
@@ -189,10 +193,8 @@
   optional uint64 callstack_iid = 4;
 
   // If set, stack unwinding was incomplete due to an error.
-  // Unset values should be treated as UNWIND_ERROR_NONE. Decoder is responsible
-  // for correctly handling the "unknown on-the-wire values are decoded as the
-  // first enum value" caveat.
-  optional Profiling.StackUnwindError unwind_error = 16;
+  // Unset values should be treated as UNWIND_ERROR_NONE.
+  oneof optional_unwind_error { Profiling.StackUnwindError unwind_error = 16; };
 
   // If set, indicates that this message is not a sample, but rather an
   // indication of data loss in the ring buffer allocated for |cpu|. Such data
@@ -207,4 +209,16 @@
   // specific time bounds of that loss (which would require tracking precedessor
   // & successor timestamps, which is not deemed necessary at the moment).
   optional uint64 kernel_records_lost = 17;
+
+  // If set, indicates that the profiler encountered a sample that was relevant,
+  // but was skipped as it was considered to be not unwindable (e.g. the process
+  // no longer exists).
+  enum ProfilerStage {
+    PROFILER_STAGE_UNKNOWN = 0;
+    PROFILER_STAGE_READ = 1;
+    PROFILER_STAGE_UNWIND = 2;
+  }
+  oneof optional_sample_skipped_reason {
+    ProfilerStage sample_skipped_reason = 18;
+  };
 }
\ No newline at end of file
diff --git a/src/android_internal/atrace_hal.cc b/src/android_internal/atrace_hal.cc
index 67e445d..486a44a 100644
--- a/src/android_internal/atrace_hal.cc
+++ b/src/android_internal/atrace_hal.cc
@@ -22,10 +22,11 @@
 namespace perfetto {
 namespace android_internal {
 
-using android::hardware::atrace::V1_0::IAtraceDevice;
-using android::hardware::atrace::V1_0::TracingCategory;
+using android::hardware::hidl_string;
 using android::hardware::hidl_vec;
 using android::hardware::Return;
+using android::hardware::atrace::V1_0::IAtraceDevice;
+using android::hardware::atrace::V1_0::TracingCategory;
 
 namespace {
 
@@ -40,7 +41,7 @@
 
 }  // namespace
 
-bool GetCategories(TracingVendorCategory* categories, size_t* size_of_arr) {
+bool ListCategories(TracingVendorCategory* categories, size_t* size_of_arr) {
   const size_t in_array_size = *size_of_arr;
   *size_of_arr = 0;
   if (!GetService())
@@ -64,5 +65,30 @@
   return true;
 }
 
+bool EnableCategories(const char** categories, size_t categories_count) {
+  if (!GetService())
+    return false;
+  std::vector<hidl_string> args;
+  args.resize(categories_count);
+  for (size_t i = 0; i < categories_count; ++i) {
+    args[i] = categories[i];
+  }
+  g_atraceHal->enableCategories(args);
+  // TODO(hjd): Check status.
+  return true;
+}
+
+bool DisableAllCategories() {
+  if (!GetService())
+    return false;
+  g_atraceHal->disableAllCategories();
+  // TODO(hjd): Check status.
+  return true;
+}
+
+void ForgetService() {
+  g_atraceHal = nullptr;
+}
+
 }  // namespace android_internal
 }  // namespace perfetto
diff --git a/src/android_internal/atrace_hal.h b/src/android_internal/atrace_hal.h
index 18d099d..782f800 100644
--- a/src/android_internal/atrace_hal.h
+++ b/src/android_internal/atrace_hal.h
@@ -42,7 +42,14 @@
 // These functions are not thread safe unless specified otherwise.
 
 bool __attribute__((visibility("default")))
-GetCategories(TracingVendorCategory*, size_t* size_of_arr);
+ListCategories(TracingVendorCategory*, size_t* size_of_arr);
+
+bool __attribute__((visibility("default")))
+EnableCategories(const char** categories, size_t categories_count);
+
+bool __attribute__((visibility("default"))) DisableAllCategories();
+
+void __attribute__((visibility("default"))) ForgetService();
 
 }  // extern "C"
 
diff --git a/src/profiling/perf/perf_producer.cc b/src/profiling/perf/perf_producer.cc
index c6fd0db..fba6fe4 100644
--- a/src/profiling/perf/perf_producer.cc
+++ b/src/profiling/perf/perf_producer.cc
@@ -51,6 +51,7 @@
 // TODO(rsavitski): this is better calculated (at setup) from the buffer and
 // sample sizes.
 constexpr size_t kMaxSamplesPerCpuPerReadTick = 32;
+constexpr uint32_t kProcDescriptorTimeoutMs = 200;
 
 constexpr size_t kUnwindingMaxFrames = 1000;
 
@@ -220,10 +221,11 @@
   InitiateReaderStop(&ds);
 }
 
-// TODO(rsavitski): ignoring flushes for now, as it is involved given
-// out-of-order unwinding and proc-fd timeouts. Instead of responding to
-// explicit flushes, we can ensure that we're otherwise well-behaved (do not
-// reorder packets too much).
+// The perf data sources ignore flush requests, as flushing would be
+// unnecessarily complicated given out-of-order unwinding and proc-fd timeouts.
+// Instead of responding to explicit flushes, we can ensure that we're otherwise
+// well-behaved (do not reorder packets too much), and let the service scrape
+// the SMB.
 void PerfProducer::Flush(FlushRequestID flush_id,
                          const DataSourceInstanceID* data_source_ids,
                          size_t num_data_sources) {
@@ -316,13 +318,14 @@
       PERFETTO_DLOG("New pid: [%d]", static_cast<int>(pid));
       fd_entry.status = Status::kResolving;
       proc_fd_getter_->GetDescriptorsForPid(pid);  // response is async
-      PostDescriptorLookupTimeout(ds_id, pid, /*timeout_ms=*/1000);
+      PostDescriptorLookupTimeout(ds_id, pid, kProcDescriptorTimeoutMs);
     }
 
-    // TODO(rsavitski): consider recording skipped entries in the trace.
     if (fd_entry.status == Status::kSkip) {
       PERFETTO_DLOG("Skipping sample for previously poisoned pid [%d]",
                     static_cast<int>(pid));
+      PostEmitSkippedSample(ds_id, ProfilerStage::kRead,
+                            std::move(sample.value()));
       continue;
     }
 
@@ -461,6 +464,8 @@
     if (fd_status == Status::kSkip) {
       PERFETTO_DLOG("Skipping sample for pid [%d]",
                     static_cast<int>(sample.pid));
+      PostEmitSkippedSample(ds_id, ProfilerStage::kUnwind,
+                            std::move(entry.sample));
       entry.valid = false;
       continue;
     }
@@ -608,8 +613,8 @@
   perf_sample->set_cpu(sample.cpu);
   perf_sample->set_pid(static_cast<uint32_t>(sample.pid));
   perf_sample->set_tid(static_cast<uint32_t>(sample.tid));
-  perf_sample->set_callstack_iid(callstack_iid);
   perf_sample->set_cpu_mode(ToCpuModeEnum(sample.cpu_mode));
+  perf_sample->set_callstack_iid(callstack_iid);
   if (sample.unwind_error != unwindstack::ERROR_NONE) {
     perf_sample->set_unwind_error(ToProtoEnum(sample.unwind_error));
   }
@@ -642,6 +647,49 @@
   perf_sample->set_kernel_records_lost(records_lost);
 }
 
+void PerfProducer::PostEmitSkippedSample(DataSourceInstanceID ds_id,
+                                         ProfilerStage stage,
+                                         ParsedSample sample) {
+  // hack: c++11 lambdas can't be moved into, so stash the sample on the heap.
+  ParsedSample* raw_sample = new ParsedSample(std::move(sample));
+  auto weak_this = weak_factory_.GetWeakPtr();
+  task_runner_->PostTask([weak_this, ds_id, stage, raw_sample] {
+    if (weak_this)
+      weak_this->EmitSkippedSample(ds_id, stage, std::move(*raw_sample));
+    delete raw_sample;
+  });
+}
+
+void PerfProducer::EmitSkippedSample(DataSourceInstanceID ds_id,
+                                     ProfilerStage stage,
+                                     ParsedSample sample) {
+  auto ds_it = data_sources_.find(ds_id);
+  if (ds_it == data_sources_.end()) {
+    PERFETTO_DLOG("EmitSkippedSample(%zu): source gone",
+                  static_cast<size_t>(ds_id));
+    return;
+  }
+  DataSource& ds = ds_it->second;
+
+  auto packet = ds.trace_writer->NewTracePacket();
+  packet->set_timestamp(sample.timestamp);
+  auto* perf_sample = packet->set_perf_sample();
+  perf_sample->set_cpu(sample.cpu);
+  perf_sample->set_pid(static_cast<uint32_t>(sample.pid));
+  perf_sample->set_tid(static_cast<uint32_t>(sample.tid));
+  perf_sample->set_cpu_mode(ToCpuModeEnum(sample.cpu_mode));
+
+  using PerfSample = protos::pbzero::PerfSample;
+  switch (stage) {
+    case ProfilerStage::kRead:
+      perf_sample->set_sample_skipped_reason(PerfSample::PROFILER_STAGE_READ);
+      break;
+    case ProfilerStage::kUnwind:
+      perf_sample->set_sample_skipped_reason(PerfSample::PROFILER_STAGE_UNWIND);
+      break;
+  }
+}
+
 void PerfProducer::InitiateReaderStop(DataSource* ds) {
   PERFETTO_DLOG("InitiateReaderStop");
   ds->reader_stopping = true;
@@ -701,8 +749,9 @@
 void PerfProducer::ConnectService() {
   PERFETTO_DCHECK(state_ == kNotConnected);
   state_ = kConnecting;
-  endpoint_ = ProducerIPCClient::Connect(producer_socket_name_, this,
-                                         kProducerName, task_runner_);
+  endpoint_ = ProducerIPCClient::Connect(
+      producer_socket_name_, this, kProducerName, task_runner_,
+      TracingService::ProducerSMBScrapingMode::kEnabled);
 }
 
 void PerfProducer::IncreaseConnectionBackoff() {
diff --git a/src/profiling/perf/perf_producer.h b/src/profiling/perf/perf_producer.h
index 1b127c7..5472178 100644
--- a/src/profiling/perf/perf_producer.h
+++ b/src/profiling/perf/perf_producer.h
@@ -152,6 +152,11 @@
     unwindstack::ErrorCode unwind_error = unwindstack::ERROR_NONE;
   };
 
+  enum class ProfilerStage {
+    kRead = 0,
+    kUnwind,
+  };
+
   void ConnectService();
   void Restart();
   void ResetConnectionBackoff();
@@ -187,6 +192,14 @@
   void EmitRingBufferLoss(DataSourceInstanceID ds_id,
                           size_t cpu,
                           uint64_t records_lost);
+  // Emit a packet indicating that a sample was relevant, but skipped as it was
+  // considered to be not unwindable (e.g. the process no longer exists).
+  void PostEmitSkippedSample(DataSourceInstanceID ds_id,
+                             ProfilerStage stage,
+                             ParsedSample sample);
+  void EmitSkippedSample(DataSourceInstanceID ds_id,
+                         ProfilerStage stage,
+                         ParsedSample sample);
 
   // Starts the shutdown of the given data source instance, starting with the
   // reader frontend.
diff --git a/src/trace_processor/experimental_flamegraph_generator.cc b/src/trace_processor/experimental_flamegraph_generator.cc
index ccad480..f477386 100644
--- a/src/trace_processor/experimental_flamegraph_generator.cc
+++ b/src/trace_processor/experimental_flamegraph_generator.cc
@@ -16,6 +16,8 @@
 
 #include "src/trace_processor/experimental_flamegraph_generator.h"
 
+#include "perfetto/ext/base/string_utils.h"
+
 #include "src/trace_processor/heap_profile_tracker.h"
 #include "src/trace_processor/importers/proto/heap_graph_tracker.h"
 #include "src/trace_processor/trace_processor_context.h"
@@ -41,10 +43,15 @@
     return c.col_idx == static_cast<uint32_t>(T::ColumnIndex::profile_type) &&
            c.op == FilterOp::kEq;
   };
+  auto focus_str_fn = [](const Constraint& c) {
+    return c.col_idx == static_cast<uint32_t>(T::ColumnIndex::focus_str) &&
+           c.op == FilterOp::kEq;
+  };
 
   auto ts_it = std::find_if(cs.begin(), cs.end(), ts_fn);
   auto upid_it = std::find_if(cs.begin(), cs.end(), upid_fn);
   auto profile_type_it = std::find_if(cs.begin(), cs.end(), profile_type_fn);
+  auto focus_str_it = std::find_if(cs.begin(), cs.end(), focus_str_fn);
 
   // We should always have valid iterators here because BestIndex should only
   // allow the constraint set to be chosen when we have an equality constraint
@@ -56,10 +63,152 @@
   int64_t ts = ts_it->value.AsLong();
   UniquePid upid = static_cast<UniquePid>(upid_it->value.AsLong());
   std::string profile_type = profile_type_it->value.AsString();
-
-  return ExperimentalFlamegraphGenerator::InputValues{ts, upid, profile_type};
+  std::string focus_str =
+      focus_str_it != cs.end() ? focus_str_it->value.AsString() : "";
+  return ExperimentalFlamegraphGenerator::InputValues{ts, upid, profile_type,
+                                                      focus_str};
 }
 
+class Matcher {
+ public:
+  explicit Matcher(const std::string& str) : focus_str_(base::ToLower(str)) {}
+  Matcher(const Matcher&) = delete;
+  Matcher& operator=(const Matcher&) = delete;
+
+  bool matches(const std::string& s) const {
+    // TODO(149833691): change to regex.
+    // We cannot use regex.h (does not exist in windows) or std regex (throws
+    // exceptions).
+    return base::Contains(base::ToLower(s), focus_str_);
+  }
+
+ private:
+  const std::string focus_str_;
+};
+
+enum class FocusedState {
+  kNotFocused,
+  kFocusedPropagating,
+  kFocusedNotPropagating,
+};
+
+using tables::ExperimentalFlamegraphNodesTable;
+std::vector<FocusedState> ComputeFocusedState(
+    const ExperimentalFlamegraphNodesTable& table,
+    const Matcher& focus_matcher) {
+  // Each row corresponds to a node in the flame chart tree with its parent ptr.
+  // Root trees (no parents) will have a null parent ptr.
+  std::vector<FocusedState> focused(table.row_count());
+
+  for (uint32_t i = 0; i < table.row_count(); ++i) {
+    auto parent_id = table.parent_id()[i];
+    // Constraint: all descendants MUST come after their parents.
+    PERFETTO_DCHECK(!parent_id.has_value() || *parent_id < table.id()[i]);
+
+    if (focus_matcher.matches(table.name().GetString(i).ToStdString())) {
+      // Mark as focused
+      focused[i] = FocusedState::kFocusedPropagating;
+      auto current = parent_id;
+      // Mark all parent nodes as focused
+      while (current.has_value()) {
+        auto current_idx = *table.id().IndexOf(*current);
+        if (focused[current_idx] != FocusedState::kNotFocused) {
+          // We have already visited these nodes, skip
+          break;
+        }
+        focused[current_idx] = FocusedState::kFocusedNotPropagating;
+        current = table.parent_id()[current_idx];
+      }
+    } else if (parent_id.has_value() &&
+               focused[*table.id().IndexOf(*parent_id)] ==
+                   FocusedState::kFocusedPropagating) {
+      // Focus cascades downwards.
+      focused[i] = FocusedState::kFocusedPropagating;
+    } else {
+      focused[i] = FocusedState::kNotFocused;
+    }
+  }
+  return focused;
+}
+
+struct CumulativeCounts {
+  int64_t size;
+  int64_t count;
+  int64_t alloc_size;
+  int64_t alloc_count;
+};
+std::unique_ptr<tables::ExperimentalFlamegraphNodesTable> FocusTable(
+    TraceStorage* storage,
+    std::unique_ptr<ExperimentalFlamegraphNodesTable> in,
+    const std::string& focus_str) {
+  if (in->row_count() == 0 || focus_str.empty()) {
+    return in;
+  }
+  std::vector<FocusedState> focused_state =
+      ComputeFocusedState(*in.get(), Matcher(focus_str));
+  std::unique_ptr<ExperimentalFlamegraphNodesTable> tbl(
+      new tables::ExperimentalFlamegraphNodesTable(
+          storage->mutable_string_pool(), nullptr));
+
+  // Recompute cumulative counts
+  std::vector<CumulativeCounts> node_to_cumulatives(in->row_count());
+  for (int64_t idx = in->row_count() - 1; idx >= 0; --idx) {
+    auto i = static_cast<uint32_t>(idx);
+    if (focused_state[i] == FocusedState::kNotFocused) {
+      continue;
+    }
+    auto& cumulatives = node_to_cumulatives[i];
+    cumulatives.size += in->size()[i];
+    cumulatives.count += in->count()[i];
+    cumulatives.alloc_size += in->alloc_size()[i];
+    cumulatives.alloc_count += in->alloc_count()[i];
+
+    auto parent_id = in->parent_id()[i];
+    if (parent_id.has_value()) {
+      auto& parent_cumulatives =
+          node_to_cumulatives[*in->id().IndexOf(*parent_id)];
+      parent_cumulatives.size += cumulatives.size;
+      parent_cumulatives.count += cumulatives.count;
+      parent_cumulatives.alloc_size += cumulatives.alloc_size;
+      parent_cumulatives.alloc_count += cumulatives.alloc_count;
+    }
+  }
+
+  // Mapping between the old rows ('node') to the new identifiers.
+  std::vector<ExperimentalFlamegraphNodesTable::Id> node_to_id(in->row_count());
+  for (uint32_t i = 0; i < in->row_count(); ++i) {
+    if (focused_state[i] == FocusedState::kNotFocused) {
+      continue;
+    }
+
+    tables::ExperimentalFlamegraphNodesTable::Row alloc_row{};
+    // We must reparent the rows as every insertion will get its own identifier.
+    auto original_parent_id = in->parent_id()[i];
+    if (original_parent_id.has_value()) {
+      auto original_idx = *in->id().IndexOf(*original_parent_id);
+      alloc_row.parent_id = node_to_id[original_idx];
+    }
+
+    alloc_row.ts = in->ts()[i];
+    alloc_row.upid = in->upid()[i];
+    alloc_row.profile_type = in->profile_type()[i];
+    alloc_row.depth = in->depth()[i];
+    alloc_row.name = in->name()[i];
+    alloc_row.map_name = in->map_name()[i];
+    alloc_row.count = in->count()[i];
+    alloc_row.size = in->size()[i];
+    alloc_row.alloc_count = in->alloc_count()[i];
+    alloc_row.alloc_size = in->alloc_size()[i];
+
+    const auto& cumulative = node_to_cumulatives[i];
+    alloc_row.cumulative_count = cumulative.count;
+    alloc_row.cumulative_size = cumulative.size;
+    alloc_row.cumulative_alloc_count = cumulative.alloc_count;
+    alloc_row.cumulative_alloc_size = cumulative.alloc_size;
+    node_to_id[i] = tbl->Insert(alloc_row).id;
+  }
+  return tbl;
+}
 }  // namespace
 
 ExperimentalFlamegraphGenerator::ExperimentalFlamegraphGenerator(
@@ -112,6 +261,17 @@
     table_ =
         BuildNativeFlamegraph(context_->storage.get(), values.upid, values.ts);
   }
+  if (!values.focus_str.empty()) {
+    table_ = FocusTable(context_->storage.get(), std::move(table_),
+                        values.focus_str);
+    // The pseudocolumns must be populated because as far as SQLite is concerned
+    // these are equality constraints.
+    auto focus_id =
+        context_->storage->InternString(base::StringView(values.focus_str));
+    for (uint32_t i = 0; i < table_->row_count(); ++i) {
+      table_->mutable_focus_str()->Set(i, focus_id);
+    }
+  }
   return table_.get();
 }
 
diff --git a/src/trace_processor/experimental_flamegraph_generator.h b/src/trace_processor/experimental_flamegraph_generator.h
index b74fa6d..52170b8 100644
--- a/src/trace_processor/experimental_flamegraph_generator.h
+++ b/src/trace_processor/experimental_flamegraph_generator.h
@@ -33,6 +33,7 @@
     int64_t ts;
     UniquePid upid;
     std::string profile_type;
+    std::string focus_str;
   };
 
   ExperimentalFlamegraphGenerator(TraceProcessorContext* context);
diff --git a/src/trace_processor/importers/json/json_trace_utils_unittest.cc b/src/trace_processor/importers/json/json_trace_utils_unittest.cc
index 45408ee..57db5fc 100644
--- a/src/trace_processor/importers/json/json_trace_utils_unittest.cc
+++ b/src/trace_processor/importers/json/json_trace_utils_unittest.cc
@@ -35,10 +35,11 @@
   ASSERT_EQ(CoerceToInt64(Json::Value(42)).value_or(-1), 42);
   ASSERT_EQ(CoerceToInt64(Json::Value("42")).value_or(-1), 42);
   ASSERT_EQ(CoerceToInt64(Json::Value(42.1)).value_or(-1), 42);
-  ASSERT_EQ(CoerceToInt64(Json::Value{18446744073709551615ULL}).value_or(0),
-            -1);
   ASSERT_FALSE(CoerceToInt64(Json::Value("foo")).has_value());
   ASSERT_FALSE(CoerceToInt64(Json::Value("1234!")).has_value());
+
+  Json::UInt64 n = 18446744073709551615UL;
+  ASSERT_EQ(CoerceToInt64(Json::Value{n}).value_or(0), -1);
 }
 
 TEST(JsonTraceUtilsTest, CoerceToTs) {
diff --git a/src/trace_processor/importers/proto/proto_trace_parser.cc b/src/trace_processor/importers/proto/proto_trace_parser.cc
index a049043..bfbc0b7 100644
--- a/src/trace_processor/importers/proto/proto_trace_parser.cc
+++ b/src/trace_processor/importers/proto/proto_trace_parser.cc
@@ -333,9 +333,11 @@
     int64_t ts,
     PacketSequenceStateGeneration* sequence_state,
     ConstBytes blob) {
-  protos::pbzero::PerfSample::Decoder sample(blob.data, blob.size);
+  using PerfSample = protos::pbzero::PerfSample;
+  PerfSample::Decoder sample(blob.data, blob.size);
 
-  // Not a sample, but an indication of data loss.
+  // Not a sample, but an indication of data loss in the ring buffer shared with
+  // the kernel.
   if (sample.kernel_records_lost() > 0) {
     PERFETTO_DCHECK(sample.pid() == 0);
 
@@ -345,6 +347,13 @@
     return;
   }
 
+  // Sample that wasn't unwound (likely because we failed to look up the
+  // proc-fds for it).
+  if (sample.has_sample_skipped_reason()) {
+    context_->storage->IncrementStats(stats::perf_samples_skipped);
+    return;
+  }
+
   uint64_t callstack_iid = sample.callstack_iid();
   StackProfileTracker& stack_tracker =
       sequence_state->state()->stack_profile_tracker();
diff --git a/src/trace_processor/metrics/android/android_startup.sql b/src/trace_processor/metrics/android/android_startup.sql
index c0d65c2..c0bd541 100644
--- a/src/trace_processor/metrics/android/android_startup.sql
+++ b/src/trace_processor/metrics/android/android_startup.sql
@@ -74,6 +74,7 @@
   slice.track_id = thread_track.id
   AND slice.ts BETWEEN launches.ts AND launches.ts + launches.dur)
 WHERE slice.name IN (
+  'PostFork',
   'ActivityThreadMain',
   'bindApplication',
   'activityStart',
@@ -123,6 +124,33 @@
             WHERE launch_id = launches.id AND state = 'interruptible'
             ), 0)
       ),
+      'to_post_fork', (
+        SELECT slice.ts - l.ts
+        FROM launch_main_threads l
+        JOIN thread_track USING (utid)
+        JOIN slice ON (
+          slice.track_id = thread_track.id
+          AND slice.ts BETWEEN l.ts AND l.ts + l.dur)
+        WHERE launch_id = launches.id AND slice.name = 'PostFork'
+      ),
+      'to_activity_thread_main', (
+        SELECT slice.ts - l.ts
+        FROM launch_main_threads l
+        JOIN thread_track USING (utid)
+        JOIN slice ON (
+          slice.track_id = thread_track.id
+          AND slice.ts BETWEEN l.ts AND l.ts + l.dur)
+        WHERE launch_id = launches.id AND slice.name = 'ActivityThreadMain'
+      ),
+      'to_bind_application', (
+        SELECT slice.ts - l.ts
+        FROM launch_main_threads l
+        JOIN thread_track USING (utid)
+        JOIN slice ON (
+          slice.track_id = thread_track.id
+          AND slice.ts BETWEEN l.ts AND l.ts + l.dur)
+        WHERE launch_id = launches.id AND slice.name = 'bindApplication'
+      ),
       'other_processes_spawned_count', (
         SELECT COUNT(1) FROM process
         WHERE (process.name IS NULL OR process.name != launches.package)
@@ -135,6 +163,10 @@
           AND launching_events.ts BETWEEN launches.ts AND launches.ts + launches.dur
         )
       ),
+      'time_post_fork', (
+        SELECT slice_proto FROM main_process_slice
+        WHERE launch_id = launches.id AND name = 'PostFork'
+      ),
       'time_activity_thread_main', (
         SELECT slice_proto FROM main_process_slice
         WHERE launch_id = launches.id AND name = 'ActivityThreadMain'
diff --git a/src/trace_processor/metrics/metrics.descriptor.h b/src/trace_processor/metrics/metrics.descriptor.h
index 3f0a37a..45567ce 100644
--- a/src/trace_processor/metrics/metrics.descriptor.h
+++ b/src/trace_processor/metrics/metrics.descriptor.h
@@ -34,7 +34,7 @@
 
 namespace perfetto {
 
-constexpr std::array<uint8_t, 14234> kMetricsDescriptor{
+constexpr std::array<uint8_t, 14454> kMetricsDescriptor{
     {0x0a, 0x94, 0x03, 0x0a, 0x31, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f,
      0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74,
      0x72, 0x69, 0x63, 0x73, 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
@@ -469,13 +469,13 @@
      0x69, 0x64, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x52, 0x61, 0x69, 0x6c, 0x73,
      0x2e, 0x45, 0x6e, 0x65, 0x72, 0x67, 0x79, 0x44, 0x61, 0x74, 0x61, 0x52,
      0x0a, 0x65, 0x6e, 0x65, 0x72, 0x67, 0x79, 0x44, 0x61, 0x74, 0x61, 0x0a,
-     0xa8, 0x0e, 0x0a, 0x34, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x70,
+     0x84, 0x10, 0x0a, 0x34, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 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,
      0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 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, 0xde, 0x0d, 0x0a, 0x14, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69,
+     0x73, 0x22, 0xba, 0x0f, 0x0a, 0x14, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69,
      0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x4d, 0x65, 0x74, 0x72,
      0x69, 0x63, 0x12, 0x47, 0x0a, 0x07, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75,
      0x70, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x70, 0x65,
@@ -504,8 +504,8 @@
      0x69, 0x62, 0x6c, 0x65, 0x53, 0x6c, 0x65, 0x65, 0x70, 0x44, 0x75, 0x72,
      0x4e, 0x73, 0x1a, 0x1e, 0x0a, 0x05, 0x53, 0x6c, 0x69, 0x63, 0x65, 0x12,
      0x15, 0x0a, 0x06, 0x64, 0x75, 0x72, 0x5f, 0x6e, 0x73, 0x18, 0x01, 0x20,
-     0x01, 0x28, 0x03, 0x52, 0x05, 0x64, 0x75, 0x72, 0x4e, 0x73, 0x1a, 0xbb,
-     0x08, 0x0a, 0x0c, 0x54, 0x6f, 0x46, 0x69, 0x72, 0x73, 0x74, 0x46, 0x72,
+     0x01, 0x28, 0x03, 0x52, 0x05, 0x64, 0x75, 0x72, 0x4e, 0x73, 0x1a, 0x97,
+     0x0a, 0x0a, 0x0c, 0x54, 0x6f, 0x46, 0x69, 0x72, 0x73, 0x74, 0x46, 0x72,
      0x61, 0x6d, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x64, 0x75, 0x72, 0x5f, 0x6e,
      0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x64, 0x75, 0x72,
      0x4e, 0x73, 0x12, 0x72, 0x0a, 0x19, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x74,
@@ -595,633 +595,651 @@
      0x69, 0x6f, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x01, 0x52, 0x1e, 0x6f, 0x74,
      0x68, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f,
      0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x43, 0x70, 0x75, 0x52,
-     0x61, 0x74, 0x69, 0x6f, 0x1a, 0xbb, 0x02, 0x0a, 0x07, 0x53, 0x74, 0x61,
-     0x72, 0x74, 0x75, 0x70, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72,
-     0x74, 0x75, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d,
-     0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x49, 0x64, 0x12,
-     0x21, 0x0a, 0x0c, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x5f, 0x6e,
-     0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70,
-     0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x21,
-     0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6e, 0x61,
-     0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72,
-     0x6f, 0x63, 0x65, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2c, 0x0a,
-     0x12, 0x7a, 0x79, 0x67, 0x6f, 0x74, 0x65, 0x5f, 0x6e, 0x65, 0x77, 0x5f,
-     0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28,
-     0x08, 0x52, 0x10, 0x7a, 0x79, 0x67, 0x6f, 0x74, 0x65, 0x4e, 0x65, 0x77,
-     0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x43, 0x0a, 0x1e, 0x61,
-     0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x5f, 0x68, 0x6f, 0x73, 0x74,
-     0x69, 0x6e, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f,
-     0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52,
-     0x1b, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x48, 0x6f, 0x73,
-     0x74, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43,
-     0x6f, 0x75, 0x6e, 0x74, 0x12, 0x58, 0x0a, 0x0e, 0x74, 0x6f, 0x5f, 0x66,
-     0x69, 0x72, 0x73, 0x74, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x18, 0x05,
-     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, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75,
-     0x70, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x54, 0x6f, 0x46, 0x69,
-     0x72, 0x73, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x52, 0x0c, 0x74, 0x6f,
-     0x46, 0x69, 0x72, 0x73, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x0a, 0xae,
-     0x08, 0x0a, 0x3c, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 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, 0x68,
-     0x65, 0x61, 0x70, 0x5f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f,
-     0x63, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 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, 0x36, 0x70, 0x72,
-     0x6f, 0x74, 0x6f, 0x73, 0x2f, 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, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73,
-     0x73, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70,
-     0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa4, 0x07, 0x0a, 0x14, 0x48, 0x65, 0x61,
-     0x70, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x61, 0x6c, 0x6c,
-     0x73, 0x69, 0x74, 0x65, 0x73, 0x12, 0x5a, 0x0a, 0x0e, 0x69, 0x6e, 0x73,
-     0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18,
-     0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x70, 0x65, 0x72, 0x66,
-     0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e,
-     0x48, 0x65, 0x61, 0x70, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x43,
-     0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x73,
-     0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x0d,
-     0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74,
-     0x73, 0x1a, 0x3e, 0x0a, 0x05, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x12,
-     0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
-     0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x6d, 0x61,
-     0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02,
-     0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e,
-     0x67, 0x4e, 0x61, 0x6d, 0x65, 0x1a, 0x8e, 0x01, 0x0a, 0x08, 0x43, 0x6f,
-     0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f,
-     0x74, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20,
-     0x01, 0x28, 0x03, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x43, 0x6f,
-     0x75, 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c,
-     0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03,
-     0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, 0x79, 0x74, 0x65, 0x73,
-     0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x63, 0x6f,
-     0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x64,
-     0x65, 0x6c, 0x74, 0x61, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1f, 0x0a,
-     0x0b, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73,
-     0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x64, 0x65, 0x6c, 0x74,
-     0x61, 0x42, 0x79, 0x74, 0x65, 0x73, 0x1a, 0xa6, 0x02, 0x0a, 0x08, 0x43,
-     0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68,
-     0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x68,
-     0x61, 0x73, 0x68, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x65, 0x6e,
-     0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03,
-     0x52, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x48, 0x61, 0x73, 0x68,
-     0x12, 0x41, 0x0a, 0x05, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20,
-     0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74,
-     0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x48, 0x65,
-     0x61, 0x70, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x61, 0x6c,
-     0x6c, 0x73, 0x69, 0x74, 0x65, 0x73, 0x2e, 0x46, 0x72, 0x61, 0x6d, 0x65,
-     0x52, 0x05, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x4f, 0x0a, 0x0b, 0x73,
-     0x65, 0x6c, 0x66, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x73, 0x18, 0x04,
-     0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65,
-     0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x48,
-     0x65, 0x61, 0x70, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x61,
-     0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x73, 0x2e, 0x43, 0x6f, 0x75, 0x6e,
-     0x74, 0x65, 0x72, 0x73, 0x52, 0x0a, 0x73, 0x65, 0x6c, 0x66, 0x41, 0x6c,
-     0x6c, 0x6f, 0x63, 0x73, 0x12, 0x51, 0x0a, 0x0c, 0x63, 0x68, 0x69, 0x6c,
-     0x64, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x73, 0x18, 0x05, 0x20, 0x01,
-     0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74,
-     0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x48, 0x65, 0x61,
-     0x70, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x61, 0x6c, 0x6c,
-     0x73, 0x69, 0x74, 0x65, 0x73, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65,
-     0x72, 0x73, 0x52, 0x0b, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x41, 0x6c, 0x6c,
-     0x6f, 0x63, 0x73, 0x1a, 0xb5, 0x02, 0x0a, 0x0d, 0x49, 0x6e, 0x73, 0x74,
-     0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x10, 0x0a,
-     0x03, 0x70, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03,
-     0x70, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x63, 0x65,
-     0x73, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
-     0x09, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4e, 0x61,
-     0x6d, 0x65, 0x12, 0x41, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73,
-     0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x65,
-     0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-     0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x50, 0x72, 0x6f,
-     0x63, 0x65, 0x73, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
-     0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x4c, 0x0a,
-     0x09, 0x63, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x73, 0x18, 0x03,
-     0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65,
-     0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x48,
-     0x65, 0x61, 0x70, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x61,
-     0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x73, 0x2e, 0x43, 0x61, 0x6c, 0x6c,
-     0x73, 0x69, 0x74, 0x65, 0x52, 0x09, 0x63, 0x61, 0x6c, 0x6c, 0x73, 0x69,
-     0x74, 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x70, 0x72, 0x6f, 0x66, 0x69,
-     0x6c, 0x65, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x62, 0x79, 0x74,
-     0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x70, 0x72,
-     0x6f, 0x66, 0x69, 0x6c, 0x65, 0x44, 0x65, 0x6c, 0x74, 0x61, 0x42, 0x79,
-     0x74, 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x70, 0x72, 0x6f, 0x66, 0x69,
-     0x6c, 0x65, 0x5f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x62, 0x79, 0x74,
-     0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x70, 0x72,
-     0x6f, 0x66, 0x69, 0x6c, 0x65, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x42, 0x79,
-     0x74, 0x65, 0x73, 0x0a, 0x86, 0x0f, 0x0a, 0x31, 0x70, 0x72, 0x6f, 0x74,
-     0x6f, 0x73, 0x2f, 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, 0x68, 0x77, 0x75, 0x69, 0x5f, 0x6d, 0x65, 0x74,
-     0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x70,
+     0x61, 0x74, 0x69, 0x6f, 0x12, 0x20, 0x0a, 0x0c, 0x74, 0x6f, 0x5f, 0x70,
+     0x6f, 0x73, 0x74, 0x5f, 0x66, 0x6f, 0x72, 0x6b, 0x18, 0x0d, 0x20, 0x01,
+     0x28, 0x0d, 0x52, 0x0a, 0x74, 0x6f, 0x50, 0x6f, 0x73, 0x74, 0x46, 0x6f,
+     0x72, 0x6b, 0x12, 0x35, 0x0a, 0x17, 0x74, 0x6f, 0x5f, 0x61, 0x63, 0x74,
+     0x69, 0x76, 0x69, 0x74, 0x79, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64,
+     0x5f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0d, 0x52,
+     0x14, 0x74, 0x6f, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x54,
+     0x68, 0x72, 0x65, 0x61, 0x64, 0x4d, 0x61, 0x69, 0x6e, 0x12, 0x2e, 0x0a,
+     0x13, 0x74, 0x6f, 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x61, 0x70, 0x70,
+     0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0f, 0x20, 0x01,
+     0x28, 0x0d, 0x52, 0x11, 0x74, 0x6f, 0x42, 0x69, 0x6e, 0x64, 0x41, 0x70,
+     0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x51, 0x0a,
+     0x0e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x66,
+     0x6f, 0x72, 0x6b, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e,
+     0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f,
+     0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x53,
+     0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63,
+     0x2e, 0x53, 0x6c, 0x69, 0x63, 0x65, 0x52, 0x0c, 0x74, 0x69, 0x6d, 0x65,
+     0x50, 0x6f, 0x73, 0x74, 0x46, 0x6f, 0x72, 0x6b, 0x1a, 0xbb, 0x02, 0x0a,
+     0x07, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x1d, 0x0a, 0x0a,
+     0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x01,
+     0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75,
+     0x70, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x61, 0x63, 0x6b, 0x61,
+     0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
+     0x09, 0x52, 0x0b, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x4e, 0x61,
+     0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73,
+     0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
+     0x52, 0x0b, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4e, 0x61, 0x6d,
+     0x65, 0x12, 0x2c, 0x0a, 0x12, 0x7a, 0x79, 0x67, 0x6f, 0x74, 0x65, 0x5f,
+     0x6e, 0x65, 0x77, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18,
+     0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x7a, 0x79, 0x67, 0x6f, 0x74,
+     0x65, 0x4e, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12,
+     0x43, 0x0a, 0x1e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x5f,
+     0x68, 0x6f, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x63,
+     0x65, 0x73, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20,
+     0x01, 0x28, 0x0d, 0x52, 0x1b, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74,
+     0x79, 0x48, 0x6f, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x63,
+     0x65, 0x73, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x58, 0x0a, 0x0e,
+     0x74, 0x6f, 0x5f, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x66, 0x72, 0x61,
+     0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x70,
      0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74,
-     0x6f, 0x73, 0x22, 0xe3, 0x0d, 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x63, 0x65,
-     0x73, 0x73, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f,
-     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,
-     0x23, 0x0a, 0x0e, 0x72, 0x74, 0x5f, 0x63, 0x70, 0x75, 0x5f, 0x74, 0x69,
-     0x6d, 0x65, 0x5f, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52,
-     0x0b, 0x72, 0x74, 0x43, 0x70, 0x75, 0x54, 0x69, 0x6d, 0x65, 0x4d, 0x73,
-     0x12, 0x28, 0x0a, 0x10, 0x64, 0x72, 0x61, 0x77, 0x5f, 0x66, 0x72, 0x61,
-     0x6d, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01,
-     0x28, 0x0d, 0x52, 0x0e, 0x64, 0x72, 0x61, 0x77, 0x46, 0x72, 0x61, 0x6d,
-     0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x64, 0x72,
-     0x61, 0x77, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x5f, 0x6d, 0x61, 0x78,
-     0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x64, 0x72, 0x61, 0x77,
-     0x46, 0x72, 0x61, 0x6d, 0x65, 0x4d, 0x61, 0x78, 0x12, 0x24, 0x0a, 0x0e,
-     0x64, 0x72, 0x61, 0x77, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x5f, 0x6d,
-     0x69, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x64, 0x72,
-     0x61, 0x77, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x4d, 0x69, 0x6e, 0x12, 0x24,
-     0x0a, 0x0e, 0x64, 0x72, 0x61, 0x77, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65,
-     0x5f, 0x61, 0x76, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0c,
-     0x64, 0x72, 0x61, 0x77, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x41, 0x76, 0x67,
-     0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x5f, 0x63, 0x6f,
-     0x75, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x66,
-     0x6c, 0x75, 0x73, 0x68, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1b, 0x0a,
-     0x09, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x5f, 0x6d, 0x61, 0x78, 0x18, 0x08,
-     0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x4d,
-     0x61, 0x78, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x5f,
-     0x6d, 0x69, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x66,
-     0x6c, 0x75, 0x73, 0x68, 0x4d, 0x69, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x66,
-     0x6c, 0x75, 0x73, 0x68, 0x5f, 0x61, 0x76, 0x67, 0x18, 0x0a, 0x20, 0x01,
-     0x28, 0x01, 0x52, 0x08, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x41, 0x76, 0x67,
-     0x12, 0x2c, 0x0a, 0x12, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x5f,
-     0x74, 0x72, 0x65, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0b,
-     0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72,
-     0x65, 0x54, 0x72, 0x65, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x28,
-     0x0a, 0x10, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x5f, 0x74, 0x72,
-     0x65, 0x65, 0x5f, 0x6d, 0x61, 0x78, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x03,
-     0x52, 0x0e, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x54, 0x72, 0x65,
-     0x65, 0x4d, 0x61, 0x78, 0x12, 0x28, 0x0a, 0x10, 0x70, 0x72, 0x65, 0x70,
-     0x61, 0x72, 0x65, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x6d, 0x69, 0x6e,
-     0x18, 0x0d, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x70, 0x72, 0x65, 0x70,
-     0x61, 0x72, 0x65, 0x54, 0x72, 0x65, 0x65, 0x4d, 0x69, 0x6e, 0x12, 0x28,
-     0x0a, 0x10, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x5f, 0x74, 0x72,
-     0x65, 0x65, 0x5f, 0x61, 0x76, 0x67, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x01,
-     0x52, 0x0e, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x54, 0x72, 0x65,
-     0x65, 0x41, 0x76, 0x67, 0x12, 0x30, 0x0a, 0x14, 0x67, 0x70, 0x75, 0x5f,
-     0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63,
-     0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x12,
-     0x67, 0x70, 0x75, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f,
-     0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x12, 0x67, 0x70,
-     0x75, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e,
-     0x5f, 0x6d, 0x61, 0x78, 0x18, 0x10, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10,
-     0x67, 0x70, 0x75, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f,
-     0x6e, 0x4d, 0x61, 0x78, 0x12, 0x2c, 0x0a, 0x12, 0x67, 0x70, 0x75, 0x5f,
-     0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d,
-     0x69, 0x6e, 0x18, 0x11, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x67, 0x70,
-     0x75, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x4d,
-     0x69, 0x6e, 0x12, 0x2c, 0x0a, 0x12, 0x67, 0x70, 0x75, 0x5f, 0x63, 0x6f,
-     0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x76, 0x67,
-     0x18, 0x12, 0x20, 0x01, 0x28, 0x01, 0x52, 0x10, 0x67, 0x70, 0x75, 0x43,
-     0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x76, 0x67,
-     0x12, 0x26, 0x0a, 0x0f, 0x75, 0x69, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x72,
-     0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x13, 0x20, 0x01, 0x28,
-     0x0d, 0x52, 0x0d, 0x75, 0x69, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x43,
-     0x6f, 0x75, 0x6e, 0x74, 0x12, 0x22, 0x0a, 0x0d, 0x75, 0x69, 0x5f, 0x72,
-     0x65, 0x63, 0x6f, 0x72, 0x64, 0x5f, 0x6d, 0x61, 0x78, 0x18, 0x14, 0x20,
-     0x01, 0x28, 0x03, 0x52, 0x0b, 0x75, 0x69, 0x52, 0x65, 0x63, 0x6f, 0x72,
-     0x64, 0x4d, 0x61, 0x78, 0x12, 0x22, 0x0a, 0x0d, 0x75, 0x69, 0x5f, 0x72,
-     0x65, 0x63, 0x6f, 0x72, 0x64, 0x5f, 0x6d, 0x69, 0x6e, 0x18, 0x15, 0x20,
-     0x01, 0x28, 0x03, 0x52, 0x0b, 0x75, 0x69, 0x52, 0x65, 0x63, 0x6f, 0x72,
-     0x64, 0x4d, 0x69, 0x6e, 0x12, 0x22, 0x0a, 0x0d, 0x75, 0x69, 0x5f, 0x72,
-     0x65, 0x63, 0x6f, 0x72, 0x64, 0x5f, 0x61, 0x76, 0x67, 0x18, 0x16, 0x20,
-     0x01, 0x28, 0x01, 0x52, 0x0b, 0x75, 0x69, 0x52, 0x65, 0x63, 0x6f, 0x72,
-     0x64, 0x41, 0x76, 0x67, 0x12, 0x30, 0x0a, 0x14, 0x73, 0x68, 0x61, 0x64,
-     0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x5f, 0x63,
-     0x6f, 0x75, 0x6e, 0x74, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x12,
-     0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c,
-     0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2e, 0x0a, 0x13, 0x73, 0x68,
-     0x61, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65,
-     0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x18, 0x20, 0x01, 0x28, 0x03, 0x52,
-     0x11, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x70, 0x69,
-     0x6c, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x73, 0x68,
-     0x61, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65,
-     0x5f, 0x61, 0x76, 0x67, 0x18, 0x19, 0x20, 0x01, 0x28, 0x01, 0x52, 0x10,
-     0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c,
-     0x65, 0x41, 0x76, 0x67, 0x12, 0x26, 0x0a, 0x0f, 0x63, 0x61, 0x63, 0x68,
-     0x65, 0x5f, 0x68, 0x69, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18,
-     0x1a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x63, 0x61, 0x63, 0x68, 0x65,
-     0x48, 0x69, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x0e,
-     0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, 0x68, 0x69, 0x74, 0x5f, 0x74, 0x69,
-     0x6d, 0x65, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x61,
-     0x63, 0x68, 0x65, 0x48, 0x69, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x22,
-     0x0a, 0x0d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, 0x68, 0x69, 0x74, 0x5f,
-     0x61, 0x76, 0x67, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0b, 0x63,
-     0x61, 0x63, 0x68, 0x65, 0x48, 0x69, 0x74, 0x41, 0x76, 0x67, 0x12, 0x28,
-     0x0a, 0x10, 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, 0x6d, 0x69, 0x73, 0x73,
-     0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x0d,
-     0x52, 0x0e, 0x63, 0x61, 0x63, 0x68, 0x65, 0x4d, 0x69, 0x73, 0x73, 0x43,
-     0x6f, 0x75, 0x6e, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x63, 0x61, 0x63, 0x68,
-     0x65, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18,
-     0x1e, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x63, 0x61, 0x63, 0x68, 0x65,
-     0x4d, 0x69, 0x73, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0e,
-     0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x5f, 0x61,
-     0x76, 0x67, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0c, 0x63, 0x61,
-     0x63, 0x68, 0x65, 0x4d, 0x69, 0x73, 0x73, 0x41, 0x76, 0x67, 0x12, 0x2f,
-     0x0a, 0x14, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x5f, 0x63,
-     0x70, 0x75, 0x5f, 0x6d, 0x65, 0x6d, 0x5f, 0x6d, 0x61, 0x78, 0x18, 0x20,
-     0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69,
-     0x63, 0x73, 0x43, 0x70, 0x75, 0x4d, 0x65, 0x6d, 0x4d, 0x61, 0x78, 0x12,
-     0x2f, 0x0a, 0x14, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x5f,
-     0x63, 0x70, 0x75, 0x5f, 0x6d, 0x65, 0x6d, 0x5f, 0x6d, 0x69, 0x6e, 0x18,
-     0x21, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x67, 0x72, 0x61, 0x70, 0x68,
-     0x69, 0x63, 0x73, 0x43, 0x70, 0x75, 0x4d, 0x65, 0x6d, 0x4d, 0x69, 0x6e,
-     0x12, 0x2f, 0x0a, 0x14, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73,
-     0x5f, 0x63, 0x70, 0x75, 0x5f, 0x6d, 0x65, 0x6d, 0x5f, 0x61, 0x76, 0x67,
-     0x18, 0x22, 0x20, 0x01, 0x28, 0x01, 0x52, 0x11, 0x67, 0x72, 0x61, 0x70,
-     0x68, 0x69, 0x63, 0x73, 0x43, 0x70, 0x75, 0x4d, 0x65, 0x6d, 0x41, 0x76,
-     0x67, 0x12, 0x2f, 0x0a, 0x14, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63,
-     0x73, 0x5f, 0x67, 0x70, 0x75, 0x5f, 0x6d, 0x65, 0x6d, 0x5f, 0x6d, 0x61,
-     0x78, 0x18, 0x23, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x67, 0x72, 0x61,
-     0x70, 0x68, 0x69, 0x63, 0x73, 0x47, 0x70, 0x75, 0x4d, 0x65, 0x6d, 0x4d,
-     0x61, 0x78, 0x12, 0x2f, 0x0a, 0x14, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69,
-     0x63, 0x73, 0x5f, 0x67, 0x70, 0x75, 0x5f, 0x6d, 0x65, 0x6d, 0x5f, 0x6d,
-     0x69, 0x6e, 0x18, 0x24, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x67, 0x72,
-     0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x47, 0x70, 0x75, 0x4d, 0x65, 0x6d,
-     0x4d, 0x69, 0x6e, 0x12, 0x2f, 0x0a, 0x14, 0x67, 0x72, 0x61, 0x70, 0x68,
-     0x69, 0x63, 0x73, 0x5f, 0x67, 0x70, 0x75, 0x5f, 0x6d, 0x65, 0x6d, 0x5f,
-     0x61, 0x76, 0x67, 0x18, 0x25, 0x20, 0x01, 0x28, 0x01, 0x52, 0x11, 0x67,
-     0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x47, 0x70, 0x75, 0x4d, 0x65,
-     0x6d, 0x41, 0x76, 0x67, 0x12, 0x26, 0x0a, 0x0f, 0x74, 0x65, 0x78, 0x74,
-     0x75, 0x72, 0x65, 0x5f, 0x6d, 0x65, 0x6d, 0x5f, 0x6d, 0x61, 0x78, 0x18,
-     0x26, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x65, 0x78, 0x74, 0x75,
-     0x72, 0x65, 0x4d, 0x65, 0x6d, 0x4d, 0x61, 0x78, 0x12, 0x26, 0x0a, 0x0f,
-     0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x6d, 0x65, 0x6d, 0x5f,
-     0x6d, 0x69, 0x6e, 0x18, 0x27, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74,
-     0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x4d, 0x65, 0x6d, 0x4d, 0x69, 0x6e,
-     0x12, 0x26, 0x0a, 0x0f, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f,
-     0x6d, 0x65, 0x6d, 0x5f, 0x61, 0x76, 0x67, 0x18, 0x28, 0x20, 0x01, 0x28,
-     0x01, 0x52, 0x0d, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x4d, 0x65,
-     0x6d, 0x41, 0x76, 0x67, 0x12, 0x1e, 0x0a, 0x0b, 0x61, 0x6c, 0x6c, 0x5f,
-     0x6d, 0x65, 0x6d, 0x5f, 0x6d, 0x61, 0x78, 0x18, 0x29, 0x20, 0x01, 0x28,
-     0x03, 0x52, 0x09, 0x61, 0x6c, 0x6c, 0x4d, 0x65, 0x6d, 0x4d, 0x61, 0x78,
-     0x12, 0x1e, 0x0a, 0x0b, 0x61, 0x6c, 0x6c, 0x5f, 0x6d, 0x65, 0x6d, 0x5f,
-     0x6d, 0x69, 0x6e, 0x18, 0x2a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x61,
-     0x6c, 0x6c, 0x4d, 0x65, 0x6d, 0x4d, 0x69, 0x6e, 0x12, 0x1e, 0x0a, 0x0b,
-     0x61, 0x6c, 0x6c, 0x5f, 0x6d, 0x65, 0x6d, 0x5f, 0x61, 0x76, 0x67, 0x18,
-     0x2b, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, 0x61, 0x6c, 0x6c, 0x4d, 0x65,
-     0x6d, 0x41, 0x76, 0x67, 0x22, 0x5a, 0x0a, 0x11, 0x41, 0x6e, 0x64, 0x72,
-     0x6f, 0x69, 0x64, 0x48, 0x77, 0x75, 0x69, 0x4d, 0x65, 0x74, 0x72, 0x69,
-     0x63, 0x12, 0x45, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73,
-     0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
-     0x22, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70,
-     0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73,
-     0x73, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52,
-     0x0b, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x49, 0x6e, 0x66, 0x6f,
-     0x0a, 0x88, 0x02, 0x0a, 0x32, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f,
-     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, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x5f, 0x6c, 0x69, 0x73,
-     0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x70, 0x65, 0x72,
-     0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
-     0x22, 0xc0, 0x01, 0x0a, 0x12, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
-     0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12,
-     0x47, 0x0a, 0x08, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x18,
-     0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x65, 0x72, 0x66,
-     0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e,
-     0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x61,
-     0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61,
-     0x67, 0x65, 0x52, 0x08, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73,
-     0x1a, 0x61, 0x0a, 0x07, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12,
-     0x21, 0x0a, 0x0c, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x5f, 0x6e,
-     0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70,
-     0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x10,
-     0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52,
-     0x03, 0x75, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x76, 0x65, 0x72, 0x73,
-     0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01,
-     0x28, 0x03, 0x52, 0x0b, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x43,
-     0x6f, 0x64, 0x65, 0x0a, 0x98, 0x04, 0x0a, 0x3b, 0x70, 0x72, 0x6f, 0x74,
-     0x6f, 0x73, 0x2f, 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, 0x75, 0x6e, 0x6d, 0x61, 0x70, 0x70, 0x65, 0x64,
-     0x5f, 0x6a, 0x61, 0x76, 0x61, 0x5f, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c,
+     0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x53, 0x74,
+     0x61, 0x72, 0x74, 0x75, 0x70, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e,
+     0x54, 0x6f, 0x46, 0x69, 0x72, 0x73, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65,
+     0x52, 0x0c, 0x74, 0x6f, 0x46, 0x69, 0x72, 0x73, 0x74, 0x46, 0x72, 0x61,
+     0x6d, 0x65, 0x0a, 0xae, 0x08, 0x0a, 0x3c, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+     0x73, 0x2f, 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, 0x68, 0x65, 0x61, 0x70, 0x5f, 0x70, 0x72, 0x6f, 0x66,
+     0x69, 0x6c, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65,
      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, 0x36, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 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, 0x70, 0x72,
      0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61,
-     0x74, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x8f, 0x03, 0x0a,
-     0x13, 0x55, 0x6e, 0x6d, 0x61, 0x70, 0x70, 0x65, 0x64, 0x4a, 0x61, 0x76,
-     0x61, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x12, 0x5c, 0x0a, 0x0f,
-     0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x79, 0x6d, 0x62,
-     0x6f, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e,
+     0x74, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa4, 0x07, 0x0a,
+     0x14, 0x48, 0x65, 0x61, 0x70, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65,
+     0x43, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x73, 0x12, 0x5a, 0x0a,
+     0x0e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x73, 0x74,
+     0x61, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e,
      0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f,
-     0x74, 0x6f, 0x73, 0x2e, 0x55, 0x6e, 0x6d, 0x61, 0x70, 0x70, 0x65, 0x64,
-     0x4a, 0x61, 0x76, 0x61, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x2e,
-     0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x53, 0x79, 0x6d, 0x62, 0x6f,
-     0x6c, 0x73, 0x52, 0x0e, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x53,
-     0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x1a, 0x4e, 0x0a, 0x05, 0x46, 0x69,
-     0x65, 0x6c, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64,
-     0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
-     0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x26,
-     0x0a, 0x0f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x74, 0x79, 0x70, 0x65,
-     0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
-     0x0d, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x54, 0x79, 0x70, 0x65, 0x4e, 0x61,
-     0x6d, 0x65, 0x1a, 0xc9, 0x01, 0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x63, 0x65,
-     0x73, 0x73, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x12, 0x52, 0x0a,
-     0x10, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6d, 0x65, 0x74,
-     0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
+     0x74, 0x6f, 0x73, 0x2e, 0x48, 0x65, 0x61, 0x70, 0x50, 0x72, 0x6f, 0x66,
+     0x69, 0x6c, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x73,
+     0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61,
+     0x74, 0x73, 0x52, 0x0d, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65,
+     0x53, 0x74, 0x61, 0x74, 0x73, 0x1a, 0x3e, 0x0a, 0x05, 0x46, 0x72, 0x61,
+     0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01,
+     0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x21,
+     0x0a, 0x0c, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x6e, 0x61,
+     0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6d, 0x61,
+     0x70, 0x70, 0x69, 0x6e, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x1a, 0x8e, 0x01,
+     0x0a, 0x08, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x12, 0x1f,
+     0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x75, 0x6e,
+     0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x74, 0x6f, 0x74,
+     0x61, 0x6c, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x74,
+     0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x02,
+     0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42,
+     0x79, 0x74, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x6c, 0x74,
+     0x61, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28,
+     0x03, 0x52, 0x0a, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x43, 0x6f, 0x75, 0x6e,
+     0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x62,
+     0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a,
+     0x64, 0x65, 0x6c, 0x74, 0x61, 0x42, 0x79, 0x74, 0x65, 0x73, 0x1a, 0xa6,
+     0x02, 0x0a, 0x08, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x12,
+     0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28,
+     0x03, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x1f, 0x0a, 0x0b, 0x70,
+     0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02,
+     0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74,
+     0x48, 0x61, 0x73, 0x68, 0x12, 0x41, 0x0a, 0x05, 0x66, 0x72, 0x61, 0x6d,
+     0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x65,
+     0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+     0x73, 0x2e, 0x48, 0x65, 0x61, 0x70, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c,
+     0x65, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x73, 0x2e, 0x46,
+     0x72, 0x61, 0x6d, 0x65, 0x52, 0x05, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x12,
+     0x4f, 0x0a, 0x0b, 0x73, 0x65, 0x6c, 0x66, 0x5f, 0x61, 0x6c, 0x6c, 0x6f,
+     0x63, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x70,
+     0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+     0x6f, 0x73, 0x2e, 0x48, 0x65, 0x61, 0x70, 0x50, 0x72, 0x6f, 0x66, 0x69,
+     0x6c, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x73, 0x2e,
+     0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x52, 0x0a, 0x73, 0x65,
+     0x6c, 0x66, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x73, 0x12, 0x51, 0x0a, 0x0c,
+     0x63, 0x68, 0x69, 0x6c, 0x64, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x73,
+     0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x70, 0x65, 0x72,
+     0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
+     0x2e, 0x48, 0x65, 0x61, 0x70, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65,
+     0x43, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x73, 0x2e, 0x43, 0x6f,
+     0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x52, 0x0b, 0x63, 0x68, 0x69, 0x6c,
+     0x64, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x73, 0x1a, 0xb5, 0x02, 0x0a, 0x0d,
+     0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74,
+     0x73, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
+     0x28, 0x0d, 0x52, 0x03, 0x70, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70,
+     0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18,
+     0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x63, 0x65,
+     0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x41, 0x0a, 0x07, 0x70, 0x72,
+     0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32,
      0x27, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70,
      0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69,
      0x64, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4d, 0x65, 0x74, 0x61,
-     0x64, 0x61, 0x74, 0x61, 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73,
-     0x73, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1b, 0x0a,
-     0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02,
-     0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61,
-     0x6d, 0x65, 0x12, 0x40, 0x0a, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18,
-     0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x70, 0x65, 0x72, 0x66,
-     0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e,
-     0x55, 0x6e, 0x6d, 0x61, 0x70, 0x70, 0x65, 0x64, 0x4a, 0x61, 0x76, 0x61,
-     0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x2e, 0x46, 0x69, 0x65, 0x6c,
-     0x64, 0x52, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4a, 0x04, 0x08, 0x03,
-     0x10, 0x04, 0x0a, 0xfc, 0x01, 0x0a, 0x39, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-     0x73, 0x2f, 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, 0x75, 0x6e, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x69,
-     0x7a, 0x65, 0x64, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x2e, 0x70,
-     0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74,
-     0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x22, 0xad, 0x01,
-     0x0a, 0x12, 0x55, 0x6e, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x69, 0x7a,
-     0x65, 0x64, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x41, 0x0a, 0x06,
-     0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
-     0x32, 0x29, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e,
-     0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x55, 0x6e, 0x73, 0x79, 0x6d,
-     0x62, 0x6f, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x46, 0x72, 0x61, 0x6d, 0x65,
-     0x73, 0x2e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x52, 0x06, 0x66, 0x72, 0x61,
-     0x6d, 0x65, 0x73, 0x1a, 0x54, 0x0a, 0x05, 0x46, 0x72, 0x61, 0x6d, 0x65,
-     0x12, 0x16, 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x01,
-     0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65,
-     0x12, 0x19, 0x0a, 0x08, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x69, 0x64,
-     0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x75, 0x69, 0x6c,
-     0x64, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65,
-     0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x61, 0x64,
-     0x64, 0x72, 0x65, 0x73, 0x73, 0x0a, 0xf8, 0x03, 0x0a, 0x35, 0x70, 0x72,
-     0x6f, 0x74, 0x6f, 0x73, 0x2f, 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, 0x6a, 0x61, 0x76, 0x61, 0x5f, 0x68,
-     0x65, 0x61, 0x70, 0x5f, 0x73, 0x74, 0x61, 0x74, 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, 0x36, 0x70, 0x72,
-     0x6f, 0x74, 0x6f, 0x73, 0x2f, 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, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73,
-     0x73, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70,
-     0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf5, 0x02, 0x0a, 0x0d, 0x4a, 0x61, 0x76,
-     0x61, 0x48, 0x65, 0x61, 0x70, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x53,
-     0x0a, 0x0e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x73,
-     0x74, 0x61, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c,
-     0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72,
-     0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x4a, 0x61, 0x76, 0x61, 0x48, 0x65, 0x61,
-     0x70, 0x53, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61,
-     0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x0d, 0x69, 0x6e,
-     0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x1a,
-     0x65, 0x0a, 0x06, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x12, 0x0e, 0x0a,
-     0x02, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x74,
-     0x73, 0x12, 0x1b, 0x0a, 0x09, 0x68, 0x65, 0x61, 0x70, 0x5f, 0x73, 0x69,
-     0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x68, 0x65,
-     0x61, 0x70, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x72, 0x65,
-     0x61, 0x63, 0x68, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x68, 0x65, 0x61, 0x70,
-     0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52,
-     0x11, 0x72, 0x65, 0x61, 0x63, 0x68, 0x61, 0x62, 0x6c, 0x65, 0x48, 0x65,
-     0x61, 0x70, 0x53, 0x69, 0x7a, 0x65, 0x1a, 0xa7, 0x01, 0x0a, 0x0d, 0x49,
-     0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73,
-     0x12, 0x12, 0x0a, 0x04, 0x75, 0x70, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
-     0x28, 0x0d, 0x52, 0x04, 0x75, 0x70, 0x69, 0x64, 0x12, 0x41, 0x0a, 0x07,
-     0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28,
-     0x0b, 0x32, 0x27, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f,
-     0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72,
-     0x6f, 0x69, 0x64, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4d, 0x65,
-     0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63,
-     0x65, 0x73, 0x73, 0x12, 0x3f, 0x0a, 0x07, 0x73, 0x61, 0x6d, 0x70, 0x6c,
-     0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70,
+     0x64, 0x61, 0x74, 0x61, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73,
+     0x73, 0x12, 0x4c, 0x0a, 0x09, 0x63, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74,
+     0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x70,
      0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74,
-     0x6f, 0x73, 0x2e, 0x4a, 0x61, 0x76, 0x61, 0x48, 0x65, 0x61, 0x70, 0x53,
-     0x74, 0x61, 0x74, 0x73, 0x2e, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x52,
-     0x07, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x0a, 0xbb, 0x14, 0x0a,
-     0x25, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 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, 0x31, 0x70, 0x72, 0x6f,
+     0x6f, 0x73, 0x2e, 0x48, 0x65, 0x61, 0x70, 0x50, 0x72, 0x6f, 0x66, 0x69,
+     0x6c, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x73, 0x2e,
+     0x43, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x52, 0x09, 0x63, 0x61,
+     0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x70,
+     0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61,
+     0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03,
+     0x52, 0x11, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x44, 0x65, 0x6c,
+     0x74, 0x61, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x70,
+     0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x74, 0x6f, 0x74, 0x61, 0x6c,
+     0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03,
+     0x52, 0x11, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x54, 0x6f, 0x74,
+     0x61, 0x6c, 0x42, 0x79, 0x74, 0x65, 0x73, 0x0a, 0x86, 0x0f, 0x0a, 0x31,
+     0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 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, 0x68, 0x77, 0x75, 0x69,
+     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, 0xe3, 0x0d, 0x0a, 0x11, 0x50,
+     0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72,
+     0x49, 0x6e, 0x66, 0x6f, 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, 0x23, 0x0a, 0x0e, 0x72, 0x74, 0x5f, 0x63, 0x70,
+     0x75, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6d, 0x73, 0x18, 0x02, 0x20,
+     0x01, 0x28, 0x03, 0x52, 0x0b, 0x72, 0x74, 0x43, 0x70, 0x75, 0x54, 0x69,
+     0x6d, 0x65, 0x4d, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x64, 0x72, 0x61, 0x77,
+     0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74,
+     0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x64, 0x72, 0x61, 0x77,
+     0x46, 0x72, 0x61, 0x6d, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x24,
+     0x0a, 0x0e, 0x64, 0x72, 0x61, 0x77, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65,
+     0x5f, 0x6d, 0x61, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c,
+     0x64, 0x72, 0x61, 0x77, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x4d, 0x61, 0x78,
+     0x12, 0x24, 0x0a, 0x0e, 0x64, 0x72, 0x61, 0x77, 0x5f, 0x66, 0x72, 0x61,
+     0x6d, 0x65, 0x5f, 0x6d, 0x69, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03,
+     0x52, 0x0c, 0x64, 0x72, 0x61, 0x77, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x4d,
+     0x69, 0x6e, 0x12, 0x24, 0x0a, 0x0e, 0x64, 0x72, 0x61, 0x77, 0x5f, 0x66,
+     0x72, 0x61, 0x6d, 0x65, 0x5f, 0x61, 0x76, 0x67, 0x18, 0x06, 0x20, 0x01,
+     0x28, 0x01, 0x52, 0x0c, 0x64, 0x72, 0x61, 0x77, 0x46, 0x72, 0x61, 0x6d,
+     0x65, 0x41, 0x76, 0x67, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x6c, 0x75, 0x73,
+     0x68, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28,
+     0x0d, 0x52, 0x0a, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x43, 0x6f, 0x75, 0x6e,
+     0x74, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x5f, 0x6d,
+     0x61, 0x78, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x66, 0x6c,
+     0x75, 0x73, 0x68, 0x4d, 0x61, 0x78, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x6c,
+     0x75, 0x73, 0x68, 0x5f, 0x6d, 0x69, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28,
+     0x03, 0x52, 0x08, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x4d, 0x69, 0x6e, 0x12,
+     0x1b, 0x0a, 0x09, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x5f, 0x61, 0x76, 0x67,
+     0x18, 0x0a, 0x20, 0x01, 0x28, 0x01, 0x52, 0x08, 0x66, 0x6c, 0x75, 0x73,
+     0x68, 0x41, 0x76, 0x67, 0x12, 0x2c, 0x0a, 0x12, 0x70, 0x72, 0x65, 0x70,
+     0x61, 0x72, 0x65, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x63, 0x6f, 0x75,
+     0x6e, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x70, 0x72,
+     0x65, 0x70, 0x61, 0x72, 0x65, 0x54, 0x72, 0x65, 0x65, 0x43, 0x6f, 0x75,
+     0x6e, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72,
+     0x65, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x6d, 0x61, 0x78, 0x18, 0x0c,
+     0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72,
+     0x65, 0x54, 0x72, 0x65, 0x65, 0x4d, 0x61, 0x78, 0x12, 0x28, 0x0a, 0x10,
+     0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x5f, 0x74, 0x72, 0x65, 0x65,
+     0x5f, 0x6d, 0x69, 0x6e, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e,
+     0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x54, 0x72, 0x65, 0x65, 0x4d,
+     0x69, 0x6e, 0x12, 0x28, 0x0a, 0x10, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72,
+     0x65, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x61, 0x76, 0x67, 0x18, 0x0e,
+     0x20, 0x01, 0x28, 0x01, 0x52, 0x0e, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72,
+     0x65, 0x54, 0x72, 0x65, 0x65, 0x41, 0x76, 0x67, 0x12, 0x30, 0x0a, 0x14,
+     0x67, 0x70, 0x75, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69,
+     0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0f, 0x20, 0x01,
+     0x28, 0x0d, 0x52, 0x12, 0x67, 0x70, 0x75, 0x43, 0x6f, 0x6d, 0x70, 0x6c,
+     0x65, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2c,
+     0x0a, 0x12, 0x67, 0x70, 0x75, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65,
+     0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x61, 0x78, 0x18, 0x10, 0x20, 0x01,
+     0x28, 0x03, 0x52, 0x10, 0x67, 0x70, 0x75, 0x43, 0x6f, 0x6d, 0x70, 0x6c,
+     0x65, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x78, 0x12, 0x2c, 0x0a, 0x12,
+     0x67, 0x70, 0x75, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69,
+     0x6f, 0x6e, 0x5f, 0x6d, 0x69, 0x6e, 0x18, 0x11, 0x20, 0x01, 0x28, 0x03,
+     0x52, 0x10, 0x67, 0x70, 0x75, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74,
+     0x69, 0x6f, 0x6e, 0x4d, 0x69, 0x6e, 0x12, 0x2c, 0x0a, 0x12, 0x67, 0x70,
+     0x75, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e,
+     0x5f, 0x61, 0x76, 0x67, 0x18, 0x12, 0x20, 0x01, 0x28, 0x01, 0x52, 0x10,
+     0x67, 0x70, 0x75, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f,
+     0x6e, 0x41, 0x76, 0x67, 0x12, 0x26, 0x0a, 0x0f, 0x75, 0x69, 0x5f, 0x72,
+     0x65, 0x63, 0x6f, 0x72, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18,
+     0x13, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x75, 0x69, 0x52, 0x65, 0x63,
+     0x6f, 0x72, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x22, 0x0a, 0x0d,
+     0x75, 0x69, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x5f, 0x6d, 0x61,
+     0x78, 0x18, 0x14, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x75, 0x69, 0x52,
+     0x65, 0x63, 0x6f, 0x72, 0x64, 0x4d, 0x61, 0x78, 0x12, 0x22, 0x0a, 0x0d,
+     0x75, 0x69, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x5f, 0x6d, 0x69,
+     0x6e, 0x18, 0x15, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x75, 0x69, 0x52,
+     0x65, 0x63, 0x6f, 0x72, 0x64, 0x4d, 0x69, 0x6e, 0x12, 0x22, 0x0a, 0x0d,
+     0x75, 0x69, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x5f, 0x61, 0x76,
+     0x67, 0x18, 0x16, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0b, 0x75, 0x69, 0x52,
+     0x65, 0x63, 0x6f, 0x72, 0x64, 0x41, 0x76, 0x67, 0x12, 0x30, 0x0a, 0x14,
+     0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x69,
+     0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x17, 0x20, 0x01,
+     0x28, 0x0d, 0x52, 0x12, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x43, 0x6f,
+     0x6d, 0x70, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2e,
+     0x0a, 0x13, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6d,
+     0x70, 0x69, 0x6c, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x18, 0x20,
+     0x01, 0x28, 0x03, 0x52, 0x11, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x43,
+     0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x2c,
+     0x0a, 0x12, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6d,
+     0x70, 0x69, 0x6c, 0x65, 0x5f, 0x61, 0x76, 0x67, 0x18, 0x19, 0x20, 0x01,
+     0x28, 0x01, 0x52, 0x10, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x43, 0x6f,
+     0x6d, 0x70, 0x69, 0x6c, 0x65, 0x41, 0x76, 0x67, 0x12, 0x26, 0x0a, 0x0f,
+     0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, 0x68, 0x69, 0x74, 0x5f, 0x63, 0x6f,
+     0x75, 0x6e, 0x74, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x63,
+     0x61, 0x63, 0x68, 0x65, 0x48, 0x69, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74,
+     0x12, 0x24, 0x0a, 0x0e, 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, 0x68, 0x69,
+     0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x03,
+     0x52, 0x0c, 0x63, 0x61, 0x63, 0x68, 0x65, 0x48, 0x69, 0x74, 0x54, 0x69,
+     0x6d, 0x65, 0x12, 0x22, 0x0a, 0x0d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f,
+     0x68, 0x69, 0x74, 0x5f, 0x61, 0x76, 0x67, 0x18, 0x1c, 0x20, 0x01, 0x28,
+     0x01, 0x52, 0x0b, 0x63, 0x61, 0x63, 0x68, 0x65, 0x48, 0x69, 0x74, 0x41,
+     0x76, 0x67, 0x12, 0x28, 0x0a, 0x10, 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f,
+     0x6d, 0x69, 0x73, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x1d,
+     0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x63, 0x61, 0x63, 0x68, 0x65, 0x4d,
+     0x69, 0x73, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x26, 0x0a, 0x0f,
+     0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x5f, 0x74,
+     0x69, 0x6d, 0x65, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x63,
+     0x61, 0x63, 0x68, 0x65, 0x4d, 0x69, 0x73, 0x73, 0x54, 0x69, 0x6d, 0x65,
+     0x12, 0x24, 0x0a, 0x0e, 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, 0x6d, 0x69,
+     0x73, 0x73, 0x5f, 0x61, 0x76, 0x67, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x01,
+     0x52, 0x0c, 0x63, 0x61, 0x63, 0x68, 0x65, 0x4d, 0x69, 0x73, 0x73, 0x41,
+     0x76, 0x67, 0x12, 0x2f, 0x0a, 0x14, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69,
+     0x63, 0x73, 0x5f, 0x63, 0x70, 0x75, 0x5f, 0x6d, 0x65, 0x6d, 0x5f, 0x6d,
+     0x61, 0x78, 0x18, 0x20, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x67, 0x72,
+     0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x43, 0x70, 0x75, 0x4d, 0x65, 0x6d,
+     0x4d, 0x61, 0x78, 0x12, 0x2f, 0x0a, 0x14, 0x67, 0x72, 0x61, 0x70, 0x68,
+     0x69, 0x63, 0x73, 0x5f, 0x63, 0x70, 0x75, 0x5f, 0x6d, 0x65, 0x6d, 0x5f,
+     0x6d, 0x69, 0x6e, 0x18, 0x21, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x67,
+     0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x43, 0x70, 0x75, 0x4d, 0x65,
+     0x6d, 0x4d, 0x69, 0x6e, 0x12, 0x2f, 0x0a, 0x14, 0x67, 0x72, 0x61, 0x70,
+     0x68, 0x69, 0x63, 0x73, 0x5f, 0x63, 0x70, 0x75, 0x5f, 0x6d, 0x65, 0x6d,
+     0x5f, 0x61, 0x76, 0x67, 0x18, 0x22, 0x20, 0x01, 0x28, 0x01, 0x52, 0x11,
+     0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x43, 0x70, 0x75, 0x4d,
+     0x65, 0x6d, 0x41, 0x76, 0x67, 0x12, 0x2f, 0x0a, 0x14, 0x67, 0x72, 0x61,
+     0x70, 0x68, 0x69, 0x63, 0x73, 0x5f, 0x67, 0x70, 0x75, 0x5f, 0x6d, 0x65,
+     0x6d, 0x5f, 0x6d, 0x61, 0x78, 0x18, 0x23, 0x20, 0x01, 0x28, 0x03, 0x52,
+     0x11, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x47, 0x70, 0x75,
+     0x4d, 0x65, 0x6d, 0x4d, 0x61, 0x78, 0x12, 0x2f, 0x0a, 0x14, 0x67, 0x72,
+     0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x5f, 0x67, 0x70, 0x75, 0x5f, 0x6d,
+     0x65, 0x6d, 0x5f, 0x6d, 0x69, 0x6e, 0x18, 0x24, 0x20, 0x01, 0x28, 0x03,
+     0x52, 0x11, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x47, 0x70,
+     0x75, 0x4d, 0x65, 0x6d, 0x4d, 0x69, 0x6e, 0x12, 0x2f, 0x0a, 0x14, 0x67,
+     0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x5f, 0x67, 0x70, 0x75, 0x5f,
+     0x6d, 0x65, 0x6d, 0x5f, 0x61, 0x76, 0x67, 0x18, 0x25, 0x20, 0x01, 0x28,
+     0x01, 0x52, 0x11, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x47,
+     0x70, 0x75, 0x4d, 0x65, 0x6d, 0x41, 0x76, 0x67, 0x12, 0x26, 0x0a, 0x0f,
+     0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x6d, 0x65, 0x6d, 0x5f,
+     0x6d, 0x61, 0x78, 0x18, 0x26, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74,
+     0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x4d, 0x65, 0x6d, 0x4d, 0x61, 0x78,
+     0x12, 0x26, 0x0a, 0x0f, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f,
+     0x6d, 0x65, 0x6d, 0x5f, 0x6d, 0x69, 0x6e, 0x18, 0x27, 0x20, 0x01, 0x28,
+     0x03, 0x52, 0x0d, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x4d, 0x65,
+     0x6d, 0x4d, 0x69, 0x6e, 0x12, 0x26, 0x0a, 0x0f, 0x74, 0x65, 0x78, 0x74,
+     0x75, 0x72, 0x65, 0x5f, 0x6d, 0x65, 0x6d, 0x5f, 0x61, 0x76, 0x67, 0x18,
+     0x28, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0d, 0x74, 0x65, 0x78, 0x74, 0x75,
+     0x72, 0x65, 0x4d, 0x65, 0x6d, 0x41, 0x76, 0x67, 0x12, 0x1e, 0x0a, 0x0b,
+     0x61, 0x6c, 0x6c, 0x5f, 0x6d, 0x65, 0x6d, 0x5f, 0x6d, 0x61, 0x78, 0x18,
+     0x29, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x61, 0x6c, 0x6c, 0x4d, 0x65,
+     0x6d, 0x4d, 0x61, 0x78, 0x12, 0x1e, 0x0a, 0x0b, 0x61, 0x6c, 0x6c, 0x5f,
+     0x6d, 0x65, 0x6d, 0x5f, 0x6d, 0x69, 0x6e, 0x18, 0x2a, 0x20, 0x01, 0x28,
+     0x03, 0x52, 0x09, 0x61, 0x6c, 0x6c, 0x4d, 0x65, 0x6d, 0x4d, 0x69, 0x6e,
+     0x12, 0x1e, 0x0a, 0x0b, 0x61, 0x6c, 0x6c, 0x5f, 0x6d, 0x65, 0x6d, 0x5f,
+     0x61, 0x76, 0x67, 0x18, 0x2b, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, 0x61,
+     0x6c, 0x6c, 0x4d, 0x65, 0x6d, 0x41, 0x76, 0x67, 0x22, 0x5a, 0x0a, 0x11,
+     0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x48, 0x77, 0x75, 0x69, 0x4d,
+     0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x45, 0x0a, 0x0c, 0x70, 0x72, 0x6f,
+     0x63, 0x65, 0x73, 0x73, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20,
+     0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74,
+     0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x50, 0x72,
+     0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x49,
+     0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73,
+     0x49, 0x6e, 0x66, 0x6f, 0x0a, 0x88, 0x02, 0x0a, 0x32, 0x70, 0x72, 0x6f,
      0x74, 0x6f, 0x73, 0x2f, 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, 0x62, 0x61, 0x74, 0x74, 0x5f, 0x6d, 0x65,
-     0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x30,
-     0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 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, 0x63, 0x70, 0x75, 0x5f,
-     0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-     0x1a, 0x30, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 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, 0x1a, 0x36, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 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, 0x75, 0x6e, 0x61, 0x67, 0x67, 0x5f, 0x6d, 0x65,
-     0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x30,
-     0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 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, 0x69, 0x6f, 0x6e, 0x5f,
-     0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-     0x1a, 0x30, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 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, 0x6c, 0x6d,
-     0x6b, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f,
-     0x74, 0x6f, 0x1a, 0x37, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 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,
-     0x6c, 0x6d, 0x6b, 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x5f, 0x6d,
-     0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a,
-     0x35, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 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, 0x70, 0x6f, 0x77,
-     0x72, 0x61, 0x69, 0x6c, 0x73, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63,
-     0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x34, 0x70, 0x72, 0x6f, 0x74,
-     0x6f, 0x73, 0x2f, 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, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x5f,
-     0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-     0x1a, 0x3c, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 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, 0x68, 0x65,
-     0x61, 0x70, 0x5f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x63,
-     0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f,
-     0x74, 0x6f, 0x1a, 0x31, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 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,
-     0x68, 0x77, 0x75, 0x69, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e,
-     0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x32, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-     0x73, 0x2f, 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, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x5f, 0x6c,
-     0x69, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x3b, 0x70,
-     0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 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, 0x75, 0x6e, 0x6d, 0x61, 0x70,
-     0x70, 0x65, 0x64, 0x5f, 0x6a, 0x61, 0x76, 0x61, 0x5f, 0x73, 0x79, 0x6d,
-     0x62, 0x6f, 0x6c, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x39,
-     0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 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, 0x75, 0x6e, 0x73, 0x79,
-     0x6d, 0x62, 0x6f, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x66, 0x72, 0x61,
-     0x6d, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x35, 0x70,
-     0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 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, 0x6a, 0x61, 0x76, 0x61, 0x5f,
-     0x68, 0x65, 0x61, 0x70, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x70,
-     0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa2, 0x03, 0x0a, 0x0d, 0x54, 0x72, 0x61,
-     0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x50,
-     0x0a, 0x11, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x74,
-     0x73, 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x01, 0x20, 0x03, 0x28,
-     0x0b, 0x32, 0x24, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f,
-     0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x54, 0x72, 0x61, 0x63,
-     0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x6e,
-     0x74, 0x72, 0x79, 0x52, 0x0f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x53, 0x74,
-     0x61, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x2a, 0x0a, 0x11,
-     0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69,
-     0x6f, 0x6e, 0x5f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52,
-     0x0f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69,
-     0x6f, 0x6e, 0x4e, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x72, 0x61, 0x63,
-     0x65, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
-     0x52, 0x09, 0x74, 0x72, 0x61, 0x63, 0x65, 0x55, 0x75, 0x69, 0x64, 0x12,
-     0x3a, 0x0a, 0x19, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x5f, 0x62,
-     0x75, 0x69, 0x6c, 0x64, 0x5f, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70,
-     0x72, 0x69, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x17,
-     0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64,
-     0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x12,
-     0x49, 0x0a, 0x21, 0x73, 0x74, 0x61, 0x74, 0x73, 0x64, 0x5f, 0x74, 0x72,
-     0x69, 0x67, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x75, 0x62,
-     0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64,
-     0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x1e, 0x73, 0x74, 0x61, 0x74,
-     0x73, 0x64, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x67,
-     0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e,
-     0x49, 0x64, 0x12, 0x28, 0x0a, 0x10, 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f,
-     0x73, 0x69, 0x7a, 0x65, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x06,
-     0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x53,
-     0x69, 0x7a, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x1a, 0x43, 0x0a, 0x05,
-     0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
-     0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d,
-     0x65, 0x12, 0x10, 0x0a, 0x03, 0x69, 0x64, 0x78, 0x18, 0x02, 0x20, 0x01,
-     0x28, 0x0d, 0x52, 0x03, 0x69, 0x64, 0x78, 0x12, 0x14, 0x0a, 0x05, 0x76,
-     0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05,
-     0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xae, 0x0a, 0x0a, 0x0c, 0x54, 0x72,
-     0x61, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x48,
-     0x0a, 0x0c, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x5f, 0x62, 0x61,
-     0x74, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70,
-     0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74,
-     0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x42, 0x61,
-     0x74, 0x74, 0x65, 0x72, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52,
-     0x0b, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x42, 0x61, 0x74, 0x74,
-     0x12, 0x42, 0x0a, 0x0b, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x5f,
-     0x63, 0x70, 0x75, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e,
+     0x72, 0x6f, 0x69, 0x64, 0x2f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65,
+     0x5f, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
+     0x0f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72,
+     0x6f, 0x74, 0x6f, 0x73, 0x22, 0xc0, 0x01, 0x0a, 0x12, 0x41, 0x6e, 0x64,
+     0x72, 0x6f, 0x69, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x4c,
+     0x69, 0x73, 0x74, 0x12, 0x47, 0x0a, 0x08, 0x70, 0x61, 0x63, 0x6b, 0x61,
+     0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e,
      0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f,
-     0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x43,
-     0x70, 0x75, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x0a, 0x61, 0x6e,
-     0x64, 0x72, 0x6f, 0x69, 0x64, 0x43, 0x70, 0x75, 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, 0x12, 0x5c, 0x0a, 0x11, 0x61,
-     0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x5f, 0x6d, 0x65, 0x6d, 0x5f, 0x75,
-     0x6e, 0x61, 0x67, 0x67, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30,
-     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, 0x55, 0x6e, 0x61, 0x67, 0x67, 0x72,
-     0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63,
-     0x52, 0x0f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x4d, 0x65, 0x6d,
-     0x55, 0x6e, 0x61, 0x67, 0x67, 0x12, 0x55, 0x0a, 0x14, 0x61, 0x6e, 0x64,
-     0x72, 0x6f, 0x69, 0x64, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65,
-     0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32,
-     0x23, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70,
-     0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69,
-     0x64, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74,
-     0x52, 0x12, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x50, 0x61, 0x63,
-     0x6b, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x42, 0x0a, 0x0b,
-     0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x5f, 0x69, 0x6f, 0x6e, 0x18,
-     0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x65, 0x72, 0x66,
-     0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e,
-     0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x49, 0x6f, 0x6e, 0x4d, 0x65,
-     0x74, 0x72, 0x69, 0x63, 0x52, 0x0a, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69,
-     0x64, 0x49, 0x6f, 0x6e, 0x12, 0x42, 0x0a, 0x0b, 0x61, 0x6e, 0x64, 0x72,
-     0x6f, 0x69, 0x64, 0x5f, 0x6c, 0x6d, 0x6b, 0x18, 0x08, 0x20, 0x01, 0x28,
-     0x0b, 0x32, 0x21, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f,
-     0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72,
-     0x6f, 0x69, 0x64, 0x4c, 0x6d, 0x6b, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63,
-     0x52, 0x0a, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x4c, 0x6d, 0x6b,
-     0x12, 0x4d, 0x0a, 0x10, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x5f,
-     0x70, 0x6f, 0x77, 0x72, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x07, 0x20, 0x01,
-     0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74,
-     0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64,
-     0x72, 0x6f, 0x69, 0x64, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x52, 0x61, 0x69,
-     0x6c, 0x73, 0x52, 0x0f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x50,
-     0x6f, 0x77, 0x72, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x4e, 0x0a, 0x0f, 0x61,
-     0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74,
-     0x75, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70,
-     0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74,
-     0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x53, 0x74,
-     0x61, 0x72, 0x74, 0x75, 0x70, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52,
-     0x0e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x53, 0x74, 0x61, 0x72,
-     0x74, 0x75, 0x70, 0x12, 0x5b, 0x0a, 0x16, 0x68, 0x65, 0x61, 0x70, 0x5f,
-     0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c,
-     0x73, 0x69, 0x74, 0x65, 0x73, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32,
-     0x25, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70,
-     0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x48, 0x65, 0x61, 0x70, 0x50, 0x72,
-     0x6f, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74,
-     0x65, 0x73, 0x52, 0x14, 0x68, 0x65, 0x61, 0x70, 0x50, 0x72, 0x6f, 0x66,
-     0x69, 0x6c, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x73,
-     0x12, 0x45, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x6d, 0x65,
-     0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b,
-     0x32, 0x1e, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e,
-     0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x65,
-     0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x0d, 0x74, 0x72,
-     0x61, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12,
-     0x54, 0x0a, 0x13, 0x75, 0x6e, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x69,
-     0x7a, 0x65, 0x64, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x0f,
-     0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65,
+     0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x50,
+     0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x50,
+     0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x52, 0x08, 0x70, 0x61, 0x63, 0x6b,
+     0x61, 0x67, 0x65, 0x73, 0x1a, 0x61, 0x0a, 0x07, 0x50, 0x61, 0x63, 0x6b,
+     0x61, 0x67, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x61, 0x63, 0x6b, 0x61,
+     0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
+     0x09, 0x52, 0x0b, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x4e, 0x61,
+     0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20,
+     0x01, 0x28, 0x03, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c,
+     0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x64, 0x65,
+     0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x76, 0x65, 0x72, 0x73,
+     0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x64, 0x65, 0x0a, 0x98, 0x04, 0x0a, 0x3b,
+     0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 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, 0x75, 0x6e, 0x6d, 0x61,
+     0x70, 0x70, 0x65, 0x64, 0x5f, 0x6a, 0x61, 0x76, 0x61, 0x5f, 0x73, 0x79,
+     0x6d, 0x62, 0x6f, 0x6c, 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, 0x36, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
+     0x2f, 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, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6d, 0x65,
+     0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+     0x22, 0x8f, 0x03, 0x0a, 0x13, 0x55, 0x6e, 0x6d, 0x61, 0x70, 0x70, 0x65,
+     0x64, 0x4a, 0x61, 0x76, 0x61, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73,
+     0x12, 0x5c, 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f,
+     0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
+     0x0b, 0x32, 0x33, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f,
+     0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x55, 0x6e, 0x6d, 0x61,
+     0x70, 0x70, 0x65, 0x64, 0x4a, 0x61, 0x76, 0x61, 0x53, 0x79, 0x6d, 0x62,
+     0x6f, 0x6c, 0x73, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x53,
+     0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x52, 0x0e, 0x70, 0x72, 0x6f, 0x63,
+     0x65, 0x73, 0x73, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x1a, 0x4e,
+     0x0a, 0x05, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x66,
+     0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20,
+     0x01, 0x28, 0x09, 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4e, 0x61,
+     0x6d, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f,
+     0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20,
+     0x01, 0x28, 0x09, 0x52, 0x0d, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x54, 0x79,
+     0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x1a, 0xc9, 0x01, 0x0a, 0x0e, 0x50,
+     0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c,
+     0x73, 0x12, 0x52, 0x0a, 0x10, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73,
+     0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20,
+     0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74,
+     0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e,
+     0x64, 0x72, 0x6f, 0x69, 0x64, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73,
+     0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x0f, 0x70, 0x72,
+     0x6f, 0x63, 0x65, 0x73, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
+     0x61, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61,
+     0x6d, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79,
+     0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x40, 0x0a, 0x05, 0x66, 0x69,
+     0x65, 0x6c, 0x64, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e,
+     0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f,
+     0x74, 0x6f, 0x73, 0x2e, 0x55, 0x6e, 0x6d, 0x61, 0x70, 0x70, 0x65, 0x64,
+     0x4a, 0x61, 0x76, 0x61, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x2e,
+     0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64,
+     0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x0a, 0xfc, 0x01, 0x0a, 0x39, 0x70,
+     0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 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, 0x75, 0x6e, 0x73, 0x79, 0x6d,
+     0x62, 0x6f, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x66, 0x72, 0x61, 0x6d,
+     0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x70, 0x65,
+     0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+     0x73, 0x22, 0xad, 0x01, 0x0a, 0x12, 0x55, 0x6e, 0x73, 0x79, 0x6d, 0x62,
+     0x6f, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73,
+     0x12, 0x41, 0x0a, 0x06, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01,
+     0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65,
      0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x55,
      0x6e, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x46,
-     0x72, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x12, 0x75, 0x6e, 0x73, 0x79, 0x6d,
-     0x62, 0x6f, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x46, 0x72, 0x61, 0x6d, 0x65,
-     0x73, 0x12, 0x46, 0x0a, 0x0f, 0x6a, 0x61, 0x76, 0x61, 0x5f, 0x68, 0x65,
-     0x61, 0x70, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x11, 0x20, 0x01,
-     0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74,
+     0x72, 0x61, 0x6d, 0x65, 0x73, 0x2e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x52,
+     0x06, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x1a, 0x54, 0x0a, 0x05, 0x46,
+     0x72, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x75,
+     0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x6f,
+     0x64, 0x75, 0x6c, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x62, 0x75, 0x69, 0x6c,
+     0x64, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
+     0x62, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x61,
+     0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03,
+     0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x0a, 0xf8, 0x03,
+     0x0a, 0x35, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 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, 0x6a, 0x61,
+     0x76, 0x61, 0x5f, 0x68, 0x65, 0x61, 0x70, 0x5f, 0x73, 0x74, 0x61, 0x74,
+     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, 0x36, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 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, 0x70, 0x72,
+     0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61,
+     0x74, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf5, 0x02, 0x0a,
+     0x0d, 0x4a, 0x61, 0x76, 0x61, 0x48, 0x65, 0x61, 0x70, 0x53, 0x74, 0x61,
+     0x74, 0x73, 0x12, 0x53, 0x0a, 0x0e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e,
+     0x63, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03,
+     0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74,
      0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x4a, 0x61, 0x76,
-     0x61, 0x48, 0x65, 0x61, 0x70, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x0d,
-     0x6a, 0x61, 0x76, 0x61, 0x48, 0x65, 0x61, 0x70, 0x53, 0x74, 0x61, 0x74,
-     0x73, 0x12, 0x55, 0x0a, 0x12, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
-     0x5f, 0x6c, 0x6d, 0x6b, 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18,
-     0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x65, 0x72, 0x66,
+     0x61, 0x48, 0x65, 0x61, 0x70, 0x53, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x49,
+     0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73,
+     0x52, 0x0d, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74,
+     0x61, 0x74, 0x73, 0x1a, 0x65, 0x0a, 0x06, 0x53, 0x61, 0x6d, 0x70, 0x6c,
+     0x65, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28,
+     0x03, 0x52, 0x02, 0x74, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x68, 0x65, 0x61,
+     0x70, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03,
+     0x52, 0x08, 0x68, 0x65, 0x61, 0x70, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x2e,
+     0x0a, 0x13, 0x72, 0x65, 0x61, 0x63, 0x68, 0x61, 0x62, 0x6c, 0x65, 0x5f,
+     0x68, 0x65, 0x61, 0x70, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20,
+     0x01, 0x28, 0x03, 0x52, 0x11, 0x72, 0x65, 0x61, 0x63, 0x68, 0x61, 0x62,
+     0x6c, 0x65, 0x48, 0x65, 0x61, 0x70, 0x53, 0x69, 0x7a, 0x65, 0x1a, 0xa7,
+     0x01, 0x0a, 0x0d, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53,
+     0x74, 0x61, 0x74, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x70, 0x69, 0x64,
+     0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x75, 0x70, 0x69, 0x64,
+     0x12, 0x41, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18,
+     0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x65, 0x72, 0x66,
      0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e,
-     0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x4c, 0x6d, 0x6b, 0x52, 0x65,
-     0x61, 0x73, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x10,
-     0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x4c, 0x6d, 0x6b, 0x52, 0x65,
-     0x61, 0x73, 0x6f, 0x6e, 0x12, 0x58, 0x0a, 0x15, 0x75, 0x6e, 0x6d, 0x61,
-     0x70, 0x70, 0x65, 0x64, 0x5f, 0x6a, 0x61, 0x76, 0x61, 0x5f, 0x73, 0x79,
-     0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32,
-     0x24, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70,
-     0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x55, 0x6e, 0x6d, 0x61, 0x70, 0x70,
-     0x65, 0x64, 0x4a, 0x61, 0x76, 0x61, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c,
-     0x73, 0x52, 0x13, 0x75, 0x6e, 0x6d, 0x61, 0x70, 0x70, 0x65, 0x64, 0x4a,
-     0x61, 0x76, 0x61, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x12, 0x52,
-     0x0a, 0x13, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x5f, 0x68, 0x77,
-     0x75, 0x69, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x18, 0x14, 0x20,
-     0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74,
+     0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x50, 0x72, 0x6f, 0x63, 0x65,
+     0x73, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x07,
+     0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x3f, 0x0a, 0x07, 0x73,
+     0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b,
+     0x32, 0x25, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e,
+     0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x4a, 0x61, 0x76, 0x61, 0x48,
+     0x65, 0x61, 0x70, 0x53, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x53, 0x61, 0x6d,
+     0x70, 0x6c, 0x65, 0x52, 0x07, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73,
+     0x0a, 0xbb, 0x14, 0x0a, 0x25, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f,
+     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,
+     0x31, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 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, 0x62, 0x61, 0x74,
+     0x74, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f,
+     0x74, 0x6f, 0x1a, 0x30, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 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,
+     0x63, 0x70, 0x75, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70,
+     0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x30, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
+     0x2f, 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, 0x1a, 0x36, 0x70, 0x72, 0x6f, 0x74,
+     0x6f, 0x73, 0x2f, 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, 0x75, 0x6e, 0x61, 0x67,
+     0x67, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f,
+     0x74, 0x6f, 0x1a, 0x30, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 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,
+     0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70,
+     0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x30, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
+     0x2f, 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, 0x6c, 0x6d, 0x6b, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63,
+     0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x37, 0x70, 0x72, 0x6f, 0x74,
+     0x6f, 0x73, 0x2f, 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, 0x6c, 0x6d, 0x6b, 0x5f, 0x72, 0x65, 0x61, 0x73,
+     0x6f, 0x6e, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72,
+     0x6f, 0x74, 0x6f, 0x1a, 0x35, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f,
+     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, 0x70, 0x6f, 0x77, 0x72, 0x61, 0x69, 0x6c, 0x73, 0x5f, 0x6d, 0x65,
+     0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x34,
+     0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 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, 0x73, 0x74, 0x61, 0x72,
+     0x74, 0x75, 0x70, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70,
+     0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x3c, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
+     0x2f, 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, 0x68, 0x65, 0x61, 0x70, 0x5f, 0x70, 0x72, 0x6f, 0x66, 0x69,
+     0x6c, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x73,
+     0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x31, 0x70, 0x72, 0x6f, 0x74,
+     0x6f, 0x73, 0x2f, 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, 0x68, 0x77, 0x75, 0x69, 0x5f, 0x6d, 0x65, 0x74,
+     0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x32, 0x70,
+     0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 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, 0x70, 0x61, 0x63, 0x6b, 0x61,
+     0x67, 0x65, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+     0x6f, 0x1a, 0x3b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 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, 0x75,
+     0x6e, 0x6d, 0x61, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x6a, 0x61, 0x76, 0x61,
+     0x5f, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x2e, 0x70, 0x72, 0x6f,
+     0x74, 0x6f, 0x1a, 0x39, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 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,
+     0x75, 0x6e, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x69, 0x7a, 0x65, 0x64,
+     0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+     0x6f, 0x1a, 0x35, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 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, 0x6a,
+     0x61, 0x76, 0x61, 0x5f, 0x68, 0x65, 0x61, 0x70, 0x5f, 0x73, 0x74, 0x61,
+     0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa2, 0x03, 0x0a,
+     0x0d, 0x54, 0x72, 0x61, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61,
+     0x74, 0x61, 0x12, 0x50, 0x0a, 0x11, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f,
+     0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x18,
+     0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x70, 0x65, 0x72, 0x66,
+     0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e,
+     0x54, 0x72, 0x61, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
+     0x61, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0f, 0x65, 0x72, 0x72,
+     0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79,
+     0x12, 0x2a, 0x0a, 0x11, 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x64, 0x75,
+     0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x73, 0x18, 0x02, 0x20,
+     0x01, 0x28, 0x03, 0x52, 0x0f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x44, 0x75,
+     0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x73, 0x12, 0x1d, 0x0a, 0x0a,
+     0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x18, 0x03,
+     0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x72, 0x61, 0x63, 0x65, 0x55,
+     0x75, 0x69, 0x64, 0x12, 0x3a, 0x0a, 0x19, 0x61, 0x6e, 0x64, 0x72, 0x6f,
+     0x69, 0x64, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x66, 0x69, 0x6e,
+     0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01,
+     0x28, 0x09, 0x52, 0x17, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x42,
+     0x75, 0x69, 0x6c, 0x64, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72,
+     0x69, 0x6e, 0x74, 0x12, 0x49, 0x0a, 0x21, 0x73, 0x74, 0x61, 0x74, 0x73,
+     0x64, 0x5f, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x67,
+     0x5f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,
+     0x6e, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x1e,
+     0x73, 0x74, 0x61, 0x74, 0x73, 0x64, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65,
+     0x72, 0x69, 0x6e, 0x67, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70,
+     0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x10, 0x74, 0x72,
+     0x61, 0x63, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x62, 0x79, 0x74,
+     0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x74, 0x72,
+     0x61, 0x63, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73,
+     0x1a, 0x43, 0x0a, 0x05, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x12, 0x0a,
+     0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+     0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x69, 0x64, 0x78,
+     0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x69, 0x64, 0x78, 0x12,
+     0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01,
+     0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xae, 0x0a,
+     0x0a, 0x0c, 0x54, 0x72, 0x61, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69,
+     0x63, 0x73, 0x12, 0x48, 0x0a, 0x0c, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69,
+     0x64, 0x5f, 0x62, 0x61, 0x74, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b,
+     0x32, 0x25, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e,
+     0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f,
+     0x69, 0x64, 0x42, 0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x4d, 0x65, 0x74,
+     0x72, 0x69, 0x63, 0x52, 0x0b, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
+     0x42, 0x61, 0x74, 0x74, 0x12, 0x42, 0x0a, 0x0b, 0x61, 0x6e, 0x64, 0x72,
+     0x6f, 0x69, 0x64, 0x5f, 0x63, 0x70, 0x75, 0x18, 0x06, 0x20, 0x01, 0x28,
+     0x0b, 0x32, 0x21, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f,
+     0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72,
+     0x6f, 0x69, 0x64, 0x43, 0x70, 0x75, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63,
+     0x52, 0x0a, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x43, 0x70, 0x75,
+     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, 0x12,
+     0x5c, 0x0a, 0x11, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x5f, 0x6d,
+     0x65, 0x6d, 0x5f, 0x75, 0x6e, 0x61, 0x67, 0x67, 0x18, 0x0b, 0x20, 0x01,
+     0x28, 0x0b, 0x32, 0x30, 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, 0x55, 0x6e,
+     0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x4d, 0x65,
+     0x74, 0x72, 0x69, 0x63, 0x52, 0x0f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69,
+     0x64, 0x4d, 0x65, 0x6d, 0x55, 0x6e, 0x61, 0x67, 0x67, 0x12, 0x55, 0x0a,
+     0x14, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x5f, 0x70, 0x61, 0x63,
+     0x6b, 0x61, 0x67, 0x65, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x0c, 0x20,
+     0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74,
      0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e,
-     0x64, 0x72, 0x6f, 0x69, 0x64, 0x48, 0x77, 0x75, 0x69, 0x4d, 0x65, 0x74,
-     0x72, 0x69, 0x63, 0x52, 0x11, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
-     0x48, 0x77, 0x75, 0x69, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2a, 0x06,
-     0x08, 0xc2, 0x03, 0x10, 0xf4, 0x03, 0x2a, 0x06, 0x08, 0xf4, 0x03, 0x10,
-     0xe9, 0x07, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x4a, 0x04, 0x08, 0x0a,
-     0x10, 0x0b, 0x4a, 0x04, 0x08, 0x0d, 0x10, 0x0e, 0x4a, 0x04, 0x08, 0x0e,
-     0x10, 0x0f}};
+     0x64, 0x72, 0x6f, 0x69, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65,
+     0x4c, 0x69, 0x73, 0x74, 0x52, 0x12, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69,
+     0x64, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74,
+     0x12, 0x42, 0x0a, 0x0b, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x5f,
+     0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e,
+     0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f,
+     0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x49,
+     0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x0a, 0x61, 0x6e,
+     0x64, 0x72, 0x6f, 0x69, 0x64, 0x49, 0x6f, 0x6e, 0x12, 0x42, 0x0a, 0x0b,
+     0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x5f, 0x6c, 0x6d, 0x6b, 0x18,
+     0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x65, 0x72, 0x66,
+     0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e,
+     0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x4c, 0x6d, 0x6b, 0x4d, 0x65,
+     0x74, 0x72, 0x69, 0x63, 0x52, 0x0a, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69,
+     0x64, 0x4c, 0x6d, 0x6b, 0x12, 0x4d, 0x0a, 0x10, 0x61, 0x6e, 0x64, 0x72,
+     0x6f, 0x69, 0x64, 0x5f, 0x70, 0x6f, 0x77, 0x72, 0x61, 0x69, 0x6c, 0x73,
+     0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x65, 0x72,
+     0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
+     0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x50, 0x6f, 0x77, 0x65,
+     0x72, 0x52, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x0f, 0x61, 0x6e, 0x64, 0x72,
+     0x6f, 0x69, 0x64, 0x50, 0x6f, 0x77, 0x72, 0x61, 0x69, 0x6c, 0x73, 0x12,
+     0x4e, 0x0a, 0x0f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x5f, 0x73,
+     0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
+     0x32, 0x25, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e,
+     0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f,
+     0x69, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x4d, 0x65, 0x74,
+     0x72, 0x69, 0x63, 0x52, 0x0e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
+     0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x5b, 0x0a, 0x16, 0x68,
+     0x65, 0x61, 0x70, 0x5f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f,
+     0x63, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x73, 0x18, 0x10, 0x20,
+     0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74,
+     0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x48, 0x65,
+     0x61, 0x70, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x61, 0x6c,
+     0x6c, 0x73, 0x69, 0x74, 0x65, 0x73, 0x52, 0x14, 0x68, 0x65, 0x61, 0x70,
+     0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x73,
+     0x69, 0x74, 0x65, 0x73, 0x12, 0x45, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x63,
+     0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03,
+     0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65,
+     0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x54,
+     0x72, 0x61, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
+     0x52, 0x0d, 0x74, 0x72, 0x61, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64,
+     0x61, 0x74, 0x61, 0x12, 0x54, 0x0a, 0x13, 0x75, 0x6e, 0x73, 0x79, 0x6d,
+     0x62, 0x6f, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x66, 0x72, 0x61, 0x6d,
+     0x65, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x70,
+     0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+     0x6f, 0x73, 0x2e, 0x55, 0x6e, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x69,
+     0x7a, 0x65, 0x64, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x12, 0x75,
+     0x6e, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x46,
+     0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x46, 0x0a, 0x0f, 0x6a, 0x61, 0x76,
+     0x61, 0x5f, 0x68, 0x65, 0x61, 0x70, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73,
+     0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x65, 0x72,
+     0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
+     0x2e, 0x4a, 0x61, 0x76, 0x61, 0x48, 0x65, 0x61, 0x70, 0x53, 0x74, 0x61,
+     0x74, 0x73, 0x52, 0x0d, 0x6a, 0x61, 0x76, 0x61, 0x48, 0x65, 0x61, 0x70,
+     0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x55, 0x0a, 0x12, 0x61, 0x6e, 0x64,
+     0x72, 0x6f, 0x69, 0x64, 0x5f, 0x6c, 0x6d, 0x6b, 0x5f, 0x72, 0x65, 0x61,
+     0x73, 0x6f, 0x6e, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e,
+     0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f,
+     0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x4c,
+     0x6d, 0x6b, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x72,
+     0x69, 0x63, 0x52, 0x10, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x4c,
+     0x6d, 0x6b, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x58, 0x0a, 0x15,
+     0x75, 0x6e, 0x6d, 0x61, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x6a, 0x61, 0x76,
+     0x61, 0x5f, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x18, 0x13, 0x20,
+     0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74,
+     0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x55, 0x6e,
+     0x6d, 0x61, 0x70, 0x70, 0x65, 0x64, 0x4a, 0x61, 0x76, 0x61, 0x53, 0x79,
+     0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x52, 0x13, 0x75, 0x6e, 0x6d, 0x61, 0x70,
+     0x70, 0x65, 0x64, 0x4a, 0x61, 0x76, 0x61, 0x53, 0x79, 0x6d, 0x62, 0x6f,
+     0x6c, 0x73, 0x12, 0x52, 0x0a, 0x13, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69,
+     0x64, 0x5f, 0x68, 0x77, 0x75, 0x69, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69,
+     0x63, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x65,
+     0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+     0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x48, 0x77, 0x75,
+     0x69, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x11, 0x61, 0x6e, 0x64,
+     0x72, 0x6f, 0x69, 0x64, 0x48, 0x77, 0x75, 0x69, 0x4d, 0x65, 0x74, 0x72,
+     0x69, 0x63, 0x2a, 0x06, 0x08, 0xc2, 0x03, 0x10, 0xf4, 0x03, 0x2a, 0x06,
+     0x08, 0xf4, 0x03, 0x10, 0xe9, 0x07, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05,
+     0x4a, 0x04, 0x08, 0x0a, 0x10, 0x0b, 0x4a, 0x04, 0x08, 0x0d, 0x10, 0x0e,
+     0x4a, 0x04, 0x08, 0x0e, 0x10, 0x0f}};
 
 }  // namespace perfetto
 
diff --git a/src/trace_processor/storage/stats.h b/src/trace_processor/storage/stats.h
index 5c54c47..d2a562c 100644
--- a/src/trace_processor/storage/stats.h
+++ b/src/trace_processor/storage/stats.h
@@ -132,7 +132,8 @@
   F(compact_sched_waking_skipped,             kSingle,  kInfo,     kAnalysis), \
   F(empty_chrome_metadata,                    kSingle,  kError,    kTrace),    \
   F(perf_cpu_lost_records,                    kIndexed, kDataLoss, kTrace),    \
-  F(ninja_parse_errors,                       kSingle,  kError,    kTrace)
+  F(ninja_parse_errors,                       kSingle,  kError,    kTrace),    \
+  F(perf_samples_skipped,                     kSingle,  kInfo,     kTrace)
 // clang-format on
 
 enum Type {
diff --git a/src/trace_processor/tables/profiler_tables.h b/src/trace_processor/tables/profiler_tables.h
index 1fe5d9a..e96772b 100644
--- a/src/trace_processor/tables/profiler_tables.h
+++ b/src/trace_processor/tables/profiler_tables.h
@@ -91,6 +91,7 @@
   C(int64_t, ts, Column::Flag::kSorted | Column::Flag::kHidden)           \
   C(uint32_t, upid, Column::Flag::kHidden)                                \
   C(StringPool::Id, profile_type, Column::Flag::kHidden)                  \
+  C(StringPool::Id, focus_str, Column::Flag::kHidden)                     \
   C(uint32_t, depth)                                                      \
   C(StringPool::Id, name)                                                 \
   C(StringPool::Id, map_name)                                             \
diff --git a/src/traced/probes/ftrace/BUILD.gn b/src/traced/probes/ftrace/BUILD.gn
index 5d9cd70..0ffd645 100644
--- a/src/traced/probes/ftrace/BUILD.gn
+++ b/src/traced/probes/ftrace/BUILD.gn
@@ -60,6 +60,7 @@
   sources = [
     "cpu_reader_unittest.cc",
     "cpu_stats_parser_unittest.cc",
+    "discover_vendor_tracepoints_unittest.cc",
     "event_info_unittest.cc",
     "format_parser_unittest.cc",
     "ftrace_config_muxer_unittest.cc",
@@ -122,6 +123,8 @@
     "cpu_reader.h",
     "cpu_stats_parser.cc",
     "cpu_stats_parser.h",
+    "discover_vendor_tracepoints.cc",
+    "discover_vendor_tracepoints.h",
     "event_info.cc",
     "event_info.h",
     "event_info_constants.cc",
diff --git a/src/traced/probes/ftrace/atrace_hal_wrapper.cc b/src/traced/probes/ftrace/atrace_hal_wrapper.cc
index 11cdd89..78f4114 100644
--- a/src/traced/probes/ftrace/atrace_hal_wrapper.cc
+++ b/src/traced/probes/ftrace/atrace_hal_wrapper.cc
@@ -13,8 +13,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 #include "src/traced/probes/ftrace/atrace_hal_wrapper.h"
 
+#include "perfetto/base/build_config.h"
 #include "src/android_internal/atrace_hal.h"
 #include "src/android_internal/lazy_library_loader.h"
 
@@ -25,38 +27,83 @@
 }
 
 struct AtraceHalWrapper::DynamicLibLoader {
-  PERFETTO_LAZY_LOAD(android_internal::GetCategories, get_categories_);
+  PERFETTO_LAZY_LOAD(android_internal::ForgetService, forget_service_);
+  PERFETTO_LAZY_LOAD(android_internal::ListCategories, list_categories_);
+  PERFETTO_LAZY_LOAD(android_internal::EnableCategories, enable_categories_);
+  PERFETTO_LAZY_LOAD(android_internal::DisableAllCategories,
+                     disable_all_categories_);
 
-  std::vector<android_internal::TracingVendorCategory> GetCategories() {
-    if (!get_categories_)
-      return std::vector<android_internal::TracingVendorCategory>();
+  std::vector<std::string> ListCategories() {
+    std::vector<std::string> results;
+    if (!list_categories_)
+      return results;
 
     std::vector<android_internal::TracingVendorCategory> categories(
         kMaxNumCategories);
     size_t num_cat = categories.size();
-    get_categories_(&categories[0], &num_cat);
+    bool success = list_categories_(&categories[0], &num_cat);
+    if (!success)
+      return results;
     categories.resize(num_cat);
-    return categories;
+
+    for (const auto& category : categories) {
+      results.push_back(category.name);
+    }
+
+    return results;
+  }
+
+  bool EnableCategories(const std::vector<std::string>& categories) {
+    if (!enable_categories_)
+      return false;
+    std::vector<const char*> args;
+    for (const std::string& category : categories) {
+      args.push_back(category.c_str());
+    }
+    return enable_categories_(&args[0], args.size());
+  }
+
+  bool DisableAllCategories() {
+    if (!disable_all_categories_)
+      return false;
+    return disable_all_categories_();
+  }
+
+  void ForgetService() {
+    if (!forget_service_)
+      return;
+    forget_service_();
   }
 };
 
 AtraceHalWrapper::AtraceHalWrapper() {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
   lib_.reset(new DynamicLibLoader());
+#endif
 }
 
-AtraceHalWrapper::~AtraceHalWrapper() = default;
+AtraceHalWrapper::~AtraceHalWrapper() {
+  if (lib_)
+    lib_->ForgetService();
+}
 
-std::vector<AtraceHalWrapper::TracingVendorCategory>
-AtraceHalWrapper::GetAvailableCategories() {
-  auto details = lib_->GetCategories();
-  std::vector<AtraceHalWrapper::TracingVendorCategory> result;
-  for (size_t i = 0; i < details.size(); i++) {
-    AtraceHalWrapper::TracingVendorCategory cat;
-    cat.name = details[i].name;
-    cat.description = details[i].description;
-    result.emplace_back(cat);
-  }
-  return result;
+std::vector<std::string> AtraceHalWrapper::ListCategories() {
+  if (!lib_)
+    return {};
+  return lib_->ListCategories();
+}
+
+bool AtraceHalWrapper::EnableCategories(
+    const std::vector<std::string>& categories) {
+  if (!lib_)
+    return true;
+  return lib_->EnableCategories(categories);
+}
+
+bool AtraceHalWrapper::DisableAllCategories() {
+  if (!lib_)
+    return true;
+  return lib_->DisableAllCategories();
 }
 
 }  // namespace perfetto
diff --git a/src/traced/probes/ftrace/atrace_hal_wrapper.h b/src/traced/probes/ftrace/atrace_hal_wrapper.h
index db215ae..6f95fdf 100644
--- a/src/traced/probes/ftrace/atrace_hal_wrapper.h
+++ b/src/traced/probes/ftrace/atrace_hal_wrapper.h
@@ -28,17 +28,11 @@
 class AtraceHalWrapper {
  public:
   AtraceHalWrapper();
-  ~AtraceHalWrapper();
+  virtual ~AtraceHalWrapper();
 
-  struct TracingVendorCategory {
-    // The name identifying the category.
-    std::string name;
-
-    // A longer description of the category.
-    std::string description;
-  };
-
-  std::vector<TracingVendorCategory> GetAvailableCategories();
+  virtual std::vector<std::string> ListCategories();
+  virtual bool EnableCategories(const std::vector<std::string>& categories);
+  virtual bool DisableAllCategories();
 
  private:
   struct DynamicLibLoader;
diff --git a/src/traced/probes/ftrace/discover_vendor_tracepoints.cc b/src/traced/probes/ftrace/discover_vendor_tracepoints.cc
new file mode 100644
index 0000000..68625c0
--- /dev/null
+++ b/src/traced/probes/ftrace/discover_vendor_tracepoints.cc
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/traced/probes/ftrace/discover_vendor_tracepoints.h"
+
+#include "perfetto/ext/base/string_splitter.h"
+#include "perfetto/ext/base/string_utils.h"
+#include "src/traced/probes/ftrace/atrace_wrapper.h"
+
+namespace perfetto {
+namespace vendor_tracepoints {
+
+std::vector<GroupAndName> DiscoverTracepoints(AtraceHalWrapper* hal,
+                                              FtraceProcfs* ftrace,
+                                              const std::string& category) {
+  ftrace->DisableAllEvents();
+  hal->EnableCategories({category});
+
+  std::vector<GroupAndName> events;
+  for (const std::string& group_name : ftrace->ReadEnabledEvents()) {
+    size_t pos = group_name.find('/');
+    PERFETTO_CHECK(pos != std::string::npos);
+    events.push_back(
+        GroupAndName(group_name.substr(0, pos), group_name.substr(pos + 1)));
+  }
+
+  hal->DisableAllCategories();
+  ftrace->DisableAllEvents();
+  return events;
+}
+
+std::map<std::string, std::vector<GroupAndName>> DiscoverVendorTracepoints(
+    AtraceHalWrapper* hal,
+    FtraceProcfs* ftrace) {
+  std::map<std::string, std::vector<GroupAndName>> results;
+  for (const auto& category : hal->ListCategories()) {
+    results.emplace(category, DiscoverTracepoints(hal, ftrace, category));
+  }
+  return results;
+}
+
+}  // namespace vendor_tracepoints
+}  // namespace perfetto
diff --git a/src/traced/probes/ftrace/discover_vendor_tracepoints.h b/src/traced/probes/ftrace/discover_vendor_tracepoints.h
new file mode 100644
index 0000000..f5d791b
--- /dev/null
+++ b/src/traced/probes/ftrace/discover_vendor_tracepoints.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACED_PROBES_FTRACE_DISCOVER_VENDOR_TRACEPOINTS_H_
+#define SRC_TRACED_PROBES_FTRACE_DISCOVER_VENDOR_TRACEPOINTS_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "src/traced/probes/ftrace/atrace_hal_wrapper.h"
+#include "src/traced/probes/ftrace/ftrace_procfs.h"
+#include "src/traced/probes/ftrace/proto_translation_table.h"
+
+namespace perfetto {
+namespace vendor_tracepoints {
+
+// Exposed for testing.
+std::vector<GroupAndName> DiscoverTracepoints(AtraceHalWrapper* hal,
+                                              FtraceProcfs* ftrace,
+                                              const std::string& category);
+
+// Returns a map from vendor category to events we should enable
+std::map<std::string, std::vector<GroupAndName>> DiscoverVendorTracepoints(
+    AtraceHalWrapper* hal,
+    FtraceProcfs* ftrace);
+
+}  // namespace vendor_tracepoints
+}  // namespace perfetto
+
+#endif  // SRC_TRACED_PROBES_FTRACE_DISCOVER_VENDOR_TRACEPOINTS_H_
diff --git a/src/traced/probes/ftrace/discover_vendor_tracepoints_unittest.cc b/src/traced/probes/ftrace/discover_vendor_tracepoints_unittest.cc
new file mode 100644
index 0000000..a859c15
--- /dev/null
+++ b/src/traced/probes/ftrace/discover_vendor_tracepoints_unittest.cc
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/traced/probes/ftrace/discover_vendor_tracepoints.h"
+
+#include <vector>
+
+#include "test/gtest_and_gmock.h"
+
+#include "src/traced/probes/ftrace/atrace_hal_wrapper.h"
+#include "src/traced/probes/ftrace/atrace_wrapper.h"
+#include "src/traced/probes/ftrace/ftrace_procfs.h"
+
+using testing::_;
+using testing::AnyNumber;
+using testing::ElementsAre;
+using testing::NiceMock;
+using testing::Return;
+using testing::Sequence;
+
+namespace perfetto {
+namespace vendor_tracepoints {
+namespace {
+
+class MockHal : public AtraceHalWrapper {
+ public:
+  MockHal() : AtraceHalWrapper() {}
+  MOCK_METHOD0(ListCategories, std::vector<std::string>());
+  MOCK_METHOD1(EnableCategories, bool(const std::vector<std::string>&));
+  MOCK_METHOD0(DisableAllCategories, bool());
+};
+
+class MockFtraceProcfs : public FtraceProcfs {
+ public:
+  MockFtraceProcfs() : FtraceProcfs("/root/") {
+    ON_CALL(*this, NumberOfCpus()).WillByDefault(Return(1));
+    ON_CALL(*this, WriteToFile(_, _)).WillByDefault(Return(true));
+    ON_CALL(*this, ClearFile(_)).WillByDefault(Return(true));
+    EXPECT_CALL(*this, NumberOfCpus()).Times(AnyNumber());
+  }
+
+  MOCK_METHOD2(WriteToFile,
+               bool(const std::string& path, const std::string& str));
+  MOCK_METHOD2(AppendToFile,
+               bool(const std::string& path, const std::string& str));
+  MOCK_METHOD1(ReadOneCharFromFile, char(const std::string& path));
+  MOCK_METHOD1(ClearFile, bool(const std::string& path));
+  MOCK_CONST_METHOD1(ReadFileIntoString, std::string(const std::string& path));
+  MOCK_METHOD0(ReadEnabledEvents, std::vector<std::string>());
+  MOCK_CONST_METHOD0(NumberOfCpus, size_t());
+  MOCK_CONST_METHOD1(GetEventNamesForGroup,
+                     const std::set<std::string>(const std::string& path));
+};
+
+TEST(DiscoverVendorTracepointsTest, DiscoverTracepointsTest) {
+  MockHal hal;
+  MockFtraceProcfs ftrace;
+  Sequence s;
+
+  EXPECT_CALL(ftrace, WriteToFile("/root/events/enable", "0"))
+      .InSequence(s)
+      .WillOnce(Return(true));
+  EXPECT_CALL(hal, EnableCategories(ElementsAre("gfx")))
+      .InSequence(s)
+      .WillOnce(Return(true));
+  EXPECT_CALL(ftrace, ReadEnabledEvents())
+      .InSequence(s)
+      .WillOnce(Return(std::vector<std::string>({"foo/bar", "a/b"})));
+  EXPECT_CALL(hal, DisableAllCategories()).InSequence(s).WillOnce(Return(true));
+  EXPECT_CALL(ftrace, WriteToFile("/root/events/enable", "0"))
+      .InSequence(s)
+      .WillOnce(Return(true));
+
+  EXPECT_THAT(DiscoverTracepoints(&hal, &ftrace, "gfx"),
+              ElementsAre(GroupAndName("foo", "bar"), GroupAndName("a", "b")));
+}
+
+}  // namespace
+}  // namespace vendor_tracepoints
+}  // namespace perfetto
diff --git a/src/traced/probes/ftrace/format_parser.cc b/src/traced/probes/ftrace/format_parser.cc
index d4e119f..2be687d 100644
--- a/src/traced/probes/ftrace/format_parser.cc
+++ b/src/traced/probes/ftrace/format_parser.cc
@@ -72,8 +72,9 @@
       if (IsCommonFieldName(GetNameFromTypeAndName(type_and_name))) {
         if (common_fields)
           common_fields->push_back(field);
-      } else if (fields)
+      } else if (fields) {
         fields->push_back(field);
+      }
       continue;
     }
 
diff --git a/src/traced/probes/ftrace/ftrace_config_muxer.cc b/src/traced/probes/ftrace/ftrace_config_muxer.cc
index f3917dc..fa53c36 100644
--- a/src/traced/probes/ftrace/ftrace_config_muxer.cc
+++ b/src/traced/probes/ftrace/ftrace_config_muxer.cc
@@ -152,6 +152,7 @@
         events.insert(GroupAndName("mdss", "mdp_sspp_change"));
         events.insert(GroupAndName("mdss", "mdp_sspp_set"));
         AddEventGroup(table, "mali_systrace", &events);
+
         AddEventGroup(table, "sde", &events);
         events.insert(GroupAndName("sde", "tracing_mark_write"));
         events.insert(GroupAndName("sde", "sde_perf_update_bus"));
@@ -417,9 +418,15 @@
   return pages;
 }
 
-FtraceConfigMuxer::FtraceConfigMuxer(FtraceProcfs* ftrace,
-                                     ProtoTranslationTable* table)
-    : ftrace_(ftrace), table_(table), current_state_(), ds_configs_() {}
+FtraceConfigMuxer::FtraceConfigMuxer(
+    FtraceProcfs* ftrace,
+    ProtoTranslationTable* table,
+    std::map<std::string, std::vector<GroupAndName>> vendor_events)
+    : ftrace_(ftrace),
+      table_(table),
+      current_state_(),
+      ds_configs_(),
+      vendor_events_(vendor_events) {}
 FtraceConfigMuxer::~FtraceConfigMuxer() = default;
 
 FtraceConfigId FtraceConfigMuxer::SetupConfig(const FtraceConfig& request) {
@@ -448,6 +455,18 @@
 
   std::set<GroupAndName> events = GetFtraceEvents(request, table_);
 
+  // Vendors can provide a set of extra ftrace categories to be enabled when a
+  // specific atrace category is used (e.g. "gfx" -> ["my_hw/my_custom_event",
+  // "my_hw/my_special_gpu"]). Merge them with the hard coded events for each
+  // categories.
+  for (const std::string& category : request.atrace_categories()) {
+    if (vendor_events_.count(category)) {
+      for (const GroupAndName& event : vendor_events_[category]) {
+        events.insert(event);
+      }
+    }
+  }
+
   if (RequiresAtrace(request))
     UpdateAtrace(request);
 
diff --git a/src/traced/probes/ftrace/ftrace_config_muxer.h b/src/traced/probes/ftrace/ftrace_config_muxer.h
index 71100e9..dc758ea 100644
--- a/src/traced/probes/ftrace/ftrace_config_muxer.h
+++ b/src/traced/probes/ftrace/ftrace_config_muxer.h
@@ -68,7 +68,10 @@
  public:
   // The FtraceConfigMuxer and ProtoTranslationTable
   // should outlive this instance.
-  FtraceConfigMuxer(FtraceProcfs* ftrace, ProtoTranslationTable* table);
+  FtraceConfigMuxer(
+      FtraceProcfs* ftrace,
+      ProtoTranslationTable* table,
+      std::map<std::string, std::vector<GroupAndName>> vendor_events);
   virtual ~FtraceConfigMuxer();
 
   // Ask FtraceConfigMuxer to adjust ftrace procfs settings to
@@ -153,6 +156,8 @@
   // sizes and events, but don't enable ftrace (i.e. tracing_on).
   std::map<FtraceConfigId, FtraceDataSourceConfig> ds_configs_;
 
+  std::map<std::string, std::vector<GroupAndName>> vendor_events_;
+
   // Subset of |ds_configs_| that are currently active. At any time ftrace is
   // enabled iff |active_configs_| is not empty.
   std::set<FtraceConfigId> active_configs_;
diff --git a/src/traced/probes/ftrace/ftrace_config_muxer_unittest.cc b/src/traced/probes/ftrace/ftrace_config_muxer_unittest.cc
index 0b069c2..d9b5911 100644
--- a/src/traced/probes/ftrace/ftrace_config_muxer_unittest.cc
+++ b/src/traced/probes/ftrace/ftrace_config_muxer_unittest.cc
@@ -197,7 +197,7 @@
 
   FtraceConfig config = CreateFtraceConfig({"power/cpu_frequency"});
 
-  FtraceConfigMuxer model(&ftrace, mock_table.get());
+  FtraceConfigMuxer model(&ftrace, mock_table.get(), {});
 
   ON_CALL(ftrace, ReadFileIntoString("/root/trace_clock"))
       .WillByDefault(Return("[local] global boot"));
@@ -244,7 +244,7 @@
 
   FtraceConfig config = CreateFtraceConfig({"group_one/foo", "group_two/foo"});
 
-  FtraceConfigMuxer model(&ftrace, mock_table.get());
+  FtraceConfigMuxer model(&ftrace, mock_table.get(), {});
 
   static constexpr int kEventId1 = 1;
   Event event1;
@@ -298,7 +298,7 @@
   EXPECT_CALL(ftrace,
               WriteToFile("/root/events/sched/sched_new_event/enable", "1"));
 
-  FtraceConfigMuxer model(&ftrace, mock_table.get());
+  FtraceConfigMuxer model(&ftrace, mock_table.get(), {});
   std::set<std::string> n = {"sched_switch", "sched_new_event"};
   ON_CALL(ftrace, GetEventNamesForGroup("events/sched"))
       .WillByDefault(Return(n));
@@ -346,7 +346,7 @@
 
   FtraceConfig config = CreateFtraceConfig({"group_one/*", "group_two/*"});
 
-  FtraceConfigMuxer model(&ftrace, mock_table.get());
+  FtraceConfigMuxer model(&ftrace, mock_table.get(), {});
 
   std::set<std::string> event_names = {"foo"};
   ON_CALL(ftrace, GetEventNamesForGroup("events/group_one"))
@@ -395,7 +395,7 @@
 
   FtraceConfig config = CreateFtraceConfig({"sched_switch", "foo"});
 
-  FtraceConfigMuxer model(&ftrace, table_.get());
+  FtraceConfigMuxer model(&ftrace, table_.get(), {});
 
   ON_CALL(ftrace, ReadFileIntoString("/root/trace_clock"))
       .WillByDefault(Return("[local] global boot"));
@@ -445,7 +445,7 @@
 
   FtraceConfig config = CreateFtraceConfig({"sched/sched_switch"});
 
-  FtraceConfigMuxer model(&ftrace, table_.get());
+  FtraceConfigMuxer model(&ftrace, table_.get(), {});
 
   // If someone is using ftrace already don't stomp on what they are doing.
   EXPECT_CALL(ftrace, ReadOneCharFromFile("/root/tracing_on"))
@@ -461,7 +461,7 @@
   FtraceConfig config = CreateFtraceConfig({"sched/sched_switch"});
   *config.add_atrace_categories() = "sched";
 
-  FtraceConfigMuxer model(&ftrace, table_.get());
+  FtraceConfigMuxer model(&ftrace, table_.get(), {});
 
   EXPECT_CALL(ftrace, ReadOneCharFromFile("/root/tracing_on"))
       .WillOnce(Return('0'));
@@ -501,7 +501,7 @@
   *config.add_atrace_apps() = "com.google.android.gms.persistent";
   *config.add_atrace_apps() = "com.google.android.gms";
 
-  FtraceConfigMuxer model(&ftrace, table_.get());
+  FtraceConfigMuxer model(&ftrace, table_.get(), {});
 
   EXPECT_CALL(ftrace, ReadOneCharFromFile("/root/tracing_on"))
       .WillOnce(Return('0'));
@@ -542,7 +542,7 @@
   *config_c.add_atrace_apps() = "app_c";
   *config_c.add_atrace_categories() = "cat_c";
 
-  FtraceConfigMuxer model(&ftrace, table_.get());
+  FtraceConfigMuxer model(&ftrace, table_.get(), {});
 
   EXPECT_CALL(atrace, RunAtrace(ElementsAreArray({"atrace", "--async_start",
                                                   "--only_userspace", "cat_a",
@@ -606,7 +606,7 @@
   *config_c.add_atrace_categories() = "cat_1";
   *config_c.add_atrace_categories() = "cat_3";
 
-  FtraceConfigMuxer model(&ftrace, table_.get());
+  FtraceConfigMuxer model(&ftrace, table_.get(), {});
 
   EXPECT_CALL(
       atrace,
@@ -661,7 +661,7 @@
   *config_b.add_atrace_apps() = "app_1";
   *config_b.add_atrace_categories() = "cat_1";
 
-  FtraceConfigMuxer model(&ftrace, table_.get());
+  FtraceConfigMuxer model(&ftrace, table_.get(), {});
 
   EXPECT_CALL(atrace, RunAtrace(ElementsAreArray({"atrace", "--async_start",
                                                   "--only_userspace", "cat_1",
@@ -695,7 +695,7 @@
   FtraceConfig config_d = CreateFtraceConfig({"sched/sched_cpu_hotplug"});
   *config_d.add_atrace_categories() = "d";
 
-  FtraceConfigMuxer model(&ftrace, table_.get());
+  FtraceConfigMuxer model(&ftrace, table_.get(), {});
 
   FtraceConfigId id_a = model.SetupConfig(config_a);
   ASSERT_TRUE(id_a);
@@ -735,7 +735,7 @@
   MockFtraceProcfs ftrace;
   FtraceConfig config;
 
-  FtraceConfigMuxer model(&ftrace, table_.get());
+  FtraceConfigMuxer model(&ftrace, table_.get(), {});
 
   EXPECT_CALL(ftrace, ReadFileIntoString("/root/trace_clock"))
       .Times(AnyNumber());
@@ -761,7 +761,7 @@
 
 TEST_F(FtraceConfigMuxerTest, GetFtraceEvents) {
   MockFtraceProcfs ftrace;
-  FtraceConfigMuxer model(&ftrace, table_.get());
+  FtraceConfigMuxer model(&ftrace, table_.get(), {});
 
   FtraceConfig config = CreateFtraceConfig({"sched/sched_switch"});
   std::set<GroupAndName> events =
@@ -773,7 +773,7 @@
 
 TEST_F(FtraceConfigMuxerTest, GetFtraceEventsAtrace) {
   MockFtraceProcfs ftrace;
-  FtraceConfigMuxer model(&ftrace, table_.get());
+  FtraceConfigMuxer model(&ftrace, table_.get(), {});
 
   FtraceConfig config = CreateFtraceConfig({});
   *config.add_atrace_categories() = "sched";
@@ -787,7 +787,7 @@
 
 TEST_F(FtraceConfigMuxerTest, GetFtraceEventsAtraceCategories) {
   MockFtraceProcfs ftrace;
-  FtraceConfigMuxer model(&ftrace, table_.get());
+  FtraceConfigMuxer model(&ftrace, table_.get(), {});
 
   FtraceConfig config = CreateFtraceConfig({});
   *config.add_atrace_categories() = "sched";
@@ -811,7 +811,7 @@
   MockFtraceProcfs ftrace;
   FtraceConfig config =
       CreateFtraceConfig({"sched/sched_switch", "cgroup/cgroup_mkdir"});
-  FtraceConfigMuxer model(&ftrace, table_.get());
+  FtraceConfigMuxer model(&ftrace, table_.get(), {});
 
   ON_CALL(ftrace, ReadFileIntoString("/root/trace_clock"))
       .WillByDefault(Return("[local] global boot"));
@@ -872,7 +872,7 @@
 
   NiceMock<MockFtraceProcfs> ftrace;
   table_ = CreateFakeTable(valid_compact_format);
-  FtraceConfigMuxer model(&ftrace, table_.get());
+  FtraceConfigMuxer model(&ftrace, table_.get(), {});
 
   // First data source - request compact encoding.
   FtraceConfig config_enabled = CreateFtraceConfig({"sched/sched_switch"});
@@ -903,7 +903,7 @@
 
 TEST_F(FtraceConfigMuxerTest, CompactSchedConfigWithInvalidFormat) {
   NiceMock<MockFtraceProcfs> ftrace;
-  FtraceConfigMuxer model(&ftrace, table_.get());
+  FtraceConfigMuxer model(&ftrace, table_.get(), {});
 
   // Request compact encoding.
   FtraceConfig config = CreateFtraceConfig({"sched/sched_switch"});
diff --git a/src/traced/probes/ftrace/ftrace_controller.cc b/src/traced/probes/ftrace/ftrace_controller.cc
index ac960e7..da88e3d 100644
--- a/src/traced/probes/ftrace/ftrace_controller.cc
+++ b/src/traced/probes/ftrace/ftrace_controller.cc
@@ -34,8 +34,10 @@
 #include "perfetto/ext/base/file_utils.h"
 #include "perfetto/ext/base/metatrace.h"
 #include "perfetto/ext/tracing/core/trace_writer.h"
+#include "src/traced/probes/ftrace/atrace_hal_wrapper.h"
 #include "src/traced/probes/ftrace/cpu_reader.h"
 #include "src/traced/probes/ftrace/cpu_stats_parser.h"
+#include "src/traced/probes/ftrace/discover_vendor_tracepoints.h"
 #include "src/traced/probes/ftrace/event_info.h"
 #include "src/traced/probes/ftrace/ftrace_config_muxer.h"
 #include "src/traced/probes/ftrace/ftrace_data_source.h"
@@ -138,8 +140,12 @@
   if (!table)
     return nullptr;
 
+  AtraceHalWrapper hal;
+  auto vendor_evts =
+      vendor_tracepoints::DiscoverVendorTracepoints(&hal, ftrace_procfs.get());
+
   std::unique_ptr<FtraceConfigMuxer> model = std::unique_ptr<FtraceConfigMuxer>(
-      new FtraceConfigMuxer(ftrace_procfs.get(), table.get()));
+      new FtraceConfigMuxer(ftrace_procfs.get(), table.get(), vendor_evts));
   return std::unique_ptr<FtraceController>(
       new FtraceController(std::move(ftrace_procfs), std::move(table),
                            std::move(model), runner, observer));
diff --git a/src/traced/probes/ftrace/ftrace_controller_unittest.cc b/src/traced/probes/ftrace/ftrace_controller_unittest.cc
index 1f40c83..dca24c8 100644
--- a/src/traced/probes/ftrace/ftrace_controller_unittest.cc
+++ b/src/traced/probes/ftrace/ftrace_controller_unittest.cc
@@ -93,7 +93,7 @@
 std::unique_ptr<FtraceConfigMuxer> FakeModel(FtraceProcfs* ftrace,
                                              ProtoTranslationTable* table) {
   return std::unique_ptr<FtraceConfigMuxer>(
-      new FtraceConfigMuxer(ftrace, table));
+      new FtraceConfigMuxer(ftrace, table, {}));
 }
 
 class MockFtraceProcfs : public FtraceProcfs {
diff --git a/src/traced/probes/ftrace/ftrace_procfs.cc b/src/traced/probes/ftrace/ftrace_procfs.cc
index ddccbe1..480d303 100644
--- a/src/traced/probes/ftrace/ftrace_procfs.cc
+++ b/src/traced/probes/ftrace/ftrace_procfs.cc
@@ -27,6 +27,8 @@
 
 #include "perfetto/base/logging.h"
 #include "perfetto/ext/base/file_utils.h"
+#include "perfetto/ext/base/string_splitter.h"
+#include "perfetto/ext/base/string_utils.h"
 #include "perfetto/ext/base/utils.h"
 
 namespace perfetto {
@@ -107,6 +109,20 @@
   return ReadFileIntoString(path);
 }
 
+std::vector<std::string> FtraceProcfs::ReadEnabledEvents() {
+  std::string path = root_ + "set_event";
+  std::string s = ReadFileIntoString(path);
+  base::StringSplitter ss(s, '\n');
+  std::vector<std::string> events;
+  while (ss.Next()) {
+    std::string event = ss.cur_token();
+    if (event.size() == 0)
+      continue;
+    events.push_back(base::StripChars(event, ":", '/'));
+  }
+  return events;
+}
+
 std::string FtraceProcfs::ReadPageHeaderFormat() const {
   std::string path = root_ + "events/header_page";
   return ReadFileIntoString(path);
diff --git a/src/traced/probes/ftrace/ftrace_procfs.h b/src/traced/probes/ftrace/ftrace_procfs.h
index cd05adb..3d8186f 100644
--- a/src/traced/probes/ftrace/ftrace_procfs.h
+++ b/src/traced/probes/ftrace/ftrace_procfs.h
@@ -20,6 +20,7 @@
 #include <memory>
 #include <set>
 #include <string>
+#include <vector>
 
 #include "perfetto/ext/base/scoped_file.h"
 
@@ -91,6 +92,9 @@
   // Get all the available clocks.
   std::set<std::string> AvailableClocks();
 
+  // Get all the enabled events.
+  virtual std::vector<std::string> ReadEnabledEvents();
+
   // Open the raw pipe for |cpu|.
   virtual base::ScopedFile OpenPipeForCpu(size_t cpu);
 
@@ -98,7 +102,7 @@
       const std::string& path) const;
 
  protected:
-  // virtual and public for testing.
+  // virtual and protected for testing.
   virtual bool WriteToFile(const std::string& path, const std::string& str);
   virtual bool AppendToFile(const std::string& path, const std::string& str);
   virtual bool ClearFile(const std::string& path);
diff --git a/src/traced/probes/ftrace/ftrace_procfs_integrationtest.cc b/src/traced/probes/ftrace/ftrace_procfs_integrationtest.cc
index b8bf269..b002581 100644
--- a/src/traced/probes/ftrace/ftrace_procfs_integrationtest.cc
+++ b/src/traced/probes/ftrace/ftrace_procfs_integrationtest.cc
@@ -24,9 +24,21 @@
 #include "src/traced/probes/ftrace/ftrace_procfs.h"
 #include "test/gtest_and_gmock.h"
 
-using testing::HasSubstr;
-using testing::Not;
 using testing::Contains;
+using testing::HasSubstr;
+using testing::IsEmpty;
+using testing::Not;
+using testing::UnorderedElementsAre;
+
+// These tests run only on Android because on linux they require access to
+// ftrace, which would be problematic in the CI when multiple tests run
+// concurrently on the same machine. Android instead uses one emulator instance
+// for each worker.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#define ANDROID_ONLY_TEST(x) x
+#else
+#define ANDROID_ONLY_TEST(x) DISABLED_##x
+#endif
 
 namespace perfetto {
 namespace {
@@ -39,12 +51,6 @@
   return std::string(FtraceController::kTracingPaths[i]);
 }
 
-void ResetFtrace(FtraceProcfs* ftrace) {
-  ftrace->DisableAllEvents();
-  ftrace->ClearTrace();
-  ftrace->EnableTracing();
-}
-
 std::string ReadFile(const std::string& name) {
   std::string result;
   PERFETTO_CHECK(base::ReadFile(GetFtracePath() + name, &result));
@@ -59,156 +65,106 @@
   return output;
 }
 
-}  // namespace
+class FtraceProcfsIntegrationTest : public testing::Test {
+ public:
+  void SetUp() override;
+  void TearDown() override;
 
-// TODO(lalitm): reenable these tests (see b/72306171).
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
-#define MAYBE_CreateWithGoodPath CreateWithGoodPath
-#else
-#define MAYBE_CreateWithGoodPath DISABLED_CreateWithGoodPath
-#endif
-TEST(FtraceProcfsIntegrationTest, MAYBE_CreateWithGoodPath) {
-  EXPECT_TRUE(FtraceProcfs::Create(GetFtracePath()));
+  std::unique_ptr<FtraceProcfs> ftrace_;
+};
+
+void FtraceProcfsIntegrationTest::SetUp() {
+  ftrace_ = FtraceProcfs::Create(GetFtracePath());
+  ASSERT_TRUE(ftrace_);
+  if (ftrace_->IsTracingEnabled()) {
+    GTEST_SKIP() << "Something else is using ftrace, skipping";
+  }
+
+  ftrace_->DisableAllEvents();
+  ftrace_->ClearTrace();
+  ftrace_->EnableTracing();
 }
 
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
-#define MAYBE_CreateWithBadPath CreateWithBadPath
-#else
-#define MAYBE_CreateWithBadPath DISABLED_CreateWithBadath
-#endif
-TEST(FtraceProcfsIntegrationTest, MAYBE_CreateWithBadPath) {
+void FtraceProcfsIntegrationTest::TearDown() {
+  ftrace_->DisableAllEvents();
+  ftrace_->ClearTrace();
+  ftrace_->DisableTracing();
+}
+
+TEST_F(FtraceProcfsIntegrationTest, ANDROID_ONLY_TEST(CreateWithBadPath)) {
   EXPECT_FALSE(FtraceProcfs::Create(GetFtracePath() + std::string("bad_path")));
 }
 
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
-#define MAYBE_ClearTrace ClearTrace
-#else
-#define MAYBE_ClearTrace DISABLED_ClearTrace
-#endif
-TEST(FtraceProcfsIntegrationTest, MAYBE_ClearTrace) {
-  FtraceProcfs ftrace(GetFtracePath());
-  ResetFtrace(&ftrace);
-  ftrace.WriteTraceMarker("Hello, World!");
-  ftrace.ClearTrace();
+TEST_F(FtraceProcfsIntegrationTest, ANDROID_ONLY_TEST(ClearTrace)) {
+  ftrace_->WriteTraceMarker("Hello, World!");
+  ftrace_->ClearTrace();
   EXPECT_THAT(GetTraceOutput(), Not(HasSubstr("Hello, World!")));
 }
 
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
-#define MAYBE_TraceMarker TraceMarker
-#else
-#define MAYBE_TraceMarker DISABLED_TraceMarker
-#endif
-TEST(FtraceProcfsIntegrationTest, MAYBE_TraceMarker) {
-  FtraceProcfs ftrace(GetFtracePath());
-  ResetFtrace(&ftrace);
-  ftrace.WriteTraceMarker("Hello, World!");
+TEST_F(FtraceProcfsIntegrationTest, ANDROID_ONLY_TEST(TraceMarker)) {
+  ftrace_->WriteTraceMarker("Hello, World!");
   EXPECT_THAT(GetTraceOutput(), HasSubstr("Hello, World!"));
 }
 
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
-#define MAYBE_EnableDisableEvent EnableDisableEvent
-#else
-#define MAYBE_EnableDisableEvent DISABLED_EnableDisableEvent
-#endif
-TEST(FtraceProcfsIntegrationTest, MAYBE_EnableDisableEvent) {
-  FtraceProcfs ftrace(GetFtracePath());
-  ResetFtrace(&ftrace);
-  ftrace.EnableEvent("sched", "sched_switch");
+TEST_F(FtraceProcfsIntegrationTest, ANDROID_ONLY_TEST(EnableDisableEvent)) {
+  ftrace_->EnableEvent("sched", "sched_switch");
   sleep(1);
   EXPECT_THAT(GetTraceOutput(), HasSubstr("sched_switch"));
 
-  ftrace.DisableEvent("sched", "sched_switch");
-  ftrace.ClearTrace();
+  ftrace_->DisableEvent("sched", "sched_switch");
+  ftrace_->ClearTrace();
   sleep(1);
   EXPECT_THAT(GetTraceOutput(), Not(HasSubstr("sched_switch")));
 }
 
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
-#define MAYBE_EnableDisableTracing EnableDisableTracing
-#else
-#define MAYBE_EnableDisableTracing DISABLED_EnableDisableTracing
-#endif
-TEST(FtraceProcfsIntegrationTest, MAYBE_EnableDisableTracing) {
-  FtraceProcfs ftrace(GetFtracePath());
-  ResetFtrace(&ftrace);
-  EXPECT_TRUE(ftrace.IsTracingEnabled());
-  ftrace.WriteTraceMarker("Before");
-  ftrace.DisableTracing();
-  EXPECT_FALSE(ftrace.IsTracingEnabled());
-  ftrace.WriteTraceMarker("During");
-  ftrace.EnableTracing();
-  EXPECT_TRUE(ftrace.IsTracingEnabled());
-  ftrace.WriteTraceMarker("After");
+TEST_F(FtraceProcfsIntegrationTest, ANDROID_ONLY_TEST(EnableDisableTracing)) {
+  EXPECT_TRUE(ftrace_->IsTracingEnabled());
+  ftrace_->WriteTraceMarker("Before");
+  ftrace_->DisableTracing();
+  EXPECT_FALSE(ftrace_->IsTracingEnabled());
+  ftrace_->WriteTraceMarker("During");
+  ftrace_->EnableTracing();
+  EXPECT_TRUE(ftrace_->IsTracingEnabled());
+  ftrace_->WriteTraceMarker("After");
   EXPECT_THAT(GetTraceOutput(), HasSubstr("Before"));
   EXPECT_THAT(GetTraceOutput(), Not(HasSubstr("During")));
   EXPECT_THAT(GetTraceOutput(), HasSubstr("After"));
 }
 
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
-#define MAYBE_ReadFormatFile ReadFormatFile
-#else
-#define MAYBE_ReadFormatFile DISABLED_ReadFormatFile
-#endif
-TEST(FtraceProcfsIntegrationTest, MAYBE_ReadFormatFile) {
-  FtraceProcfs ftrace(GetFtracePath());
-  std::string format = ftrace.ReadEventFormat("ftrace", "print");
+TEST_F(FtraceProcfsIntegrationTest, ANDROID_ONLY_TEST(ReadFormatFile)) {
+  std::string format = ftrace_->ReadEventFormat("ftrace", "print");
   EXPECT_THAT(format, HasSubstr("name: print"));
   EXPECT_THAT(format, HasSubstr("field:char buf"));
 }
 
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
-#define MAYBE_CanOpenTracePipeRaw CanOpenTracePipeRaw
-#else
-#define MAYBE_CanOpenTracePipeRaw DISABLED_CanOpenTracePipeRaw
-#endif
-TEST(FtraceProcfsIntegrationTest, MAYBE_CanOpenTracePipeRaw) {
-  FtraceProcfs ftrace(GetFtracePath());
-  EXPECT_TRUE(ftrace.OpenPipeForCpu(0));
+TEST_F(FtraceProcfsIntegrationTest, ANDROID_ONLY_TEST(CanOpenTracePipeRaw)) {
+  EXPECT_TRUE(ftrace_->OpenPipeForCpu(0));
 }
 
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
-#define MAYBE_Clock Clock
-#else
-#define MAYBE_Clock DISABLED_Clock
-#endif
-TEST(FtraceProcfsIntegrationTest, MAYBE_Clock) {
-  FtraceProcfs ftrace(GetFtracePath());
-  std::set<std::string> clocks = ftrace.AvailableClocks();
+TEST_F(FtraceProcfsIntegrationTest, ANDROID_ONLY_TEST(Clock)) {
+  std::set<std::string> clocks = ftrace_->AvailableClocks();
   EXPECT_THAT(clocks, Contains("local"));
   EXPECT_THAT(clocks, Contains("global"));
 
-  EXPECT_TRUE(ftrace.SetClock("global"));
-  EXPECT_EQ(ftrace.GetClock(), "global");
-  EXPECT_TRUE(ftrace.SetClock("local"));
-  EXPECT_EQ(ftrace.GetClock(), "local");
+  EXPECT_TRUE(ftrace_->SetClock("global"));
+  EXPECT_EQ(ftrace_->GetClock(), "global");
+  EXPECT_TRUE(ftrace_->SetClock("local"));
+  EXPECT_EQ(ftrace_->GetClock(), "local");
 }
 
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
-#define MAYBE_CanSetBufferSize CanSetBufferSize
-#else
-#define MAYBE_CanSetBufferSize DISABLED_CanSetBufferSize
-#endif
-TEST(FtraceProcfsIntegrationTest, MAYBE_CanSetBufferSize) {
-  FtraceProcfs ftrace(GetFtracePath());
-  EXPECT_TRUE(ftrace.SetCpuBufferSizeInPages(4ul));
+TEST_F(FtraceProcfsIntegrationTest, ANDROID_ONLY_TEST(CanSetBufferSize)) {
+  EXPECT_TRUE(ftrace_->SetCpuBufferSizeInPages(4ul));
   EXPECT_EQ(ReadFile("buffer_size_kb"), "16\n");  // (4096 * 4) / 1024
-  EXPECT_TRUE(ftrace.SetCpuBufferSizeInPages(5ul));
+  EXPECT_TRUE(ftrace_->SetCpuBufferSizeInPages(5ul));
   EXPECT_EQ(ReadFile("buffer_size_kb"), "20\n");  // (4096 * 5) / 1024
 }
 
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
-#define MAYBE_FtraceControllerHardReset FtraceControllerHardReset
-#else
-#define MAYBE_FtraceControllerHardReset DISABLED_FtraceControllerHardReset
-#endif
-TEST(FtraceProcfsIntegrationTest, MAYBE_FtraceControllerHardReset) {
-  FtraceProcfs ftrace(GetFtracePath());
-  ResetFtrace(&ftrace);
-
-  ftrace.SetCpuBufferSizeInPages(4ul);
-  ftrace.EnableTracing();
-  ftrace.EnableEvent("sched", "sched_switch");
-  ftrace.WriteTraceMarker("Hello, World!");
+TEST_F(FtraceProcfsIntegrationTest,
+       ANDROID_ONLY_TEST(FtraceControllerHardReset)) {
+  ftrace_->SetCpuBufferSizeInPages(4ul);
+  ftrace_->EnableTracing();
+  ftrace_->EnableEvent("sched", "sched_switch");
+  ftrace_->WriteTraceMarker("Hello, World!");
 
   EXPECT_EQ(ReadFile("buffer_size_kb"), "16\n");
   EXPECT_EQ(ReadFile("tracing_on"), "1\n");
@@ -223,4 +179,20 @@
   EXPECT_THAT(GetTraceOutput(), Not(HasSubstr("Hello")));
 }
 
+TEST_F(FtraceProcfsIntegrationTest, ANDROID_ONLY_TEST(ReadEnabledEvents)) {
+  EXPECT_THAT(ftrace_->ReadEnabledEvents(), IsEmpty());
+
+  ftrace_->EnableEvent("sched", "sched_switch");
+  ftrace_->EnableEvent("kmem", "kmalloc");
+
+  EXPECT_THAT(ftrace_->ReadEnabledEvents(),
+              UnorderedElementsAre("sched/sched_switch", "kmem/kmalloc"));
+
+  ftrace_->DisableEvent("sched", "sched_switch");
+  ftrace_->DisableEvent("kmem", "kmalloc");
+
+  EXPECT_THAT(ftrace_->ReadEnabledEvents(), IsEmpty());
+}
+
+}  // namespace
 }  // namespace perfetto
diff --git a/src/traced/probes/ftrace/proto_translation_table.h b/src/traced/probes/ftrace/proto_translation_table.h
index f9c5be6..83dd19d 100644
--- a/src/traced/probes/ftrace/proto_translation_table.h
+++ b/src/traced/probes/ftrace/proto_translation_table.h
@@ -19,6 +19,7 @@
 
 #include <stdint.h>
 
+#include <iostream>
 #include <map>
 #include <memory>
 #include <set>
@@ -65,6 +66,10 @@
   std::string name_;
 };
 
+inline void PrintTo(const GroupAndName& event, ::std::ostream* os) {
+  *os << "GroupAndName(" << event.group() << ", " << event.name() << ")";
+}
+
 bool InferFtraceType(const std::string& type_and_name,
                      size_t size,
                      bool is_signed,
diff --git a/src/tracing/test/api_integrationtest.cc b/src/tracing/test/api_integrationtest.cc
index 76ce6ab..c666bb0 100644
--- a/src/tracing/test/api_integrationtest.cc
+++ b/src/tracing/test/api_integrationtest.cc
@@ -662,6 +662,13 @@
   }
 }
 
+// This is a build-only regression test that checks you can have a track event
+// inside a template.
+template <typename T>
+void TestTrackEventInsideTemplate(T) {
+  TRACE_EVENT_BEGIN("cat", "Name");
+}
+
 TEST_F(PerfettoApiTest, TrackEvent) {
   // Create a new trace session.
   auto* tracing_session = NewTraceWithCategories({"test"});
@@ -765,6 +772,9 @@
   EXPECT_TRUE(process_descriptor_found);
   EXPECT_TRUE(begin_found);
   EXPECT_TRUE(end_found);
+
+  // Dummy instantiation of test template.
+  TestTrackEventInsideTemplate(true);
 }
 
 TEST_F(PerfettoApiTest, TrackEventCategories) {
@@ -2311,10 +2321,13 @@
 TEST_F(PerfettoApiTest, LegacyCategoryGroupEnabledState) {
   bool foo_status;
   bool bar_status;
+  bool dynamic_status;
   TRACE_EVENT_CATEGORY_GROUP_ENABLED("foo", &foo_status);
   TRACE_EVENT_CATEGORY_GROUP_ENABLED("bar", &bar_status);
+  TRACE_EVENT_CATEGORY_GROUP_ENABLED("dynamic", &dynamic_status);
   EXPECT_FALSE(foo_status);
   EXPECT_FALSE(bar_status);
+  EXPECT_FALSE(dynamic_status);
 
   const uint8_t* foo_enabled =
       TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED("foo");
@@ -2323,12 +2336,14 @@
   EXPECT_FALSE(*foo_enabled);
   EXPECT_FALSE(*bar_enabled);
 
-  auto* tracing_session = NewTraceWithCategories({"foo"});
+  auto* tracing_session = NewTraceWithCategories({"foo", "dynamic"});
   tracing_session->get()->StartBlocking();
   TRACE_EVENT_CATEGORY_GROUP_ENABLED("foo", &foo_status);
   TRACE_EVENT_CATEGORY_GROUP_ENABLED("bar", &bar_status);
+  TRACE_EVENT_CATEGORY_GROUP_ENABLED("dynamic", &dynamic_status);
   EXPECT_TRUE(foo_status);
   EXPECT_FALSE(bar_status);
+  EXPECT_TRUE(dynamic_status);
 
   EXPECT_TRUE(*foo_enabled);
   EXPECT_FALSE(*bar_enabled);
@@ -2336,12 +2351,41 @@
   tracing_session->get()->StopBlocking();
   TRACE_EVENT_CATEGORY_GROUP_ENABLED("foo", &foo_status);
   TRACE_EVENT_CATEGORY_GROUP_ENABLED("bar", &bar_status);
+  TRACE_EVENT_CATEGORY_GROUP_ENABLED("dynamic", &dynamic_status);
   EXPECT_FALSE(foo_status);
   EXPECT_FALSE(bar_status);
+  EXPECT_FALSE(dynamic_status);
   EXPECT_FALSE(*foo_enabled);
   EXPECT_FALSE(*bar_enabled);
 }
 
+TEST_F(PerfettoApiTest, CategoryEnabledState) {
+  perfetto::DynamicCategory dynamic{"dynamic"};
+  EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("foo"));
+  EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("bar"));
+  EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("red,green,blue,foo"));
+  EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("dynamic"));
+  EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("dynamic_2"));
+  EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED(dynamic));
+
+  auto* tracing_session = NewTraceWithCategories({"foo", "dynamic"});
+  tracing_session->get()->StartBlocking();
+  EXPECT_TRUE(TRACE_EVENT_CATEGORY_ENABLED("foo"));
+  EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("bar"));
+  EXPECT_TRUE(TRACE_EVENT_CATEGORY_ENABLED("red,green,blue,foo"));
+  EXPECT_TRUE(TRACE_EVENT_CATEGORY_ENABLED("dynamic"));
+  EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("dynamic_2"));
+  EXPECT_TRUE(TRACE_EVENT_CATEGORY_ENABLED(dynamic));
+
+  tracing_session->get()->StopBlocking();
+  EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("foo"));
+  EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("bar"));
+  EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("red,green,blue,foo"));
+  EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("dynamic"));
+  EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("dynamic_2"));
+  EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED(dynamic));
+}
+
 }  // namespace
 
 PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(MockDataSource);
diff --git a/test/configs/traced_perf.cfg b/test/configs/traced_perf.cfg
new file mode 100644
index 0000000..3334a4b
--- /dev/null
+++ b/test/configs/traced_perf.cfg
@@ -0,0 +1,26 @@
+buffers {
+  size_kb: 10240
+  fill_policy: RING_BUFFER
+}
+
+data_sources {
+  config {
+    name: "linux.perf"
+    perf_event_config {
+      all_cpus: true
+      sampling_frequency: 10
+    }
+  }
+}
+
+data_sources {
+  config {
+    name: "linux.process_stats"
+    target_buffer: 0
+    process_stats_config {
+      proc_stats_poll_ms: 100
+    }
+  }
+}
+
+duration_ms: 60000
diff --git a/test/cts/traced_perf_test_cts.cc b/test/cts/traced_perf_test_cts.cc
index d6745fc..e0cef1f 100644
--- a/test/cts/traced_perf_test_cts.cc
+++ b/test/cts/traced_perf_test_cts.cc
@@ -15,6 +15,7 @@
  */
 
 #include <stdlib.h>
+#include <sys/system_properties.h>
 #include <sys/types.h>
 
 #include "perfetto/base/logging.h"
@@ -32,6 +33,16 @@
 namespace perfetto {
 namespace {
 
+// Skip these tests if the device in question doesn't have the necessary kernel
+// LSM hooks in perf_event_open. This comes up when a device with an older
+// kernel upgrades to R.
+bool HasPerfLsmHooks() {
+  char buf[PROP_VALUE_MAX + 1] = {};
+  int ret = __system_property_get("sys.init.perf_lsm_hooks", buf);
+  PERFETTO_CHECK(ret >= 0);
+  return std::string(buf) == "1";
+}
+
 std::vector<protos::gen::TracePacket> ProfileSystemWide(std::string app_name) {
   base::TestTaskRunner task_runner;
 
@@ -51,8 +62,9 @@
   helper.WaitForConsumerConnect();
 
   TraceConfig trace_config;
-  trace_config.add_buffers()->set_size_kb(10 * 1024);
-  trace_config.set_duration_ms(2000);
+  trace_config.add_buffers()->set_size_kb(20 * 1024);
+  trace_config.set_duration_ms(3000);
+  trace_config.set_data_source_stop_timeout_ms(8000);
 
   auto* ds_config = trace_config.add_data_sources()->mutable_config();
   ds_config->set_name("linux.perf");
@@ -66,7 +78,7 @@
 
   // start tracing
   helper.StartTracing(trace_config);
-  helper.WaitForTracingDisabled(10000 /*ms*/);
+  helper.WaitForTracingDisabled(15000 /*ms*/);
   helper.ReadData();
   helper.WaitForReadData();
 
@@ -77,39 +89,50 @@
                                   int target_pid) {
   ASSERT_GT(packets.size(), 0u);
 
-  int samples_found = 0;
+  int total_perf_packets = 0;
+  int total_samples = 0;
+  int target_samples = 0;
   for (const auto& packet : packets) {
     if (!packet.has_perf_sample())
       continue;
 
-    EXPECT_GT(packet.timestamp(), 0u) << "all samples should have a timestamp";
+    total_perf_packets++;
+    EXPECT_GT(packet.timestamp(), 0u) << "all packets should have a timestamp";
     const auto& sample = packet.perf_sample();
-    if (sample.pid() != static_cast<uint32_t>(target_pid))
-      continue;
-
-    // TODO(rsavitski): include |sample.has_sample_skipped_reason| once that is
-    // merged.
     if (sample.has_kernel_records_lost())
       continue;
+    if (sample.has_sample_skipped_reason())
+      continue;
 
-    // A full sample
+    total_samples++;
     EXPECT_GT(sample.tid(), 0u);
     EXPECT_GT(sample.callstack_iid(), 0u);
-    samples_found += 1;
+
+    if (sample.pid() == static_cast<uint32_t>(target_pid))
+      target_samples++;
   }
-  EXPECT_GT(samples_found, 0);
+
+  EXPECT_GT(target_samples, 0) << "packets.size(): " << packets.size()
+                               << ", total_perf_packets: " << total_perf_packets
+                               << ", total_samples: " << total_samples << "\n";
 }
 
 void AssertNoStacksForPid(std::vector<protos::gen::TracePacket> packets,
                           int target_pid) {
+  // The process can still be sampled, but the stacks should be discarded
+  // without unwinding.
   for (const auto& packet : packets) {
     if (packet.perf_sample().pid() == static_cast<uint32_t>(target_pid)) {
       EXPECT_EQ(packet.perf_sample().callstack_iid(), 0u);
+      EXPECT_TRUE(packet.perf_sample().has_sample_skipped_reason());
     }
   }
 }
 
 TEST(TracedPerfCtsTest, SystemWideDebuggableApp) {
+  if (!HasPerfLsmHooks())
+    return;
+
   std::string app_name = "android.perfetto.cts.app.debuggable";
   const auto& packets = ProfileSystemWide(app_name);
   int app_pid = PidForProcessName(app_name);
@@ -120,6 +143,9 @@
 }
 
 TEST(TracedPerfCtsTest, SystemWideProfileableApp) {
+  if (!HasPerfLsmHooks())
+    return;
+
   std::string app_name = "android.perfetto.cts.app.profileable";
   const auto& packets = ProfileSystemWide(app_name);
   int app_pid = PidForProcessName(app_name);
@@ -130,6 +156,9 @@
 }
 
 TEST(TracedPerfCtsTest, SystemWideReleaseApp) {
+  if (!HasPerfLsmHooks())
+    return;
+
   std::string app_name = "android.perfetto.cts.app.release";
   const auto& packets = ProfileSystemWide(app_name);
   int app_pid = PidForProcessName(app_name);
diff --git a/test/cts/utils.cc b/test/cts/utils.cc
index c61eff7..79e5d4d 100644
--- a/test/cts/utils.cc
+++ b/test/cts/utils.cc
@@ -54,7 +54,7 @@
 
 // note: cannot use gtest macros due to return type
 bool IsAppRunning(const std::string& name) {
-  std::string cmd = "pgrep -f " + name;
+  std::string cmd = "pgrep -f ^" + name + "$";
   int retcode = system(cmd.c_str());
   PERFETTO_CHECK(retcode >= 0);
   int exit_status = WEXITSTATUS(retcode);
@@ -66,9 +66,7 @@
 }
 
 int PidForProcessName(const std::string& name) {
-  // quirk: need to exclude ourselves from the result as the pgrep's cmdline
-  // matches itself when invoked via popen.
-  std::string cmd = "pgrep -f " + name + " | grep -v $$";
+  std::string cmd = "pgrep -f ^" + name + "$";
   FILE* fp = popen(cmd.c_str(), "re");
   if (!fp)
     return -1;
diff --git a/test/metrics/android_startup_breakdown.out b/test/metrics/android_startup_breakdown.out
index 2dc19cd..4f6cfa9 100644
--- a/test/metrics/android_startup_breakdown.out
+++ b/test/metrics/android_startup_breakdown.out
@@ -25,6 +25,7 @@
       time_during_start_process {
         dur_ns: 35
       }
+      to_bind_application: 83
     }
     activity_hosting_process_count: 1
   }
diff --git a/test/trace_processor/heap_graph_branching.textproto b/test/trace_processor/heap_graph_branching.textproto
new file mode 100644
index 0000000..d876fd0
--- /dev/null
+++ b/test/trace_processor/heap_graph_branching.textproto
@@ -0,0 +1,95 @@
+packet {
+  process_tree {
+    processes {
+      pid: 1
+      ppid: 0
+      cmdline: "init"
+      uid: 0
+    }
+    processes {
+      pid: 2
+      ppid: 1
+      cmdline: "system_server"
+      uid: 1000
+    }
+  }
+}
+packet {
+  trusted_packet_sequence_id: 999
+  timestamp: 10
+  heap_graph {
+    pid: 2
+    roots {
+      root_type: ROOT_JAVA_FRAME
+      object_ids: 0x01
+    }
+    objects {
+      id: 0x01
+      type_id: 1
+      self_size: 100
+      reference_field_id: 1
+      reference_object_id: 0x02
+      reference_field_id: 1
+      reference_object_id: 0x04
+    }
+    objects {
+      id: 0x02
+      type_id: 2
+      self_size: 200
+      reference_field_id: 1
+      reference_object_id: 0x03
+    }
+    objects {
+      id: 0x03
+      type_id: 3
+      self_size: 400
+    }
+    objects {
+      id: 0x04
+      type_id: 4
+      self_size: 800
+      reference_field_id: 1
+      reference_object_id: 0x05
+    }
+    objects {
+      id: 0x05
+      type_id: 5
+      self_size: 1600
+    }
+    continued: true
+    index: 0
+  }
+}
+packet {
+  trusted_packet_sequence_id: 999
+  heap_graph {
+    pid: 2
+    type_names {
+      iid: 1
+      str: "RootNode"
+    }
+    type_names {
+      iid: 2
+      str: "LeftChild0"
+    }
+    type_names {
+      iid: 3
+      str: "LeftChild1"
+    }
+    type_names {
+      iid: 4
+      str: "RightChild0"
+    }
+    type_names {
+      iid: 5
+      str: "RightChild1"
+    }
+    field_names {
+      iid: 1
+      str: "Node.next"
+    }
+    continued: false
+    index: 1
+  }
+}
+
diff --git a/test/trace_processor/heap_graph_flamegraph_focused.out b/test/trace_processor/heap_graph_flamegraph_focused.out
new file mode 100644
index 0000000..bb26353
--- /dev/null
+++ b/test/trace_processor/heap_graph_flamegraph_focused.out
@@ -0,0 +1,4 @@
+"id","depth","name","count","cumulative_count","size","cumulative_size","parent_id"
+0,0,"RootNode",1,3,100,700,"[NULL]"
+1,1,"LeftChild0",1,2,200,600,0
+2,2,"LeftChild1",1,1,400,400,1
diff --git a/test/trace_processor/heap_graph_flamegraph_focused.sql b/test/trace_processor/heap_graph_flamegraph_focused.sql
new file mode 100644
index 0000000..95d498a
--- /dev/null
+++ b/test/trace_processor/heap_graph_flamegraph_focused.sql
@@ -0,0 +1,15 @@
+SELECT
+  id,
+  depth,
+  name,
+  count,
+  cumulative_count,
+  size,
+  cumulative_size,
+  parent_id
+FROM experimental_flamegraph(
+  (select max(graph_sample_ts) from heap_graph_object),
+  (select max(upid) from heap_graph_object),
+  'graph')
+WHERE focus_str = 'left'
+LIMIT 10
diff --git a/test/trace_processor/index b/test/trace_processor/index
index 5a5403c..5ea7739 100644
--- a/test/trace_processor/index
+++ b/test/trace_processor/index
@@ -157,6 +157,7 @@
 ../data/system-server-heap-graph.pftrace heap_graph_flamegraph.sql heap_graph_flamegraph_system-server-heap-graph.out
 ../data/system-server-native-profile heap_profile_flamegraph.sql heap_profile_flamegraph_system-server-native-profile.out
 heap_profile_tracker_new_stack.textproto heap_profile_tracker_new_stack.sql heap_profile_tracker_new_stack.out
+heap_graph_branching.textproto heap_graph_flamegraph_focused.sql heap_graph_flamegraph_focused.out
 
 stack_profile_tracker_empty_callstack.textproto stack_profile_tracker_empty_callstack.sql stack_profile_tracker_empty_callstack.out
 
diff --git a/tools/dev_server b/tools/dev_server
index bd74df7..fb836b8 100755
--- a/tools/dev_server
+++ b/tools/dev_server
@@ -68,6 +68,7 @@
           self.send_response(200)
           self.send_header("Content-type", "text/html")
           self.end_headers()
+          self.wfile.write("<pre>")
           self.wfile.write(e.stdout_and_stderr)
           return
         return SimpleHTTPRequestHandler.do_GET(self)
diff --git a/ui/index.html b/ui/index.html
index a893d30..5a9190f 100644
--- a/ui/index.html
+++ b/ui/index.html
@@ -2,8 +2,6 @@
 <html lang="en-us">
 <head>
   <title>Perfetto UI</title>
-  <!-- See b/149573396 for CSP rationale -->
-  <meta http-equiv="Content-Security-Policy" content="default-src 'self'; object-src 'none'; connect-src 'self' http://127.0.0.1:9001 https://*.googleapis.com; navigate-to https://*.perfetto.dev;">
   <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport" />
   <!-- WebComponents V0 origin trial token for https://ui.perfetto.dev Expires 17 Dec 2020.
   See https://crbug.com/1021137. -->