Merge "TrackEvent: Add entry point for track+timestamp+lambda"
diff --git a/NOTICE b/NOTICE
deleted file mode 100644
index 25f8ab9..0000000
--- a/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
-   Copyright (c) 2017, The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-
-   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.
-
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
diff --git a/README.chromium b/README.chromium
index 33541c5..25ec614 100644
--- a/README.chromium
+++ b/README.chromium
@@ -2,7 +2,7 @@
 URL: https://android.googlesource.com/platform/external/perfetto/
 Version: unknown
 License: Apache2
-License File: NOTICE
+License File: LICENSE
 Security Critical: yes
 License Android Compatible: yes
 Description: Performance instrumentation and logging for Google client platforms
diff --git a/heapprofd.rc b/heapprofd.rc
index 26c602f..dd96325 100644
--- a/heapprofd.rc
+++ b/heapprofd.rc
@@ -31,5 +31,8 @@
 on property:traced.lazy.heapprofd=1
     start heapprofd
 
-on property:persist.heapprofd.enable=0 && property:traced.lazy.heapprofd=""
+on property:persist.heapprofd.enable="" && property:traced.lazy.heapprofd=""
     stop heapprofd
+
+on property:persist.heapprofd.enable=0
+    setprop persist.heapprofd.enable ""
diff --git a/include/perfetto/ext/tracing/core/shared_memory_arbiter.h b/include/perfetto/ext/tracing/core/shared_memory_arbiter.h
index 3519a88..8811ef2 100644
--- a/include/perfetto/ext/tracing/core/shared_memory_arbiter.h
+++ b/include/perfetto/ext/tracing/core/shared_memory_arbiter.h
@@ -128,6 +128,14 @@
       std::unique_ptr<StartupTraceWriterRegistry>,
       BufferID target_buffer) = 0;
 
+  // Treat the reservation as resolved to an invalid buffer. Commits for this
+  // reservation will be flushed to the service ASAP. The service will free
+  // committed chunks but otherwise ignore them. The producer can call this
+  // method, for example, if connection to the tracing service failed or the
+  // session was stopped concurrently before the connection was established.
+  virtual void AbortStartupTracingForReservation(
+      uint16_t target_buffer_reservation_id) = 0;
+
   // Notifies the service that all data for the given FlushRequestID has been
   // committed in the shared memory buffer. Should only be called while bound.
   virtual void NotifyFlushComplete(FlushRequestID) = 0;
