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) {