diff --git a/include/perfetto/tracing/debug_annotation.h b/include/perfetto/tracing/debug_annotation.h
index f13fbd9..2c5b6d3 100644
--- a/include/perfetto/tracing/debug_annotation.h
+++ b/include/perfetto/tracing/debug_annotation.h
@@ -44,18 +44,28 @@
 namespace internal {
 
 // Overloads for all the supported built in debug annotation types.
-void WriteDebugAnnotation(protos::pbzero::DebugAnnotation*, bool);
-void WriteDebugAnnotation(protos::pbzero::DebugAnnotation*, uint64_t);
-void WriteDebugAnnotation(protos::pbzero::DebugAnnotation*, unsigned);
-void WriteDebugAnnotation(protos::pbzero::DebugAnnotation*, int64_t);
-void WriteDebugAnnotation(protos::pbzero::DebugAnnotation*, int);
-void WriteDebugAnnotation(protos::pbzero::DebugAnnotation*, double);
-void WriteDebugAnnotation(protos::pbzero::DebugAnnotation*, float);
-void WriteDebugAnnotation(protos::pbzero::DebugAnnotation*, const char*);
-void WriteDebugAnnotation(protos::pbzero::DebugAnnotation*, const std::string&);
-void WriteDebugAnnotation(protos::pbzero::DebugAnnotation*, const void*);
-void WriteDebugAnnotation(protos::pbzero::DebugAnnotation*,
-                          const DebugAnnotation&);
+void PERFETTO_EXPORT WriteDebugAnnotation(protos::pbzero::DebugAnnotation*,
+                                          bool);
+void PERFETTO_EXPORT WriteDebugAnnotation(protos::pbzero::DebugAnnotation*,
+                                          uint64_t);
+void PERFETTO_EXPORT WriteDebugAnnotation(protos::pbzero::DebugAnnotation*,
+                                          unsigned);
+void PERFETTO_EXPORT WriteDebugAnnotation(protos::pbzero::DebugAnnotation*,
+                                          int64_t);
+void PERFETTO_EXPORT WriteDebugAnnotation(protos::pbzero::DebugAnnotation*,
+                                          int);
+void PERFETTO_EXPORT WriteDebugAnnotation(protos::pbzero::DebugAnnotation*,
+                                          double);
+void PERFETTO_EXPORT WriteDebugAnnotation(protos::pbzero::DebugAnnotation*,
+                                          float);
+void PERFETTO_EXPORT WriteDebugAnnotation(protos::pbzero::DebugAnnotation*,
+                                          const char*);
+void PERFETTO_EXPORT WriteDebugAnnotation(protos::pbzero::DebugAnnotation*,
+                                          const std::string&);
+void PERFETTO_EXPORT WriteDebugAnnotation(protos::pbzero::DebugAnnotation*,
+                                          const void*);
+void PERFETTO_EXPORT WriteDebugAnnotation(protos::pbzero::DebugAnnotation*,
+                                          const DebugAnnotation&);
 
 template <typename T>
 void WriteDebugAnnotation(protos::pbzero::DebugAnnotation* annotation,
diff --git a/include/perfetto/tracing/internal/track_event_internal.h b/include/perfetto/tracing/internal/track_event_internal.h
index 48ed760..82de8d7 100644
--- a/include/perfetto/tracing/internal/track_event_internal.h
+++ b/include/perfetto/tracing/internal/track_event_internal.h
@@ -92,7 +92,7 @@
 // The backend portion of the track event trace point implemention. Outlined to
 // a separate .cc file so it can be shared by different track event category
 // namespaces.
-class TrackEventInternal {
+class PERFETTO_EXPORT TrackEventInternal {
  public:
   static bool Initialize(
       const TrackEventCategoryRegistry&,
diff --git a/include/perfetto/tracing/track_event_category_registry.h b/include/perfetto/tracing/track_event_category_registry.h
index 23f423e..e51c4d6 100644
--- a/include/perfetto/tracing/track_event_category_registry.h
+++ b/include/perfetto/tracing/track_event_category_registry.h
@@ -29,7 +29,7 @@
 
 // A compile-time representation of a track event category. See
 // PERFETTO_DEFINE_CATEGORIES for registering your own categories.
-struct Category {
+struct PERFETTO_EXPORT Category {
   using Tags = std::array<const char*, 4>;
 
   const char* const name = nullptr;
@@ -150,7 +150,7 @@
 // container type to make it less likely for trace points to accidentally start
 // using dynamic categories. Events with dynamic categories will always be
 // slightly more expensive than regular events, so use them sparingly.
-class DynamicCategory final {
+class PERFETTO_EXPORT DynamicCategory final {
  public:
   explicit DynamicCategory(const std::string& name_) : name(name_) {}
   explicit DynamicCategory(const char* name_) : name(name_) {}
@@ -190,7 +190,7 @@
 
 // Holds all the registered categories for one category namespace. See
 // PERFETTO_DEFINE_CATEGORIES for building the registry.
-class TrackEventCategoryRegistry {
+class PERFETTO_EXPORT TrackEventCategoryRegistry {
  public:
   constexpr TrackEventCategoryRegistry(size_t category_count,
                                        const Category* categories,
diff --git a/include/perfetto/tracing/track_event_legacy.h b/include/perfetto/tracing/track_event_legacy.h
index ede2d8a..96ec110 100644
--- a/include/perfetto/tracing/track_event_legacy.h
+++ b/include/perfetto/tracing/track_event_legacy.h
@@ -189,17 +189,17 @@
 
 // Built-in implementation for events referring to the current thread.
 template <>
-bool ConvertThreadId(const PerfettoLegacyCurrentThreadId&,
-                     uint64_t*,
-                     int32_t*,
-                     int32_t*);
+bool PERFETTO_EXPORT ConvertThreadId(const PerfettoLegacyCurrentThreadId&,
+                                     uint64_t*,
+                                     int32_t*,
+                                     int32_t*);
 
 }  // namespace legacy
 
 namespace internal {
 
 // LegacyTraceId encapsulates an ID that can either be an integer or pointer.
-class LegacyTraceId {
+class PERFETTO_EXPORT LegacyTraceId {
  public:
   // Can be combined with WithScope.
   class LocalId {
@@ -312,7 +312,7 @@
 namespace perfetto {
 namespace internal {
 
-class TrackEventLegacy {
+class PERFETTO_EXPORT TrackEventLegacy {
  public:
   static constexpr protos::pbzero::TrackEvent::Type PhaseToType(char phase) {
     // clang-format off
diff --git a/protos/perfetto/metrics/android/display_metrics.proto b/protos/perfetto/metrics/android/display_metrics.proto
index 7fd765c..fc858ac 100644
--- a/protos/perfetto/metrics/android/display_metrics.proto
+++ b/protos/perfetto/metrics/android/display_metrics.proto
@@ -24,4 +24,7 @@
   // pixels values but where still submitted. It is tracked based on
   // comparing the MISR of the current frame vs previous frame.
   optional uint32 total_duplicate_frames = 1;
+
+  // Stat reports whether there is any duplicate_frames tracked
+  optional uint32 duplicate_frames_logged = 2;
 }
\ No newline at end of file
diff --git a/protos/perfetto/metrics/perfetto_merged_metrics.proto b/protos/perfetto/metrics/perfetto_merged_metrics.proto
index 99255d28..ed31294 100644
--- a/protos/perfetto/metrics/perfetto_merged_metrics.proto
+++ b/protos/perfetto/metrics/perfetto_merged_metrics.proto
@@ -627,6 +627,9 @@
   // pixels values but where still submitted. It is tracked based on
   // comparing the MISR of the current frame vs previous frame.
   optional uint32 total_duplicate_frames = 1;
+
+  // Stat reports whether there is any duplicate_frames tracked
+  optional uint32 duplicate_frames_logged = 2;
 }
 // End of protos/perfetto/metrics/android/display_metrics.proto
 
diff --git a/src/profiling/perf/perf_producer.cc b/src/profiling/perf/perf_producer.cc
index 1d4d45c..c1737d7 100644
--- a/src/profiling/perf/perf_producer.cc
+++ b/src/profiling/perf/perf_producer.cc
@@ -19,6 +19,7 @@
 #include <random>
 #include <utility>
 
+#include <malloc.h>
 #include <unistd.h>
 
 #include <unwindstack/Error.h>
@@ -652,6 +653,13 @@
   // Clean up resources if there are no more active sources.
   if (data_sources_.empty()) {
     callstack_trie_.ClearTrie();  // purge internings
+#if defined(__BIONIC__)
+    // TODO(b/152414415): libunwindstack's volume of small allocations is
+    // adverarial to scudo, which doesn't automatically release small
+    // allocation regions back to the OS. Forceful purge does reclaim all size
+    // classes.
+    mallopt(M_PURGE, 0);
+#endif
   }
 }
 
diff --git a/src/trace_processor/metrics/android/android_task_names.sql b/src/trace_processor/metrics/android/android_task_names.sql
index 5c67757..be88267 100644
--- a/src/trace_processor/metrics/android/android_task_names.sql
+++ b/src/trace_processor/metrics/android/android_task_names.sql
@@ -31,8 +31,8 @@
   SELECT
     upid,
     RepeatedField(package_list.package_name) AS packages
-  FROM proc_uid
-  JOIN package_list USING (uid)
+  FROM process
+  JOIN package_list ON process.android_appid = package_list.uid
   GROUP BY 1
 )
 SELECT AndroidTaskNames(
diff --git a/src/trace_processor/metrics/android/display_metrics.sql b/src/trace_processor/metrics/android/display_metrics.sql
index ad8c77d..321ef4d 100644
--- a/src/trace_processor/metrics/android/display_metrics.sql
+++ b/src/trace_processor/metrics/android/display_metrics.sql
@@ -19,8 +19,15 @@
 WHERE name='SAME_FRAME'
 AND value=1;
 
+CREATE VIEW duplicate_frames_logged AS
+SELECT CASE WHEN COUNT(name) > 0 THEN 1 ELSE 0 END AS logs_found
+FROM counters
+WHERE name='SAME_FRAME' AND value=0;
+
 CREATE VIEW display_metrics_output AS
 SELECT AndroidDisplayMetrics(
     'total_duplicate_frames', (SELECT total_duplicate_frames
-                            FROM same_frame)
+                            FROM same_frame),
+    'duplicate_frames_logged', (SELECT logs_found
+                            FROM duplicate_frames_logged)
 );
\ No newline at end of file
diff --git a/src/trace_processor/metrics/android/process_metadata.sql b/src/trace_processor/metrics/android/process_metadata.sql
index 74eb82a..d38795f 100644
--- a/src/trace_processor/metrics/android/process_metadata.sql
+++ b/src/trace_processor/metrics/android/process_metadata.sql
@@ -16,13 +16,6 @@
 
 SELECT RUN_METRIC('android/android_package_list.sql');
 
--- Create a view of the process with the app ID as defined in
--- //frameworks/base/core/java/android/os/UserHandle.java
--- TODO: move this to the trace processor once the table migration is complete.
-CREATE VIEW IF NOT EXISTS proc_uid AS
-SELECT upid, name, uid % 100000 AS uid
-FROM process;
-
 DROP TABLE IF EXISTS uid_package_count;
 
 CREATE TABLE uid_package_count AS
@@ -34,24 +27,24 @@
 
 CREATE TABLE process_metadata_table AS
 SELECT
-  proc_uid.upid,
-  proc_uid.name AS process_name,
-  proc_uid.uid,
+  process.upid,
+  process.name AS process_name,
+  process.android_appid AS uid,
   CASE WHEN uid_package_count.cnt > 1 THEN TRUE ELSE NULL END AS shared_uid,
   plist.package_name,
   plist.version_code,
   plist.debuggable
-FROM proc_uid
-LEFT JOIN uid_package_count USING (uid)
+FROM process
+LEFT JOIN uid_package_count ON process.android_appid = uid_package_count.uid
 LEFT JOIN package_list plist
 ON (
-  proc_uid.uid = plist.uid
+  process.android_appid = plist.uid
   AND uid_package_count.uid = plist.uid
   AND (
     -- unique match
     uid_package_count.cnt = 1
     -- or process name starts with the package name
-    OR proc_uid.name LIKE plist.package_name || '%')
+    OR process.name LIKE plist.package_name || '%')
   );
 
 CREATE VIEW IF NOT EXISTS process_metadata AS
@@ -63,8 +56,8 @@
     'apk_version_code', package_list.version_code,
     'debuggable', package_list.debuggable
   )) packages_for_uid
-  FROM proc_uid
-  JOIN package_list USING (uid)
+  FROM process
+  JOIN package_list ON process.android_appid = package_list.uid
   GROUP BY upid
 )
 SELECT
diff --git a/src/trace_processor/metrics/metrics.descriptor.h b/src/trace_processor/metrics/metrics.descriptor.h
index 58a8996..6e5496c 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, 16359> kMetricsDescriptor{
+constexpr std::array<uint8_t, 16416> 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,
@@ -1106,299 +1106,303 @@
      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, 0x97, 0x01, 0x0a, 0x35, 0x70, 0x72, 0x6f, 0x74,
+     0x6c, 0x65, 0x73, 0x0a, 0xd0, 0x01, 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, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f,
      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, 0x22, 0x4d, 0x0a, 0x15, 0x41, 0x6e,
-     0x64, 0x72, 0x6f, 0x69, 0x64, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79,
-     0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x34, 0x0a, 0x16, 0x74,
-     0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x64, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61,
-     0x74, 0x65, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20,
-     0x01, 0x28, 0x0d, 0x52, 0x14, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x44, 0x75,
-     0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x46, 0x72, 0x61, 0x6d, 0x65,
-     0x73, 0x0a, 0xbb, 0x02, 0x0a, 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, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x6e, 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,
-     0xf5, 0x01, 0x0a, 0x10, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x54,
-     0x61, 0x73, 0x6b, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x43, 0x0a, 0x07,
-     0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 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, 0x41, 0x6e, 0x64, 0x72,
-     0x6f, 0x69, 0x64, 0x54, 0x61, 0x73, 0x6b, 0x4e, 0x61, 0x6d, 0x65, 0x73,
-     0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x07, 0x70, 0x72,
-     0x6f, 0x63, 0x65, 0x73, 0x73, 0x1a, 0x9b, 0x01, 0x0a, 0x07, 0x50, 0x72,
-     0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64,
-     0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 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, 0x1f,
-     0x0a, 0x0b, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x6e, 0x61, 0x6d,
-     0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x68, 0x72,
-     0x65, 0x61, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75,
-     0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x75, 0x69,
-     0x64, 0x12, 0x28, 0x0a, 0x10, 0x75, 0x69, 0x64, 0x5f, 0x70, 0x61, 0x63,
-     0x6b, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20,
-     0x03, 0x28, 0x09, 0x52, 0x0e, 0x75, 0x69, 0x64, 0x50, 0x61, 0x63, 0x6b,
-     0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x0a, 0xd5, 0x17, 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,
+     0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x22, 0x85, 0x01, 0x0a, 0x15, 0x41,
+     0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61,
+     0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x34, 0x0a, 0x16,
+     0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x64, 0x75, 0x70, 0x6c, 0x69, 0x63,
+     0x61, 0x74, 0x65, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01,
+     0x20, 0x01, 0x28, 0x0d, 0x52, 0x14, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x44,
+     0x75, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x46, 0x72, 0x61, 0x6d,
+     0x65, 0x73, 0x12, 0x36, 0x0a, 0x17, 0x64, 0x75, 0x70, 0x6c, 0x69, 0x63,
+     0x61, 0x74, 0x65, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x5f, 0x6c,
+     0x6f, 0x67, 0x67, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52,
+     0x15, 0x64, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x46, 0x72,
+     0x61, 0x6d, 0x65, 0x73, 0x4c, 0x6f, 0x67, 0x67, 0x65, 0x64, 0x0a, 0xbb,
+     0x02, 0x0a, 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, 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, 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, 0x6a, 0x61, 0x76, 0x61, 0x5f, 0x68,
-     0x65, 0x61, 0x70, 0x5f, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61,
-     0x6d, 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, 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,
-     0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6d, 0x65, 0x74, 0x72,
-     0x69, 0x63, 0x73, 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, 0x74, 0x61, 0x73, 0x6b, 0x5f,
-     0x6e, 0x61, 0x6d, 0x65, 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, 0xa4, 0x0c, 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, 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, 0x52, 0x0a, 0x13,
-     0x6a, 0x61, 0x76, 0x61, 0x5f, 0x68, 0x65, 0x61, 0x70, 0x5f, 0x68, 0x69,
-     0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x18, 0x15, 0x20, 0x01, 0x28,
-     0x0b, 0x32, 0x22, 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, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61,
-     0x6d, 0x52, 0x11, 0x6a, 0x61, 0x76, 0x61, 0x48, 0x65, 0x61, 0x70, 0x48,
-     0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 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,
+     0x63, 0x73, 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x74,
+     0x61, 0x73, 0x6b, 0x5f, 0x6e, 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, 0xf5, 0x01, 0x0a,
+     0x10, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x54, 0x61, 0x73, 0x6b,
+     0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x43, 0x0a, 0x07, 0x70, 0x72, 0x6f,
+     0x63, 0x65, 0x73, 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, 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, 0x12, 0x4f, 0x0a, 0x0f, 0x64, 0x69, 0x73,
+     0x54, 0x61, 0x73, 0x6b, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x2e, 0x50, 0x72,
+     0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65,
+     0x73, 0x73, 0x1a, 0x9b, 0x01, 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x63, 0x65,
+     0x73, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x01, 0x20,
+     0x01, 0x28, 0x03, 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, 0x1f, 0x0a, 0x0b, 0x74,
+     0x68, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03,
+     0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64,
+     0x4e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18,
+     0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x28,
+     0x0a, 0x10, 0x75, 0x69, 0x64, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67,
+     0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09,
+     0x52, 0x0e, 0x75, 0x69, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65,
+     0x4e, 0x61, 0x6d, 0x65, 0x0a, 0xd5, 0x17, 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, 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, 0x6a, 0x61, 0x76, 0x61, 0x5f, 0x68, 0x65, 0x61, 0x70,
+     0x5f, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 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, 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, 0x64, 0x69, 0x73,
      0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73,
-     0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x70, 0x65, 0x72,
+     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, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x6e, 0x61, 0x6d,
+     0x65, 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, 0xa4, 0x0c,
+     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, 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, 0x44, 0x69, 0x73, 0x70,
-     0x6c, 0x61, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x0e,
-     0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69,
-     0x63, 0x73, 0x12, 0x4f, 0x0a, 0x12, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69,
-     0x64, 0x5f, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73,
-     0x18, 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x65, 0x72,
+     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, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x54, 0x61, 0x73, 0x6b,
-     0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x10, 0x61, 0x6e, 0x64, 0x72, 0x6f,
-     0x69, 0x64, 0x54, 0x61, 0x73, 0x6b, 0x4e, 0x61, 0x6d, 0x65, 0x73, 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}};
+     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, 0x52, 0x0a, 0x13, 0x6a, 0x61, 0x76,
+     0x61, 0x5f, 0x68, 0x65, 0x61, 0x70, 0x5f, 0x68, 0x69, 0x73, 0x74, 0x6f,
+     0x67, 0x72, 0x61, 0x6d, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22,
+     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, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x52, 0x11,
+     0x6a, 0x61, 0x76, 0x61, 0x48, 0x65, 0x61, 0x70, 0x48, 0x69, 0x73, 0x74,
+     0x6f, 0x67, 0x72, 0x61, 0x6d, 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, 0x12, 0x4f, 0x0a, 0x0f, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61,
+     0x79, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x16, 0x20,
+     0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74,
+     0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e,
+     0x64, 0x72, 0x6f, 0x69, 0x64, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79,
+     0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x0e, 0x64, 0x69, 0x73,
+     0x70, 0x6c, 0x61, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12,
+     0x4f, 0x0a, 0x12, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x5f, 0x74,
+     0x61, 0x73, 0x6b, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x17, 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, 0x54, 0x61, 0x73, 0x6b, 0x4e, 0x61, 0x6d,
+     0x65, 0x73, 0x52, 0x10, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x54,
+     0x61, 0x73, 0x6b, 0x4e, 0x61, 0x6d, 0x65, 0x73, 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/process_tracker.cc b/src/trace_processor/process_tracker.cc
index c62c94e..628dd6b 100644
--- a/src/trace_processor/process_tracker.cc
+++ b/src/trace_processor/process_tracker.cc
@@ -255,6 +255,10 @@
 void ProcessTracker::SetProcessUid(UniquePid upid, uint32_t uid) {
   auto* process_table = context_->storage->mutable_process_table();
   process_table->mutable_uid()->Set(upid, uid);
+
+  // The notion of the app ID (as derived from the uid) is defined in
+  // frameworks/base/core/java/android/os/UserHandle.java
+  process_table->mutable_android_appid()->Set(upid, uid % 100000);
 }
 
 void ProcessTracker::SetProcessNameIfUnset(UniquePid upid,
diff --git a/src/trace_processor/tables/metadata_tables.h b/src/trace_processor/tables/metadata_tables.h
index dfcb98b..d1a9283 100644
--- a/src/trace_processor/tables/metadata_tables.h
+++ b/src/trace_processor/tables/metadata_tables.h
@@ -76,7 +76,8 @@
   C(base::Optional<int64_t>, start_ts)                 \
   C(base::Optional<int64_t>, end_ts)                   \
   C(base::Optional<uint32_t>, parent_upid)             \
-  C(base::Optional<uint32_t>, uid)
+  C(base::Optional<uint32_t>, uid)                     \
+  C(base::Optional<uint32_t>, android_appid)
 
 PERFETTO_TP_TABLE(PERFETTO_TP_PROCESS_TABLE_DEF);
 
diff --git a/src/tracing/core/shared_memory_arbiter_impl.cc b/src/tracing/core/shared_memory_arbiter_impl.cc
index f4ee8b3..14ba0d6 100644
--- a/src/tracing/core/shared_memory_arbiter_impl.cc
+++ b/src/tracing/core/shared_memory_arbiter_impl.cc
@@ -54,7 +54,7 @@
     SharedMemoryABI::PageLayout::kPageDiv1;
 
 // static
-constexpr BufferID SharedMemoryArbiterImpl::kUnboundReservationBufferId;
+constexpr BufferID SharedMemoryArbiterImpl::kInvalidBufferId;
 
 // static
 std::unique_ptr<SharedMemoryArbiter> SharedMemoryArbiter::CreateInstance(
@@ -452,42 +452,94 @@
   PERFETTO_DCHECK(target_buffer_id > 0);
   PERFETTO_CHECK(!initially_bound_);
 
+  std::unique_lock<std::mutex> scoped_lock(lock_);
+
+  // We should already be bound to an endpoint, but not fully bound.
+  PERFETTO_CHECK(!fully_bound_);
+  PERFETTO_CHECK(producer_endpoint_);
+  PERFETTO_CHECK(task_runner_);
+  PERFETTO_CHECK(task_runner_->RunsTasksOnCurrentThread());
+
+  BindStartupTargetBufferImpl(std::move(scoped_lock),
+                              target_buffer_reservation_id, target_buffer_id);
+}
+
+void SharedMemoryArbiterImpl::AbortStartupTracingForReservation(
+    uint16_t target_buffer_reservation_id) {
+  PERFETTO_CHECK(!initially_bound_);
+
+  std::unique_lock<std::mutex> scoped_lock(lock_);
+
+  // If we are already bound to an arbiter, we may need to flush after aborting
+  // the session, and thus should be running on the arbiter's task runner.
+  if (task_runner_ && !task_runner_->RunsTasksOnCurrentThread()) {
+    // We shouldn't post tasks while locked.
+    auto* task_runner = task_runner_;
+    scoped_lock.unlock();
+
+    auto weak_this = weak_ptr_factory_.GetWeakPtr();
+    task_runner->PostTask([weak_this, target_buffer_reservation_id]() {
+      if (!weak_this)
+        return;
+      weak_this->AbortStartupTracingForReservation(
+          target_buffer_reservation_id);
+    });
+    return;
+  }
+
+  PERFETTO_CHECK(!fully_bound_);
+
+  // Bind the target buffer reservation to an invalid buffer (ID 0), so that
+  // existing commits, as well as future commits (of currently acquired chunks),
+  // will be released as free free by the service but otherwise ignored (i.e.
+  // not copied into any valid target buffer).
+  BindStartupTargetBufferImpl(std::move(scoped_lock),
+                              target_buffer_reservation_id,
+                              /*target_buffer_id=*/kInvalidBufferId);
+}
+
+void SharedMemoryArbiterImpl::BindStartupTargetBufferImpl(
+    std::unique_lock<std::mutex> scoped_lock,
+    uint16_t target_buffer_reservation_id,
+    BufferID target_buffer_id) {
+  // We should already be bound to an endpoint if the target buffer is valid.
+  PERFETTO_DCHECK((producer_endpoint_ && task_runner_) ||
+                  target_buffer_id == kInvalidBufferId);
+
   MaybeUnboundBufferID reserved_id =
       MakeTargetBufferIdForReservation(target_buffer_reservation_id);
 
   bool should_flush = false;
   std::function<void()> flush_callback;
   std::vector<std::pair<WriterID, BufferID>> writers_to_register;
-  {
-    std::lock_guard<std::mutex> scoped_lock(lock_);
 
-    // We should already be bound to an endpoint, but not fully bound.
-    PERFETTO_CHECK(!fully_bound_);
-    PERFETTO_CHECK(producer_endpoint_);
-    PERFETTO_CHECK(task_runner_);
-    PERFETTO_CHECK(task_runner_->RunsTasksOnCurrentThread());
+  TargetBufferReservation& reservation =
+      target_buffer_reservations_[reserved_id];
+  PERFETTO_CHECK(!reservation.resolved);
+  reservation.resolved = true;
+  reservation.target_buffer = target_buffer_id;
 
-    PERFETTO_CHECK(target_buffer_reservations_[reserved_id] ==
-                   kUnboundReservationBufferId);
-    target_buffer_reservations_[reserved_id] = target_buffer_id;
-
-    // Collect trace writers associated with the reservation.
-    for (auto it = pending_writers_.begin(); it != pending_writers_.end();) {
-      if (it->second == reserved_id) {
+  // Collect trace writers associated with the reservation.
+  for (auto it = pending_writers_.begin(); it != pending_writers_.end();) {
+    if (it->second == reserved_id) {
+      // No need to register writers that have an invalid target buffer.
+      if (target_buffer_id != kInvalidBufferId) {
         writers_to_register.push_back(
             std::make_pair(it->first, target_buffer_id));
-        it = pending_writers_.erase(it);
-      } else {
-        it++;
       }
+      it = pending_writers_.erase(it);
+    } else {
+      it++;
     }
+  }
 
-    // If all buffer reservations are bound, we can flush pending commits.
-    if (UpdateFullyBoundLocked()) {
-      should_flush = true;
-      flush_callback = TakePendingFlushCallbacksLocked();
-    }
-  }  // scoped_lock
+  // If all buffer reservations are bound, we can flush pending commits.
+  if (UpdateFullyBoundLocked()) {
+    should_flush = true;
+    flush_callback = TakePendingFlushCallbacksLocked();
+  }
+
+  scoped_lock.unlock();
 
   // Register any newly bound trace writers with the service.
   for (const auto& writer_and_target_buffer : writers_to_register) {
@@ -620,9 +672,9 @@
       // |target_buffer_reservations_|. Otherwise, if the reservation was
       // already bound, choose the bound buffer ID now.
       auto it_and_inserted = target_buffer_reservations_.insert(
-          {target_buffer, kUnboundReservationBufferId});
-      if (it_and_inserted.first->second != kUnboundReservationBufferId)
-        target_buffer = it_and_inserted.first->second;
+          {target_buffer, TargetBufferReservation()});
+      if (it_and_inserted.first->second.resolved)
+        target_buffer = it_and_inserted.first->second.target_buffer;
     }
 
     if (IsReservationTargetBufferId(target_buffer)) {
@@ -633,7 +685,7 @@
       // Mark the arbiter as not fully bound, since we now have at least one
       // unbound trace writer / target buffer reservation.
       fully_bound_ = false;
-    } else {
+    } else if (target_buffer != kInvalidBufferId) {
       // Trace writer is bound, so arbiter should be bound to an endpoint, too.
       PERFETTO_CHECK(producer_endpoint_ && task_runner_);
       task_runner_to_register_on = task_runner_;
@@ -658,6 +710,8 @@
   base::TaskRunner* task_runner = nullptr;
   {
     std::lock_guard<std::mutex> scoped_lock(lock_);
+    active_writer_ids_.Free(id);
+
     auto it = pending_writers_.find(id);
     if (it != pending_writers_.end()) {
       // Writer hasn't been bound yet and thus also not yet registered with the
@@ -666,7 +720,6 @@
       return;
     }
 
-    active_writer_ids_.Free(id);
     task_runner = task_runner_;
   }  // scoped_lock
 
@@ -689,34 +742,37 @@
       continue;
     const auto it = target_buffer_reservations_.find(chunk.target_buffer());
     PERFETTO_DCHECK(it != target_buffer_reservations_.end());
-    if (it->second == kUnboundReservationBufferId) {
+    if (!it->second.resolved) {
       all_placeholders_replaced = false;
       continue;
     }
-    chunk.set_target_buffer(it->second);
+    chunk.set_target_buffer(it->second.target_buffer);
   }
   for (auto& chunk : *commit_data_req_->mutable_chunks_to_patch()) {
     if (!IsReservationTargetBufferId(chunk.target_buffer()))
       continue;
     const auto it = target_buffer_reservations_.find(chunk.target_buffer());
     PERFETTO_DCHECK(it != target_buffer_reservations_.end());
-    if (it->second == kUnboundReservationBufferId) {
+    if (!it->second.resolved) {
       all_placeholders_replaced = false;
       continue;
     }
-    chunk.set_target_buffer(it->second);
+    chunk.set_target_buffer(it->second.target_buffer);
   }
   return all_placeholders_replaced;
 }
 
 bool SharedMemoryArbiterImpl::UpdateFullyBoundLocked() {
-  PERFETTO_DCHECK(producer_endpoint_);
+  if (!producer_endpoint_) {
+    PERFETTO_DCHECK(!fully_bound_);
+    return false;
+  }
   // We're fully bound if all target buffer reservations have a valid associated
   // BufferID.
   fully_bound_ = std::none_of(
       target_buffer_reservations_.begin(), target_buffer_reservations_.end(),
-      [](std::pair<MaybeUnboundBufferID, BufferID> entry) {
-        return entry.second == kUnboundReservationBufferId;
+      [](std::pair<MaybeUnboundBufferID, TargetBufferReservation> entry) {
+        return !entry.second.resolved;
       });
   return fully_bound_;
 }
diff --git a/src/tracing/core/shared_memory_arbiter_impl.h b/src/tracing/core/shared_memory_arbiter_impl.h
index e5ec610..6bcdeb8 100644
--- a/src/tracing/core/shared_memory_arbiter_impl.h
+++ b/src/tracing/core/shared_memory_arbiter_impl.h
@@ -151,6 +151,8 @@
   void BindStartupTraceWriterRegistry(
       std::unique_ptr<StartupTraceWriterRegistry>,
       BufferID target_buffer) override;
+  void AbortStartupTracingForReservation(
+      uint16_t target_buffer_reservation_id) override;
   void NotifyFlushComplete(FlushRequestID) override;
 
   base::TaskRunner* task_runner() const { return task_runner_; }
@@ -166,9 +168,14 @@
   friend class StartupTraceWriterTest;
   friend class SharedMemoryArbiterImplTest;
 
+  struct TargetBufferReservation {
+    bool resolved = false;
+    BufferID target_buffer = kInvalidBufferId;
+  };
+
   // Placeholder for the actual target buffer ID of a startup target buffer
   // reservation ID in |target_buffer_reservations_|.
-  static constexpr BufferID kUnboundReservationBufferId = 0;
+  static constexpr BufferID kInvalidBufferId = 0;
 
   static SharedMemoryABI::PageLayout default_page_layout;
 
@@ -187,6 +194,10 @@
   // Called by the TraceWriter destructor.
   void ReleaseWriterID(WriterID);
 
+  void BindStartupTargetBufferImpl(std::unique_lock<std::mutex> scoped_lock,
+                                   uint16_t target_buffer_reservation_id,
+                                   BufferID target_buffer_id);
+
   // If any flush callbacks were queued up while the arbiter or any target
   // buffer reservation was unbound, this wraps the pending callbacks into a new
   // std::function and returns it. Otherwise returns an invalid std::function.
@@ -237,14 +248,15 @@
   std::vector<std::function<void()>> pending_flush_callbacks_;
 
   // Stores target buffer reservations for writers created via
-  // CreateStartupTraceWriter(). An unbound reservation will be associated with
-  // kStartupBufferPlaceholderId; a bound one is associated with the actual
+  // CreateStartupTraceWriter(). A bound reservation sets
+  // TargetBufferReservation::resolved to true and is associated with the actual
   // BufferID supplied in BindStartupTargetBuffer().
   //
   // TODO(eseckler): Clean up entries from this map. This would probably require
   // a method in SharedMemoryArbiter that allows a producer to invalidate a
   // reservation ID.
-  std::map<MaybeUnboundBufferID, BufferID> target_buffer_reservations_;
+  std::map<MaybeUnboundBufferID, TargetBufferReservation>
+      target_buffer_reservations_;
 
   // --- End lock-protected members ---
 
diff --git a/src/tracing/core/shared_memory_arbiter_impl_unittest.cc b/src/tracing/core/shared_memory_arbiter_impl_unittest.cc
index 73dc066..78343c9 100644
--- a/src/tracing/core/shared_memory_arbiter_impl_unittest.cc
+++ b/src/tracing/core/shared_memory_arbiter_impl_unittest.cc
@@ -402,6 +402,161 @@
   EXPECT_TRUE(flush_completed);
 }
 
+TEST_P(SharedMemoryArbiterImplTest, AbortStartupTracingForReservation) {
+  constexpr uint16_t kTargetBufferReservationId1 = 1;
+  constexpr uint16_t kTargetBufferReservationId2 = 2;
+
+  // Create an unbound arbiter and a startup writer.
+  arbiter_.reset(new SharedMemoryArbiterImpl(buf(), buf_size(), page_size(),
+                                             nullptr, nullptr));
+  SharedMemoryABI* shmem_abi = arbiter_->shmem_abi_for_testing();
+  std::unique_ptr<TraceWriter> writer =
+      arbiter_->CreateStartupTraceWriter(kTargetBufferReservationId1);
+
+  // Write two packet while unbound and flush the chunk after each packet. The
+  // writer will return the chunk to the arbiter and grab a new chunk for the
+  // second packet. The flush should only add the chunk into the queued commit
+  // request.
+  for (int i = 0; i < 2; i++) {
+    {
+      auto packet = writer->NewTracePacket();
+      packet->set_for_testing()->set_str("foo");
+    }
+    writer->Flush();
+  }
+
+  // Abort the first session. This should clear resolve the two chunks committed
+  // up to this point to an invalid target buffer (ID 0). They will remain
+  // buffered until bound to an endpoint.
+  arbiter_->AbortStartupTracingForReservation(kTargetBufferReservationId1);
+
+  // Bind to producer endpoint. The trace writer should not be registered as its
+  // target buffer is invalid. Since no startup sessions are active anymore, the
+  // arbiter should be fully bound. The commit data request is flushed.
+  EXPECT_CALL(mock_producer_endpoint_, RegisterTraceWriter(_, _)).Times(0);
+  EXPECT_CALL(mock_producer_endpoint_, CommitData(_, _))
+      .WillOnce(Invoke([shmem_abi](const CommitDataRequest& req,
+                                   MockProducerEndpoint::CommitDataCallback) {
+        ASSERT_EQ(2, req.chunks_to_move_size());
+        for (size_t i = 0; i < 2; i++) {
+          EXPECT_EQ(0u, req.chunks_to_move()[i].target_buffer());
+          SharedMemoryABI::Chunk chunk = shmem_abi->TryAcquireChunkForReading(
+              req.chunks_to_move()[i].page(), req.chunks_to_move()[i].chunk());
+          shmem_abi->ReleaseChunkAsFree(std::move(chunk));
+        }
+      }));
+  arbiter_->BindToProducerEndpoint(&mock_producer_endpoint_,
+                                   task_runner_.get());
+  EXPECT_TRUE(IsArbiterFullyBound());
+
+  // SMB should be free again, as no writer holds on to any chunk anymore.
+  for (size_t i = 0; i < shmem_abi->num_pages(); i++)
+    EXPECT_TRUE(shmem_abi->is_page_free(i));
+
+  // Write another packet into another chunk and commit it. It should be sent
+  // to the arbiter with invalid target buffer (ID 0).
+  {
+    auto packet = writer->NewTracePacket();
+    packet->set_for_testing()->set_str("foo");
+  }
+  EXPECT_CALL(mock_producer_endpoint_, CommitData(_, _))
+      .WillOnce(Invoke([shmem_abi](
+                           const CommitDataRequest& req,
+                           MockProducerEndpoint::CommitDataCallback callback) {
+        ASSERT_EQ(1, req.chunks_to_move_size());
+        EXPECT_EQ(0u, req.chunks_to_move()[0].target_buffer());
+        SharedMemoryABI::Chunk chunk = shmem_abi->TryAcquireChunkForReading(
+            req.chunks_to_move()[0].page(), req.chunks_to_move()[0].chunk());
+        shmem_abi->ReleaseChunkAsFree(std::move(chunk));
+        callback();
+      }));
+  bool flush_completed = false;
+  writer->Flush([&flush_completed] { flush_completed = true; });
+  EXPECT_TRUE(flush_completed);
+
+  // Creating a new startup writer for the same buffer does not cause it to
+  // register.
+  EXPECT_CALL(mock_producer_endpoint_, RegisterTraceWriter(_, _)).Times(0);
+  std::unique_ptr<TraceWriter> writer1b =
+      arbiter_->CreateStartupTraceWriter(kTargetBufferReservationId1);
+
+  // And a commit on this new writer should again be flushed to the invalid
+  // target buffer.
+  {
+    auto packet = writer1b->NewTracePacket();
+    packet->set_for_testing()->set_str("foo");
+  }
+  EXPECT_CALL(mock_producer_endpoint_, CommitData(_, _))
+      .WillOnce(Invoke([shmem_abi](
+                           const CommitDataRequest& req,
+                           MockProducerEndpoint::CommitDataCallback callback) {
+        ASSERT_EQ(1, req.chunks_to_move_size());
+        EXPECT_EQ(0u, req.chunks_to_move()[0].target_buffer());
+        SharedMemoryABI::Chunk chunk = shmem_abi->TryAcquireChunkForReading(
+            req.chunks_to_move()[0].page(), req.chunks_to_move()[0].chunk());
+        shmem_abi->ReleaseChunkAsFree(std::move(chunk));
+        callback();
+      }));
+  flush_completed = false;
+  writer1b->Flush([&flush_completed] { flush_completed = true; });
+  EXPECT_TRUE(flush_completed);
+
+  // Create another startup writer for another target buffer, which puts the
+  // arbiter back into unbound state.
+  std::unique_ptr<TraceWriter> writer2 =
+      arbiter_->CreateStartupTraceWriter(kTargetBufferReservationId2);
+  EXPECT_FALSE(IsArbiterFullyBound());
+
+  // Write a chunk into both writers. Both should be queued up into the next
+  // commit request.
+  {
+    auto packet = writer->NewTracePacket();
+    packet->set_for_testing()->set_str("foo");
+  }
+  writer->Flush();
+  {
+    auto packet = writer2->NewTracePacket();
+    packet->set_for_testing()->set_str("bar");
+  }
+  flush_completed = false;
+  writer2->Flush([&flush_completed] { flush_completed = true; });
+
+  // Destroy the first trace writer, which should cause the arbiter to post a
+  // task to unregister it.
+  auto checkpoint_writer =
+      task_runner_->CreateCheckpoint("writer_unregistered");
+  EXPECT_CALL(mock_producer_endpoint_,
+              UnregisterTraceWriter(writer->writer_id()))
+      .WillOnce(testing::InvokeWithoutArgs(checkpoint_writer));
+  writer.reset();
+  task_runner_->RunUntilCheckpoint("writer_unregistered", 5000);
+
+  // Abort the second session. Its commits should now also be associated with
+  // target buffer 0, and both writers' commits flushed.
+  EXPECT_CALL(mock_producer_endpoint_, RegisterTraceWriter(_, _)).Times(0);
+  EXPECT_CALL(mock_producer_endpoint_, CommitData(_, _))
+      .WillOnce(Invoke([shmem_abi](
+                           const CommitDataRequest& req,
+                           MockProducerEndpoint::CommitDataCallback callback) {
+        ASSERT_EQ(2, req.chunks_to_move_size());
+        for (size_t i = 0; i < 2; i++) {
+          EXPECT_EQ(0u, req.chunks_to_move()[i].target_buffer());
+          SharedMemoryABI::Chunk chunk = shmem_abi->TryAcquireChunkForReading(
+              req.chunks_to_move()[i].page(), req.chunks_to_move()[i].chunk());
+          shmem_abi->ReleaseChunkAsFree(std::move(chunk));
+        }
+        callback();
+      }));
+
+  arbiter_->AbortStartupTracingForReservation(kTargetBufferReservationId2);
+  EXPECT_TRUE(IsArbiterFullyBound());
+  EXPECT_TRUE(flush_completed);
+
+  // SMB should be free again, as no writer holds on to any chunk anymore.
+  for (size_t i = 0; i < shmem_abi->num_pages(); i++)
+    EXPECT_TRUE(shmem_abi->is_page_free(i));
+}
+
 // TODO(primiano): add multi-threaded tests.
 
 }  // namespace perfetto
diff --git a/test/cts/heapprofd_java_test_cts.cc b/test/cts/heapprofd_java_test_cts.cc
index 090bc48..e8d4701 100644
--- a/test/cts/heapprofd_java_test_cts.cc
+++ b/test/cts/heapprofd_java_test_cts.cc
@@ -34,6 +34,18 @@
 namespace perfetto {
 namespace {
 
+std::string RandomSessionName() {
+  std::random_device rd;
+  std::default_random_engine generator(rd());
+  std::uniform_int_distribution<char> distribution('a', 'z');
+
+  constexpr size_t kSessionNameLen = 20;
+  std::string result(kSessionNameLen, '\0');
+  for (size_t i = 0; i < kSessionNameLen; ++i)
+    result[i] = distribution(generator);
+  return result;
+}
+
 std::vector<protos::gen::TracePacket> ProfileRuntime(std::string app_name) {
   base::TestTaskRunner task_runner;
 
@@ -56,6 +68,7 @@
   TraceConfig trace_config;
   trace_config.add_buffers()->set_size_kb(20 * 1024);
   trace_config.set_duration_ms(6000);
+  trace_config.set_unique_session_name(RandomSessionName().c_str());
 
   auto* ds_config = trace_config.add_data_sources()->mutable_config();
   ds_config->set_name("android.java_hprof");
diff --git a/traced_perf.rc b/traced_perf.rc
index 2996558..692977c 100644
--- a/traced_perf.rc
+++ b/traced_perf.rc
@@ -22,6 +22,7 @@
 # * foreground task group as unwinding based on minidebug info is a heavyweight action.
 service traced_perf /system/bin/traced_perf
     class late_start
+    disabled
     socket traced_perf stream 0666 root root
     user nobody
     group nobody readproc
@@ -29,16 +30,18 @@
     writepid /dev/cpuset/foreground/tasks
 
 # Daemon run state:
-# * initially off (no clauses match by default)
+# * initially off
 # * |persist.traced_perf.enable| forces daemon to run unconditionally
 # * if kernel doesn't have perf_event_open LSM hooks, daemon is stopped
 # * otherwise, follow |traced.lazy.traced_perf| as an on-demand service
 on property:persist.traced_perf.enable=1
     start traced_perf
-on property:persist.traced_perf.enable=0 && property:sys.init.perf_lsm_hooks=""
+on property:persist.traced_perf.enable="" && property:sys.init.perf_lsm_hooks=""
     stop traced_perf
-on property:persist.traced_perf.enable=0 && property:sys.init.perf_lsm_hooks=1 && property:traced.lazy.traced_perf=1
+on property:persist.traced_perf.enable="" && property:sys.init.perf_lsm_hooks=1 && property:traced.lazy.traced_perf=1
     start traced_perf
-on property:persist.traced_perf.enable=0 && property:sys.init.perf_lsm_hooks=1 && property:traced.lazy.traced_perf=""
+on property:persist.traced_perf.enable="" && property:sys.init.perf_lsm_hooks=1 && property:traced.lazy.traced_perf=""
     stop traced_perf
 
+on property:persist.traced_perf.enable=0
+    setprop persist.traced_perf.enable ""
diff --git a/ui/src/controller/heap_profile_controller.ts b/ui/src/controller/heap_profile_controller.ts
index d6a22c1..ea7357f 100644
--- a/ui/src/controller/heap_profile_controller.ts
+++ b/ui/src/controller/heap_profile_controller.ts
@@ -96,7 +96,9 @@
             this.copyHeapProfile(selection);
 
         this.getHeapProfileMetadata(
-                selectedHeapProfile.ts, selectedHeapProfile.upid)
+                selection.type,
+                selectedHeapProfile.ts,
+                selectedHeapProfile.upid)
             .then(result => {
               if (result !== undefined) {
                 Object.assign(this.heapProfileDetails, result);
@@ -330,7 +332,7 @@
     return MIN_PIXEL_DISPLAYED * rootSize / width;
   }
 
-  async getHeapProfileMetadata(ts: number, upid: number) {
+  async getHeapProfileMetadata(type: string, ts: number, upid: number) {
     // Don't do anything if selection of the marker stayed the same.
     if ((this.lastSelectedHeapProfile !== undefined &&
          ((this.lastSelectedHeapProfile.ts === ts &&
@@ -343,15 +345,7 @@
     const pidValue = await this.args.engine.query(
         `select pid from process where upid = ${upid}`);
     const pid = pidValue.columns[0].longValues![0];
-    const allocatedMemory = await this.args.engine.query(
-        `select sum(size) from heap_profile_allocation where ts <= ${
-            ts} and size > 0 and upid = ${upid}`);
-    const allocated = allocatedMemory.columns[0].longValues![0];
-    const allocatedNotFreedMemory = await this.args.engine.query(
-        `select sum(size) from heap_profile_allocation where ts <= ${
-            ts} and upid = ${upid}`);
-    const allocatedNotFreed = allocatedNotFreedMemory.columns[0].longValues![0];
     const startTime = fromNs(ts) - globals.state.traceTime.startSec;
-    return {ts: startTime, allocated, allocatedNotFreed, tsNs: ts, pid, upid};
+    return {ts: startTime, tsNs: ts, pid, upid, type};
   }
 }
diff --git a/ui/src/frontend/flamegraph.ts b/ui/src/frontend/flamegraph.ts
index 79b6d69..ddd8c39 100644
--- a/ui/src/frontend/flamegraph.ts
+++ b/ui/src/frontend/flamegraph.ts
@@ -44,8 +44,14 @@
   return totalSize;
 }
 
+export interface NodeRendering {
+  totalSize?: string;
+  selfSize?: string;
+}
+
 export class Flamegraph {
   private isThumbnail = false;
+  private nodeRendering: NodeRendering = {};
   private flamegraphData: CallsiteInfo[];
   private maxDepth = -1;
   private totalSize = -1;
@@ -98,7 +104,9 @@
    * graph.
    */
   updateDataIfChanged(
-      flamegraphData: CallsiteInfo[], clickedCallsite?: CallsiteInfo) {
+      nodeRendering: NodeRendering, flamegraphData: CallsiteInfo[],
+      clickedCallsite?: CallsiteInfo) {
+    this.nodeRendering = nodeRendering;
     this.clickedCallsite = clickedCallsite;
     if (this.flamegraphData === flamegraphData) {
       return;
@@ -237,47 +245,45 @@
       const nameText = this.getCallsiteName(this.hoveredCallsite);
       lineSplitter =
           splitIfTooBig(nameText, width, ctx.measureText(nameText).width);
-      const nameTextWidth = lineSplitter.lineWidth;
+      let textWidth = lineSplitter.lineWidth;
       lines.push(...lineSplitter.lines);
 
       const mappingText = this.hoveredCallsite.mapping;
       lineSplitter =
           splitIfTooBig(mappingText, width, ctx.measureText(mappingText).width);
-      const mappingTextWidth = lineSplitter.lineWidth;
+      textWidth = Math.max(textWidth, lineSplitter.lineWidth);
       lines.push(...lineSplitter.lines);
 
-      const percentage = this.hoveredCallsite.totalSize / this.totalSize * 100;
-      const totalSizeText = `total: ${
-          this.displaySize(
-              this.hoveredCallsite.totalSize,
-              unit,
-              unit === 'B' ? 1024 : 1000)} (${percentage.toFixed(2)}%)`;
-      lineSplitter = splitIfTooBig(
-          totalSizeText, width, ctx.measureText(totalSizeText).width);
-      const totalSizeTextWidth = lineSplitter.lineWidth;
-      lines.push(...lineSplitter.lines);
+      if (this.nodeRendering.totalSize !== undefined) {
+        const percentage =
+            this.hoveredCallsite.totalSize / this.totalSize * 100;
+        const totalSizeText = `${this.nodeRendering.totalSize}: ${
+            this.displaySize(
+                this.hoveredCallsite.totalSize,
+                unit,
+                unit === 'B' ? 1024 : 1000)} (${percentage.toFixed(2)}%)`;
+        lineSplitter = splitIfTooBig(
+            totalSizeText, width, ctx.measureText(totalSizeText).width);
+        textWidth = Math.max(textWidth, lineSplitter.lineWidth);
+        lines.push(...lineSplitter.lines);
+      }
 
-      let selfSizeWidth = 0;
-      if (this.hoveredCallsite.selfSize > 0) {
+      if (this.nodeRendering.selfSize !== undefined &&
+          this.hoveredCallsite.selfSize > 0) {
         const selfPercentage =
             this.hoveredCallsite.selfSize / this.totalSize * 100;
-        const selfSizeText = `self: ${
+        const selfSizeText = `${this.nodeRendering.selfSize}: ${
             this.displaySize(
                 this.hoveredCallsite.selfSize,
                 unit,
                 unit === 'B' ? 1024 : 1000)} (${selfPercentage.toFixed(2)}%)`;
         lineSplitter = splitIfTooBig(
             selfSizeText, width, ctx.measureText(selfSizeText).width);
-        selfSizeWidth = lineSplitter.lineWidth;
+        textWidth = Math.max(textWidth, lineSplitter.lineWidth);
         lines.push(...lineSplitter.lines);
       }
 
-      const rectWidth = Math.max(
-                            nameTextWidth,
-                            mappingTextWidth,
-                            totalSizeTextWidth,
-                            selfSizeWidth) +
-          16;
+      const rectWidth = textWidth + 16;
       const rectXStart = this.hoveredX + 8 + rectWidth > width ?
           width - rectWidth - 8 :
           this.hoveredX + 8;
diff --git a/ui/src/frontend/globals.ts b/ui/src/frontend/globals.ts
index 5e3b3d3..4b45c88 100644
--- a/ui/src/frontend/globals.ts
+++ b/ui/src/frontend/globals.ts
@@ -51,11 +51,10 @@
 }
 
 export interface HeapProfileDetails {
+  type?: string;
   id?: number;
   ts?: number;
   tsNs?: number;
-  allocated?: number;
-  allocatedNotFreed?: number;
   pid?: number;
   upid?: number;
   flamegraph?: CallsiteInfo[];
diff --git a/ui/src/frontend/heap_profile_panel.ts b/ui/src/frontend/heap_profile_panel.ts
index 8c92778..6b131e2 100644
--- a/ui/src/frontend/heap_profile_panel.ts
+++ b/ui/src/frontend/heap_profile_panel.ts
@@ -24,7 +24,7 @@
 import {HeapProfileFlamegraphViewingOption} from '../common/state';
 import {timeToCode} from '../common/time';
 
-import {Flamegraph} from './flamegraph';
+import {Flamegraph, NodeRendering} from './flamegraph';
 import {globals} from './globals';
 import {Panel, PanelSize} from './panel';
 import {debounce} from './rate_limiters';
@@ -33,8 +33,34 @@
 
 const HEADER_HEIGHT = 30;
 
+enum ProfileType {
+  NATIVE_HEAP_PROFILE = 'native',
+  JAVA_HEAP_GRAPH = 'graph',
+}
+
+function isProfileType(s: string): s is ProfileType {
+  return Object.values(ProfileType).includes(s as ProfileType);
+}
+
+function toProfileType(s: string): ProfileType {
+  if (!isProfileType(s)) {
+    throw new Error('Unknown type ${s}');
+  }
+  return s;
+}
+
+const RENDER_SELF_AND_TOTAL: NodeRendering = {
+  selfSize: 'Self',
+  totalSize: 'Total',
+};
+const RENDER_OBJ_COUNT: NodeRendering = {
+  selfSize: 'Self objects',
+  totalSize: 'Subtree objects',
+};
+
 export class HeapProfileDetailsPanel extends
     Panel<HeapProfileDetailsPanelAttrs> {
+  private profileType?: ProfileType = undefined;
   private ts = 0;
   private pid = 0;
   private flamegraph: Flamegraph = new Flamegraph([]);
@@ -43,18 +69,17 @@
     this.updateFocusRegex();
   }, 20);
 
-
   view() {
     const heapDumpInfo = globals.heapProfileDetails;
-    if (heapDumpInfo && heapDumpInfo.ts !== undefined &&
-        heapDumpInfo.allocated !== undefined &&
-        heapDumpInfo.allocatedNotFreed !== undefined &&
-        heapDumpInfo.tsNs !== undefined && heapDumpInfo.pid !== undefined &&
-        heapDumpInfo.upid !== undefined) {
+    if (heapDumpInfo && heapDumpInfo.type !== undefined &&
+        heapDumpInfo.ts !== undefined && heapDumpInfo.tsNs !== undefined &&
+        heapDumpInfo.pid !== undefined && heapDumpInfo.upid !== undefined) {
+      this.profileType = toProfileType(heapDumpInfo.type);
       this.ts = heapDumpInfo.tsNs;
       this.pid = heapDumpInfo.pid;
       if (heapDumpInfo.flamegraph) {
-        this.flamegraph.updateDataIfChanged(heapDumpInfo.flamegraph);
+        this.flamegraph.updateDataIfChanged(
+            this.nodeRendering(), heapDumpInfo.flamegraph);
       }
       const height = heapDumpInfo.flamegraph ?
           this.flamegraph.getHeight() + HEADER_HEIGHT :
@@ -86,7 +111,7 @@
             [
               m('div.options',
                 [
-                  m('div.title', `Heap Profile:`),
+                  m('div.title', this.getTitle()),
                   this.getViewingOptionButtons(),
                 ]),
               m('div.details',
@@ -121,6 +146,34 @@
     }
   }
 
+  private getTitle(): string {
+    switch (this.profileType!) {
+      case ProfileType.NATIVE_HEAP_PROFILE:
+        return 'Heap Profile:';
+      case ProfileType.JAVA_HEAP_GRAPH:
+        return 'Java Heap:';
+      default:
+        throw new Error('unknown type');
+    }
+  }
+
+  private nodeRendering(): NodeRendering {
+    const viewingOption =
+        globals.state.currentHeapProfileFlamegraph!.viewingOption;
+    switch (this.profileType!) {
+      case ProfileType.NATIVE_HEAP_PROFILE:
+        return RENDER_SELF_AND_TOTAL;
+      case ProfileType.JAVA_HEAP_GRAPH:
+        if (viewingOption === OBJECTS_ALLOCATED_NOT_FREED_KEY) {
+          return RENDER_OBJ_COUNT;
+        } else {
+          return RENDER_SELF_AND_TOTAL;
+        }
+      default:
+        throw new Error('unknown type');
+    }
+  }
+
   private updateFocusRegex() {
     globals.dispatch(Actions.changeFocusHeapProfileFlamegraph({
       focusRegex: this.focusRegex,
@@ -135,36 +188,41 @@
   }
 
   getViewingOptionButtons(): m.Children {
-    return m(
-        'div',
-        m(`button${this.getButtonsClass(SPACE_MEMORY_ALLOCATED_NOT_FREED_KEY)}`,
-          {
-            onclick: () => {
-              this.changeViewingOption(SPACE_MEMORY_ALLOCATED_NOT_FREED_KEY);
-            }
-          },
-          'space'),
-        m(`button${this.getButtonsClass(ALLOC_SPACE_MEMORY_ALLOCATED_KEY)}`,
-          {
-            onclick: () => {
-              this.changeViewingOption(ALLOC_SPACE_MEMORY_ALLOCATED_KEY);
-            }
-          },
-          'alloc space'),
-        m(`button${this.getButtonsClass(OBJECTS_ALLOCATED_NOT_FREED_KEY)}`,
-          {
-            onclick: () => {
-              this.changeViewingOption(OBJECTS_ALLOCATED_NOT_FREED_KEY);
-            }
-          },
-          'objects'),
-        m(`button${this.getButtonsClass(OBJECTS_ALLOCATED_KEY)}`,
-          {
-            onclick: () => {
-              this.changeViewingOption(OBJECTS_ALLOCATED_KEY);
-            }
-          },
-          'alloc objects'));
+    const viewingOptions = [
+      m(`button${this.getButtonsClass(SPACE_MEMORY_ALLOCATED_NOT_FREED_KEY)}`,
+        {
+          onclick: () => {
+            this.changeViewingOption(SPACE_MEMORY_ALLOCATED_NOT_FREED_KEY);
+          }
+        },
+        'space'),
+      m(`button${this.getButtonsClass(OBJECTS_ALLOCATED_NOT_FREED_KEY)}`,
+        {
+          onclick: () => {
+            this.changeViewingOption(OBJECTS_ALLOCATED_NOT_FREED_KEY);
+          }
+        },
+        'objects'),
+    ];
+
+    if (this.profileType === ProfileType.NATIVE_HEAP_PROFILE) {
+      viewingOptions.push(
+          m(`button${this.getButtonsClass(ALLOC_SPACE_MEMORY_ALLOCATED_KEY)}`,
+            {
+              onclick: () => {
+                this.changeViewingOption(ALLOC_SPACE_MEMORY_ALLOCATED_KEY);
+              }
+            },
+            'alloc space'),
+          m(`button${this.getButtonsClass(OBJECTS_ALLOCATED_KEY)}`,
+            {
+              onclick: () => {
+                this.changeViewingOption(OBJECTS_ALLOCATED_KEY);
+              }
+            },
+            'alloc objects'));
+    }
+    return m('div', ...viewingOptions);
   }
 
   changeViewingOption(viewingOption: HeapProfileFlamegraphViewingOption) {
@@ -182,7 +240,8 @@
   private changeFlamegraphData() {
     const data = globals.heapProfileDetails;
     const flamegraphData = data.flamegraph === undefined ? [] : data.flamegraph;
-    this.flamegraph.updateDataIfChanged(flamegraphData, data.expandedCallsite);
+    this.flamegraph.updateDataIfChanged(
+        this.nodeRendering(), flamegraphData, data.expandedCallsite);
   }
 
   renderCanvas(ctx: CanvasRenderingContext2D, size: PanelSize) {