Merge "processor: Ignore misordered slice events."
diff --git a/Android.bp b/Android.bp
index 7be3725..7ec6c76 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1411,6 +1411,7 @@
name: "perfetto_protos_perfetto_trace_android_lite_gen",
srcs: [
"protos/perfetto/trace/android/android_log.proto",
+ "protos/perfetto/trace/android/graphics_frame_event.proto",
"protos/perfetto/trace/android/packages_list.proto",
],
tools: [
@@ -1419,6 +1420,7 @@
cmd: "mkdir -p $(genDir)/external/perfetto/protos && $(location aprotoc) --cpp_out=$(genDir)/external/perfetto/protos --proto_path=external/perfetto/protos $(in)",
out: [
"external/perfetto/protos/perfetto/trace/android/android_log.pb.cc",
+ "external/perfetto/protos/perfetto/trace/android/graphics_frame_event.pb.cc",
"external/perfetto/protos/perfetto/trace/android/packages_list.pb.cc",
],
}
@@ -1428,6 +1430,7 @@
name: "perfetto_protos_perfetto_trace_android_lite_gen_headers",
srcs: [
"protos/perfetto/trace/android/android_log.proto",
+ "protos/perfetto/trace/android/graphics_frame_event.proto",
"protos/perfetto/trace/android/packages_list.proto",
],
tools: [
@@ -1436,6 +1439,7 @@
cmd: "mkdir -p $(genDir)/external/perfetto/protos && $(location aprotoc) --cpp_out=$(genDir)/external/perfetto/protos --proto_path=external/perfetto/protos $(in)",
out: [
"external/perfetto/protos/perfetto/trace/android/android_log.pb.h",
+ "external/perfetto/protos/perfetto/trace/android/graphics_frame_event.pb.h",
"external/perfetto/protos/perfetto/trace/android/packages_list.pb.h",
],
export_include_dirs: [
@@ -1448,6 +1452,7 @@
name: "perfetto_protos_perfetto_trace_android_zero_gen",
srcs: [
"protos/perfetto/trace/android/android_log.proto",
+ "protos/perfetto/trace/android/graphics_frame_event.proto",
"protos/perfetto/trace/android/packages_list.proto",
],
tools: [
@@ -1457,6 +1462,7 @@
cmd: "mkdir -p $(genDir)/external/perfetto/protos && $(location aprotoc) --cpp_out=$(genDir)/external/perfetto/protos --proto_path=external/perfetto/protos --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_protozero_plugin___gn_standalone_toolchain_gcc_like_host_) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/protos $(in)",
out: [
"external/perfetto/protos/perfetto/trace/android/android_log.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/android/graphics_frame_event.pbzero.cc",
"external/perfetto/protos/perfetto/trace/android/packages_list.pbzero.cc",
],
}
@@ -1466,6 +1472,7 @@
name: "perfetto_protos_perfetto_trace_android_zero_gen_headers",
srcs: [
"protos/perfetto/trace/android/android_log.proto",
+ "protos/perfetto/trace/android/graphics_frame_event.proto",
"protos/perfetto/trace/android/packages_list.proto",
],
tools: [
@@ -1475,6 +1482,7 @@
cmd: "mkdir -p $(genDir)/external/perfetto/protos && $(location aprotoc) --cpp_out=$(genDir)/external/perfetto/protos --proto_path=external/perfetto/protos --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_protozero_plugin___gn_standalone_toolchain_gcc_like_host_) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/protos $(in)",
out: [
"external/perfetto/protos/perfetto/trace/android/android_log.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/android/graphics_frame_event.pbzero.h",
"external/perfetto/protos/perfetto/trace/android/packages_list.pbzero.h",
],
export_include_dirs: [
@@ -2109,6 +2117,7 @@
"protos/perfetto/trace/test_event.proto",
"protos/perfetto/trace/trace.proto",
"protos/perfetto/trace/trace_packet.proto",
+ "protos/perfetto/trace/trace_packet_defaults.proto",
],
tools: [
"aprotoc",
@@ -2118,6 +2127,7 @@
"external/perfetto/protos/perfetto/trace/test_event.pb.cc",
"external/perfetto/protos/perfetto/trace/trace.pb.cc",
"external/perfetto/protos/perfetto/trace/trace_packet.pb.cc",
+ "external/perfetto/protos/perfetto/trace/trace_packet_defaults.pb.cc",
],
}
@@ -2128,6 +2138,7 @@
"protos/perfetto/trace/test_event.proto",
"protos/perfetto/trace/trace.proto",
"protos/perfetto/trace/trace_packet.proto",
+ "protos/perfetto/trace/trace_packet_defaults.proto",
],
tools: [
"aprotoc",
@@ -2137,6 +2148,7 @@
"external/perfetto/protos/perfetto/trace/test_event.pb.h",
"external/perfetto/protos/perfetto/trace/trace.pb.h",
"external/perfetto/protos/perfetto/trace/trace_packet.pb.h",
+ "external/perfetto/protos/perfetto/trace/trace_packet_defaults.pb.h",
],
export_include_dirs: [
"protos",
@@ -2749,6 +2761,7 @@
"protos/perfetto/trace/test_event.proto",
"protos/perfetto/trace/trace.proto",
"protos/perfetto/trace/trace_packet.proto",
+ "protos/perfetto/trace/trace_packet_defaults.proto",
"protos/perfetto/trace/trigger.proto",
],
tools: [
@@ -2762,6 +2775,7 @@
"external/perfetto/protos/perfetto/trace/test_event.pbzero.cc",
"external/perfetto/protos/perfetto/trace/trace.pbzero.cc",
"external/perfetto/protos/perfetto/trace/trace_packet.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/trace_packet_defaults.pbzero.cc",
"external/perfetto/protos/perfetto/trace/trigger.pbzero.cc",
],
}
@@ -2775,6 +2789,7 @@
"protos/perfetto/trace/test_event.proto",
"protos/perfetto/trace/trace.proto",
"protos/perfetto/trace/trace_packet.proto",
+ "protos/perfetto/trace/trace_packet_defaults.proto",
"protos/perfetto/trace/trigger.proto",
],
tools: [
@@ -2788,6 +2803,7 @@
"external/perfetto/protos/perfetto/trace/test_event.pbzero.h",
"external/perfetto/protos/perfetto/trace/trace.pbzero.h",
"external/perfetto/protos/perfetto/trace/trace_packet.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/trace_packet_defaults.pbzero.h",
"external/perfetto/protos/perfetto/trace/trigger.pbzero.h",
],
export_include_dirs: [
@@ -3731,6 +3747,7 @@
"src/trace_processor/counter_values_table.cc",
"src/trace_processor/event_tracker.cc",
"src/trace_processor/filtered_row_index.cc",
+ "src/trace_processor/forwarding_trace_parser.cc",
"src/trace_processor/ftrace_descriptors.cc",
"src/trace_processor/ftrace_utils.cc",
"src/trace_processor/fuchsia_provider_view.cc",
@@ -3902,6 +3919,7 @@
"src/trace_processor/counter_values_table.cc",
"src/trace_processor/event_tracker.cc",
"src/trace_processor/filtered_row_index.cc",
+ "src/trace_processor/forwarding_trace_parser.cc",
"src/trace_processor/ftrace_descriptors.cc",
"src/trace_processor/ftrace_utils.cc",
"src/trace_processor/fuchsia_provider_view.cc",
diff --git a/BUILD b/BUILD
index 144c09f..6703ee1 100644
--- a/BUILD
+++ b/BUILD
@@ -299,6 +299,8 @@
"src/trace_processor/export_json.h",
"src/trace_processor/filtered_row_index.cc",
"src/trace_processor/filtered_row_index.h",
+ "src/trace_processor/forwarding_trace_parser.cc",
+ "src/trace_processor/forwarding_trace_parser.h",
"src/trace_processor/ftrace_descriptors.cc",
"src/trace_processor/ftrace_descriptors.h",
"src/trace_processor/ftrace_utils.cc",
@@ -591,6 +593,8 @@
"src/trace_processor/export_json.h",
"src/trace_processor/filtered_row_index.cc",
"src/trace_processor/filtered_row_index.h",
+ "src/trace_processor/forwarding_trace_parser.cc",
+ "src/trace_processor/forwarding_trace_parser.h",
"src/trace_processor/ftrace_descriptors.cc",
"src/trace_processor/ftrace_descriptors.h",
"src/trace_processor/ftrace_utils.cc",
@@ -835,6 +839,8 @@
"src/trace_processor/export_json.h",
"src/trace_processor/filtered_row_index.cc",
"src/trace_processor/filtered_row_index.h",
+ "src/trace_processor/forwarding_trace_parser.cc",
+ "src/trace_processor/forwarding_trace_parser.h",
"src/trace_processor/ftrace_descriptors.cc",
"src/trace_processor/ftrace_descriptors.h",
"src/trace_processor/ftrace_utils.cc",
diff --git a/BUILD.gn b/BUILD.gn
index bf85e54..b14cf0c 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -296,11 +296,11 @@
if (perfetto_build_with_embedder) {
if (build_with_chromium) {
- libperfetto_target_type = "component"
+ lib_target_type = "component"
} else {
- libperfetto_target_type = "source_set"
+ lib_target_type = "source_set"
}
- target(libperfetto_target_type, "libperfetto") {
+ target(lib_target_type, "libperfetto") {
public_configs = [ "gn:public_config" ]
deps = [
"src/tracing",
@@ -316,6 +316,17 @@
"protos/perfetto/trace/track_event:zero",
]
}
+ target(lib_target_type, "libtrace_processor") {
+ public_configs = [ "gn:public_config" ]
+ deps = [
+ "src/trace_processor:lib",
+ ]
+ configs -= [ "//build/config/compiler:chromium_code" ]
+ configs += [ "//build/config/compiler:no_chromium_code" ]
+ public_deps = [
+ "include/perfetto/trace_processor",
+ ]
+ }
}
if (perfetto_build_standalone) {
diff --git a/include/perfetto/ext/base/uuid.h b/include/perfetto/ext/base/uuid.h
index c4e8e67..7994021 100644
--- a/include/perfetto/ext/base/uuid.h
+++ b/include/perfetto/ext/base/uuid.h
@@ -18,11 +18,16 @@
#define INCLUDE_PERFETTO_EXT_BASE_UUID_H_
#include <array>
+#include <string>
namespace perfetto {
namespace base {
-std::array<uint8_t, 16> Uuidv4();
+using Uuid = std::array<uint8_t, 16>;
+Uuid Uuidv4();
+
+Uuid StringToUuid(const std::string&);
+std::string UuidToString(const Uuid&);
} // namespace base
} // namespace perfetto
diff --git a/include/perfetto/ext/base/watchdog.h b/include/perfetto/ext/base/watchdog.h
index 02f1918..a10fde1 100644
--- a/include/perfetto/ext/base/watchdog.h
+++ b/include/perfetto/ext/base/watchdog.h
@@ -21,9 +21,17 @@
#include "perfetto/base/build_config.h"
+// The POSIX watchdog is only supported on Linux and Android in non-embedder
+// builds.
#if (PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)) && \
!PERFETTO_BUILDFLAG(PERFETTO_EMBEDDER_BUILD)
+#define PERFETTO_USE_POSIX_WATCHDOG() 1
+#else
+#define PERFETTO_USE_POSIX_WATCHDOG() 0
+#endif
+
+#if PERFETTO_USE_POSIX_WATCHDOG()
#include "perfetto/ext/base/watchdog_posix.h"
#else
#include "perfetto/ext/base/watchdog_noop.h"
diff --git a/include/perfetto/ext/tracing/core/BUILD.gn b/include/perfetto/ext/tracing/core/BUILD.gn
index cac4d6c..5dc8c88 100644
--- a/include/perfetto/ext/tracing/core/BUILD.gn
+++ b/include/perfetto/ext/tracing/core/BUILD.gn
@@ -19,6 +19,7 @@
]
sources = [
"basic_types.h",
+ "buffer_exhausted_policy.h",
"commit_data_request.h",
"consumer.h",
"observable_events.h",
diff --git a/include/perfetto/ext/tracing/core/buffer_exhausted_policy.h b/include/perfetto/ext/tracing/core/buffer_exhausted_policy.h
new file mode 100644
index 0000000..cd8ec2c
--- /dev/null
+++ b/include/perfetto/ext/tracing/core/buffer_exhausted_policy.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_BUFFER_EXHAUSTED_POLICY_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_CORE_BUFFER_EXHAUSTED_POLICY_H_
+
+namespace perfetto {
+
+// Determines how SharedMemoryArbiterImpl::GetNewChunk() behaves when no free
+// chunks are available.
+enum class BufferExhaustedPolicy {
+ // SharedMemoryArbiterImpl::GetNewChunk() will stall if no free SMB chunk is
+ // available and wait for the tracing service to free one. Note that this
+ // requires that messages the arbiter sends to the tracing service (from any
+ // TraceWriter thread) will be received by it, even if all TraceWriter threads
+ // are stalled.
+ kStall,
+
+ // SharedMemoryArbiterImpl::GetNewChunk() will return an invalid chunk if no
+ // free SMB chunk is available. In this case, the TraceWriter will fall back
+ // to a garbage chunk and drop written data until acquiring a future chunk
+ // succeeds again.
+ kDrop,
+
+ // TODO(eseckler): Switch to kDrop by default and change the Android code to
+ // explicitly request kStall instead.
+ kDefault = kStall
+};
+
+} // namespace perfetto
+
+#endif // INCLUDE_PERFETTO_EXT_TRACING_CORE_BUFFER_EXHAUSTED_POLICY_H_
diff --git a/include/perfetto/ext/tracing/core/shared_memory_arbiter.h b/include/perfetto/ext/tracing/core/shared_memory_arbiter.h
index d2a6f73..4e757ee 100644
--- a/include/perfetto/ext/tracing/core/shared_memory_arbiter.h
+++ b/include/perfetto/ext/tracing/core/shared_memory_arbiter.h
@@ -25,6 +25,7 @@
#include "perfetto/base/export.h"
#include "perfetto/ext/tracing/core/basic_types.h"
+#include "perfetto/ext/tracing/core/buffer_exhausted_policy.h"
#include "perfetto/ext/tracing/core/tracing_service.h"
namespace perfetto {
@@ -43,26 +44,6 @@
// from the SharedMemory it receives from the Service-side.
class PERFETTO_EXPORT SharedMemoryArbiter {
public:
- // Determines how GetNewChunk() behaves when no free chunks are available.
- enum class BufferExhaustedPolicy {
- // SharedMemoryArbiterImpl::GetNewChunk() will stall if no free SMB chunk is
- // available and wait for the tracing service to free one. Note that this
- // requires that messages the arbiter sends to the tracing service (from any
- // TraceWriter thread) will be received by it, even if all TraceWriter
- // threads are stalled.
- kStall,
-
- // SharedMemoryArbiterImpl::GetNewChunk() will return an invalid chunk if no
- // free SMB chunk is available. In this case, the TraceWriter will fall back
- // to a garbage chunk and drop written data until acquiring a future chunk
- // succeeds again.
- kDrop,
-
- // TODO(eseckler): Switch to kDrop by default and change the Android code to
- // explicitly request kStall instead.
- kDefault = kStall
- };
-
virtual ~SharedMemoryArbiter();
// Creates a new TraceWriter and assigns it a new WriterID. The WriterID is
diff --git a/include/perfetto/ext/tracing/core/startup_trace_writer.h b/include/perfetto/ext/tracing/core/startup_trace_writer.h
index 7503e49..52d18eb 100644
--- a/include/perfetto/ext/tracing/core/startup_trace_writer.h
+++ b/include/perfetto/ext/tracing/core/startup_trace_writer.h
@@ -26,6 +26,7 @@
#include "perfetto/ext/base/optional.h"
#include "perfetto/ext/base/thread_checker.h"
#include "perfetto/ext/tracing/core/basic_types.h"
+#include "perfetto/ext/tracing/core/buffer_exhausted_policy.h"
#include "perfetto/ext/tracing/core/shared_memory_abi.h"
#include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
#include "perfetto/ext/tracing/core/trace_writer.h"
@@ -125,7 +126,7 @@
// to by the handle. The writer can later be bound by calling
// BindToTraceWriter(). The registry handle may be nullptr in tests.
StartupTraceWriter(std::shared_ptr<StartupTraceWriterRegistryHandle>,
- SharedMemoryArbiter::BufferExhaustedPolicy);
+ BufferExhaustedPolicy);
StartupTraceWriter(const StartupTraceWriter&) = delete;
StartupTraceWriter& operator=(const StartupTraceWriter&) = delete;
@@ -169,8 +170,8 @@
// check on later calls to NewTracePacket().
bool was_bound_ = false;
- const SharedMemoryArbiter::BufferExhaustedPolicy buffer_exhausted_policy_ =
- SharedMemoryArbiter::BufferExhaustedPolicy::kDefault;
+ const BufferExhaustedPolicy buffer_exhausted_policy_ =
+ BufferExhaustedPolicy::kDefault;
// All variables below this point are protected by |lock_|.
std::mutex lock_;
diff --git a/include/perfetto/ext/tracing/core/startup_trace_writer_registry.h b/include/perfetto/ext/tracing/core/startup_trace_writer_registry.h
index e49a910..5b839bb 100644
--- a/include/perfetto/ext/tracing/core/startup_trace_writer_registry.h
+++ b/include/perfetto/ext/tracing/core/startup_trace_writer_registry.h
@@ -25,6 +25,7 @@
#include "perfetto/base/export.h"
#include "perfetto/ext/base/weak_ptr.h"
#include "perfetto/ext/tracing/core/basic_types.h"
+#include "perfetto/ext/tracing/core/buffer_exhausted_policy.h"
#include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
namespace perfetto {
@@ -74,8 +75,7 @@
// destroyed by the caller directly, but instead returned to the registry by
// calling StartupTraceWriter::ReturnToRegistry.
std::unique_ptr<StartupTraceWriter> CreateUnboundTraceWriter(
- SharedMemoryArbiter::BufferExhaustedPolicy =
- SharedMemoryArbiter::BufferExhaustedPolicy::kDefault);
+ BufferExhaustedPolicy = BufferExhaustedPolicy::kDefault);
// Binds all StartupTraceWriters created by this registry to the given arbiter
// and target buffer. Should only be called once and on the passed
diff --git a/include/perfetto/ext/tracing/core/tracing_service.h b/include/perfetto/ext/tracing/core/tracing_service.h
index 0cb7dbd..e1abe58 100644
--- a/include/perfetto/ext/tracing/core/tracing_service.h
+++ b/include/perfetto/ext/tracing/core/tracing_service.h
@@ -26,6 +26,7 @@
#include "perfetto/base/export.h"
#include "perfetto/ext/base/scoped_file.h"
#include "perfetto/ext/tracing/core/basic_types.h"
+#include "perfetto/ext/tracing/core/buffer_exhausted_policy.h"
#include "perfetto/ext/tracing/core/shared_memory.h"
namespace perfetto {
@@ -104,7 +105,9 @@
// upon creation of the data source (StartDataSource()) in the
// DataSourceConfig.target_buffer().
virtual std::unique_ptr<TraceWriter> CreateTraceWriter(
- BufferID target_buffer) = 0;
+ BufferID target_buffer,
+ BufferExhaustedPolicy buffer_exhausted_policy =
+ BufferExhaustedPolicy::kDefault) = 0;
// If TracingService::ConnectProducer is called with |in_process=true|,
// this returns the producer's SharedMemoryArbiter which can be used
diff --git a/include/perfetto/trace_processor/basic_types.h b/include/perfetto/trace_processor/basic_types.h
index 76d14d6..59fb559 100644
--- a/include/perfetto/trace_processor/basic_types.h
+++ b/include/perfetto/trace_processor/basic_types.h
@@ -22,14 +22,15 @@
#include <stdint.h>
#include <string>
+#include "perfetto/base/export.h"
+
namespace perfetto {
namespace trace_processor {
-struct Config {
-};
+struct PERFETTO_EXPORT Config {};
// Represents a dynamically typed value returned by SQL.
-struct SqlValue {
+struct PERFETTO_EXPORT SqlValue {
// Represents the type of the value.
enum Type {
kNull = 0,
diff --git a/include/perfetto/trace_processor/status.h b/include/perfetto/trace_processor/status.h
index 934c01b..ee7271a 100644
--- a/include/perfetto/trace_processor/status.h
+++ b/include/perfetto/trace_processor/status.h
@@ -20,6 +20,8 @@
#include <stdarg.h>
#include <string>
+#include "perfetto/base/export.h"
+
namespace perfetto {
namespace trace_processor {
@@ -31,7 +33,7 @@
// This can used as the return type of functions which would usually return an
// bool for success or int for errno but also wants to add some string context
// (ususally for logging).
-class Status {
+class PERFETTO_EXPORT Status {
public:
Status() : ok_(true) {}
explicit Status(std::string error) : ok_(false), message_(std::move(error)) {}
diff --git a/include/perfetto/trace_processor/trace_processor.h b/include/perfetto/trace_processor/trace_processor.h
index 2ab067f..0b879f8 100644
--- a/include/perfetto/trace_processor/trace_processor.h
+++ b/include/perfetto/trace_processor/trace_processor.h
@@ -20,6 +20,7 @@
#include <memory>
#include <vector>
+#include "perfetto/base/export.h"
#include "perfetto/trace_processor/basic_types.h"
#include "perfetto/trace_processor/status.h"
@@ -29,7 +30,7 @@
// Coordinates the loading of traces from an arbitrary source and allows
// execution of SQL queries on the events in these traces.
-class TraceProcessor {
+class PERFETTO_EXPORT TraceProcessor {
public:
class IteratorImpl;
@@ -118,7 +119,7 @@
};
// When set, logs SQLite actions on the console.
-void EnableSQLiteVtableDebugging();
+void PERFETTO_EXPORT EnableSQLiteVtableDebugging();
} // namespace trace_processor
} // namespace perfetto
diff --git a/include/perfetto/tracing/core/trace_config.h b/include/perfetto/tracing/core/trace_config.h
index 7a4b2a8..26cdfcd 100644
--- a/include/perfetto/tracing/core/trace_config.h
+++ b/include/perfetto/tracing/core/trace_config.h
@@ -647,6 +647,12 @@
return incident_report_config_.get();
}
+ const std::string& trace_uuid() const { return trace_uuid_; }
+ void set_trace_uuid(const std::string& value) { trace_uuid_ = value; }
+ void set_trace_uuid(const void* p, size_t s) {
+ trace_uuid_.assign(reinterpret_cast<const char*>(p), s);
+ }
+
private:
std::vector<BufferConfig> buffers_;
std::vector<DataSource> data_sources_;
@@ -673,6 +679,7 @@
std::string unique_session_name_{};
CompressionType compression_type_{};
::perfetto::base::CopyablePtr<IncidentReportConfig> incident_report_config_;
+ std::string trace_uuid_{};
// Allows to preserve unknown protobuf fields for compatibility
// with future versions of .proto files.
diff --git a/include/perfetto/tracing/internal/data_source_internal.h b/include/perfetto/tracing/internal/data_source_internal.h
index 7321aaf..8488cf2 100644
--- a/include/perfetto/tracing/internal/data_source_internal.h
+++ b/include/perfetto/tracing/internal/data_source_internal.h
@@ -79,7 +79,7 @@
// This is to prevent that accessing the data source on an arbitrary embedder
// thread races with the internal IPC thread destroying the data source
// because of a end-of-tracing notification from the service.
- std::mutex lock;
+ std::recursive_mutex lock;
std::unique_ptr<DataSourceBase> data_source;
};
diff --git a/include/perfetto/tracing/locked_handle.h b/include/perfetto/tracing/locked_handle.h
index f9ae8e5..3d4c461 100644
--- a/include/perfetto/tracing/locked_handle.h
+++ b/include/perfetto/tracing/locked_handle.h
@@ -27,7 +27,7 @@
template <typename T>
class LockedHandle {
public:
- LockedHandle(std::mutex* mutex, T* obj) : lock_(*mutex), obj_(obj) {}
+ LockedHandle(std::recursive_mutex* mtx, T* obj) : lock_(*mtx), obj_(obj) {}
LockedHandle() = default; // For the invalid case.
LockedHandle(LockedHandle&&) = default;
LockedHandle& operator=(LockedHandle&&) = default;
@@ -43,7 +43,7 @@
T& operator*() { return *(this->operator->()); }
private:
- std::unique_lock<std::mutex> lock_;
+ std::unique_lock<std::recursive_mutex> lock_;
T* obj_ = nullptr;
};
diff --git a/infra/ci/worker/Dockerfile b/infra/ci/worker/Dockerfile
index 4157350..8b1788a 100644
--- a/infra/ci/worker/Dockerfile
+++ b/infra/ci/worker/Dockerfile
@@ -23,6 +23,7 @@
COPY tmp/config.py /home/perfetto/config.py
COPY tmp/common_utils.py /home/perfetto/common_utils.py
COPY artifacts_uploader.py /home/perfetto/
+COPY perf_metrics_uploader.py /home/perfetto/
COPY run_job.py /home/perfetto/
COPY worker.py /home/perfetto/
@@ -42,4 +43,4 @@
WORKDIR /home/perfetto
ENTRYPOINT [ "tini", "--" ]
-CMD [ "python2", "/home/perfetto/worker.py" ]
\ No newline at end of file
+CMD [ "python2", "/home/perfetto/worker.py" ]
diff --git a/infra/ci/worker/artifacts_uploader.py b/infra/ci/worker/artifacts_uploader.py
index 97b9d37..be9567c 100644
--- a/infra/ci/worker/artifacts_uploader.py
+++ b/infra/ci/worker/artifacts_uploader.py
@@ -28,6 +28,7 @@
from multiprocessing.pool import ThreadPool
from oauth2client.client import GoogleCredentials
+CUR_DIR = os.path.dirname(__file__)
RESCAN_PERIOD_SEC = 5 # Scan for new artifact directories every X seconds.
tls = threading.local()
@@ -72,6 +73,16 @@
yield fpath
+def scan_and_upload_perf_folder(job_id, dirpath):
+ perf_folder = os.path.join(dirpath, "perf")
+ if not os.path.isdir(perf_folder):
+ return
+
+ uploader = os.path.join(CUR_DIR, 'perf_metrics_uploader.py')
+ for path in list_files(perf_folder):
+ subprocess.call([uploader, '--job-id', job_id, path])
+
+
def scan_and_uplod_artifacts(pool, remove_after_upload=False):
root = os.getenv('ARTIFACTS_DIR')
for job_id in (x for x in os.listdir(root) if not x.endswith('.tmp')):
@@ -88,6 +99,8 @@
total_size += max(upl_size, 0)
logging.info('Uploaded artifacts for %s: %d files, %s failures, %d KB',
job_id, uploads, failures, total_size / 1e3)
+
+ scan_and_upload_perf_folder(job_id, dirpath)
if remove_after_upload:
subprocess.call(['sudo', 'rm', '-rf', dirpath])
diff --git a/infra/ci/worker/perf_metrics_uploader.py b/infra/ci/worker/perf_metrics_uploader.py
new file mode 100755
index 0000000..4a43052
--- /dev/null
+++ b/infra/ci/worker/perf_metrics_uploader.py
@@ -0,0 +1,114 @@
+#!/usr/bin/env python
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import argparse
+import json
+import hashlib
+import sys
+
+from config import DB, PROJECT
+from common_utils import req
+
+'''
+Uploads the performance metrics of the Perfetto tests to StackDriver and
+Firebase.
+
+The expected format of the JSON is as follows:
+{
+ metrics: [
+ {
+ 'metric': *metric name*,
+ 'value': *metric value*,
+ 'unit': *either s (seconds) or b (bytes)*,
+ 'tags': {
+ *tag name*: *tag value*,
+ ...
+ },
+ 'labels': {
+ *label name*: *label value*,
+ ...
+ }
+ },
+ ...
+ ]
+}
+'''
+
+
+STACKDRIVER_API = 'https://monitoring.googleapis.com/v3/projects/%s' % PROJECT
+
+
+def sha1(obj):
+ hasher = hashlib.sha1()
+ hasher.update(json.dumps(obj, sort_keys=True, separators=(',', ':')))
+ return hasher.hexdigest()
+
+
+def metric_list_to_hash_dict(raw_metrics):
+ metrics = {}
+ for metric in raw_metrics:
+ key = '%s-%s' % (metric['metric'], sha1(metric['tags']))
+ metrics[key] = metric
+ return metrics
+
+
+def create_stackdriver_metrics(ts, metrics):
+ desc = {'timeSeries': []}
+ for _, metric in metrics.iteritems():
+ metric_name = metric['metric']
+ desc['timeSeries'] += [{
+ 'metric': {
+ 'type': 'custom.googleapis.com/perfetto-ci/perf/%s' % metric_name,
+ 'labels': dict(
+ list(metric.get('tags', {}).items()) +
+ list(metric.get('labels', {}).items())
+ ),
+ },
+ 'resource': {'type': 'global'},
+ 'points': [{
+ 'interval': {'endTime': ts},
+ 'value': {'doubleValue': str(metric['value'])}
+ }]}]
+ return desc
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--job-id', type=str, required=True,
+ help='The Perfetto CI job ID to tie this upload to')
+ parser.add_argument('metrics_file', type=str,
+ help='File containing the metrics to upload')
+ args = parser.parse_args()
+
+ with open(args.metrics_file, 'r') as metrics_file:
+ raw_metrics = json.loads(metrics_file.read())
+
+ job = req('GET', '%s/jobs/%s.json' % (DB, args.job_id))
+ ts = job['time_ended']
+ git_ref = job['env'].get('PERFETTO_TEST_GIT_REF')
+
+ metrics = metric_list_to_hash_dict(raw_metrics['metrics'])
+ req('PUT', '%s/perf/%s.json' % (DB, args.job_id), body=metrics)
+
+ # Only upload Stackdriver metrics for post-submit runs.
+ if git_ref == 'refs/heads/master':
+ sd_metrics = create_stackdriver_metrics(ts, metrics)
+ req('POST', STACKDRIVER_API + '/timeSeries', body=sd_metrics)
+
+ return 0
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/infra/kokoro_ci/dockerfiles/Dockerfile b/infra/kokoro_ci/dockerfiles/Dockerfile
deleted file mode 100644
index 3e37e11..0000000
--- a/infra/kokoro_ci/dockerfiles/Dockerfile
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-# Creates an image that can check out / build / test the perfetto source. The
-# image is used by the Kokoro continuous integration jobs, but is also suitable
-# for local development. There is no pre-defined entrypoint on purpose (to keep
-# it flexible).
-#
-# The built image is available as asia.gcr.io/perfetto-ci/perfetto-ci:latest
-
-FROM debian:latest
-
-ENV DEBIAN_FRONTEND noninteractive
-
-RUN echo deb http://deb.debian.org/debian testing main > /etc/apt/sources.list.d/testing.list
-RUN apt-get update
-RUN apt-get -y install python git curl libxml2 libtinfo5
-# gcc-7 for sysroot
-RUN apt-get -y -t testing install gcc-7
-
-# pip for installing certiain test script dependencies
-RUN curl https://bootstrap.pypa.io/get-pip.py | python -
-
-RUN useradd -m perfetto
-USER perfetto:perfetto
-WORKDIR /home/perfetto
diff --git a/infra/kokoro_ci/kokoro_entry.sh b/infra/kokoro_ci/kokoro_entry.sh
deleted file mode 100755
index 6c3997f..0000000
--- a/infra/kokoro_ci/kokoro_entry.sh
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/bin/bash
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-# Initial script invoked by Kokoro continuous integration / presubmit jobs.
-# Sets up Kokoro-specific environment, invoking the test script afterwards.
-# What & how to run is carried by environment variables.
-#
-# You shouldn't need to invoke this when running tests locally.
-
-set -eux
-
-SCRIPT_DIR="$(realpath "$(dirname "${BASH_SOURCE[0]}")")"
-ROOT_DIR="$(realpath ${SCRIPT_DIR}/../..)"
-
-cd ${ROOT_DIR}
-
-# Check that the expected environment variables are present (due to set -u).
-echo PERFETTO_TEST_GN_ARGS: ${PERFETTO_TEST_GN_ARGS}
-echo PERFETTO_TEST_ENTRYPT: ${PERFETTO_TEST_ENTRYPT}
-
-# Make space for docker image by symlinking the hardcoded /var/lib/docker path
-# to a tmpfs mount. Cargo culted from other projects' scripts.
-sudo -n /etc/init.d/docker stop
-sudo -n mv /var/lib/docker /tmpfs/
-sudo -n ln -s /tmpfs/docker /var/lib/docker
-sudo -n /etc/init.d/docker start
-
-# Invoke the tests within a container.
-${SCRIPT_DIR}/run_test_in_container.sh
diff --git a/infra/kokoro_ci/linux/ci-clang-x86_64-asan_lsan_ubsan.cfg b/infra/kokoro_ci/linux/ci-clang-x86_64-asan_lsan_ubsan.cfg
deleted file mode 100644
index 8aa1dba..0000000
--- a/infra/kokoro_ci/linux/ci-clang-x86_64-asan_lsan_ubsan.cfg
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-# Location of the shell script that is the entry point for continuous
-# integration jobs. The first directory in the path is where Kokoro will check
-# out the repository. The rest is the path relative to the repository's root.
-build_file: "perfetto/infra/kokoro_ci/kokoro_entry.sh"
-
-env_vars {
- key: "PERFETTO_TEST_GN_ARGS"
- value: "is_debug=false is_ubsan=true is_asan=true is_lsan=true"
-}
-
-env_vars {
- key: "PERFETTO_TEST_ENTRYPT"
- value: "infra/kokoro_ci/run_standalone_tests.sh"
-}
-
diff --git a/infra/kokoro_ci/linux/ci-clang-x86_64-msan.cfg b/infra/kokoro_ci/linux/ci-clang-x86_64-msan.cfg
deleted file mode 100644
index 1e85fa4..0000000
--- a/infra/kokoro_ci/linux/ci-clang-x86_64-msan.cfg
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-# Location of the shell script that is the entry point for continuous
-# integration jobs. The first directory in the path is where Kokoro will check
-# out the repository. The rest is the path relative to the repository's root.
-build_file: "perfetto/infra/kokoro_ci/kokoro_entry.sh"
-
-env_vars {
- key: "PERFETTO_TEST_GN_ARGS"
- value: "is_debug=false is_msan=true"
-}
-
-env_vars {
- key: "PERFETTO_TEST_ENTRYPT"
- value: "infra/kokoro_ci/run_standalone_tests.sh"
-}
-
diff --git a/infra/kokoro_ci/linux/ci-clang-x86_64-tsan.cfg b/infra/kokoro_ci/linux/ci-clang-x86_64-tsan.cfg
deleted file mode 100644
index 22fd946..0000000
--- a/infra/kokoro_ci/linux/ci-clang-x86_64-tsan.cfg
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-# Location of the shell script that is the entry point for continuous
-# integration jobs. The first directory in the path is where Kokoro will check
-# out the repository. The rest is the path relative to the repository's root.
-build_file: "perfetto/infra/kokoro_ci/kokoro_entry.sh"
-
-env_vars {
- key: "PERFETTO_TEST_GN_ARGS"
- value: "is_debug=false is_tsan=true"
-}
-
-env_vars {
- key: "PERFETTO_TEST_ENTRYPT"
- value: "infra/kokoro_ci/run_standalone_tests.sh"
-}
-
diff --git a/infra/kokoro_ci/linux/ci-ui-clang-x86_64-debug.cfg b/infra/kokoro_ci/linux/ci-ui-clang-x86_64-debug.cfg
deleted file mode 100644
index c67a806..0000000
--- a/infra/kokoro_ci/linux/ci-ui-clang-x86_64-debug.cfg
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-# Location of the shell script that is the entry point for continuous
-# integration jobs. The first directory in the path is where Kokoro will check
-# out the repository. The rest is the path relative to the repository's root.
-build_file: "perfetto/infra/kokoro_ci/kokoro_entry.sh"
-
-env_vars {
- key: "PERFETTO_TEST_GN_ARGS"
- value: "is_debug=true"
-}
-
-env_vars {
- key: "PERFETTO_TEST_ENTRYPT"
- value: "infra/kokoro_ci/run_ui_tests.sh"
-}
-
diff --git a/infra/kokoro_ci/run_standalone_tests.sh b/infra/kokoro_ci/run_standalone_tests.sh
deleted file mode 100755
index fa3e4e7..0000000
--- a/infra/kokoro_ci/run_standalone_tests.sh
+++ /dev/null
@@ -1,52 +0,0 @@
-#!/bin/bash
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-set -eux
-
-SCRIPT_DIR="$(realpath "$(dirname "${BASH_SOURCE[0]}")")"
-ROOT_DIR="$(realpath ${SCRIPT_DIR}/../..)"
-
-cd ${ROOT_DIR}
-
-# Check that the expected environment variables are present (due to set -u).
-echo PERFETTO_TEST_GN_ARGS: ${PERFETTO_TEST_GN_ARGS}
-
-OUT_PATH="out/dist"
-
-if [[ "$PERFETTO_TEST_GN_ARGS" =~ "android" ]]; then
-tools/install-build-deps
-else
-tools/install-build-deps --no-android
-fi
-
-pip install --quiet --user protobuf
-
-if [[ -e buildtools/clang/bin/llvm-symbolizer ]]; then
- export ASAN_SYMBOLIZER_PATH="buildtools/clang/bin/llvm-symbolizer"
- export MSAN_SYMBOLIZER_PATH="buildtools/clang/bin/llvm-symbolizer"
-fi
-
-tools/gn gen ${OUT_PATH} --args="${PERFETTO_TEST_GN_ARGS}" --check
-tools/ninja -C ${OUT_PATH}
-
-# Run the tests
-${OUT_PATH}/perfetto_unittests
-${OUT_PATH}/perfetto_integrationtests
-
-BENCHMARK_FUNCTIONAL_TEST_ONLY=true ${OUT_PATH}/perfetto_benchmarks
-tools/diff_test_trace_processor.py \
- --test-type=queries ${OUT_PATH}/trace_processor_shell
-tools/diff_test_trace_processor.py \
- --test-type=metrics ${OUT_PATH}/trace_processor_shell
diff --git a/infra/kokoro_ci/run_test_in_container.sh b/infra/kokoro_ci/run_test_in_container.sh
deleted file mode 100755
index ec743ea..0000000
--- a/infra/kokoro_ci/run_test_in_container.sh
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/bin/bash
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-set -eux
-
-SCRIPT_DIR="$(realpath "$(dirname "${BASH_SOURCE[0]}")")"
-ROOT_DIR="$(realpath ${SCRIPT_DIR}/../..)"
-
-cd ${ROOT_DIR}
-
-# Check that the expected environment variables are present (due to set -u).
-echo PERFETTO_TEST_GN_ARGS: ${PERFETTO_TEST_GN_ARGS}
-echo PERFETTO_TEST_ENTRYPT: ${PERFETTO_TEST_ENTRYPT}
-
-# Run PERFETTO_TEST_ENTRYPOINT inside the container with the following setup:
-# Mount (readonly) the current source directory inside the container. Enter the
-# container as root, make a mutable copy the source tree, and then invoke
-# the test script as that user.
-#
-# SYS_PTRACE capability is added for [at least] the leak sanitizer.
-# TODO(rsavitski): figure out why "su perfetto -c" was messing with the test
-# scripts (at least the output truncation).
-sudo docker run --rm -t \
- --user=root:root \
- --cap-add=SYS_PTRACE \
- -e PERFETTO_TEST_GN_ARGS="${PERFETTO_TEST_GN_ARGS}" \
- -v ${ROOT_DIR}:/perfetto:ro \
- asia.gcr.io/perfetto-ci/perfetto-ci:latest \
- /bin/bash \
- "-c" \
- "cp -r /perfetto /home/perfetto/src && \
- cd /home/perfetto/src && \
- ${PERFETTO_TEST_ENTRYPT}"
diff --git a/infra/kokoro_ci/run_ui_tests.sh b/infra/kokoro_ci/run_ui_tests.sh
deleted file mode 100755
index 906d9ea..0000000
--- a/infra/kokoro_ci/run_ui_tests.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/bin/bash
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-set -eux
-
-SCRIPT_DIR="$(realpath "$(dirname "${BASH_SOURCE[0]}")")"
-ROOT_DIR="$(realpath ${SCRIPT_DIR}/../..)"
-
-cd ${ROOT_DIR}
-
-# Check that the expected environment variables are present (due to set -u).
-echo PERFETTO_TEST_GN_ARGS: ${PERFETTO_TEST_GN_ARGS}
-
-OUT_PATH="out/dist"
-
-tools/install-build-deps --no-android --ui
-
-tools/gn gen ${OUT_PATH} --args="${PERFETTO_TEST_GN_ARGS}" --check
-tools/ninja -C ${OUT_PATH} ui 2>&1 | grep -v "no version information available"
-
-# Run the tests
-${OUT_PATH}/ui_unittests --ci
diff --git a/protos/BUILD b/protos/BUILD
index 0c88c40..b5ea3bd 100644
--- a/protos/BUILD
+++ b/protos/BUILD
@@ -387,6 +387,7 @@
"perfetto/trace/test_event.proto",
"perfetto/trace/trace.proto",
"perfetto/trace/trace_packet.proto",
+ "perfetto/trace/trace_packet_defaults.proto",
],
has_services = 1,
cc_api_version = 2,
@@ -418,6 +419,7 @@
name = "trace_android",
srcs = [
"perfetto/trace/android/android_log.proto",
+ "perfetto/trace/android/graphics_frame_event.proto",
"perfetto/trace/android/packages_list.proto",
],
has_services = 1,
@@ -458,6 +460,7 @@
name = "trace_android_zero",
srcs = [
"perfetto/trace/android/android_log.proto",
+ "perfetto/trace/android/graphics_frame_event.proto",
"perfetto/trace/android/packages_list.proto",
],
deps = [
@@ -1336,6 +1339,7 @@
"perfetto/trace/test_event.proto",
"perfetto/trace/trace.proto",
"perfetto/trace/trace_packet.proto",
+ "perfetto/trace/trace_packet_defaults.proto",
"perfetto/trace/trigger.proto",
],
deps = [
diff --git a/protos/perfetto/config/perfetto_config.proto b/protos/perfetto/config/perfetto_config.proto
index 7561682..c1c0917 100644
--- a/protos/perfetto/config/perfetto_config.proto
+++ b/protos/perfetto/config/perfetto_config.proto
@@ -518,7 +518,7 @@
// It contains the general config for the logging buffer(s) and the configs for
// all the data source being enabled.
//
-// Next id: 26.
+// Next id: 27.
message TraceConfig {
message BufferConfig {
optional uint32 size_kb = 1;
@@ -793,6 +793,9 @@
optional bool skip_dropbox = 4;
}
optional IncidentReportConfig incident_report_config = 25;
+
+ // An identifier clients can use to tie this trace to other logging.
+ optional bytes trace_uuid = 26;
}
// End of protos/perfetto/config/trace_config.proto
diff --git a/protos/perfetto/config/trace_config.proto b/protos/perfetto/config/trace_config.proto
index e684c66..a823fbe 100644
--- a/protos/perfetto/config/trace_config.proto
+++ b/protos/perfetto/config/trace_config.proto
@@ -29,7 +29,7 @@
// It contains the general config for the logging buffer(s) and the configs for
// all the data source being enabled.
//
-// Next id: 26.
+// Next id: 27.
message TraceConfig {
message BufferConfig {
optional uint32 size_kb = 1;
@@ -304,4 +304,7 @@
optional bool skip_dropbox = 4;
}
optional IncidentReportConfig incident_report_config = 25;
+
+ // An identifier clients can use to tie this trace to other logging.
+ optional bytes trace_uuid = 26;
}
diff --git a/protos/perfetto/ipc/producer_port.proto b/protos/perfetto/ipc/producer_port.proto
index 9368912..75a89de 100644
--- a/protos/perfetto/ipc/producer_port.proto
+++ b/protos/perfetto/ipc/producer_port.proto
@@ -114,6 +114,17 @@
// If provided, overrides the service's SMB scraping setting for the producer.
optional ProducerSMBScrapingMode smb_scraping_mode = 4;
+
+ enum ProducerBuildFlags {
+ BUILD_FLAGS_UNSPECIFIED = 0;
+ BUILD_FLAGS_DCHECKS_ON = 1;
+ BUILD_FLAGS_DCHECKS_OFF = 2;
+ }
+
+ // If provided, reports the build flags of the producer. It's used merely for
+ // error reporting, to print a log message when a producer connects to a
+ // service that has mismatching build flags.
+ optional ProducerBuildFlags build_flags = 5;
}
message InitializeConnectionResponse {
diff --git a/protos/perfetto/metrics/android/mem_metric.proto b/protos/perfetto/metrics/android/mem_metric.proto
index 25f198b..0443c0d 100644
--- a/protos/perfetto/metrics/android/mem_metric.proto
+++ b/protos/perfetto/metrics/android/mem_metric.proto
@@ -37,6 +37,9 @@
optional Counter file_rss = 2;
optional Counter swap = 3;
optional Counter anon_and_swap = 4;
+
+ // Available when ART trace events are available.
+ optional Counter java_heap = 5;
}
message Counter {
diff --git a/protos/perfetto/trace/BUILD.gn b/protos/perfetto/trace/BUILD.gn
index bbab12a..8c6934a 100644
--- a/protos/perfetto/trace/BUILD.gn
+++ b/protos/perfetto/trace/BUILD.gn
@@ -28,6 +28,7 @@
proto_sources_trusted = [ "trusted_packet.proto" ]
proto_sources = [
+ "trace_packet_defaults.proto",
"test_event.proto",
"trace_packet.proto",
"trace.proto",
diff --git a/protos/perfetto/trace/android/BUILD.gn b/protos/perfetto/trace/android/BUILD.gn
index 72a3e3c..9a382aa 100644
--- a/protos/perfetto/trace/android/BUILD.gn
+++ b/protos/perfetto/trace/android/BUILD.gn
@@ -18,6 +18,7 @@
android_proto_names = [
"android_log.proto",
+ "graphics_frame_event.proto",
"packages_list.proto",
]
diff --git a/protos/perfetto/trace/android/graphics_frame_event.proto b/protos/perfetto/trace/android/graphics_frame_event.proto
new file mode 100644
index 0000000..68248f9
--- /dev/null
+++ b/protos/perfetto/trace/android/graphics_frame_event.proto
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+option optimize_for = LITE_RUNTIME;
+package perfetto.protos;
+
+// Generated by Android's SurfaceFlinger.
+message GraphicsFrameEvent {
+ enum BufferEventType {
+ UNSPECIFIED = 0;
+ DEQUEUE = 1;
+ QUEUE = 2;
+ POST = 3;
+ ACQUIRE_FENCE = 4;
+ LATCH = 5;
+ HWC_COMPOSITION_QUEUED = 6; // HWC will compose this buffer
+ FALLBACK_COMPOSITION = 7; // renderEngine composition
+ PRESENT_FENCE = 8;
+ RELEASE_FENCE = 9;
+ MODIFY = 10;
+ }
+
+ message BufferEvent {
+ optional uint32 frame_number = 1;
+ optional BufferEventType type = 2;
+ optional string layer_name = 3;
+ // If no duration is set, the event is an instant event.
+ optional uint64 duration_ns = 4;
+ // Unique buffer identifier.
+ optional uint32 buffer_id = 5;
+ }
+
+ optional BufferEvent buffer_event = 1;
+}
diff --git a/protos/perfetto/trace/clock_snapshot.proto b/protos/perfetto/trace/clock_snapshot.proto
index 7cf74ba..12ce1b6 100644
--- a/protos/perfetto/trace/clock_snapshot.proto
+++ b/protos/perfetto/trace/clock_snapshot.proto
@@ -22,7 +22,7 @@
// A snapshot of clock readings to allow for trace alignment.
message ClockSnapshot {
message Clock {
- enum Type {
+ enum BuiltinClocks {
UNKNOWN = 0;
REALTIME = 1;
REALTIME_COARSE = 2;
@@ -32,9 +32,35 @@
BOOTTIME = 6;
PROCESS_CPUTIME = 7;
THREAD_CPUTIME = 8;
+ BUILTIN_CLOCK_MAX_ID = 63;
}
- optional Type type = 1;
+
+ // Clock IDs have the following semantic:
+ // [1, 63]: Builtin types, see BuiltinClocks above.
+ // [64, 127]: User-defined clocks. These clocks are sequence-scoped. They
+ // are only valid within the same |trusted_packet_sequence_id|
+ // (i.e. only for TracePacket(s) emitted by the same TraceWriter
+ // that emitted the clock snapshot).
+ // [128, MAX]: Reserved for future use. The idea is to allow global clock
+ // IDs and setting this ID to hash(full_clock_name) & ~127.
+ optional uint32 clock_id = 1;
+
+ // Unit is ns unless specified otherwise by the resolution_* fields below.
optional uint64 timestamp = 2;
+
+ // TODO(eseckler): the fields below and sequence-scoped clock IDs are not
+ // supported yet by the trace processor.
+
+ // When true the timestamp should be interpreted as a delta from the last
+ // TracePacket's timestamp emitted by the same packet_sequence_id.
+ // The first packet timestamp after a ClockSnapshot is relative to the last
+ // ClockSnapshot seen on the packet sequence.
+ // optional bool is_incremental = 3;
+
+ // Allows to specify a custom unit different than the default (ns)
+ // for this clock domain. A multiplier of 1000 means that a timestamp = 3
+ // should be interpreted as 3000 ns = 3 us.
+ // optional uint64 unit_multiplier_ns = 4;
}
repeated Clock clocks = 1;
}
diff --git a/protos/perfetto/trace/perfetto_trace.proto b/protos/perfetto/trace/perfetto_trace.proto
index e52ed45..b69b9f0 100644
--- a/protos/perfetto/trace/perfetto_trace.proto
+++ b/protos/perfetto/trace/perfetto_trace.proto
@@ -389,6 +389,39 @@
// End of protos/perfetto/trace/android/android_log.proto
+// Begin of protos/perfetto/trace/android/graphics_frame_event.proto
+
+// Generated by Android's SurfaceFlinger.
+message GraphicsFrameEvent {
+ enum BufferEventType {
+ UNSPECIFIED = 0;
+ DEQUEUE = 1;
+ QUEUE = 2;
+ POST = 3;
+ ACQUIRE_FENCE = 4;
+ LATCH = 5;
+ HWC_COMPOSITION_QUEUED = 6; // HWC will compose this buffer
+ FALLBACK_COMPOSITION = 7; // renderEngine composition
+ PRESENT_FENCE = 8;
+ RELEASE_FENCE = 9;
+ MODIFY = 10;
+ }
+
+ message BufferEvent {
+ optional uint32 frame_number = 1;
+ optional BufferEventType type = 2;
+ optional string layer_name = 3;
+ // If no duration is set, the event is an instant event.
+ optional uint64 duration_ns = 4;
+ // Unique buffer identifier.
+ optional uint32 buffer_id = 5;
+ }
+
+ optional BufferEvent buffer_event = 1;
+}
+
+// End of protos/perfetto/trace/android/graphics_frame_event.proto
+
// Begin of protos/perfetto/trace/android/packages_list.proto
message PackagesList {
@@ -510,7 +543,7 @@
// A snapshot of clock readings to allow for trace alignment.
message ClockSnapshot {
message Clock {
- enum Type {
+ enum BuiltinClocks {
UNKNOWN = 0;
REALTIME = 1;
REALTIME_COARSE = 2;
@@ -520,9 +553,35 @@
BOOTTIME = 6;
PROCESS_CPUTIME = 7;
THREAD_CPUTIME = 8;
+ BUILTIN_CLOCK_MAX_ID = 63;
}
- optional Type type = 1;
+
+ // Clock IDs have the following semantic:
+ // [1, 63]: Builtin types, see BuiltinClocks above.
+ // [64, 127]: User-defined clocks. These clocks are sequence-scoped. They
+ // are only valid within the same |trusted_packet_sequence_id|
+ // (i.e. only for TracePacket(s) emitted by the same TraceWriter
+ // that emitted the clock snapshot).
+ // [128, MAX]: Reserved for future use. The idea is to allow global clock
+ // IDs and setting this ID to hash(full_clock_name) & ~127.
+ optional uint32 clock_id = 1;
+
+ // Unit is ns unless specified otherwise by the resolution_* fields below.
optional uint64 timestamp = 2;
+
+ // TODO(eseckler): the fields below and sequence-scoped clock IDs are not
+ // supported yet by the trace processor.
+
+ // When true the timestamp should be interpreted as a delta from the last
+ // TracePacket's timestamp emitted by the same packet_sequence_id.
+ // The first packet timestamp after a ClockSnapshot is relative to the last
+ // ClockSnapshot seen on the packet sequence.
+ // optional bool is_incremental = 3;
+
+ // Allows to specify a custom unit different than the default (ns)
+ // for this clock domain. A multiplier of 1000 means that a timestamp = 3
+ // should be interpreted as 3000 ns = 3 us.
+ // optional uint64 unit_multiplier_ns = 4;
}
repeated Clock clocks = 1;
}
@@ -3132,11 +3191,22 @@
// TracePacket(s).
//
// Next reserved id: 13 (up to 15).
-// Next id: 57.
+// Next id: 60.
message TracePacket {
- // TODO(primiano): in future we should add a timestamp_clock_domain field to
- // allow mixing timestamps from different clock domains.
- optional uint64 timestamp = 8; // Timestamp [ns].
+ // The timestamp of the TracePacket.
+ // By default this timestamps refers to the trace clock (CLOCK_BOOTTIME on
+ // Android). It can be overridden using a different timestamp_clock_id.
+ // The clock domain definition in ClockSnapshot can also override:
+ // - The unit (default: 1ns).
+ // - The absolute vs delta encoding (default: absolute timestamp).
+ optional uint64 timestamp = 8;
+
+ // Specifies the ID of the clock used for the TracePacket |timestamp|. Can be
+ // one of the built-in types from ClockSnapshot::BuiltinClocks, or a
+ // producer-defined clock id.
+ // If unspecified and if no default per-sequence value has been provided via
+ // TracePacketDefaults, it defaults to BuiltinClocks::BOOTTIME.
+ optional uint32 timestamp_clock_id = 58;
oneof data {
FtraceEventBundle ftrace_events = 1;
@@ -3168,6 +3238,7 @@
GpuRenderStageEvent gpu_render_stage_event = 53;
StreamingProfilePacket streaming_profile_packet = 54;
HeapGraph heap_graph = 56;
+ GraphicsFrameEvent graphics_frame_event = 57;
// Only used in profile packets.
ProfiledFrameSymbols profiled_frame_symbols = 55;
@@ -3218,22 +3289,47 @@
// proactively in advance of referring to them in later packets.
optional InternedData interned_data = 12;
- // Set to true by the writer to indicate that it will re-emit any incremental
- // data for the packet's sequence before referring to it again. This includes
- // interned data as well as periodically emitted data like
- // Process/ThreadDescriptors. This flag only affects the current packet
- // sequence (see |trusted_packet_sequence_id|).
- //
- // When set to true, this TracePacket and subsequent TracePackets on the same
- // sequence will not refer to any incremental data emitted before this
- // TracePacket. For example, previously emitted interned data will be
- // re-emitted if it is referred to again.
- //
- // When the reader detects packet loss (|previous_packet_dropped|), it needs
- // to skip packets in the sequence until the next one with this flag set, to
- // ensure intact incremental data.
+ enum SequenceFlags {
+ SEQ_UNSPECIFIED = 0;
+
+ // Set by the writer to indicate that it will re-emit any incremental data
+ // for the packet's sequence before referring to it again. This includes
+ // interned data as well as periodically emitted data like
+ // Process/ThreadDescriptors. This flag only affects the current packet
+ // sequence (see |trusted_packet_sequence_id|).
+ //
+ // When set, this TracePacket and subsequent TracePackets on the same
+ // sequence will not refer to any incremental data emitted before this
+ // TracePacket. For example, previously emitted interned data will be
+ // re-emitted if it is referred to again.
+ //
+ // When the reader detects packet loss (|previous_packet_dropped|), it needs
+ // to skip packets in the sequence until the next one with this flag set, to
+ // ensure intact incremental data.
+ SEQ_INCREMENTAL_STATE_CLEARED = 1;
+
+ // This packet requires incremental state, such as TracePacketDefaults or
+ // InternedData, to be parsed correctly. The trace reader should skip this
+ // packet if incremental state is not valid on this sequence, i.e. if no
+ // packet with the SEQ_INCREMENTAL_STATE_CLEARED flag has been seen on the
+ // current |trusted_packet_sequence_id|.
+ SEQ_NEEDS_INCREMENTAL_STATE = 2;
+ };
+ optional uint32 sequence_flags = 13;
+
+ // DEPRECATED. Moved to SequenceFlags::SEQ_INCREMENTAL_STATE_CLEARED.
optional bool incremental_state_cleared = 41;
+ // Default values for fields of later TracePackets emitted on this packet's
+ // sequence (TracePackets with the same |trusted_packet_sequence_id|).
+ // It must be reemitted when incremental state is cleared (see
+ // |incremental_state_cleared|).
+ // Requires that any future packet emitted on the same sequence specifies
+ // the SEQ_NEEDS_INCREMENTAL_STATE flag.
+ // TracePacketDefaults always override the global defaults for any future
+ // packet on this sequence (regardless of SEQ_NEEDS_INCREMENTAL_STATE).
+ optional TracePacketDefaults trace_packet_defaults = 59;
+
// Flag set by the service if, for the current packet sequence (see
// |trusted_packet_sequence_id|), either:
// * this is the first packet, or
@@ -3250,6 +3346,24 @@
// End of protos/perfetto/trace/trace_packet.proto
+// Begin of protos/perfetto/trace/trace_packet_defaults.proto
+
+// Default values for TracePacket fields that hold for a particular TraceWriter
+// packet sequence. This message contains a subset of the TracePacket fields
+// with matching IDs. When provided, these fields define the default values
+// that should be applied, at import time, to all TracePacket(s) with the same
+// |trusted_packet_sequence_id|, unless otherwise specified in each packet.
+message TracePacketDefaults {
+ optional uint32 timestamp_clock_id = 58;
+
+ // TODO(eseckler): Add default values for TrackEvents (e.g. default track).
+ message TrackEventDefaults {
+ // optional int32 tid = ...;
+ }
+ optional TrackEventDefaults track_event = 11;
+}
+// End of protos/perfetto/trace/trace_packet_defaults.proto
+
// Begin of protos/perfetto/trace/track_event/debug_annotation.proto
// Key/value annotations provided in untyped TRACE_EVENT macros. These
@@ -3450,7 +3564,7 @@
// association) are emitted as part of ProcessDescriptor and ThreadDescriptor
// messages in separate TracePackets instead.
//
-// Next reserved id: 8 (up to 15).
+// Next reserved id: 10 (up to 15).
// Next id: 22.
message TrackEvent {
// Timestamp in microseconds (usually CLOCK_MONOTONIC).
@@ -3489,11 +3603,33 @@
int64 thread_instruction_count_absolute = 20;
}
+ // TODO(eseckler): Add a way to specify Tracks.
+
// We intend to add a binary symbol version of this in the future.
repeated uint64 category_iids = 3; // interned EventCategoryName.
// TODO(eseckler): May also want a debug_name for untyped debug-only events.
+ // Type of the TrackEvent (required if |phase| in LegacyEvent is not set).
+ enum Type {
+ TYPE_UNSPECIFIED = 0;
+
+ // Slice events are always formed by a pair of BEGIN + END events. END
+ // events do not need to repeat any TrackEvent fields they have in common
+ // with their corresponding BEGIN event. Arguments and debug annotations of
+ // the BEGIN + END pair will be merged during trace import.
+ //
+ // Note that we deliberately chose not to support COMPLETE events since
+ // clients would need to delay writing them until the slice is completed,
+ // which can result in reordered events in the trace and loss of unfinished
+ // events at the end of a trace.
+ TYPE_SLICE_BEGIN = 1;
+ TYPE_SLICE_END = 2;
+
+ // TODO(eseckler): Add support for counters.
+ }
+ optional Type type = 9;
+
// Unstable key/value annotations shown in the trace viewer but not intended
// for metrics use.
repeated DebugAnnotation debug_annotations = 4;
@@ -4171,7 +4307,7 @@
// It contains the general config for the logging buffer(s) and the configs for
// all the data source being enabled.
//
-// Next id: 26.
+// Next id: 27.
message TraceConfig {
message BufferConfig {
optional uint32 size_kb = 1;
@@ -4446,6 +4582,9 @@
optional bool skip_dropbox = 4;
}
optional IncidentReportConfig incident_report_config = 25;
+
+ // An identifier clients can use to tie this trace to other logging.
+ optional bytes trace_uuid = 26;
}
// End of protos/perfetto/config/trace_config.proto
diff --git a/protos/perfetto/trace/trace_packet.proto b/protos/perfetto/trace/trace_packet.proto
index 8b79a22..7bd383a 100644
--- a/protos/perfetto/trace/trace_packet.proto
+++ b/protos/perfetto/trace/trace_packet.proto
@@ -20,6 +20,7 @@
import "perfetto/common/trace_stats.proto";
import "perfetto/config/trace_config.proto";
import "perfetto/trace/android/android_log.proto";
+import "perfetto/trace/android/graphics_frame_event.proto";
import "perfetto/trace/android/packages_list.proto";
import "perfetto/trace/chrome/chrome_benchmark_metadata.proto";
import "perfetto/trace/chrome/chrome_metadata.proto";
@@ -41,6 +42,7 @@
import "perfetto/trace/ps/process_tree.proto";
import "perfetto/trace/sys_stats/sys_stats.proto";
import "perfetto/trace/system_info.proto";
+import "perfetto/trace/trace_packet_defaults.proto";
import "perfetto/trace/track_event/process_descriptor.proto";
import "perfetto/trace/track_event/thread_descriptor.proto";
import "perfetto/trace/track_event/track_event.proto";
@@ -53,11 +55,22 @@
// TracePacket(s).
//
// Next reserved id: 13 (up to 15).
-// Next id: 57.
+// Next id: 60.
message TracePacket {
- // TODO(primiano): in future we should add a timestamp_clock_domain field to
- // allow mixing timestamps from different clock domains.
- optional uint64 timestamp = 8; // Timestamp [ns].
+ // The timestamp of the TracePacket.
+ // By default this timestamps refers to the trace clock (CLOCK_BOOTTIME on
+ // Android). It can be overridden using a different timestamp_clock_id.
+ // The clock domain definition in ClockSnapshot can also override:
+ // - The unit (default: 1ns).
+ // - The absolute vs delta encoding (default: absolute timestamp).
+ optional uint64 timestamp = 8;
+
+ // Specifies the ID of the clock used for the TracePacket |timestamp|. Can be
+ // one of the built-in types from ClockSnapshot::BuiltinClocks, or a
+ // producer-defined clock id.
+ // If unspecified and if no default per-sequence value has been provided via
+ // TracePacketDefaults, it defaults to BuiltinClocks::BOOTTIME.
+ optional uint32 timestamp_clock_id = 58;
oneof data {
FtraceEventBundle ftrace_events = 1;
@@ -89,6 +102,7 @@
GpuRenderStageEvent gpu_render_stage_event = 53;
StreamingProfilePacket streaming_profile_packet = 54;
HeapGraph heap_graph = 56;
+ GraphicsFrameEvent graphics_frame_event = 57;
// Only used in profile packets.
ProfiledFrameSymbols profiled_frame_symbols = 55;
@@ -139,22 +153,47 @@
// proactively in advance of referring to them in later packets.
optional InternedData interned_data = 12;
- // Set to true by the writer to indicate that it will re-emit any incremental
- // data for the packet's sequence before referring to it again. This includes
- // interned data as well as periodically emitted data like
- // Process/ThreadDescriptors. This flag only affects the current packet
- // sequence (see |trusted_packet_sequence_id|).
- //
- // When set to true, this TracePacket and subsequent TracePackets on the same
- // sequence will not refer to any incremental data emitted before this
- // TracePacket. For example, previously emitted interned data will be
- // re-emitted if it is referred to again.
- //
- // When the reader detects packet loss (|previous_packet_dropped|), it needs
- // to skip packets in the sequence until the next one with this flag set, to
- // ensure intact incremental data.
+ enum SequenceFlags {
+ SEQ_UNSPECIFIED = 0;
+
+ // Set by the writer to indicate that it will re-emit any incremental data
+ // for the packet's sequence before referring to it again. This includes
+ // interned data as well as periodically emitted data like
+ // Process/ThreadDescriptors. This flag only affects the current packet
+ // sequence (see |trusted_packet_sequence_id|).
+ //
+ // When set, this TracePacket and subsequent TracePackets on the same
+ // sequence will not refer to any incremental data emitted before this
+ // TracePacket. For example, previously emitted interned data will be
+ // re-emitted if it is referred to again.
+ //
+ // When the reader detects packet loss (|previous_packet_dropped|), it needs
+ // to skip packets in the sequence until the next one with this flag set, to
+ // ensure intact incremental data.
+ SEQ_INCREMENTAL_STATE_CLEARED = 1;
+
+ // This packet requires incremental state, such as TracePacketDefaults or
+ // InternedData, to be parsed correctly. The trace reader should skip this
+ // packet if incremental state is not valid on this sequence, i.e. if no
+ // packet with the SEQ_INCREMENTAL_STATE_CLEARED flag has been seen on the
+ // current |trusted_packet_sequence_id|.
+ SEQ_NEEDS_INCREMENTAL_STATE = 2;
+ };
+ optional uint32 sequence_flags = 13;
+
+ // DEPRECATED. Moved to SequenceFlags::SEQ_INCREMENTAL_STATE_CLEARED.
optional bool incremental_state_cleared = 41;
+ // Default values for fields of later TracePackets emitted on this packet's
+ // sequence (TracePackets with the same |trusted_packet_sequence_id|).
+ // It must be reemitted when incremental state is cleared (see
+ // |incremental_state_cleared|).
+ // Requires that any future packet emitted on the same sequence specifies
+ // the SEQ_NEEDS_INCREMENTAL_STATE flag.
+ // TracePacketDefaults always override the global defaults for any future
+ // packet on this sequence (regardless of SEQ_NEEDS_INCREMENTAL_STATE).
+ optional TracePacketDefaults trace_packet_defaults = 59;
+
// Flag set by the service if, for the current packet sequence (see
// |trusted_packet_sequence_id|), either:
// * this is the first packet, or
diff --git a/protos/perfetto/trace/trace_packet_defaults.proto b/protos/perfetto/trace/trace_packet_defaults.proto
new file mode 100644
index 0000000..8b973de
--- /dev/null
+++ b/protos/perfetto/trace/trace_packet_defaults.proto
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+option optimize_for = LITE_RUNTIME;
+
+package perfetto.protos;
+
+// Default values for TracePacket fields that hold for a particular TraceWriter
+// packet sequence. This message contains a subset of the TracePacket fields
+// with matching IDs. When provided, these fields define the default values
+// that should be applied, at import time, to all TracePacket(s) with the same
+// |trusted_packet_sequence_id|, unless otherwise specified in each packet.
+message TracePacketDefaults {
+ optional uint32 timestamp_clock_id = 58;
+
+ // TODO(eseckler): Add default values for TrackEvents (e.g. default track).
+ message TrackEventDefaults {
+ // optional int32 tid = ...;
+ }
+ optional TrackEventDefaults track_event = 11;
+}
\ No newline at end of file
diff --git a/protos/perfetto/trace/track_event/track_event.proto b/protos/perfetto/trace/track_event/track_event.proto
index 414bb8b7..6cd4e8a 100644
--- a/protos/perfetto/trace/track_event/track_event.proto
+++ b/protos/perfetto/trace/track_event/track_event.proto
@@ -40,7 +40,7 @@
// association) are emitted as part of ProcessDescriptor and ThreadDescriptor
// messages in separate TracePackets instead.
//
-// Next reserved id: 8 (up to 15).
+// Next reserved id: 10 (up to 15).
// Next id: 22.
message TrackEvent {
// Timestamp in microseconds (usually CLOCK_MONOTONIC).
@@ -79,11 +79,33 @@
int64 thread_instruction_count_absolute = 20;
}
+ // TODO(eseckler): Add a way to specify Tracks.
+
// We intend to add a binary symbol version of this in the future.
repeated uint64 category_iids = 3; // interned EventCategoryName.
// TODO(eseckler): May also want a debug_name for untyped debug-only events.
+ // Type of the TrackEvent (required if |phase| in LegacyEvent is not set).
+ enum Type {
+ TYPE_UNSPECIFIED = 0;
+
+ // Slice events are always formed by a pair of BEGIN + END events. END
+ // events do not need to repeat any TrackEvent fields they have in common
+ // with their corresponding BEGIN event. Arguments and debug annotations of
+ // the BEGIN + END pair will be merged during trace import.
+ //
+ // Note that we deliberately chose not to support COMPLETE events since
+ // clients would need to delay writing them until the slice is completed,
+ // which can result in reordered events in the trace and loss of unfinished
+ // events at the end of a trace.
+ TYPE_SLICE_BEGIN = 1;
+ TYPE_SLICE_END = 2;
+
+ // TODO(eseckler): Add support for counters.
+ }
+ optional Type type = 9;
+
// Unstable key/value annotations shown in the trace viewer but not intended
// for metrics use.
repeated DebugAnnotation debug_annotations = 4;
diff --git a/src/base/BUILD.gn b/src/base/BUILD.gn
index 0afcd5e..1d2e8a3 100644
--- a/src/base/BUILD.gn
+++ b/src/base/BUILD.gn
@@ -36,6 +36,7 @@
"uuid.cc",
"virtual_destructors.cc",
"waitable_event.cc",
+ "watchdog_posix.cc",
]
# TODO(brucedawson): Enable these for Windows when possible.
@@ -49,10 +50,6 @@
]
}
- if ((perfetto_build_standalone || perfetto_build_with_android) &&
- (is_linux || is_android) && !is_wasm) {
- sources += [ "watchdog_posix.cc" ]
- }
if (is_debug && perfetto_build_standalone && !is_wasm) {
deps += [ ":debug_crash_stack_trace" ]
}
diff --git a/src/base/uuid.cc b/src/base/uuid.cc
index 32eea20..3375661 100644
--- a/src/base/uuid.cc
+++ b/src/base/uuid.cc
@@ -24,9 +24,9 @@
namespace base {
// See https://www.ietf.org/rfc/rfc4122.txt
-std::array<uint8_t, 16> Uuidv4() {
+Uuid Uuidv4() {
static std::minstd_rand rng(static_cast<uint32_t>(GetBootTimeNs().count()));
- std::array<uint8_t, 16> uuid;
+ Uuid uuid;
for (size_t i = 0; i < 16; ++i)
uuid[i] = static_cast<uint8_t>(rng());
@@ -38,5 +38,18 @@
return uuid;
}
+std::string UuidToString(const Uuid& uuid) {
+ return std::string(reinterpret_cast<const char*>(uuid.data()), uuid.size());
+}
+
+Uuid StringToUuid(const std::string& s) {
+ Uuid uuid;
+ PERFETTO_CHECK(s.size() == uuid.size());
+ for (size_t i = 0; i < uuid.size(); ++i) {
+ uuid[i] = static_cast<uint8_t>(s[i]);
+ }
+ return uuid;
+}
+
} // namespace base
} // namespace perfetto
diff --git a/src/base/uuid_unittest.cc b/src/base/uuid_unittest.cc
index 913e755..aa03837 100644
--- a/src/base/uuid_unittest.cc
+++ b/src/base/uuid_unittest.cc
@@ -23,11 +23,16 @@
namespace {
TEST(Uuid, TwoUuidsShouldBeDifferent) {
- std::array<uint8_t, 16> a = Uuidv4();
- std::array<uint8_t, 16> b = Uuidv4();
+ Uuid a = Uuidv4();
+ Uuid b = Uuidv4();
EXPECT_NE(a, b);
}
+TEST(Uuid, CanRoundTripUuid) {
+ Uuid uuid = Uuidv4();
+ EXPECT_EQ(StringToUuid(UuidToString(uuid)), uuid);
+}
+
} // namespace
} // namespace base
} // namespace perfetto
diff --git a/src/base/watchdog_posix.cc b/src/base/watchdog_posix.cc
index 9a8965e..98a3d3c 100644
--- a/src/base/watchdog_posix.cc
+++ b/src/base/watchdog_posix.cc
@@ -14,16 +14,9 @@
* limitations under the License.
*/
-#include "perfetto/base/build_config.h"
+#include "perfetto/ext/base/watchdog.h"
-// Watchdog is currently not supported on Mac. This ifdef-based exclusion is
-// here only for the Mac build in AOSP. The standalone and chromium builds
-// exclude this file at the GN level. However, propagating the per-os exclusion
-// through our GN -> BP build file translator is not worth the effort for a
-// one-off case.
-#if !PERFETTO_BUILDFLAG(PERFETTO_OS_MACOSX)
-
-#include "perfetto/ext/base/watchdog_posix.h"
+#if PERFETTO_USE_POSIX_WATCHDOG()
#include <fcntl.h>
#include <inttypes.h>
@@ -38,10 +31,6 @@
#include "perfetto/ext/base/scoped_file.h"
#include "perfetto/ext/base/thread_utils.h"
-#if PERFETTO_BUILDFLAG(PERFETTO_EMBEDDER_BUILD)
-#error perfetto::base::Watchdog should not be used in Chromium or embedders
-#endif
-
namespace perfetto {
namespace base {
@@ -270,4 +259,4 @@
} // namespace base
} // namespace perfetto
-#endif // PERFETTO_OS_MACOSX
+#endif // PERFETTO_USE_POSIX_WATCHDOG()
diff --git a/src/perfetto_cmd/perfetto_cmd.cc b/src/perfetto_cmd/perfetto_cmd.cc
index 4078a88..523067d 100644
--- a/src/perfetto_cmd/perfetto_cmd.cc
+++ b/src/perfetto_cmd/perfetto_cmd.cc
@@ -452,6 +452,10 @@
return 1;
}
+ if (trace_config_->trace_uuid().empty() || !dropbox_tag_.empty()) {
+ trace_config_->set_trace_uuid(base::UuidToString(base::Uuidv4()));
+ }
+
if (!trace_config_->incident_report_config().destination_package().empty()) {
if (dropbox_tag_.empty()) {
PERFETTO_ELOG("Unexpected IncidentReportConfig without --dropbox.");
diff --git a/src/perfetto_cmd/perfetto_cmd.h b/src/perfetto_cmd/perfetto_cmd.h
index 7395936..ce4ef6b 100644
--- a/src/perfetto_cmd/perfetto_cmd.h
+++ b/src/perfetto_cmd/perfetto_cmd.h
@@ -28,6 +28,7 @@
#include "perfetto/ext/base/optional.h"
#include "perfetto/ext/base/scoped_file.h"
#include "perfetto/ext/base/unix_task_runner.h"
+#include "perfetto/ext/base/uuid.h"
#include "perfetto/ext/tracing/core/consumer.h"
#include "perfetto/ext/tracing/ipc/consumer_ipc_client.h"
#include "src/perfetto_cmd/rate_limiter.h"
diff --git a/src/perfetto_cmd/perfetto_config.descriptor.h b/src/perfetto_cmd/perfetto_config.descriptor.h
index a007470..a088984 100644
--- a/src/perfetto_cmd/perfetto_config.descriptor.h
+++ b/src/perfetto_cmd/perfetto_config.descriptor.h
@@ -12,15 +12,15 @@
// SHA1(tools/gen_binary_descriptors)
// 750d7d8f95621b45d4b6430d6f8808087a8702e6
// SHA1(protos/perfetto/config/perfetto_config.proto)
-// f2788058e253eabce51edb438294ceb1a1256c29
+// 52d9cff0b3e68b039fbf8cfacd4976c4cc5c10d4
// This is the proto PerfettoConfig encoded as a ProtoFileDescriptor to allow
// for reflection without libprotobuf full/non-lite protos.
namespace perfetto {
-constexpr std::array<uint8_t, 12319> kPerfettoConfigDescriptor{
- {0x0a, 0x9c, 0x60, 0x0a, 0x25, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74,
+constexpr std::array<uint8_t, 12350> kPerfettoConfigDescriptor{
+ {0x0a, 0xbb, 0x60, 0x0a, 0x25, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74,
0x6f, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x70, 0x65, 0x72,
0x66, 0x65, 0x74, 0x74, 0x6f, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x70, 0x65, 0x72, 0x66,
@@ -374,7 +374,7 @@
0x72, 0x69, 0x6e, 0x67, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x69, 0x65, 0x6c,
0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x0e, 0x20, 0x01, 0x28,
0x0c, 0x52, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x42, 0x79, 0x74, 0x65,
- 0x73, 0x22, 0xb2, 0x1a, 0x0a, 0x0b, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43,
+ 0x73, 0x22, 0xd1, 0x1a, 0x0a, 0x0b, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43,
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x43, 0x0a, 0x07, 0x62, 0x75, 0x66,
0x66, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29,
0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72,
@@ -506,547 +506,550 @@
0x69, 0x67, 0x2e, 0x49, 0x6e, 0x63, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x52,
0x65, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52,
0x14, 0x69, 0x6e, 0x63, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70,
- 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0xc7, 0x01,
- 0x0a, 0x0c, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66,
- 0x69, 0x67, 0x12, 0x17, 0x0a, 0x07, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x6b,
- 0x62, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x73, 0x69, 0x7a,
- 0x65, 0x4b, 0x62, 0x12, 0x55, 0x0a, 0x0b, 0x66, 0x69, 0x6c, 0x6c, 0x5f,
- 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e,
- 0x32, 0x34, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e,
+ 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1d, 0x0a,
+ 0x0a, 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x18,
+ 0x1a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x74, 0x72, 0x61, 0x63, 0x65,
+ 0x55, 0x75, 0x69, 0x64, 0x1a, 0xc7, 0x01, 0x0a, 0x0c, 0x42, 0x75, 0x66,
+ 0x66, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x17, 0x0a,
+ 0x07, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x6b, 0x62, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x0d, 0x52, 0x06, 0x73, 0x69, 0x7a, 0x65, 0x4b, 0x62, 0x12, 0x55,
+ 0x0a, 0x0b, 0x66, 0x69, 0x6c, 0x6c, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63,
+ 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x70, 0x65,
+ 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x73, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+ 0x67, 0x2e, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66,
+ 0x69, 0x67, 0x2e, 0x46, 0x69, 0x6c, 0x6c, 0x50, 0x6f, 0x6c, 0x69, 0x63,
+ 0x79, 0x52, 0x0a, 0x66, 0x69, 0x6c, 0x6c, 0x50, 0x6f, 0x6c, 0x69, 0x63,
+ 0x79, 0x22, 0x3b, 0x0a, 0x0a, 0x46, 0x69, 0x6c, 0x6c, 0x50, 0x6f, 0x6c,
+ 0x69, 0x63, 0x79, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x4e, 0x53, 0x50, 0x45,
+ 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b,
+ 0x52, 0x49, 0x4e, 0x47, 0x5f, 0x42, 0x55, 0x46, 0x46, 0x45, 0x52, 0x10,
+ 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x49, 0x53, 0x43, 0x41, 0x52, 0x44,
+ 0x10, 0x02, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x03,
+ 0x10, 0x04, 0x1a, 0x79, 0x0a, 0x0a, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f,
+ 0x75, 0x72, 0x63, 0x65, 0x12, 0x39, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66,
+ 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70,
+ 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x73, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63,
+ 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x63, 0x6f, 0x6e,
+ 0x66, 0x69, 0x67, 0x12, 0x30, 0x0a, 0x14, 0x70, 0x72, 0x6f, 0x64, 0x75,
+ 0x63, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x66, 0x69, 0x6c,
+ 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x70,
+ 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x46,
+ 0x69, 0x6c, 0x74, 0x65, 0x72, 0x1a, 0xb3, 0x01, 0x0a, 0x11, 0x42, 0x75,
+ 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75,
+ 0x72, 0x63, 0x65, 0x12, 0x3c, 0x0a, 0x1a, 0x64, 0x69, 0x73, 0x61, 0x62,
+ 0x6c, 0x65, 0x5f, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x73, 0x6e, 0x61,
+ 0x70, 0x73, 0x68, 0x6f, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x08, 0x52, 0x18, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65,
+ 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f,
+ 0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x30, 0x0a, 0x14, 0x64, 0x69, 0x73,
+ 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x63,
+ 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52,
+ 0x12, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x72, 0x61, 0x63,
+ 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2e, 0x0a, 0x13, 0x64,
+ 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x79, 0x73, 0x74, 0x65,
+ 0x6d, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08,
+ 0x52, 0x11, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x79, 0x73,
+ 0x74, 0x65, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x1a, 0x77, 0x0a, 0x0e, 0x50,
+ 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+ 0x67, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65,
+ 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x4e, 0x61,
+ 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0b, 0x73, 0x68, 0x6d, 0x5f, 0x73, 0x69,
+ 0x7a, 0x65, 0x5f, 0x6b, 0x62, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52,
+ 0x09, 0x73, 0x68, 0x6d, 0x53, 0x69, 0x7a, 0x65, 0x4b, 0x62, 0x12, 0x20,
+ 0x0a, 0x0c, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f,
+ 0x6b, 0x62, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x70, 0x61,
+ 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x4b, 0x62, 0x1a, 0xe4, 0x01, 0x0a,
+ 0x0e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x64, 0x4d, 0x65, 0x74, 0x61, 0x64,
+ 0x61, 0x74, 0x61, 0x12, 0x2e, 0x0a, 0x13, 0x74, 0x72, 0x69, 0x67, 0x67,
+ 0x65, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x5f,
+ 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x74, 0x72,
+ 0x69, 0x67, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x41, 0x6c, 0x65, 0x72,
+ 0x74, 0x49, 0x64, 0x12, 0x32, 0x0a, 0x15, 0x74, 0x72, 0x69, 0x67, 0x67,
+ 0x65, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+ 0x5f, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x13,
+ 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x43, 0x6f,
+ 0x6e, 0x66, 0x69, 0x67, 0x55, 0x69, 0x64, 0x12, 0x30, 0x0a, 0x14, 0x74,
+ 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x6f,
+ 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28,
+ 0x03, 0x52, 0x12, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x69, 0x6e,
+ 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x64, 0x12, 0x3c, 0x0a,
+ 0x1a, 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, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x18, 0x74,
+ 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x75, 0x62,
+ 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x1a,
+ 0x4c, 0x0a, 0x12, 0x47, 0x75, 0x61, 0x72, 0x64, 0x72, 0x61, 0x69, 0x6c,
+ 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x12, 0x36, 0x0a,
+ 0x18, 0x6d, 0x61, 0x78, 0x5f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x5f,
+ 0x70, 0x65, 0x72, 0x5f, 0x64, 0x61, 0x79, 0x5f, 0x62, 0x79, 0x74, 0x65,
+ 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x14, 0x6d, 0x61, 0x78,
+ 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x65, 0x72, 0x44, 0x61, 0x79,
+ 0x42, 0x79, 0x74, 0x65, 0x73, 0x1a, 0xa0, 0x03, 0x0a, 0x0d, 0x54, 0x72,
+ 0x69, 0x67, 0x67, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
+ 0x59, 0x0a, 0x0c, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x5f, 0x6d,
+ 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x36, 0x2e,
+ 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x73, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e,
+ 0x66, 0x69, 0x67, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x43,
+ 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65,
+ 0x72, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x0b, 0x74, 0x72, 0x69, 0x67, 0x67,
+ 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x4e, 0x0a, 0x08, 0x74, 0x72,
+ 0x69, 0x67, 0x67, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b,
+ 0x32, 0x32, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x65,
- 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x42, 0x75, 0x66, 0x66, 0x65,
- 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x46, 0x69, 0x6c, 0x6c,
- 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x0a, 0x66, 0x69, 0x6c, 0x6c,
- 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0x3b, 0x0a, 0x0a, 0x46, 0x69,
- 0x6c, 0x6c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x0f, 0x0a, 0x0b,
- 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10,
- 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x52, 0x49, 0x4e, 0x47, 0x5f, 0x42, 0x55,
- 0x46, 0x46, 0x45, 0x52, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x49,
- 0x53, 0x43, 0x41, 0x52, 0x44, 0x10, 0x02, 0x4a, 0x04, 0x08, 0x02, 0x10,
- 0x03, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x1a, 0x79, 0x0a, 0x0a, 0x44,
- 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x39, 0x0a,
- 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28,
- 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f,
- 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x44, 0x61, 0x74, 0x61,
- 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
- 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x30, 0x0a, 0x14,
- 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d,
- 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x03,
- 0x28, 0x09, 0x52, 0x12, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72,
- 0x4e, 0x61, 0x6d, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x1a, 0xb3,
- 0x01, 0x0a, 0x11, 0x42, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x44, 0x61,
- 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x3c, 0x0a, 0x1a,
- 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x6c, 0x6f, 0x63,
- 0x6b, 0x5f, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x74, 0x69,
- 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x64, 0x69,
- 0x73, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x6e,
- 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x30,
- 0x0a, 0x14, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x74, 0x72,
- 0x61, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02,
- 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c,
- 0x65, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
- 0x12, 0x2e, 0x0a, 0x13, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f,
- 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18,
- 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x64, 0x69, 0x73, 0x61, 0x62,
- 0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x49, 0x6e, 0x66, 0x6f,
- 0x1a, 0x77, 0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72,
- 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72,
- 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18,
- 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x64, 0x75,
- 0x63, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0b, 0x73,
- 0x68, 0x6d, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x6b, 0x62, 0x18, 0x02,
- 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x73, 0x68, 0x6d, 0x53, 0x69, 0x7a,
- 0x65, 0x4b, 0x62, 0x12, 0x20, 0x0a, 0x0c, 0x70, 0x61, 0x67, 0x65, 0x5f,
- 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x6b, 0x62, 0x18, 0x03, 0x20, 0x01, 0x28,
- 0x0d, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x4b,
- 0x62, 0x1a, 0xe4, 0x01, 0x0a, 0x0e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x64,
- 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x2e, 0x0a, 0x13,
- 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x61,
- 0x6c, 0x65, 0x72, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
- 0x03, 0x52, 0x11, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x69, 0x6e,
- 0x67, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x49, 0x64, 0x12, 0x32, 0x0a, 0x15,
- 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x63,
- 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20,
- 0x01, 0x28, 0x05, 0x52, 0x13, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72,
- 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x55, 0x69, 0x64,
- 0x12, 0x30, 0x0a, 0x14, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x69,
- 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x64,
- 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x12, 0x74, 0x72, 0x69, 0x67,
- 0x67, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
- 0x49, 0x64, 0x12, 0x3c, 0x0a, 0x1a, 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, 0x04, 0x20, 0x01,
- 0x28, 0x03, 0x52, 0x18, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x69,
- 0x6e, 0x67, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69,
- 0x6f, 0x6e, 0x49, 0x64, 0x1a, 0x4c, 0x0a, 0x12, 0x47, 0x75, 0x61, 0x72,
- 0x64, 0x72, 0x61, 0x69, 0x6c, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64,
- 0x65, 0x73, 0x12, 0x36, 0x0a, 0x18, 0x6d, 0x61, 0x78, 0x5f, 0x75, 0x70,
- 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x64, 0x61, 0x79,
- 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04,
- 0x52, 0x14, 0x6d, 0x61, 0x78, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x50,
- 0x65, 0x72, 0x44, 0x61, 0x79, 0x42, 0x79, 0x74, 0x65, 0x73, 0x1a, 0xa0,
- 0x03, 0x0a, 0x0d, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x43, 0x6f,
- 0x6e, 0x66, 0x69, 0x67, 0x12, 0x59, 0x0a, 0x0c, 0x74, 0x72, 0x69, 0x67,
- 0x67, 0x65, 0x72, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x0e, 0x32, 0x36, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74,
- 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x54, 0x72, 0x61,
- 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x54, 0x72, 0x69,
- 0x67, 0x67, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x54,
- 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x0b,
- 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x65, 0x12,
- 0x4e, 0x0a, 0x08, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x73, 0x18,
- 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x70, 0x65, 0x72, 0x66,
- 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e,
- 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e,
- 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69,
- 0x67, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x08, 0x74,
- 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x74,
- 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f,
- 0x75, 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52,
- 0x10, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x54, 0x69, 0x6d, 0x65,
- 0x6f, 0x75, 0x74, 0x4d, 0x73, 0x1a, 0x71, 0x0a, 0x07, 0x54, 0x72, 0x69,
- 0x67, 0x67, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,
- 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
- 0x12, 0x2e, 0x0a, 0x13, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72,
- 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x72, 0x65, 0x67, 0x65, 0x78, 0x18,
- 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x70, 0x72, 0x6f, 0x64, 0x75,
- 0x63, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x67, 0x65, 0x78,
- 0x12, 0x22, 0x0a, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x64, 0x65, 0x6c,
- 0x61, 0x79, 0x5f, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52,
- 0x0b, 0x73, 0x74, 0x6f, 0x70, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x4d, 0x73,
- 0x22, 0x43, 0x0a, 0x0b, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x4d,
- 0x6f, 0x64, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x4e, 0x53, 0x50, 0x45,
- 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d,
- 0x53, 0x54, 0x41, 0x52, 0x54, 0x5f, 0x54, 0x52, 0x41, 0x43, 0x49, 0x4e,
- 0x47, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x54, 0x4f, 0x50, 0x5f,
- 0x54, 0x52, 0x41, 0x43, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x1a, 0x40, 0x0a,
- 0x16, 0x49, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6c,
- 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
- 0x26, 0x0a, 0x0f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x70, 0x65, 0x72,
- 0x69, 0x6f, 0x64, 0x5f, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d,
- 0x52, 0x0d, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x50, 0x65, 0x72, 0x69, 0x6f,
- 0x64, 0x4d, 0x73, 0x1a, 0xbc, 0x01, 0x0a, 0x14, 0x49, 0x6e, 0x63, 0x69,
- 0x64, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x6f,
- 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2f, 0x0a, 0x13, 0x64, 0x65, 0x73, 0x74,
- 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x63, 0x6b,
- 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x64,
- 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61,
- 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x2b, 0x0a, 0x11, 0x64, 0x65, 0x73,
- 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6c, 0x61,
- 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x64, 0x65,
- 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6c, 0x61,
- 0x73, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x69, 0x76, 0x61, 0x63,
- 0x79, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28,
- 0x05, 0x52, 0x0c, 0x70, 0x72, 0x69, 0x76, 0x61, 0x63, 0x79, 0x4c, 0x65,
- 0x76, 0x65, 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x6b, 0x69, 0x70, 0x5f,
- 0x64, 0x72, 0x6f, 0x70, 0x62, 0x6f, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28,
- 0x08, 0x52, 0x0b, 0x73, 0x6b, 0x69, 0x70, 0x44, 0x72, 0x6f, 0x70, 0x62,
- 0x6f, 0x78, 0x22, 0x55, 0x0a, 0x15, 0x4c, 0x6f, 0x63, 0x6b, 0x64, 0x6f,
- 0x77, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74,
- 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x12, 0x4c, 0x4f, 0x43, 0x4b, 0x44,
- 0x4f, 0x57, 0x4e, 0x5f, 0x55, 0x4e, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45,
- 0x44, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x4c, 0x4f, 0x43, 0x4b, 0x44,
- 0x4f, 0x57, 0x4e, 0x5f, 0x43, 0x4c, 0x45, 0x41, 0x52, 0x10, 0x01, 0x12,
- 0x10, 0x0a, 0x0c, 0x4c, 0x4f, 0x43, 0x4b, 0x44, 0x4f, 0x57, 0x4e, 0x5f,
- 0x53, 0x45, 0x54, 0x10, 0x02, 0x22, 0x51, 0x0a, 0x0f, 0x43, 0x6f, 0x6d,
- 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65,
- 0x12, 0x20, 0x0a, 0x1c, 0x43, 0x4f, 0x4d, 0x50, 0x52, 0x45, 0x53, 0x53,
- 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53,
- 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1c,
- 0x0a, 0x18, 0x43, 0x4f, 0x4d, 0x50, 0x52, 0x45, 0x53, 0x53, 0x49, 0x4f,
- 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x45, 0x46, 0x4c, 0x41,
- 0x54, 0x45, 0x10, 0x01, 0x4a, 0x04, 0x08, 0x0f, 0x10, 0x10, 0x22, 0xed,
- 0x04, 0x0a, 0x0f, 0x48, 0x65, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x66, 0x64,
- 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x36, 0x0a, 0x17, 0x73, 0x61,
- 0x6d, 0x70, 0x6c, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72,
- 0x76, 0x61, 0x6c, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x04, 0x52, 0x15, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x6e,
- 0x67, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x42, 0x79, 0x74,
- 0x65, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73,
- 0x73, 0x5f, 0x63, 0x6d, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x02, 0x20,
- 0x03, 0x28, 0x09, 0x52, 0x0e, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73,
- 0x43, 0x6d, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x70,
- 0x69, 0x64, 0x18, 0x04, 0x20, 0x03, 0x28, 0x04, 0x52, 0x03, 0x70, 0x69,
- 0x64, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x6c, 0x6c, 0x18, 0x05, 0x20, 0x01,
- 0x28, 0x08, 0x52, 0x03, 0x61, 0x6c, 0x6c, 0x12, 0x2c, 0x0a, 0x12, 0x73,
- 0x6b, 0x69, 0x70, 0x5f, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x5f, 0x70,
- 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52,
- 0x10, 0x73, 0x6b, 0x69, 0x70, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x50,
- 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x6b, 0x0a, 0x16, 0x63, 0x6f, 0x6e,
- 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x64, 0x75, 0x6d, 0x70,
- 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28,
- 0x0b, 0x32, 0x35, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f,
- 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x48, 0x65, 0x61, 0x70,
- 0x70, 0x72, 0x6f, 0x66, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e,
- 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x44, 0x75,
- 0x6d, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x14, 0x63, 0x6f,
- 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x44, 0x75, 0x6d, 0x70,
- 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x68,
- 0x6d, 0x65, 0x6d, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x62, 0x79, 0x74,
- 0x65, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x73, 0x68,
- 0x6d, 0x65, 0x6d, 0x53, 0x69, 0x7a, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73,
- 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x63, 0x6c,
- 0x69, 0x65, 0x6e, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b,
- 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12,
- 0x1d, 0x0a, 0x0a, 0x6e, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75,
- 0x70, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x6e, 0x6f, 0x53,
- 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x6f,
- 0x5f, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x18, 0x0b, 0x20, 0x01,
- 0x28, 0x08, 0x52, 0x09, 0x6e, 0x6f, 0x52, 0x75, 0x6e, 0x6e, 0x69, 0x6e,
- 0x67, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x64, 0x6c, 0x65, 0x5f, 0x61, 0x6c,
- 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0c, 0x20,
- 0x01, 0x28, 0x08, 0x52, 0x0f, 0x69, 0x64, 0x6c, 0x65, 0x41, 0x6c, 0x6c,
- 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1e, 0x0a, 0x0b,
- 0x64, 0x75, 0x6d, 0x70, 0x5f, 0x61, 0x74, 0x5f, 0x6d, 0x61, 0x78, 0x18,
- 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x64, 0x75, 0x6d, 0x70, 0x41,
- 0x74, 0x4d, 0x61, 0x78, 0x1a, 0x64, 0x0a, 0x14, 0x43, 0x6f, 0x6e, 0x74,
- 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x44, 0x75, 0x6d, 0x70, 0x43, 0x6f,
- 0x6e, 0x66, 0x69, 0x67, 0x12, 0x22, 0x0a, 0x0d, 0x64, 0x75, 0x6d, 0x70,
- 0x5f, 0x70, 0x68, 0x61, 0x73, 0x65, 0x5f, 0x6d, 0x73, 0x18, 0x05, 0x20,
- 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x64, 0x75, 0x6d, 0x70, 0x50, 0x68, 0x61,
- 0x73, 0x65, 0x4d, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x64, 0x75, 0x6d, 0x70,
- 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x6d, 0x73,
- 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x64, 0x75, 0x6d, 0x70,
- 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x4d, 0x73, 0x22, 0x5f,
- 0x0a, 0x10, 0x47, 0x70, 0x75, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72,
- 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2a, 0x0a, 0x11, 0x63, 0x6f,
- 0x75, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64,
- 0x5f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x63,
- 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64,
- 0x4e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65,
- 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0d, 0x52,
- 0x0a, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x49, 0x64, 0x73, 0x22,
- 0x44, 0x0a, 0x12, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x4c,
- 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2e, 0x0a,
- 0x13, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d,
- 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x03,
- 0x28, 0x09, 0x52, 0x11, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x4e,
- 0x61, 0x6d, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x2a, 0x8e, 0x01,
- 0x0a, 0x0c, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x4c, 0x6f, 0x67,
- 0x49, 0x64, 0x12, 0x0f, 0x0a, 0x0b, 0x4c, 0x49, 0x44, 0x5f, 0x44, 0x45,
- 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x4c,
- 0x49, 0x44, 0x5f, 0x52, 0x41, 0x44, 0x49, 0x4f, 0x10, 0x01, 0x12, 0x0e,
- 0x0a, 0x0a, 0x4c, 0x49, 0x44, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x53,
- 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x4c, 0x49, 0x44, 0x5f, 0x53, 0x59,
- 0x53, 0x54, 0x45, 0x4d, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x4c, 0x49,
- 0x44, 0x5f, 0x43, 0x52, 0x41, 0x53, 0x48, 0x10, 0x04, 0x12, 0x0d, 0x0a,
- 0x09, 0x4c, 0x49, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x53, 0x10, 0x05,
- 0x12, 0x10, 0x0a, 0x0c, 0x4c, 0x49, 0x44, 0x5f, 0x53, 0x45, 0x43, 0x55,
- 0x52, 0x49, 0x54, 0x59, 0x10, 0x06, 0x12, 0x0e, 0x0a, 0x0a, 0x4c, 0x49,
- 0x44, 0x5f, 0x4b, 0x45, 0x52, 0x4e, 0x45, 0x4c, 0x10, 0x07, 0x2a, 0x9b,
- 0x01, 0x0a, 0x12, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x4c, 0x6f,
- 0x67, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x14, 0x0a,
- 0x10, 0x50, 0x52, 0x49, 0x4f, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43,
- 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x50,
- 0x52, 0x49, 0x4f, 0x5f, 0x55, 0x4e, 0x55, 0x53, 0x45, 0x44, 0x10, 0x01,
- 0x12, 0x10, 0x0a, 0x0c, 0x50, 0x52, 0x49, 0x4f, 0x5f, 0x56, 0x45, 0x52,
- 0x42, 0x4f, 0x53, 0x45, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x50, 0x52,
- 0x49, 0x4f, 0x5f, 0x44, 0x45, 0x42, 0x55, 0x47, 0x10, 0x03, 0x12, 0x0d,
- 0x0a, 0x09, 0x50, 0x52, 0x49, 0x4f, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10,
- 0x04, 0x12, 0x0d, 0x0a, 0x09, 0x50, 0x52, 0x49, 0x4f, 0x5f, 0x57, 0x41,
- 0x52, 0x4e, 0x10, 0x05, 0x12, 0x0e, 0x0a, 0x0a, 0x50, 0x52, 0x49, 0x4f,
- 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x06, 0x12, 0x0e, 0x0a, 0x0a,
- 0x50, 0x52, 0x49, 0x4f, 0x5f, 0x46, 0x41, 0x54, 0x41, 0x4c, 0x10, 0x07,
- 0x2a, 0xbf, 0x06, 0x0a, 0x0f, 0x4d, 0x65, 0x6d, 0x69, 0x6e, 0x66, 0x6f,
- 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x12, 0x17, 0x0a, 0x13,
- 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x55, 0x4e, 0x53, 0x50,
- 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a,
- 0x11, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x4d, 0x45, 0x4d,
- 0x5f, 0x54, 0x4f, 0x54, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10,
- 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x4d, 0x45, 0x4d, 0x5f,
- 0x46, 0x52, 0x45, 0x45, 0x10, 0x02, 0x12, 0x19, 0x0a, 0x15, 0x4d, 0x45,
- 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x4d, 0x45, 0x4d, 0x5f, 0x41, 0x56,
- 0x41, 0x49, 0x4c, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x03, 0x12, 0x13, 0x0a,
- 0x0f, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x42, 0x55, 0x46,
- 0x46, 0x45, 0x52, 0x53, 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x45,
- 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x43, 0x41, 0x43, 0x48, 0x45, 0x44,
- 0x10, 0x05, 0x12, 0x17, 0x0a, 0x13, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46,
- 0x4f, 0x5f, 0x53, 0x57, 0x41, 0x50, 0x5f, 0x43, 0x41, 0x43, 0x48, 0x45,
- 0x44, 0x10, 0x06, 0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x45, 0x4d, 0x49, 0x4e,
- 0x46, 0x4f, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x07, 0x12,
- 0x14, 0x0a, 0x10, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x49,
- 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x08, 0x12, 0x17, 0x0a,
- 0x13, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x41, 0x43, 0x54,
- 0x49, 0x56, 0x45, 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x10, 0x09, 0x12, 0x19,
- 0x0a, 0x15, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x49, 0x4e,
- 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x10,
- 0x0a, 0x12, 0x17, 0x0a, 0x13, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f,
- 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45,
- 0x10, 0x0b, 0x12, 0x19, 0x0a, 0x15, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46,
- 0x4f, 0x5f, 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x46,
- 0x49, 0x4c, 0x45, 0x10, 0x0c, 0x12, 0x17, 0x0a, 0x13, 0x4d, 0x45, 0x4d,
- 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54,
- 0x41, 0x42, 0x4c, 0x45, 0x10, 0x0d, 0x12, 0x13, 0x0a, 0x0f, 0x4d, 0x45,
- 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x4d, 0x4c, 0x4f, 0x43, 0x4b, 0x45,
- 0x44, 0x10, 0x0e, 0x12, 0x16, 0x0a, 0x12, 0x4d, 0x45, 0x4d, 0x49, 0x4e,
- 0x46, 0x4f, 0x5f, 0x53, 0x57, 0x41, 0x50, 0x5f, 0x54, 0x4f, 0x54, 0x41,
- 0x4c, 0x10, 0x0f, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x45, 0x4d, 0x49, 0x4e,
- 0x46, 0x4f, 0x5f, 0x53, 0x57, 0x41, 0x50, 0x5f, 0x46, 0x52, 0x45, 0x45,
- 0x10, 0x10, 0x12, 0x11, 0x0a, 0x0d, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46,
- 0x4f, 0x5f, 0x44, 0x49, 0x52, 0x54, 0x59, 0x10, 0x11, 0x12, 0x15, 0x0a,
- 0x11, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x57, 0x52, 0x49,
- 0x54, 0x45, 0x42, 0x41, 0x43, 0x4b, 0x10, 0x12, 0x12, 0x16, 0x0a, 0x12,
- 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x41, 0x4e, 0x4f, 0x4e,
- 0x5f, 0x50, 0x41, 0x47, 0x45, 0x53, 0x10, 0x13, 0x12, 0x12, 0x0a, 0x0e,
- 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x4d, 0x41, 0x50, 0x50,
- 0x45, 0x44, 0x10, 0x14, 0x12, 0x11, 0x0a, 0x0d, 0x4d, 0x45, 0x4d, 0x49,
- 0x4e, 0x46, 0x4f, 0x5f, 0x53, 0x48, 0x4d, 0x45, 0x4d, 0x10, 0x15, 0x12,
- 0x10, 0x0a, 0x0c, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x53,
- 0x4c, 0x41, 0x42, 0x10, 0x16, 0x12, 0x1c, 0x0a, 0x18, 0x4d, 0x45, 0x4d,
- 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x53, 0x4c, 0x41, 0x42, 0x5f, 0x52, 0x45,
- 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x17, 0x12,
- 0x1e, 0x0a, 0x1a, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x53,
- 0x4c, 0x41, 0x42, 0x5f, 0x55, 0x4e, 0x52, 0x45, 0x43, 0x4c, 0x41, 0x49,
- 0x4d, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x18, 0x12, 0x18, 0x0a, 0x14, 0x4d,
- 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x4b, 0x45, 0x52, 0x4e, 0x45,
- 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x43, 0x4b, 0x10, 0x19, 0x12, 0x17, 0x0a,
- 0x13, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x50, 0x41, 0x47,
- 0x45, 0x5f, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x53, 0x10, 0x1a, 0x12, 0x18,
- 0x0a, 0x14, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x43, 0x4f,
- 0x4d, 0x4d, 0x49, 0x54, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x10, 0x1b,
+ 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67,
+ 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x54, 0x72, 0x69,
+ 0x67, 0x67, 0x65, 0x72, 0x52, 0x08, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65,
+ 0x72, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65,
+ 0x72, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x6d, 0x73,
+ 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x74, 0x72, 0x69, 0x67,
+ 0x67, 0x65, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, 0x73,
+ 0x1a, 0x71, 0x0a, 0x07, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x12,
+ 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x70,
+ 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65,
+ 0x5f, 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x11, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x4e, 0x61,
+ 0x6d, 0x65, 0x52, 0x65, 0x67, 0x65, 0x78, 0x12, 0x22, 0x0a, 0x0d, 0x73,
+ 0x74, 0x6f, 0x70, 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x6d, 0x73,
+ 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x73, 0x74, 0x6f, 0x70,
+ 0x44, 0x65, 0x6c, 0x61, 0x79, 0x4d, 0x73, 0x22, 0x43, 0x0a, 0x0b, 0x54,
+ 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x0f,
+ 0x0a, 0x0b, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45,
+ 0x44, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x54, 0x41, 0x52, 0x54,
+ 0x5f, 0x54, 0x52, 0x41, 0x43, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x10,
+ 0x0a, 0x0c, 0x53, 0x54, 0x4f, 0x50, 0x5f, 0x54, 0x52, 0x41, 0x43, 0x49,
+ 0x4e, 0x47, 0x10, 0x02, 0x1a, 0x40, 0x0a, 0x16, 0x49, 0x6e, 0x63, 0x72,
+ 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65,
+ 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x26, 0x0a, 0x0f, 0x63, 0x6c,
+ 0x65, 0x61, 0x72, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x5f, 0x6d,
+ 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x63, 0x6c, 0x65,
+ 0x61, 0x72, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x4d, 0x73, 0x1a, 0xbc,
+ 0x01, 0x0a, 0x14, 0x49, 0x6e, 0x63, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x52,
+ 0x65, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
+ 0x2f, 0x0a, 0x13, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69,
+ 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65,
+ 0x12, 0x2b, 0x0a, 0x11, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x18, 0x02, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x10, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61,
+ 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x12, 0x23, 0x0a,
+ 0x0d, 0x70, 0x72, 0x69, 0x76, 0x61, 0x63, 0x79, 0x5f, 0x6c, 0x65, 0x76,
+ 0x65, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x70, 0x72,
+ 0x69, 0x76, 0x61, 0x63, 0x79, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x21,
+ 0x0a, 0x0c, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x64, 0x72, 0x6f, 0x70, 0x62,
+ 0x6f, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x73, 0x6b,
+ 0x69, 0x70, 0x44, 0x72, 0x6f, 0x70, 0x62, 0x6f, 0x78, 0x22, 0x55, 0x0a,
+ 0x15, 0x4c, 0x6f, 0x63, 0x6b, 0x64, 0x6f, 0x77, 0x6e, 0x4d, 0x6f, 0x64,
+ 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16,
+ 0x0a, 0x12, 0x4c, 0x4f, 0x43, 0x4b, 0x44, 0x4f, 0x57, 0x4e, 0x5f, 0x55,
+ 0x4e, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x44, 0x10, 0x00, 0x12, 0x12,
+ 0x0a, 0x0e, 0x4c, 0x4f, 0x43, 0x4b, 0x44, 0x4f, 0x57, 0x4e, 0x5f, 0x43,
+ 0x4c, 0x45, 0x41, 0x52, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x4c, 0x4f,
+ 0x43, 0x4b, 0x44, 0x4f, 0x57, 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x10, 0x02,
+ 0x22, 0x51, 0x0a, 0x0f, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73,
+ 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x20, 0x0a, 0x1c, 0x43,
+ 0x4f, 0x4d, 0x50, 0x52, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x54,
+ 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46,
+ 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x4f, 0x4d,
+ 0x50, 0x52, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50,
+ 0x45, 0x5f, 0x44, 0x45, 0x46, 0x4c, 0x41, 0x54, 0x45, 0x10, 0x01, 0x4a,
+ 0x04, 0x08, 0x0f, 0x10, 0x10, 0x22, 0xed, 0x04, 0x0a, 0x0f, 0x48, 0x65,
+ 0x61, 0x70, 0x70, 0x72, 0x6f, 0x66, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+ 0x67, 0x12, 0x36, 0x0a, 0x17, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x6e,
+ 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x62,
+ 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x15,
+ 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x74, 0x65,
+ 0x72, 0x76, 0x61, 0x6c, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x27, 0x0a,
+ 0x0f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6d, 0x64,
+ 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e,
+ 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6d, 0x64, 0x6c, 0x69,
+ 0x6e, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x04, 0x20,
+ 0x03, 0x28, 0x04, 0x52, 0x03, 0x70, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03,
+ 0x61, 0x6c, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x61,
+ 0x6c, 0x6c, 0x12, 0x2c, 0x0a, 0x12, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x73,
+ 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78,
+ 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x73, 0x6b, 0x69, 0x70,
+ 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78,
+ 0x12, 0x6b, 0x0a, 0x16, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f,
+ 0x75, 0x73, 0x5f, 0x64, 0x75, 0x6d, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x66,
+ 0x69, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x70,
+ 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x73, 0x2e, 0x48, 0x65, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x66, 0x64,
+ 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x69,
+ 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x44, 0x75, 0x6d, 0x70, 0x43, 0x6f, 0x6e,
+ 0x66, 0x69, 0x67, 0x52, 0x14, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75,
+ 0x6f, 0x75, 0x73, 0x44, 0x75, 0x6d, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+ 0x67, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x68, 0x6d, 0x65, 0x6d, 0x5f, 0x73,
+ 0x69, 0x7a, 0x65, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x08, 0x20,
+ 0x01, 0x28, 0x04, 0x52, 0x0e, 0x73, 0x68, 0x6d, 0x65, 0x6d, 0x53, 0x69,
+ 0x7a, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x62,
+ 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18,
+ 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
+ 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x6f,
+ 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x18, 0x0a, 0x20, 0x01,
+ 0x28, 0x08, 0x52, 0x09, 0x6e, 0x6f, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75,
+ 0x70, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x6f, 0x5f, 0x72, 0x75, 0x6e, 0x6e,
+ 0x69, 0x6e, 0x67, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x6e,
+ 0x6f, 0x52, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x12, 0x29, 0x0a, 0x10,
+ 0x69, 0x64, 0x6c, 0x65, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f,
+ 0x69, 0x64, 0x6c, 0x65, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69,
+ 0x6f, 0x6e, 0x73, 0x12, 0x1e, 0x0a, 0x0b, 0x64, 0x75, 0x6d, 0x70, 0x5f,
+ 0x61, 0x74, 0x5f, 0x6d, 0x61, 0x78, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08,
+ 0x52, 0x09, 0x64, 0x75, 0x6d, 0x70, 0x41, 0x74, 0x4d, 0x61, 0x78, 0x1a,
+ 0x64, 0x0a, 0x14, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75,
+ 0x73, 0x44, 0x75, 0x6d, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
+ 0x22, 0x0a, 0x0d, 0x64, 0x75, 0x6d, 0x70, 0x5f, 0x70, 0x68, 0x61, 0x73,
+ 0x65, 0x5f, 0x6d, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b,
+ 0x64, 0x75, 0x6d, 0x70, 0x50, 0x68, 0x61, 0x73, 0x65, 0x4d, 0x73, 0x12,
+ 0x28, 0x0a, 0x10, 0x64, 0x75, 0x6d, 0x70, 0x5f, 0x69, 0x6e, 0x74, 0x65,
+ 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x6d, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28,
+ 0x0d, 0x52, 0x0e, 0x64, 0x75, 0x6d, 0x70, 0x49, 0x6e, 0x74, 0x65, 0x72,
+ 0x76, 0x61, 0x6c, 0x4d, 0x73, 0x22, 0x5f, 0x0a, 0x10, 0x47, 0x70, 0x75,
+ 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+ 0x67, 0x12, 0x2a, 0x0a, 0x11, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72,
+ 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x5f, 0x6e, 0x73, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65,
+ 0x72, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x4e, 0x73, 0x12, 0x1f, 0x0a,
+ 0x0b, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73,
+ 0x18, 0x02, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x0a, 0x63, 0x6f, 0x75, 0x6e,
+ 0x74, 0x65, 0x72, 0x49, 0x64, 0x73, 0x22, 0x44, 0x0a, 0x12, 0x50, 0x61,
+ 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f,
+ 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2e, 0x0a, 0x13, 0x70, 0x61, 0x63, 0x6b,
+ 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x66, 0x69, 0x6c,
+ 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x70,
+ 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x46, 0x69,
+ 0x6c, 0x74, 0x65, 0x72, 0x2a, 0x8e, 0x01, 0x0a, 0x0c, 0x41, 0x6e, 0x64,
+ 0x72, 0x6f, 0x69, 0x64, 0x4c, 0x6f, 0x67, 0x49, 0x64, 0x12, 0x0f, 0x0a,
+ 0x0b, 0x4c, 0x49, 0x44, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54,
+ 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x4c, 0x49, 0x44, 0x5f, 0x52, 0x41,
+ 0x44, 0x49, 0x4f, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x4c, 0x49, 0x44,
+ 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x53, 0x10, 0x02, 0x12, 0x0e, 0x0a,
+ 0x0a, 0x4c, 0x49, 0x44, 0x5f, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x10,
+ 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x4c, 0x49, 0x44, 0x5f, 0x43, 0x52, 0x41,
+ 0x53, 0x48, 0x10, 0x04, 0x12, 0x0d, 0x0a, 0x09, 0x4c, 0x49, 0x44, 0x5f,
+ 0x53, 0x54, 0x41, 0x54, 0x53, 0x10, 0x05, 0x12, 0x10, 0x0a, 0x0c, 0x4c,
+ 0x49, 0x44, 0x5f, 0x53, 0x45, 0x43, 0x55, 0x52, 0x49, 0x54, 0x59, 0x10,
+ 0x06, 0x12, 0x0e, 0x0a, 0x0a, 0x4c, 0x49, 0x44, 0x5f, 0x4b, 0x45, 0x52,
+ 0x4e, 0x45, 0x4c, 0x10, 0x07, 0x2a, 0x9b, 0x01, 0x0a, 0x12, 0x41, 0x6e,
+ 0x64, 0x72, 0x6f, 0x69, 0x64, 0x4c, 0x6f, 0x67, 0x50, 0x72, 0x69, 0x6f,
+ 0x72, 0x69, 0x74, 0x79, 0x12, 0x14, 0x0a, 0x10, 0x50, 0x52, 0x49, 0x4f,
+ 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44,
+ 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x50, 0x52, 0x49, 0x4f, 0x5f, 0x55,
+ 0x4e, 0x55, 0x53, 0x45, 0x44, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x50,
+ 0x52, 0x49, 0x4f, 0x5f, 0x56, 0x45, 0x52, 0x42, 0x4f, 0x53, 0x45, 0x10,
+ 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x50, 0x52, 0x49, 0x4f, 0x5f, 0x44, 0x45,
+ 0x42, 0x55, 0x47, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x50, 0x52, 0x49,
+ 0x4f, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x04, 0x12, 0x0d, 0x0a, 0x09,
+ 0x50, 0x52, 0x49, 0x4f, 0x5f, 0x57, 0x41, 0x52, 0x4e, 0x10, 0x05, 0x12,
+ 0x0e, 0x0a, 0x0a, 0x50, 0x52, 0x49, 0x4f, 0x5f, 0x45, 0x52, 0x52, 0x4f,
+ 0x52, 0x10, 0x06, 0x12, 0x0e, 0x0a, 0x0a, 0x50, 0x52, 0x49, 0x4f, 0x5f,
+ 0x46, 0x41, 0x54, 0x41, 0x4c, 0x10, 0x07, 0x2a, 0xbf, 0x06, 0x0a, 0x0f,
+ 0x4d, 0x65, 0x6d, 0x69, 0x6e, 0x66, 0x6f, 0x43, 0x6f, 0x75, 0x6e, 0x74,
+ 0x65, 0x72, 0x73, 0x12, 0x17, 0x0a, 0x13, 0x4d, 0x45, 0x4d, 0x49, 0x4e,
+ 0x46, 0x4f, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49,
+ 0x45, 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x45, 0x4d, 0x49,
+ 0x4e, 0x46, 0x4f, 0x5f, 0x4d, 0x45, 0x4d, 0x5f, 0x54, 0x4f, 0x54, 0x41,
+ 0x4c, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x45, 0x4d, 0x49, 0x4e,
+ 0x46, 0x4f, 0x5f, 0x4d, 0x45, 0x4d, 0x5f, 0x46, 0x52, 0x45, 0x45, 0x10,
+ 0x02, 0x12, 0x19, 0x0a, 0x15, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f,
+ 0x5f, 0x4d, 0x45, 0x4d, 0x5f, 0x41, 0x56, 0x41, 0x49, 0x4c, 0x41, 0x42,
+ 0x4c, 0x45, 0x10, 0x03, 0x12, 0x13, 0x0a, 0x0f, 0x4d, 0x45, 0x4d, 0x49,
+ 0x4e, 0x46, 0x4f, 0x5f, 0x42, 0x55, 0x46, 0x46, 0x45, 0x52, 0x53, 0x10,
+ 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f,
+ 0x5f, 0x43, 0x41, 0x43, 0x48, 0x45, 0x44, 0x10, 0x05, 0x12, 0x17, 0x0a,
+ 0x13, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x53, 0x57, 0x41,
+ 0x50, 0x5f, 0x43, 0x41, 0x43, 0x48, 0x45, 0x44, 0x10, 0x06, 0x12, 0x12,
+ 0x0a, 0x0e, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x41, 0x43,
+ 0x54, 0x49, 0x56, 0x45, 0x10, 0x07, 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x45,
+ 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49,
+ 0x56, 0x45, 0x10, 0x08, 0x12, 0x17, 0x0a, 0x13, 0x4d, 0x45, 0x4d, 0x49,
+ 0x4e, 0x46, 0x4f, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x41,
+ 0x4e, 0x4f, 0x4e, 0x10, 0x09, 0x12, 0x19, 0x0a, 0x15, 0x4d, 0x45, 0x4d,
+ 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56,
+ 0x45, 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x10, 0x0a, 0x12, 0x17, 0x0a, 0x13,
+ 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x41, 0x43, 0x54, 0x49,
+ 0x56, 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x0b, 0x12, 0x19, 0x0a,
+ 0x15, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x49, 0x4e, 0x41,
+ 0x43, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x0c,
0x12, 0x17, 0x0a, 0x13, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f,
- 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x45, 0x44, 0x5f, 0x41, 0x53, 0x10,
- 0x1c, 0x12, 0x19, 0x0a, 0x15, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f,
- 0x5f, 0x56, 0x4d, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x5f, 0x54, 0x4f, 0x54,
- 0x41, 0x4c, 0x10, 0x1d, 0x12, 0x18, 0x0a, 0x14, 0x4d, 0x45, 0x4d, 0x49,
- 0x4e, 0x46, 0x4f, 0x5f, 0x56, 0x4d, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x5f,
- 0x55, 0x53, 0x45, 0x44, 0x10, 0x1e, 0x12, 0x19, 0x0a, 0x15, 0x4d, 0x45,
- 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x56, 0x4d, 0x41, 0x4c, 0x4c, 0x4f,
- 0x43, 0x5f, 0x43, 0x48, 0x55, 0x4e, 0x4b, 0x10, 0x1f, 0x12, 0x15, 0x0a,
- 0x11, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x43, 0x4d, 0x41,
- 0x5f, 0x54, 0x4f, 0x54, 0x41, 0x4c, 0x10, 0x20, 0x12, 0x14, 0x0a, 0x10,
- 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x43, 0x4d, 0x41, 0x5f,
- 0x46, 0x52, 0x45, 0x45, 0x10, 0x21, 0x2a, 0xc6, 0x15, 0x0a, 0x0e, 0x56,
- 0x6d, 0x73, 0x74, 0x61, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72,
- 0x73, 0x12, 0x16, 0x0a, 0x12, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
- 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10,
- 0x00, 0x12, 0x18, 0x0a, 0x14, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
- 0x4e, 0x52, 0x5f, 0x46, 0x52, 0x45, 0x45, 0x5f, 0x50, 0x41, 0x47, 0x45,
- 0x53, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x56, 0x4d, 0x53, 0x54, 0x41,
- 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x5f, 0x42,
- 0x41, 0x54, 0x43, 0x48, 0x10, 0x02, 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4d,
- 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x49, 0x4e, 0x41, 0x43,
- 0x54, 0x49, 0x56, 0x45, 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x10, 0x03, 0x12,
- 0x19, 0x0a, 0x15, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52,
- 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x41, 0x4e, 0x4f, 0x4e,
- 0x10, 0x04, 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
- 0x5f, 0x4e, 0x52, 0x5f, 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45,
- 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x05, 0x12, 0x19, 0x0a, 0x15, 0x56,
- 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x41, 0x43, 0x54,
- 0x49, 0x56, 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x06, 0x12, 0x19,
- 0x0a, 0x15, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f,
0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x10,
- 0x07, 0x12, 0x13, 0x0a, 0x0f, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
- 0x4e, 0x52, 0x5f, 0x4d, 0x4c, 0x4f, 0x43, 0x4b, 0x10, 0x08, 0x12, 0x18,
- 0x0a, 0x14, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f,
- 0x41, 0x4e, 0x4f, 0x4e, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x53, 0x10, 0x09,
- 0x12, 0x14, 0x0a, 0x10, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e,
- 0x52, 0x5f, 0x4d, 0x41, 0x50, 0x50, 0x45, 0x44, 0x10, 0x0a, 0x12, 0x18,
- 0x0a, 0x14, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f,
- 0x46, 0x49, 0x4c, 0x45, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x53, 0x10, 0x0b,
- 0x12, 0x13, 0x0a, 0x0f, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e,
- 0x52, 0x5f, 0x44, 0x49, 0x52, 0x54, 0x59, 0x10, 0x0c, 0x12, 0x17, 0x0a,
- 0x13, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x57,
- 0x52, 0x49, 0x54, 0x45, 0x42, 0x41, 0x43, 0x4b, 0x10, 0x0d, 0x12, 0x1e,
- 0x0a, 0x1a, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f,
+ 0x0d, 0x12, 0x13, 0x0a, 0x0f, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f,
+ 0x5f, 0x4d, 0x4c, 0x4f, 0x43, 0x4b, 0x45, 0x44, 0x10, 0x0e, 0x12, 0x16,
+ 0x0a, 0x12, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x53, 0x57,
+ 0x41, 0x50, 0x5f, 0x54, 0x4f, 0x54, 0x41, 0x4c, 0x10, 0x0f, 0x12, 0x15,
+ 0x0a, 0x11, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x53, 0x57,
+ 0x41, 0x50, 0x5f, 0x46, 0x52, 0x45, 0x45, 0x10, 0x10, 0x12, 0x11, 0x0a,
+ 0x0d, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x44, 0x49, 0x52,
+ 0x54, 0x59, 0x10, 0x11, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x45, 0x4d, 0x49,
+ 0x4e, 0x46, 0x4f, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x42, 0x41, 0x43,
+ 0x4b, 0x10, 0x12, 0x12, 0x16, 0x0a, 0x12, 0x4d, 0x45, 0x4d, 0x49, 0x4e,
+ 0x46, 0x4f, 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x5f, 0x50, 0x41, 0x47, 0x45,
+ 0x53, 0x10, 0x13, 0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x45, 0x4d, 0x49, 0x4e,
+ 0x46, 0x4f, 0x5f, 0x4d, 0x41, 0x50, 0x50, 0x45, 0x44, 0x10, 0x14, 0x12,
+ 0x11, 0x0a, 0x0d, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x53,
+ 0x48, 0x4d, 0x45, 0x4d, 0x10, 0x15, 0x12, 0x10, 0x0a, 0x0c, 0x4d, 0x45,
+ 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x53, 0x4c, 0x41, 0x42, 0x10, 0x16,
+ 0x12, 0x1c, 0x0a, 0x18, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f,
0x53, 0x4c, 0x41, 0x42, 0x5f, 0x52, 0x45, 0x43, 0x4c, 0x41, 0x49, 0x4d,
- 0x41, 0x42, 0x4c, 0x45, 0x10, 0x0e, 0x12, 0x20, 0x0a, 0x1c, 0x56, 0x4d,
- 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x53, 0x4c, 0x41, 0x42,
- 0x5f, 0x55, 0x4e, 0x52, 0x45, 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x41, 0x42,
- 0x4c, 0x45, 0x10, 0x0f, 0x12, 0x1e, 0x0a, 0x1a, 0x56, 0x4d, 0x53, 0x54,
- 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x5f, 0x54,
- 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x53, 0x10, 0x10,
- 0x12, 0x1a, 0x0a, 0x16, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e,
- 0x52, 0x5f, 0x4b, 0x45, 0x52, 0x4e, 0x45, 0x4c, 0x5f, 0x53, 0x54, 0x41,
- 0x43, 0x4b, 0x10, 0x11, 0x12, 0x16, 0x0a, 0x12, 0x56, 0x4d, 0x53, 0x54,
- 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x48, 0x45,
- 0x41, 0x44, 0x10, 0x12, 0x12, 0x16, 0x0a, 0x12, 0x56, 0x4d, 0x53, 0x54,
- 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x54, 0x41, 0x42,
- 0x4c, 0x45, 0x10, 0x13, 0x12, 0x14, 0x0a, 0x10, 0x56, 0x4d, 0x53, 0x54,
- 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x42, 0x4f, 0x55, 0x4e, 0x43, 0x45,
- 0x10, 0x14, 0x12, 0x1a, 0x0a, 0x16, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
- 0x5f, 0x4e, 0x52, 0x5f, 0x56, 0x4d, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x57,
- 0x52, 0x49, 0x54, 0x45, 0x10, 0x15, 0x12, 0x26, 0x0a, 0x22, 0x56, 0x4d,
- 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x56, 0x4d, 0x53, 0x43,
- 0x41, 0x4e, 0x5f, 0x49, 0x4d, 0x4d, 0x45, 0x44, 0x49, 0x41, 0x54, 0x45,
- 0x5f, 0x52, 0x45, 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x10, 0x16, 0x12, 0x1c,
- 0x0a, 0x18, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f,
- 0x57, 0x52, 0x49, 0x54, 0x45, 0x42, 0x41, 0x43, 0x4b, 0x5f, 0x54, 0x45,
- 0x4d, 0x50, 0x10, 0x17, 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4d, 0x53, 0x54,
- 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x49, 0x53, 0x4f, 0x4c, 0x41, 0x54,
- 0x45, 0x44, 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x10, 0x18, 0x12, 0x1b, 0x0a,
+ 0x41, 0x42, 0x4c, 0x45, 0x10, 0x17, 0x12, 0x1e, 0x0a, 0x1a, 0x4d, 0x45,
+ 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x53, 0x4c, 0x41, 0x42, 0x5f, 0x55,
+ 0x4e, 0x52, 0x45, 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x41, 0x42, 0x4c, 0x45,
+ 0x10, 0x18, 0x12, 0x18, 0x0a, 0x14, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46,
+ 0x4f, 0x5f, 0x4b, 0x45, 0x52, 0x4e, 0x45, 0x4c, 0x5f, 0x53, 0x54, 0x41,
+ 0x43, 0x4b, 0x10, 0x19, 0x12, 0x17, 0x0a, 0x13, 0x4d, 0x45, 0x4d, 0x49,
+ 0x4e, 0x46, 0x4f, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x5f, 0x54, 0x41, 0x42,
+ 0x4c, 0x45, 0x53, 0x10, 0x1a, 0x12, 0x18, 0x0a, 0x14, 0x4d, 0x45, 0x4d,
+ 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x5f,
+ 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x10, 0x1b, 0x12, 0x17, 0x0a, 0x13, 0x4d,
+ 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x49,
+ 0x54, 0x45, 0x44, 0x5f, 0x41, 0x53, 0x10, 0x1c, 0x12, 0x19, 0x0a, 0x15,
+ 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x56, 0x4d, 0x41, 0x4c,
+ 0x4c, 0x4f, 0x43, 0x5f, 0x54, 0x4f, 0x54, 0x41, 0x4c, 0x10, 0x1d, 0x12,
+ 0x18, 0x0a, 0x14, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x56,
+ 0x4d, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x5f, 0x55, 0x53, 0x45, 0x44, 0x10,
+ 0x1e, 0x12, 0x19, 0x0a, 0x15, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f,
+ 0x5f, 0x56, 0x4d, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x5f, 0x43, 0x48, 0x55,
+ 0x4e, 0x4b, 0x10, 0x1f, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x45, 0x4d, 0x49,
+ 0x4e, 0x46, 0x4f, 0x5f, 0x43, 0x4d, 0x41, 0x5f, 0x54, 0x4f, 0x54, 0x41,
+ 0x4c, 0x10, 0x20, 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x45, 0x4d, 0x49, 0x4e,
+ 0x46, 0x4f, 0x5f, 0x43, 0x4d, 0x41, 0x5f, 0x46, 0x52, 0x45, 0x45, 0x10,
+ 0x21, 0x2a, 0xc6, 0x15, 0x0a, 0x0e, 0x56, 0x6d, 0x73, 0x74, 0x61, 0x74,
+ 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x12, 0x16, 0x0a, 0x12,
+ 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45,
+ 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x14,
+ 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x46, 0x52,
+ 0x45, 0x45, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x53, 0x10, 0x01, 0x12, 0x19,
+ 0x0a, 0x15, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f,
+ 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x5f, 0x42, 0x41, 0x54, 0x43, 0x48, 0x10,
+ 0x02, 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+ 0x4e, 0x52, 0x5f, 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5f,
+ 0x41, 0x4e, 0x4f, 0x4e, 0x10, 0x03, 0x12, 0x19, 0x0a, 0x15, 0x56, 0x4d,
+ 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x41, 0x43, 0x54, 0x49,
+ 0x56, 0x45, 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x10, 0x04, 0x12, 0x1b, 0x0a,
0x17, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x49,
- 0x53, 0x4f, 0x4c, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x46, 0x49, 0x4c, 0x45,
- 0x10, 0x19, 0x12, 0x13, 0x0a, 0x0f, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
- 0x5f, 0x4e, 0x52, 0x5f, 0x53, 0x48, 0x4d, 0x45, 0x4d, 0x10, 0x1a, 0x12,
- 0x15, 0x0a, 0x11, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52,
- 0x5f, 0x44, 0x49, 0x52, 0x54, 0x49, 0x45, 0x44, 0x10, 0x1b, 0x12, 0x15,
- 0x0a, 0x11, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f,
- 0x57, 0x52, 0x49, 0x54, 0x54, 0x45, 0x4e, 0x10, 0x1c, 0x12, 0x1b, 0x0a,
- 0x17, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x50,
- 0x41, 0x47, 0x45, 0x53, 0x5f, 0x53, 0x43, 0x41, 0x4e, 0x4e, 0x45, 0x44,
- 0x10, 0x1d, 0x12, 0x1d, 0x0a, 0x19, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
- 0x5f, 0x57, 0x4f, 0x52, 0x4b, 0x49, 0x4e, 0x47, 0x53, 0x45, 0x54, 0x5f,
- 0x52, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x1e, 0x12, 0x1e, 0x0a,
- 0x1a, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x57, 0x4f, 0x52, 0x4b,
- 0x49, 0x4e, 0x47, 0x53, 0x45, 0x54, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56,
- 0x41, 0x54, 0x45, 0x10, 0x1f, 0x12, 0x21, 0x0a, 0x1d, 0x56, 0x4d, 0x53,
- 0x54, 0x41, 0x54, 0x5f, 0x57, 0x4f, 0x52, 0x4b, 0x49, 0x4e, 0x47, 0x53,
- 0x45, 0x54, 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x52, 0x45, 0x43, 0x4c, 0x41,
- 0x49, 0x4d, 0x10, 0x20, 0x12, 0x28, 0x0a, 0x24, 0x56, 0x4d, 0x53, 0x54,
- 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x5f, 0x54,
- 0x52, 0x41, 0x4e, 0x53, 0x50, 0x41, 0x52, 0x45, 0x4e, 0x54, 0x5f, 0x48,
- 0x55, 0x47, 0x45, 0x50, 0x41, 0x47, 0x45, 0x53, 0x10, 0x21, 0x12, 0x16,
- 0x0a, 0x12, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f,
- 0x46, 0x52, 0x45, 0x45, 0x5f, 0x43, 0x4d, 0x41, 0x10, 0x22, 0x12, 0x17,
- 0x0a, 0x13, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f,
- 0x53, 0x57, 0x41, 0x50, 0x43, 0x41, 0x43, 0x48, 0x45, 0x10, 0x23, 0x12,
- 0x1d, 0x0a, 0x19, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52,
- 0x5f, 0x44, 0x49, 0x52, 0x54, 0x59, 0x5f, 0x54, 0x48, 0x52, 0x45, 0x53,
- 0x48, 0x4f, 0x4c, 0x44, 0x10, 0x24, 0x12, 0x28, 0x0a, 0x24, 0x56, 0x4d,
+ 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45,
+ 0x10, 0x05, 0x12, 0x19, 0x0a, 0x15, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
+ 0x5f, 0x4e, 0x52, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x46,
+ 0x49, 0x4c, 0x45, 0x10, 0x06, 0x12, 0x19, 0x0a, 0x15, 0x56, 0x4d, 0x53,
+ 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49,
+ 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x07, 0x12, 0x13, 0x0a, 0x0f,
+ 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x4d, 0x4c,
+ 0x4f, 0x43, 0x4b, 0x10, 0x08, 0x12, 0x18, 0x0a, 0x14, 0x56, 0x4d, 0x53,
+ 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x5f,
+ 0x50, 0x41, 0x47, 0x45, 0x53, 0x10, 0x09, 0x12, 0x14, 0x0a, 0x10, 0x56,
+ 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x4d, 0x41, 0x50,
+ 0x50, 0x45, 0x44, 0x10, 0x0a, 0x12, 0x18, 0x0a, 0x14, 0x56, 0x4d, 0x53,
+ 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x5f,
+ 0x50, 0x41, 0x47, 0x45, 0x53, 0x10, 0x0b, 0x12, 0x13, 0x0a, 0x0f, 0x56,
+ 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x44, 0x49, 0x52,
+ 0x54, 0x59, 0x10, 0x0c, 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4d, 0x53, 0x54,
+ 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x42,
+ 0x41, 0x43, 0x4b, 0x10, 0x0d, 0x12, 0x1e, 0x0a, 0x1a, 0x56, 0x4d, 0x53,
+ 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x53, 0x4c, 0x41, 0x42, 0x5f,
+ 0x52, 0x45, 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x41, 0x42, 0x4c, 0x45, 0x10,
+ 0x0e, 0x12, 0x20, 0x0a, 0x1c, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+ 0x4e, 0x52, 0x5f, 0x53, 0x4c, 0x41, 0x42, 0x5f, 0x55, 0x4e, 0x52, 0x45,
+ 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x0f, 0x12,
+ 0x1e, 0x0a, 0x1a, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52,
+ 0x5f, 0x50, 0x41, 0x47, 0x45, 0x5f, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x5f,
+ 0x50, 0x41, 0x47, 0x45, 0x53, 0x10, 0x10, 0x12, 0x1a, 0x0a, 0x16, 0x56,
+ 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x4b, 0x45, 0x52,
+ 0x4e, 0x45, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x43, 0x4b, 0x10, 0x11, 0x12,
+ 0x16, 0x0a, 0x12, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52,
+ 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x48, 0x45, 0x41, 0x44, 0x10, 0x12, 0x12,
+ 0x16, 0x0a, 0x12, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52,
+ 0x5f, 0x55, 0x4e, 0x53, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x13, 0x12,
+ 0x14, 0x0a, 0x10, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52,
+ 0x5f, 0x42, 0x4f, 0x55, 0x4e, 0x43, 0x45, 0x10, 0x14, 0x12, 0x1a, 0x0a,
+ 0x16, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x56,
+ 0x4d, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10,
+ 0x15, 0x12, 0x26, 0x0a, 0x22, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+ 0x4e, 0x52, 0x5f, 0x56, 0x4d, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x49, 0x4d,
+ 0x4d, 0x45, 0x44, 0x49, 0x41, 0x54, 0x45, 0x5f, 0x52, 0x45, 0x43, 0x4c,
+ 0x41, 0x49, 0x4d, 0x10, 0x16, 0x12, 0x1c, 0x0a, 0x18, 0x56, 0x4d, 0x53,
+ 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45,
+ 0x42, 0x41, 0x43, 0x4b, 0x5f, 0x54, 0x45, 0x4d, 0x50, 0x10, 0x17, 0x12,
+ 0x1b, 0x0a, 0x17, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52,
+ 0x5f, 0x49, 0x53, 0x4f, 0x4c, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x41, 0x4e,
+ 0x4f, 0x4e, 0x10, 0x18, 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4d, 0x53, 0x54,
+ 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x49, 0x53, 0x4f, 0x4c, 0x41, 0x54,
+ 0x45, 0x44, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x19, 0x12, 0x13, 0x0a,
+ 0x0f, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x53,
+ 0x48, 0x4d, 0x45, 0x4d, 0x10, 0x1a, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x4d,
0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x44, 0x49, 0x52, 0x54,
- 0x59, 0x5f, 0x42, 0x41, 0x43, 0x4b, 0x47, 0x52, 0x4f, 0x55, 0x4e, 0x44,
- 0x5f, 0x54, 0x48, 0x52, 0x45, 0x53, 0x48, 0x4f, 0x4c, 0x44, 0x10, 0x25,
- 0x12, 0x11, 0x0a, 0x0d, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50,
- 0x47, 0x50, 0x47, 0x49, 0x4e, 0x10, 0x26, 0x12, 0x12, 0x0a, 0x0e, 0x56,
- 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x50, 0x47, 0x4f, 0x55,
- 0x54, 0x10, 0x27, 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4d, 0x53, 0x54, 0x41,
- 0x54, 0x5f, 0x50, 0x47, 0x50, 0x47, 0x4f, 0x55, 0x54, 0x43, 0x4c, 0x45,
- 0x41, 0x4e, 0x10, 0x28, 0x12, 0x11, 0x0a, 0x0d, 0x56, 0x4d, 0x53, 0x54,
- 0x41, 0x54, 0x5f, 0x50, 0x53, 0x57, 0x50, 0x49, 0x4e, 0x10, 0x29, 0x12,
- 0x12, 0x0a, 0x0e, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x53,
- 0x57, 0x50, 0x4f, 0x55, 0x54, 0x10, 0x2a, 0x12, 0x16, 0x0a, 0x12, 0x56,
- 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x41, 0x4c, 0x4c, 0x4f,
- 0x43, 0x5f, 0x44, 0x4d, 0x41, 0x10, 0x2b, 0x12, 0x19, 0x0a, 0x15, 0x56,
- 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x41, 0x4c, 0x4c, 0x4f,
- 0x43, 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x2c, 0x12, 0x1a,
- 0x0a, 0x16, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x41,
- 0x4c, 0x4c, 0x4f, 0x43, 0x5f, 0x4d, 0x4f, 0x56, 0x41, 0x42, 0x4c, 0x45,
- 0x10, 0x2d, 0x12, 0x11, 0x0a, 0x0d, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
- 0x5f, 0x50, 0x47, 0x46, 0x52, 0x45, 0x45, 0x10, 0x2e, 0x12, 0x15, 0x0a,
- 0x11, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x41, 0x43,
- 0x54, 0x49, 0x56, 0x41, 0x54, 0x45, 0x10, 0x2f, 0x12, 0x17, 0x0a, 0x13,
- 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x44, 0x45, 0x41,
- 0x43, 0x54, 0x49, 0x56, 0x41, 0x54, 0x45, 0x10, 0x30, 0x12, 0x12, 0x0a,
- 0x0e, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x46, 0x41,
- 0x55, 0x4c, 0x54, 0x10, 0x31, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x4d, 0x53,
- 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x4d, 0x41, 0x4a, 0x46, 0x41, 0x55,
- 0x4c, 0x54, 0x10, 0x32, 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4d, 0x53, 0x54,
- 0x41, 0x54, 0x5f, 0x50, 0x47, 0x52, 0x45, 0x46, 0x49, 0x4c, 0x4c, 0x5f,
- 0x44, 0x4d, 0x41, 0x10, 0x33, 0x12, 0x1a, 0x0a, 0x16, 0x56, 0x4d, 0x53,
- 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x52, 0x45, 0x46, 0x49, 0x4c, 0x4c,
- 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x34, 0x12, 0x1b, 0x0a,
- 0x17, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x52, 0x45,
- 0x46, 0x49, 0x4c, 0x4c, 0x5f, 0x4d, 0x4f, 0x56, 0x41, 0x42, 0x4c, 0x45,
- 0x10, 0x35, 0x12, 0x1d, 0x0a, 0x19, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
- 0x5f, 0x50, 0x47, 0x53, 0x54, 0x45, 0x41, 0x4c, 0x5f, 0x4b, 0x53, 0x57,
- 0x41, 0x50, 0x44, 0x5f, 0x44, 0x4d, 0x41, 0x10, 0x36, 0x12, 0x20, 0x0a,
- 0x1c, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x54,
- 0x45, 0x41, 0x4c, 0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f, 0x4e,
- 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x37, 0x12, 0x21, 0x0a, 0x1d, 0x56,
- 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x54, 0x45, 0x41,
- 0x4c, 0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f, 0x4d, 0x4f, 0x56,
- 0x41, 0x42, 0x4c, 0x45, 0x10, 0x38, 0x12, 0x1d, 0x0a, 0x19, 0x56, 0x4d,
- 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x54, 0x45, 0x41, 0x4c,
- 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x44, 0x4d, 0x41, 0x10,
- 0x39, 0x12, 0x20, 0x0a, 0x1c, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
- 0x50, 0x47, 0x53, 0x54, 0x45, 0x41, 0x4c, 0x5f, 0x44, 0x49, 0x52, 0x45,
- 0x43, 0x54, 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x3a, 0x12,
- 0x21, 0x0a, 0x1d, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47,
- 0x53, 0x54, 0x45, 0x41, 0x4c, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54,
- 0x5f, 0x4d, 0x4f, 0x56, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x3b, 0x12, 0x1c,
- 0x0a, 0x18, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53,
- 0x43, 0x41, 0x4e, 0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f, 0x44,
- 0x4d, 0x41, 0x10, 0x3c, 0x12, 0x1f, 0x0a, 0x1b, 0x56, 0x4d, 0x53, 0x54,
- 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x4b, 0x53,
- 0x57, 0x41, 0x50, 0x44, 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10,
- 0x3d, 0x12, 0x20, 0x0a, 0x1c, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
- 0x50, 0x47, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50,
- 0x44, 0x5f, 0x4d, 0x4f, 0x56, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x3e, 0x12,
- 0x1c, 0x0a, 0x18, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47,
- 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x5f,
- 0x44, 0x4d, 0x41, 0x10, 0x3f, 0x12, 0x1f, 0x0a, 0x1b, 0x56, 0x4d, 0x53,
- 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x44,
- 0x49, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c,
- 0x10, 0x40, 0x12, 0x20, 0x0a, 0x1c, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
- 0x5f, 0x50, 0x47, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x44, 0x49, 0x52, 0x45,
- 0x43, 0x54, 0x5f, 0x4d, 0x4f, 0x56, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x41,
- 0x12, 0x21, 0x0a, 0x1d, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50,
- 0x47, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54,
- 0x5f, 0x54, 0x48, 0x52, 0x4f, 0x54, 0x54, 0x4c, 0x45, 0x10, 0x42, 0x12,
+ 0x49, 0x45, 0x44, 0x10, 0x1b, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x4d, 0x53,
+ 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x54,
+ 0x45, 0x4e, 0x10, 0x1c, 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4d, 0x53, 0x54,
+ 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x53, 0x5f,
+ 0x53, 0x43, 0x41, 0x4e, 0x4e, 0x45, 0x44, 0x10, 0x1d, 0x12, 0x1d, 0x0a,
+ 0x19, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x57, 0x4f, 0x52, 0x4b,
+ 0x49, 0x4e, 0x47, 0x53, 0x45, 0x54, 0x5f, 0x52, 0x45, 0x46, 0x41, 0x55,
+ 0x4c, 0x54, 0x10, 0x1e, 0x12, 0x1e, 0x0a, 0x1a, 0x56, 0x4d, 0x53, 0x54,
+ 0x41, 0x54, 0x5f, 0x57, 0x4f, 0x52, 0x4b, 0x49, 0x4e, 0x47, 0x53, 0x45,
+ 0x54, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x41, 0x54, 0x45, 0x10, 0x1f,
+ 0x12, 0x21, 0x0a, 0x1d, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x57,
+ 0x4f, 0x52, 0x4b, 0x49, 0x4e, 0x47, 0x53, 0x45, 0x54, 0x5f, 0x4e, 0x4f,
+ 0x44, 0x45, 0x52, 0x45, 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x10, 0x20, 0x12,
+ 0x28, 0x0a, 0x24, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52,
+ 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x50,
+ 0x41, 0x52, 0x45, 0x4e, 0x54, 0x5f, 0x48, 0x55, 0x47, 0x45, 0x50, 0x41,
+ 0x47, 0x45, 0x53, 0x10, 0x21, 0x12, 0x16, 0x0a, 0x12, 0x56, 0x4d, 0x53,
+ 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x46, 0x52, 0x45, 0x45, 0x5f,
+ 0x43, 0x4d, 0x41, 0x10, 0x22, 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4d, 0x53,
+ 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x53, 0x57, 0x41, 0x50, 0x43,
+ 0x41, 0x43, 0x48, 0x45, 0x10, 0x23, 0x12, 0x1d, 0x0a, 0x19, 0x56, 0x4d,
+ 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x44, 0x49, 0x52, 0x54,
+ 0x59, 0x5f, 0x54, 0x48, 0x52, 0x45, 0x53, 0x48, 0x4f, 0x4c, 0x44, 0x10,
+ 0x24, 0x12, 0x28, 0x0a, 0x24, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+ 0x4e, 0x52, 0x5f, 0x44, 0x49, 0x52, 0x54, 0x59, 0x5f, 0x42, 0x41, 0x43,
+ 0x4b, 0x47, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x54, 0x48, 0x52, 0x45,
+ 0x53, 0x48, 0x4f, 0x4c, 0x44, 0x10, 0x25, 0x12, 0x11, 0x0a, 0x0d, 0x56,
+ 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x50, 0x47, 0x49, 0x4e,
+ 0x10, 0x26, 0x12, 0x12, 0x0a, 0x0e, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
+ 0x5f, 0x50, 0x47, 0x50, 0x47, 0x4f, 0x55, 0x54, 0x10, 0x27, 0x12, 0x17,
+ 0x0a, 0x13, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x50,
+ 0x47, 0x4f, 0x55, 0x54, 0x43, 0x4c, 0x45, 0x41, 0x4e, 0x10, 0x28, 0x12,
+ 0x11, 0x0a, 0x0d, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x53,
+ 0x57, 0x50, 0x49, 0x4e, 0x10, 0x29, 0x12, 0x12, 0x0a, 0x0e, 0x56, 0x4d,
+ 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x53, 0x57, 0x50, 0x4f, 0x55, 0x54,
+ 0x10, 0x2a, 0x12, 0x16, 0x0a, 0x12, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
+ 0x5f, 0x50, 0x47, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x5f, 0x44, 0x4d, 0x41,
+ 0x10, 0x2b, 0x12, 0x19, 0x0a, 0x15, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
+ 0x5f, 0x50, 0x47, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x5f, 0x4e, 0x4f, 0x52,
+ 0x4d, 0x41, 0x4c, 0x10, 0x2c, 0x12, 0x1a, 0x0a, 0x16, 0x56, 0x4d, 0x53,
+ 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x5f,
+ 0x4d, 0x4f, 0x56, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x2d, 0x12, 0x11, 0x0a,
+ 0x0d, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x46, 0x52,
+ 0x45, 0x45, 0x10, 0x2e, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x4d, 0x53, 0x54,
+ 0x41, 0x54, 0x5f, 0x50, 0x47, 0x41, 0x43, 0x54, 0x49, 0x56, 0x41, 0x54,
+ 0x45, 0x10, 0x2f, 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4d, 0x53, 0x54, 0x41,
+ 0x54, 0x5f, 0x50, 0x47, 0x44, 0x45, 0x41, 0x43, 0x54, 0x49, 0x56, 0x41,
+ 0x54, 0x45, 0x10, 0x30, 0x12, 0x12, 0x0a, 0x0e, 0x56, 0x4d, 0x53, 0x54,
+ 0x41, 0x54, 0x5f, 0x50, 0x47, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x31,
+ 0x12, 0x15, 0x0a, 0x11, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50,
+ 0x47, 0x4d, 0x41, 0x4a, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x32, 0x12,
0x17, 0x0a, 0x13, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47,
- 0x49, 0x4e, 0x4f, 0x44, 0x45, 0x53, 0x54, 0x45, 0x41, 0x4c, 0x10, 0x43,
- 0x12, 0x18, 0x0a, 0x14, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x53,
- 0x4c, 0x41, 0x42, 0x53, 0x5f, 0x53, 0x43, 0x41, 0x4e, 0x4e, 0x45, 0x44,
- 0x10, 0x44, 0x12, 0x1c, 0x0a, 0x18, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
- 0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f, 0x49, 0x4e, 0x4f, 0x44,
- 0x45, 0x53, 0x54, 0x45, 0x41, 0x4c, 0x10, 0x45, 0x12, 0x27, 0x0a, 0x23,
+ 0x52, 0x45, 0x46, 0x49, 0x4c, 0x4c, 0x5f, 0x44, 0x4d, 0x41, 0x10, 0x33,
+ 0x12, 0x1a, 0x0a, 0x16, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50,
+ 0x47, 0x52, 0x45, 0x46, 0x49, 0x4c, 0x4c, 0x5f, 0x4e, 0x4f, 0x52, 0x4d,
+ 0x41, 0x4c, 0x10, 0x34, 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4d, 0x53, 0x54,
+ 0x41, 0x54, 0x5f, 0x50, 0x47, 0x52, 0x45, 0x46, 0x49, 0x4c, 0x4c, 0x5f,
+ 0x4d, 0x4f, 0x56, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x35, 0x12, 0x1d, 0x0a,
+ 0x19, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x54,
+ 0x45, 0x41, 0x4c, 0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f, 0x44,
+ 0x4d, 0x41, 0x10, 0x36, 0x12, 0x20, 0x0a, 0x1c, 0x56, 0x4d, 0x53, 0x54,
+ 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x54, 0x45, 0x41, 0x4c, 0x5f, 0x4b,
+ 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c,
+ 0x10, 0x37, 0x12, 0x21, 0x0a, 0x1d, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
+ 0x5f, 0x50, 0x47, 0x53, 0x54, 0x45, 0x41, 0x4c, 0x5f, 0x4b, 0x53, 0x57,
+ 0x41, 0x50, 0x44, 0x5f, 0x4d, 0x4f, 0x56, 0x41, 0x42, 0x4c, 0x45, 0x10,
+ 0x38, 0x12, 0x1d, 0x0a, 0x19, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+ 0x50, 0x47, 0x53, 0x54, 0x45, 0x41, 0x4c, 0x5f, 0x44, 0x49, 0x52, 0x45,
+ 0x43, 0x54, 0x5f, 0x44, 0x4d, 0x41, 0x10, 0x39, 0x12, 0x20, 0x0a, 0x1c,
+ 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x54, 0x45,
+ 0x41, 0x4c, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x4e, 0x4f,
+ 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x3a, 0x12, 0x21, 0x0a, 0x1d, 0x56, 0x4d,
+ 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x54, 0x45, 0x41, 0x4c,
+ 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x4d, 0x4f, 0x56, 0x41,
+ 0x42, 0x4c, 0x45, 0x10, 0x3b, 0x12, 0x1c, 0x0a, 0x18, 0x56, 0x4d, 0x53,
+ 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x4b,
+ 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f, 0x44, 0x4d, 0x41, 0x10, 0x3c, 0x12,
+ 0x1f, 0x0a, 0x1b, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47,
+ 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f,
+ 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x3d, 0x12, 0x20, 0x0a, 0x1c,
+ 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x43, 0x41,
+ 0x4e, 0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f, 0x4d, 0x4f, 0x56,
+ 0x41, 0x42, 0x4c, 0x45, 0x10, 0x3e, 0x12, 0x1c, 0x0a, 0x18, 0x56, 0x4d,
+ 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x43, 0x41, 0x4e, 0x5f,
+ 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x44, 0x4d, 0x41, 0x10, 0x3f,
+ 0x12, 0x1f, 0x0a, 0x1b, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50,
+ 0x47, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54,
+ 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x40, 0x12, 0x20, 0x0a,
+ 0x1c, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x43,
+ 0x41, 0x4e, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x4d, 0x4f,
+ 0x56, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x41, 0x12, 0x21, 0x0a, 0x1d, 0x56,
+ 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x43, 0x41, 0x4e,
+ 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x54, 0x48, 0x52, 0x4f,
+ 0x54, 0x54, 0x4c, 0x45, 0x10, 0x42, 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4d,
+ 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x49, 0x4e, 0x4f, 0x44, 0x45,
+ 0x53, 0x54, 0x45, 0x41, 0x4c, 0x10, 0x43, 0x12, 0x18, 0x0a, 0x14, 0x56,
+ 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x53, 0x4c, 0x41, 0x42, 0x53, 0x5f,
+ 0x53, 0x43, 0x41, 0x4e, 0x4e, 0x45, 0x44, 0x10, 0x44, 0x12, 0x1c, 0x0a,
+ 0x18, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4b, 0x53, 0x57, 0x41,
+ 0x50, 0x44, 0x5f, 0x49, 0x4e, 0x4f, 0x44, 0x45, 0x53, 0x54, 0x45, 0x41,
+ 0x4c, 0x10, 0x45, 0x12, 0x27, 0x0a, 0x23, 0x56, 0x4d, 0x53, 0x54, 0x41,
+ 0x54, 0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f, 0x4c, 0x4f, 0x57,
+ 0x5f, 0x57, 0x4d, 0x41, 0x52, 0x4b, 0x5f, 0x48, 0x49, 0x54, 0x5f, 0x51,
+ 0x55, 0x49, 0x43, 0x4b, 0x4c, 0x59, 0x10, 0x46, 0x12, 0x28, 0x0a, 0x24,
0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50,
- 0x44, 0x5f, 0x4c, 0x4f, 0x57, 0x5f, 0x57, 0x4d, 0x41, 0x52, 0x4b, 0x5f,
- 0x48, 0x49, 0x54, 0x5f, 0x51, 0x55, 0x49, 0x43, 0x4b, 0x4c, 0x59, 0x10,
- 0x46, 0x12, 0x28, 0x0a, 0x24, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
- 0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f, 0x48, 0x49, 0x47, 0x48, 0x5f,
- 0x57, 0x4d, 0x41, 0x52, 0x4b, 0x5f, 0x48, 0x49, 0x54, 0x5f, 0x51, 0x55,
- 0x49, 0x43, 0x4b, 0x4c, 0x59, 0x10, 0x47, 0x12, 0x15, 0x0a, 0x11, 0x56,
- 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x4f, 0x55,
- 0x54, 0x52, 0x55, 0x4e, 0x10, 0x48, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x4d,
- 0x53, 0x54, 0x41, 0x54, 0x5f, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x53, 0x54,
- 0x41, 0x4c, 0x4c, 0x10, 0x49, 0x12, 0x14, 0x0a, 0x10, 0x56, 0x4d, 0x53,
- 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x52, 0x4f, 0x54, 0x41, 0x54, 0x45,
- 0x44, 0x10, 0x4a, 0x12, 0x19, 0x0a, 0x15, 0x56, 0x4d, 0x53, 0x54, 0x41,
- 0x54, 0x5f, 0x44, 0x52, 0x4f, 0x50, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x43,
- 0x41, 0x43, 0x48, 0x45, 0x10, 0x4b, 0x12, 0x14, 0x0a, 0x10, 0x56, 0x4d,
- 0x53, 0x54, 0x41, 0x54, 0x5f, 0x44, 0x52, 0x4f, 0x50, 0x5f, 0x53, 0x4c,
- 0x41, 0x42, 0x10, 0x4c, 0x12, 0x1c, 0x0a, 0x18, 0x56, 0x4d, 0x53, 0x54,
- 0x41, 0x54, 0x5f, 0x50, 0x47, 0x4d, 0x49, 0x47, 0x52, 0x41, 0x54, 0x45,
- 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x4d, 0x12, 0x19,
- 0x0a, 0x15, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x4d,
- 0x49, 0x47, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x10,
- 0x4e, 0x12, 0x22, 0x0a, 0x1e, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
- 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x43, 0x54, 0x5f, 0x4d, 0x49, 0x47, 0x52,
- 0x41, 0x54, 0x45, 0x5f, 0x53, 0x43, 0x41, 0x4e, 0x4e, 0x45, 0x44, 0x10,
- 0x4f, 0x12, 0x1f, 0x0a, 0x1b, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
- 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x43, 0x54, 0x5f, 0x46, 0x52, 0x45, 0x45,
- 0x5f, 0x53, 0x43, 0x41, 0x4e, 0x4e, 0x45, 0x44, 0x10, 0x50, 0x12, 0x1b,
- 0x0a, 0x17, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x43, 0x4f, 0x4d,
- 0x50, 0x41, 0x43, 0x54, 0x5f, 0x49, 0x53, 0x4f, 0x4c, 0x41, 0x54, 0x45,
- 0x44, 0x10, 0x51, 0x12, 0x18, 0x0a, 0x14, 0x56, 0x4d, 0x53, 0x54, 0x41,
- 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x43, 0x54, 0x5f, 0x53, 0x54,
- 0x41, 0x4c, 0x4c, 0x10, 0x52, 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4d, 0x53,
+ 0x44, 0x5f, 0x48, 0x49, 0x47, 0x48, 0x5f, 0x57, 0x4d, 0x41, 0x52, 0x4b,
+ 0x5f, 0x48, 0x49, 0x54, 0x5f, 0x51, 0x55, 0x49, 0x43, 0x4b, 0x4c, 0x59,
+ 0x10, 0x47, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
+ 0x5f, 0x50, 0x41, 0x47, 0x45, 0x4f, 0x55, 0x54, 0x52, 0x55, 0x4e, 0x10,
+ 0x48, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+ 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x53, 0x54, 0x41, 0x4c, 0x4c, 0x10, 0x49,
+ 0x12, 0x14, 0x0a, 0x10, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50,
+ 0x47, 0x52, 0x4f, 0x54, 0x41, 0x54, 0x45, 0x44, 0x10, 0x4a, 0x12, 0x19,
+ 0x0a, 0x15, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x44, 0x52, 0x4f,
+ 0x50, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x43, 0x41, 0x43, 0x48, 0x45, 0x10,
+ 0x4b, 0x12, 0x14, 0x0a, 0x10, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+ 0x44, 0x52, 0x4f, 0x50, 0x5f, 0x53, 0x4c, 0x41, 0x42, 0x10, 0x4c, 0x12,
+ 0x1c, 0x0a, 0x18, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47,
+ 0x4d, 0x49, 0x47, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x55, 0x43, 0x43,
+ 0x45, 0x53, 0x53, 0x10, 0x4d, 0x12, 0x19, 0x0a, 0x15, 0x56, 0x4d, 0x53,
+ 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x4d, 0x49, 0x47, 0x52, 0x41, 0x54,
+ 0x45, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x10, 0x4e, 0x12, 0x22, 0x0a, 0x1e,
+ 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41,
+ 0x43, 0x54, 0x5f, 0x4d, 0x49, 0x47, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x53,
+ 0x43, 0x41, 0x4e, 0x4e, 0x45, 0x44, 0x10, 0x4f, 0x12, 0x1f, 0x0a, 0x1b,
+ 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41,
+ 0x43, 0x54, 0x5f, 0x46, 0x52, 0x45, 0x45, 0x5f, 0x53, 0x43, 0x41, 0x4e,
+ 0x4e, 0x45, 0x44, 0x10, 0x50, 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4d, 0x53,
0x54, 0x41, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x43, 0x54, 0x5f,
- 0x46, 0x41, 0x49, 0x4c, 0x10, 0x53, 0x12, 0x1a, 0x0a, 0x16, 0x56, 0x4d,
- 0x53, 0x54, 0x41, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x43, 0x54,
- 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x54, 0x12, 0x1e,
- 0x0a, 0x1a, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x43, 0x4f, 0x4d,
- 0x50, 0x41, 0x43, 0x54, 0x5f, 0x44, 0x41, 0x45, 0x4d, 0x4f, 0x4e, 0x5f,
- 0x57, 0x41, 0x4b, 0x45, 0x10, 0x55, 0x12, 0x21, 0x0a, 0x1d, 0x56, 0x4d,
- 0x53, 0x54, 0x41, 0x54, 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54,
- 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x50, 0x47, 0x53, 0x5f, 0x43, 0x55, 0x4c,
- 0x4c, 0x45, 0x44, 0x10, 0x56, 0x12, 0x22, 0x0a, 0x1e, 0x56, 0x4d, 0x53,
- 0x54, 0x41, 0x54, 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41,
- 0x42, 0x4c, 0x45, 0x5f, 0x50, 0x47, 0x53, 0x5f, 0x53, 0x43, 0x41, 0x4e,
- 0x4e, 0x45, 0x44, 0x10, 0x57, 0x12, 0x22, 0x0a, 0x1e, 0x56, 0x4d, 0x53,
- 0x54, 0x41, 0x54, 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41,
- 0x42, 0x4c, 0x45, 0x5f, 0x50, 0x47, 0x53, 0x5f, 0x52, 0x45, 0x53, 0x43,
- 0x55, 0x45, 0x44, 0x10, 0x58, 0x12, 0x22, 0x0a, 0x1e, 0x56, 0x4d, 0x53,
- 0x54, 0x41, 0x54, 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41,
- 0x42, 0x4c, 0x45, 0x5f, 0x50, 0x47, 0x53, 0x5f, 0x4d, 0x4c, 0x4f, 0x43,
- 0x4b, 0x45, 0x44, 0x10, 0x59, 0x12, 0x24, 0x0a, 0x20, 0x56, 0x4d, 0x53,
- 0x54, 0x41, 0x54, 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41,
- 0x42, 0x4c, 0x45, 0x5f, 0x50, 0x47, 0x53, 0x5f, 0x4d, 0x55, 0x4e, 0x4c,
- 0x4f, 0x43, 0x4b, 0x45, 0x44, 0x10, 0x5a, 0x12, 0x22, 0x0a, 0x1e, 0x56,
- 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43,
- 0x54, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x50, 0x47, 0x53, 0x5f, 0x43, 0x4c,
- 0x45, 0x41, 0x52, 0x45, 0x44, 0x10, 0x5b, 0x12, 0x23, 0x0a, 0x1f, 0x56,
- 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43,
- 0x54, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x50, 0x47, 0x53, 0x5f, 0x53, 0x54,
- 0x52, 0x41, 0x4e, 0x44, 0x45, 0x44, 0x10, 0x5c, 0x12, 0x15, 0x0a, 0x11,
- 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x5a, 0x53,
- 0x50, 0x41, 0x47, 0x45, 0x53, 0x10, 0x5d, 0x12, 0x16, 0x0a, 0x12, 0x56,
- 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x49, 0x4f, 0x4e,
- 0x5f, 0x48, 0x45, 0x41, 0x50, 0x10, 0x5e, 0x12, 0x16, 0x0a, 0x12, 0x56,
- 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x47, 0x50, 0x55,
- 0x5f, 0x48, 0x45, 0x41, 0x50, 0x10, 0x5f}};
+ 0x49, 0x53, 0x4f, 0x4c, 0x41, 0x54, 0x45, 0x44, 0x10, 0x51, 0x12, 0x18,
+ 0x0a, 0x14, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x43, 0x4f, 0x4d,
+ 0x50, 0x41, 0x43, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x4c, 0x4c, 0x10, 0x52,
+ 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x43,
+ 0x4f, 0x4d, 0x50, 0x41, 0x43, 0x54, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x10,
+ 0x53, 0x12, 0x1a, 0x0a, 0x16, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+ 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x43, 0x54, 0x5f, 0x53, 0x55, 0x43, 0x43,
+ 0x45, 0x53, 0x53, 0x10, 0x54, 0x12, 0x1e, 0x0a, 0x1a, 0x56, 0x4d, 0x53,
+ 0x54, 0x41, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x43, 0x54, 0x5f,
+ 0x44, 0x41, 0x45, 0x4d, 0x4f, 0x4e, 0x5f, 0x57, 0x41, 0x4b, 0x45, 0x10,
+ 0x55, 0x12, 0x21, 0x0a, 0x1d, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+ 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x5f,
+ 0x50, 0x47, 0x53, 0x5f, 0x43, 0x55, 0x4c, 0x4c, 0x45, 0x44, 0x10, 0x56,
+ 0x12, 0x22, 0x0a, 0x1e, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x55,
+ 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x50,
+ 0x47, 0x53, 0x5f, 0x53, 0x43, 0x41, 0x4e, 0x4e, 0x45, 0x44, 0x10, 0x57,
+ 0x12, 0x22, 0x0a, 0x1e, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x55,
+ 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x50,
+ 0x47, 0x53, 0x5f, 0x52, 0x45, 0x53, 0x43, 0x55, 0x45, 0x44, 0x10, 0x58,
+ 0x12, 0x22, 0x0a, 0x1e, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x55,
+ 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x50,
+ 0x47, 0x53, 0x5f, 0x4d, 0x4c, 0x4f, 0x43, 0x4b, 0x45, 0x44, 0x10, 0x59,
+ 0x12, 0x24, 0x0a, 0x20, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x55,
+ 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x50,
+ 0x47, 0x53, 0x5f, 0x4d, 0x55, 0x4e, 0x4c, 0x4f, 0x43, 0x4b, 0x45, 0x44,
+ 0x10, 0x5a, 0x12, 0x22, 0x0a, 0x1e, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
+ 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45,
+ 0x5f, 0x50, 0x47, 0x53, 0x5f, 0x43, 0x4c, 0x45, 0x41, 0x52, 0x45, 0x44,
+ 0x10, 0x5b, 0x12, 0x23, 0x0a, 0x1f, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
+ 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45,
+ 0x5f, 0x50, 0x47, 0x53, 0x5f, 0x53, 0x54, 0x52, 0x41, 0x4e, 0x44, 0x45,
+ 0x44, 0x10, 0x5c, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x4d, 0x53, 0x54, 0x41,
+ 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x5a, 0x53, 0x50, 0x41, 0x47, 0x45, 0x53,
+ 0x10, 0x5d, 0x12, 0x16, 0x0a, 0x12, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
+ 0x5f, 0x4e, 0x52, 0x5f, 0x49, 0x4f, 0x4e, 0x5f, 0x48, 0x45, 0x41, 0x50,
+ 0x10, 0x5e, 0x12, 0x16, 0x0a, 0x12, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
+ 0x5f, 0x4e, 0x52, 0x5f, 0x47, 0x50, 0x55, 0x5f, 0x48, 0x45, 0x41, 0x50,
+ 0x10, 0x5f}};
} // namespace perfetto
diff --git a/src/profiling/memory/heapprofd_producer_unittest.cc b/src/profiling/memory/heapprofd_producer_unittest.cc
index 1ff9a21..0f67b0e 100644
--- a/src/profiling/memory/heapprofd_producer_unittest.cc
+++ b/src/profiling/memory/heapprofd_producer_unittest.cc
@@ -42,7 +42,8 @@
MOCK_CONST_METHOD0(shared_memory, SharedMemory*());
MOCK_CONST_METHOD0(shared_buffer_page_size_kb, size_t());
- MOCK_METHOD1(CreateTraceWriter, std::unique_ptr<TraceWriter>(BufferID));
+ MOCK_METHOD2(CreateTraceWriter,
+ std::unique_ptr<TraceWriter>(BufferID, BufferExhaustedPolicy));
MOCK_METHOD0(GetInProcessShmemArbiter, SharedMemoryArbiter*());
MOCK_METHOD1(ActivateTriggers, void(const std::vector<std::string>&));
diff --git a/src/trace_processor/BUILD.gn b/src/trace_processor/BUILD.gn
index ef0d92f..e7b4a97 100644
--- a/src/trace_processor/BUILD.gn
+++ b/src/trace_processor/BUILD.gn
@@ -63,6 +63,8 @@
"event_tracker.h",
"filtered_row_index.cc",
"filtered_row_index.h",
+ "forwarding_trace_parser.cc",
+ "forwarding_trace_parser.h",
"ftrace_descriptors.cc",
"ftrace_descriptors.h",
"ftrace_utils.cc",
@@ -237,6 +239,7 @@
"clock_tracker_unittest.cc",
"event_tracker_unittest.cc",
"filtered_row_index_unittest.cc",
+ "forwarding_trace_parser_unittest.cc",
"ftrace_utils_unittest.cc",
"fuchsia_trace_utils_unittest.cc",
"heap_profile_tracker_unittest.cc",
@@ -254,7 +257,6 @@
"syscall_tracker_unittest.cc",
"systrace_parser_unittest.cc",
"thread_table_unittest.cc",
- "trace_processor_impl_unittest.cc",
"trace_sorter_unittest.cc",
]
deps = [
diff --git a/src/trace_processor/export_json.cc b/src/trace_processor/export_json.cc
index 2034561..93ef520 100644
--- a/src/trace_processor/export_json.cc
+++ b/src/trace_processor/export_json.cc
@@ -28,6 +28,8 @@
namespace {
+using IndexMap = perfetto::trace_processor::TraceStorage::Stats::IndexMap;
+
class TraceFormatWriter {
public:
TraceFormatWriter(FILE* output) : output_(output), first_event_(true) {
@@ -69,6 +71,12 @@
first_event_ = false;
}
+ void MergeMetadata(const Json::Value& value) {
+ for (const auto& member : value.getMemberNames()) {
+ metadata_[member] = value[member];
+ }
+ }
+
void AppendTelemetryMetadataString(const char* key, const char* value) {
metadata_["telemetry"][key].append(value);
}
@@ -85,6 +93,17 @@
metadata_["telemetry"][key] = value / 1000.0;
}
+ void SetPerfettoStats(const char* key, int64_t value) {
+ metadata_["perfetto_trace_stats"][key] = Json::Int64(value);
+ }
+
+ void SetPerfettoBufferStats(const char* key, const IndexMap& indexed_values) {
+ for (const auto& value : indexed_values) {
+ metadata_["perfetto_trace_stats"]["buffer_stats"][value.first][key] =
+ Json::Int64(value.second);
+ }
+ }
+
private:
void WriteHeader() { fputs("{\"traceEvents\":[\n", output_); }
@@ -545,6 +564,24 @@
return kResultOk;
}
+ResultCode ExportChromeMetadata(const TraceStorage* storage,
+ const ArgsBuilder& args_builder,
+ TraceFormatWriter* writer) {
+ base::Optional<StringId> raw_chrome_metadata_event_id =
+ storage->string_pool().GetId("chrome_event.metadata");
+ if (!raw_chrome_metadata_event_id)
+ return kResultOk;
+
+ const auto& events = storage->raw_events();
+ for (uint32_t i = 0; i < events.raw_event_count(); ++i) {
+ if (events.name_ids()[i] != *raw_chrome_metadata_event_id)
+ continue;
+ Json::Value args = args_builder.GetArgs(events.arg_set_ids()[i]);
+ writer->MergeMetadata(args);
+ }
+ return kResultOk;
+}
+
ResultCode ExportMetadata(const TraceStorage* storage,
TraceFormatWriter* writer) {
const auto& trace_metadata = storage->metadata();
@@ -610,6 +647,78 @@
return kResultOk;
}
+ResultCode ExportStats(const TraceStorage* storage, TraceFormatWriter* writer) {
+ const auto& stats = storage->stats();
+
+ writer->SetPerfettoStats("producers_connected",
+ stats[stats::traced_producers_connected].value);
+ writer->SetPerfettoStats("producers_seen",
+ stats[stats::traced_producers_seen].value);
+ writer->SetPerfettoStats("data_sources_registered",
+ stats[stats::traced_data_sources_registered].value);
+ writer->SetPerfettoStats("data_sources_seen",
+ stats[stats::traced_data_sources_seen].value);
+ writer->SetPerfettoStats("tracing_sessions",
+ stats[stats::traced_tracing_sessions].value);
+ writer->SetPerfettoStats("total_buffers",
+ stats[stats::traced_total_buffers].value);
+ writer->SetPerfettoStats("chunks_discarded",
+ stats[stats::traced_chunks_discarded].value);
+ writer->SetPerfettoStats("patches_discarded",
+ stats[stats::traced_patches_discarded].value);
+
+ writer->SetPerfettoBufferStats(
+ "buffer_size", stats[stats::traced_buf_buffer_size].indexed_values);
+ writer->SetPerfettoBufferStats(
+ "bytes_written", stats[stats::traced_buf_bytes_written].indexed_values);
+ writer->SetPerfettoBufferStats(
+ "bytes_overwritten",
+ stats[stats::traced_buf_bytes_overwritten].indexed_values);
+ writer->SetPerfettoBufferStats(
+ "bytes_read", stats[stats::traced_buf_bytes_read].indexed_values);
+ writer->SetPerfettoBufferStats(
+ "padding_bytes_written",
+ stats[stats::traced_buf_padding_bytes_written].indexed_values);
+ writer->SetPerfettoBufferStats(
+ "padding_bytes_cleared",
+ stats[stats::traced_buf_padding_bytes_cleared].indexed_values);
+ writer->SetPerfettoBufferStats(
+ "chunks_written", stats[stats::traced_buf_chunks_written].indexed_values);
+ writer->SetPerfettoBufferStats(
+ "chunks_rewritten",
+ stats[stats::traced_buf_chunks_rewritten].indexed_values);
+ writer->SetPerfettoBufferStats(
+ "chunks_overwritten",
+ stats[stats::traced_buf_chunks_overwritten].indexed_values);
+ writer->SetPerfettoBufferStats(
+ "chunks_discarded",
+ stats[stats::traced_buf_chunks_discarded].indexed_values);
+ writer->SetPerfettoBufferStats(
+ "chunks_read", stats[stats::traced_buf_chunks_read].indexed_values);
+ writer->SetPerfettoBufferStats(
+ "chunks_committed_out_of_order",
+ stats[stats::traced_buf_chunks_committed_out_of_order].indexed_values);
+ writer->SetPerfettoBufferStats(
+ "write_wrap_count",
+ stats[stats::traced_buf_write_wrap_count].indexed_values);
+ writer->SetPerfettoBufferStats(
+ "patches_succeeded",
+ stats[stats::traced_buf_patches_succeeded].indexed_values);
+ writer->SetPerfettoBufferStats(
+ "patches_failed", stats[stats::traced_buf_patches_failed].indexed_values);
+ writer->SetPerfettoBufferStats(
+ "readaheads_succeeded",
+ stats[stats::traced_buf_readaheads_succeeded].indexed_values);
+ writer->SetPerfettoBufferStats(
+ "readaheads_failed",
+ stats[stats::traced_buf_readaheads_failed].indexed_values);
+ writer->SetPerfettoBufferStats(
+ "trace_writer_packet_loss",
+ stats[stats::traced_buf_trace_writer_packet_loss].indexed_values);
+
+ return kResultOk;
+}
+
} // anonymous namespace
ResultCode ExportJson(const TraceStorage* storage, FILE* output) {
@@ -632,10 +741,18 @@
if (code != kResultOk)
return code;
+ code = ExportChromeMetadata(storage, args_builder, &writer);
+ if (code != kResultOk)
+ return code;
+
code = ExportMetadata(storage, &writer);
if (code != kResultOk)
return code;
+ code = ExportStats(storage, &writer);
+ if (code != kResultOk)
+ return code;
+
return kResultOk;
}
diff --git a/src/trace_processor/export_json_unittest.cc b/src/trace_processor/export_json_unittest.cc
index 8e5a289..0b0fa86 100644
--- a/src/trace_processor/export_json_unittest.cc
+++ b/src/trace_processor/export_json_unittest.cc
@@ -268,6 +268,73 @@
EXPECT_EQ(telemetry_metadata["hadFailures"][0].asBool(), kHadFailures);
}
+TEST(ExportJsonTest, StorageWithStats) {
+ int64_t kProducers = 10;
+ int64_t kBufferSize0 = 1000;
+ int64_t kBufferSize1 = 2000;
+
+ TraceStorage storage;
+
+ storage.SetStats(stats::traced_producers_connected, kProducers);
+ storage.SetIndexedStats(stats::traced_buf_buffer_size, 0, kBufferSize0);
+ storage.SetIndexedStats(stats::traced_buf_buffer_size, 1, kBufferSize1);
+
+ base::TempFile temp_file = base::TempFile::Create();
+ FILE* output = fopen(temp_file.path().c_str(), "w+");
+ int code = ExportJson(&storage, output);
+ EXPECT_EQ(code, kResultOk);
+
+ Json::Reader reader;
+ Json::Value result;
+
+ EXPECT_TRUE(reader.parse(ReadFile(output), result));
+ EXPECT_TRUE(result.isMember("metadata"));
+ EXPECT_TRUE(result["metadata"].isMember("perfetto_trace_stats"));
+ Json::Value stats = result["metadata"]["perfetto_trace_stats"];
+
+ EXPECT_EQ(stats["producers_connected"].asInt(), kProducers);
+ EXPECT_EQ(stats["buffer_stats"].size(), 2u);
+ EXPECT_EQ(stats["buffer_stats"][0]["buffer_size"].asInt(), kBufferSize0);
+ EXPECT_EQ(stats["buffer_stats"][1]["buffer_size"].asInt(), kBufferSize1);
+}
+
+TEST(ExportJsonTest, StorageWithChromeMetadata) {
+ const char* kName1 = "name1";
+ const char* kName2 = "name2";
+ const char* kValue1 = "value1";
+ const int kValue2 = 222;
+
+ TraceProcessorContext context;
+ context.storage.reset(new TraceStorage());
+ TraceStorage* storage = context.storage.get();
+ ArgsTracker args(&context);
+
+ RowId row_id = storage->mutable_raw_events()->AddRawEvent(
+ 0, storage->InternString("chrome_event.metadata"), 0, 0);
+
+ StringId name1_id = storage->InternString(base::StringView(kName1));
+ StringId name2_id = storage->InternString(base::StringView(kName2));
+ StringId value1_id = storage->InternString(base::StringView(kValue1));
+ args.AddArg(row_id, name1_id, name1_id, Variadic::String(value1_id));
+ args.AddArg(row_id, name2_id, name2_id, Variadic::Integer(kValue2));
+ args.Flush();
+
+ base::TempFile temp_file = base::TempFile::Create();
+ FILE* output = fopen(temp_file.path().c_str(), "w+");
+ int code = ExportJson(storage, output);
+ EXPECT_EQ(code, kResultOk);
+
+ Json::Reader reader;
+ Json::Value result;
+
+ EXPECT_TRUE(reader.parse(ReadFile(output), result));
+ EXPECT_TRUE(result.isMember("metadata"));
+ Json::Value metadata = result["metadata"];
+
+ EXPECT_EQ(metadata[kName1].asString(), kValue1);
+ EXPECT_EQ(metadata[kName2].asInt(), kValue2);
+}
+
TEST(ExportJsonTest, StorageWithArgs) {
const char* kCategory = "cat";
const char* kName = "name";
diff --git a/src/trace_processor/forwarding_trace_parser.cc b/src/trace_processor/forwarding_trace_parser.cc
new file mode 100644
index 0000000..ca657f8
--- /dev/null
+++ b/src/trace_processor/forwarding_trace_parser.cc
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/trace_processor/forwarding_trace_parser.h"
+
+#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/string_utils.h"
+#include "src/trace_processor/fuchsia_trace_parser.h"
+#include "src/trace_processor/fuchsia_trace_tokenizer.h"
+#include "src/trace_processor/gzip_trace_parser.h"
+#include "src/trace_processor/proto_trace_parser.h"
+#include "src/trace_processor/proto_trace_tokenizer.h"
+#include "src/trace_processor/systrace_trace_parser.h"
+
+// JSON parsing and exporting is only supported in the standalone and
+// Chromium builds.
+#if PERFETTO_BUILDFLAG(PERFETTO_STANDALONE_BUILD) || \
+ PERFETTO_BUILD_WITH_CHROMIUM
+#include "src/trace_processor/json_trace_parser.h"
+#include "src/trace_processor/json_trace_tokenizer.h"
+#endif
+
+namespace perfetto {
+namespace trace_processor {
+namespace {
+
+std::string RemoveWhitespace(const std::string& input) {
+ std::string str(input);
+ str.erase(std::remove_if(str.begin(), str.end(), ::isspace), str.end());
+ return str;
+}
+
+// Fuchsia traces have a magic number as documented here:
+// https://fuchsia.googlesource.com/fuchsia/+/HEAD/docs/development/tracing/trace-format/README.md#magic-number-record-trace-info-type-0
+constexpr uint64_t kFuchsiaMagicNumber = 0x0016547846040010;
+
+} // namespace
+
+ForwardingTraceParser::ForwardingTraceParser(TraceProcessorContext* context)
+ : context_(context) {}
+
+ForwardingTraceParser::~ForwardingTraceParser() {}
+
+util::Status ForwardingTraceParser::Parse(std::unique_ptr<uint8_t[]> data,
+ size_t size) {
+ // If this is the first Parse() call, guess the trace type and create the
+ // appropriate parser.
+
+ if (!reader_) {
+ TraceType trace_type;
+ {
+ auto scoped_trace = context_->storage->TraceExecutionTimeIntoStats(
+ stats::guess_trace_type_duration_ns);
+ trace_type = GuessTraceType(data.get(), size);
+ }
+ switch (trace_type) {
+ case kJsonTraceType: {
+ PERFETTO_DLOG("JSON trace detected");
+#if PERFETTO_BUILDFLAG(PERFETTO_STANDALONE_BUILD) || \
+ PERFETTO_BUILD_WITH_CHROMIUM
+ reader_.reset(new JsonTraceTokenizer(context_));
+ // JSON traces have no guarantees about the order of events in them.
+ int64_t window_size_ns = std::numeric_limits<int64_t>::max();
+ context_->sorter.reset(new TraceSorter(context_, window_size_ns));
+ context_->parser.reset(new JsonTraceParser(context_));
+#else
+ PERFETTO_FATAL("JSON traces not supported.");
+#endif
+ break;
+ }
+ case kProtoTraceType: {
+ PERFETTO_DLOG("Proto trace detected");
+ // This will be reduced once we read the trace config and we see flush
+ // period being set.
+ int64_t window_size_ns = std::numeric_limits<int64_t>::max();
+ reader_.reset(new ProtoTraceTokenizer(context_));
+ context_->sorter.reset(new TraceSorter(context_, window_size_ns));
+ context_->parser.reset(new ProtoTraceParser(context_));
+ break;
+ }
+ case kFuchsiaTraceType: {
+ PERFETTO_DLOG("Fuchsia trace detected");
+ // Fuschia traces can have massively out of order events.
+ int64_t window_size_ns = std::numeric_limits<int64_t>::max();
+ reader_.reset(new FuchsiaTraceTokenizer(context_));
+ context_->sorter.reset(new TraceSorter(context_, window_size_ns));
+ context_->parser.reset(new FuchsiaTraceParser(context_));
+ break;
+ }
+ case kSystraceTraceType:
+ PERFETTO_DLOG("Systrace trace detected");
+ reader_.reset(new SystraceTraceParser(context_));
+ break;
+ case kGzipTraceType:
+ PERFETTO_DLOG("gzip trace detected");
+ reader_.reset(new GzipTraceParser(context_));
+ break;
+ case kCtraceTraceType:
+ PERFETTO_DLOG("ctrace trace detected");
+ reader_.reset(new GzipTraceParser(context_));
+ break;
+ case kUnknownTraceType:
+ return util::ErrStatus("Unknown trace type provided");
+ }
+ }
+
+ return reader_->Parse(std::move(data), size);
+}
+
+TraceType GuessTraceType(const uint8_t* data, size_t size) {
+ if (size == 0)
+ return kUnknownTraceType;
+ std::string start(reinterpret_cast<const char*>(data),
+ std::min<size_t>(size, 20));
+ std::string start_minus_white_space = RemoveWhitespace(start);
+ if (base::StartsWith(start_minus_white_space, "{\"traceEvents\":["))
+ return kJsonTraceType;
+ if (base::StartsWith(start_minus_white_space, "[{"))
+ return kJsonTraceType;
+ if (size >= 8) {
+ uint64_t first_word = *reinterpret_cast<const uint64_t*>(data);
+ if (first_word == kFuchsiaMagicNumber)
+ return kFuchsiaTraceType;
+ }
+
+ // Systrace with header but no leading HTML.
+ if (base::StartsWith(start, "# tracer"))
+ return kSystraceTraceType;
+
+ // Systrace with leading HTML.
+ if (base::StartsWith(start, "<!DOCTYPE html>") ||
+ base::StartsWith(start, "<html>"))
+ return kSystraceTraceType;
+
+ // Systrace with no header or leading HTML.
+ if (base::StartsWith(start, " "))
+ return kSystraceTraceType;
+
+ // Ctrace is deflate'ed systrace.
+ if (base::StartsWith(start, "TRACE:"))
+ return kCtraceTraceType;
+
+ // gzip'ed trace containing one of the other formats.
+ if (base::StartsWith(start, "\x1f\x8b"))
+ return kGzipTraceType;
+
+ return kProtoTraceType;
+}
+
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/forwarding_trace_parser.h b/src/trace_processor/forwarding_trace_parser.h
new file mode 100644
index 0000000..f7216b3
--- /dev/null
+++ b/src/trace_processor/forwarding_trace_parser.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_FORWARDING_TRACE_PARSER_H_
+#define SRC_TRACE_PROCESSOR_FORWARDING_TRACE_PARSER_H_
+
+#include "src/trace_processor/chunked_trace_reader.h"
+
+#include "src/trace_processor/trace_processor_context.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+enum TraceType {
+ kUnknownTraceType,
+ kProtoTraceType,
+ kJsonTraceType,
+ kFuchsiaTraceType,
+ kSystraceTraceType,
+ kGzipTraceType,
+ kCtraceTraceType,
+};
+
+TraceType GuessTraceType(const uint8_t* data, size_t size);
+
+class ForwardingTraceParser : public ChunkedTraceReader {
+ public:
+ explicit ForwardingTraceParser(TraceProcessorContext*);
+ ~ForwardingTraceParser() override;
+
+ // ChunkedTraceReader implementation
+ util::Status Parse(std::unique_ptr<uint8_t[]>, size_t) override;
+
+ private:
+ TraceProcessorContext* const context_;
+ std::unique_ptr<ChunkedTraceReader> reader_;
+};
+
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_FORWARDING_TRACE_PARSER_H_
diff --git a/src/trace_processor/trace_processor_impl_unittest.cc b/src/trace_processor/forwarding_trace_parser_unittest.cc
similarity index 96%
rename from src/trace_processor/trace_processor_impl_unittest.cc
rename to src/trace_processor/forwarding_trace_parser_unittest.cc
index 24611d0..df4c013 100644
--- a/src/trace_processor/trace_processor_impl_unittest.cc
+++ b/src/trace_processor/forwarding_trace_parser_unittest.cc
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "src/trace_processor/trace_processor_impl.h"
+#include "src/trace_processor/forwarding_trace_parser.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
diff --git a/src/trace_processor/gzip_trace_parser.cc b/src/trace_processor/gzip_trace_parser.cc
index 7b93af9..a374019 100644
--- a/src/trace_processor/gzip_trace_parser.cc
+++ b/src/trace_processor/gzip_trace_parser.cc
@@ -18,7 +18,8 @@
#include <zlib.h>
-#include "src/trace_processor/systrace_trace_parser.h"
+#include "perfetto/base/logging.h"
+#include "src/trace_processor/forwarding_trace_parser.h"
namespace perfetto {
namespace trace_processor {
@@ -28,7 +29,7 @@
z_stream_->zalloc = Z_NULL;
z_stream_->zfree = Z_NULL;
z_stream_->opaque = Z_NULL;
- inflateInit(z_stream_.get());
+ inflateInit2(z_stream_.get(), 32 + 15);
}
GzipTraceParser::~GzipTraceParser() {
@@ -41,13 +42,17 @@
uint8_t* start = data.get();
size_t len = size;
- static const char kSystraceFilerHeader[] = "TRACE:\n";
if (!inner_) {
- inner_.reset(new SystraceTraceParser(context_));
+ inner_.reset(new ForwardingTraceParser(context_));
- // Strip the header by ignoring the associated bytes.
- start += strlen(kSystraceFilerHeader);
- len -= strlen(kSystraceFilerHeader);
+ // .ctrace files begin with "TRACE:" strip this if present.
+ static const char kSystraceFileHeader[] = "TRACE:\n";
+ if (size >= strlen(kSystraceFileHeader) &&
+ strncmp(reinterpret_cast<char*>(start), kSystraceFileHeader,
+ strlen(kSystraceFileHeader)) == 0) {
+ start += strlen(kSystraceFileHeader);
+ len -= strlen(kSystraceFileHeader);
+ }
}
z_stream_->next_in = start;
diff --git a/src/trace_processor/metrics/android/android_mem.sql b/src/trace_processor/metrics/android/android_mem.sql
index 4f9f5a4..34c948a 100644
--- a/src/trace_processor/metrics/android/android_mem.sql
+++ b/src/trace_processor/metrics/android/android_mem.sql
@@ -24,6 +24,8 @@
SELECT RUN_METRIC('android/span_view_stats.sql', 'table_name', 'anon_and_swap');
+SELECT RUN_METRIC('android/span_view_stats.sql', 'table_name', 'java_heap');
+
SELECT RUN_METRIC('android/mem_stats_priority_breakdown.sql', 'table_name', 'anon_rss');
SELECT RUN_METRIC('android/mem_stats_priority_breakdown.sql', 'table_name', 'file_rss');
@@ -32,76 +34,83 @@
SELECT RUN_METRIC('android/mem_stats_priority_breakdown.sql', 'table_name', 'anon_and_swap');
+SELECT RUN_METRIC('android/mem_stats_priority_breakdown.sql', 'table_name', 'java_heap');
+
+-- Find out all process + priority pairs with data to drive the joins (no outer join in sqlite).
+CREATE VIEW mem_all_processes AS
+SELECT DISTINCT process_name
+FROM
+(
+ SELECT process_name FROM anon_rss_stats_proto
+ UNION
+ SELECT process_name FROM file_rss_stats_proto
+ UNION
+ SELECT process_name FROM swap_stats_proto
+ UNION
+ SELECT process_name FROM anon_and_swap_stats_proto
+ UNION
+ SELECT process_name FROM java_heap_stats_proto
+);
+
+CREATE VIEW mem_all_process_priorities AS
+SELECT DISTINCT process_name, priority
+FROM
+(
+ SELECT process_name, priority FROM anon_rss_by_priority_stats_proto
+ UNION
+ SELECT process_name, priority FROM file_rss_by_priority_stats_proto
+ UNION
+ SELECT process_name, priority FROM swap_by_priority_stats_proto
+ UNION
+ SELECT process_name, priority FROM anon_and_swap_by_priority_stats_proto
+ UNION
+ SELECT process_name, priority FROM java_heap_by_priority_stats_proto
+);
+
CREATE VIEW process_priority_view AS
SELECT
process_name,
AndroidMemoryMetric_PriorityBreakdown(
'priority', priority,
'counters', AndroidMemoryMetric_ProcessMemoryCounters(
- 'anon_rss', AndroidMemoryMetric_Counter(
- 'min', anon_rss_by_priority_stats.min_value,
- 'max', anon_rss_by_priority_stats.max_value,
- 'avg', anon_rss_by_priority_stats.avg_value
- ),
- 'file_rss', AndroidMemoryMetric_Counter(
- 'min', file_rss_by_priority_stats.min_value,
- 'max', file_rss_by_priority_stats.max_value,
- 'avg', file_rss_by_priority_stats.avg_value
- ),
- 'swap', AndroidMemoryMetric_Counter(
- 'min', swap_by_priority_stats.min_value,
- 'max', swap_by_priority_stats.max_value,
- 'avg', swap_by_priority_stats.avg_value
- ),
- 'anon_and_swap', AndroidMemoryMetric_Counter(
- 'min', anon_and_swap_by_priority_stats.min_value,
- 'max', anon_and_swap_by_priority_stats.max_value,
- 'avg', anon_and_swap_by_priority_stats.avg_value
- )
+ 'anon_rss', anon_rss_by_priority_stats_proto.proto,
+ 'file_rss', file_rss_by_priority_stats_proto.proto,
+ 'swap', swap_by_priority_stats_proto.proto,
+ 'anon_and_swap', anon_and_swap_by_priority_stats_proto.proto,
+ 'java_heap', java_heap_by_priority_stats_proto.proto
)
) AS priority_breakdown_proto
-FROM anon_rss_by_priority_stats
-JOIN file_rss_by_priority_stats USING (process_name, priority)
-JOIN swap_by_priority_stats USING (process_name, priority)
-JOIN anon_and_swap_by_priority_stats USING (process_name, priority);
+FROM mem_all_process_priorities
+LEFT JOIN anon_rss_by_priority_stats_proto USING (process_name, priority)
+LEFT JOIN file_rss_by_priority_stats_proto USING (process_name, priority)
+LEFT JOIN swap_by_priority_stats_proto USING (process_name, priority)
+LEFT JOIN anon_and_swap_by_priority_stats_proto USING (process_name, priority)
+LEFT JOIN java_heap_by_priority_stats_proto USING (process_name, priority);
CREATE VIEW process_metrics_view AS
SELECT
AndroidMemoryMetric_ProcessMetrics(
'process_name', process_name,
'total_counters', AndroidMemoryMetric_ProcessMemoryCounters(
- 'anon_rss', AndroidMemoryMetric_Counter(
- 'min', anon_rss_stats.min_value,
- 'max', anon_rss_stats.max_value,
- 'avg', anon_rss_stats.avg_value
- ),
- 'file_rss', AndroidMemoryMetric_Counter(
- 'min', file_rss_stats.min_value,
- 'max', file_rss_stats.max_value,
- 'avg', file_rss_stats.avg_value
- ),
- 'swap', AndroidMemoryMetric_Counter(
- 'min', swap_stats.min_value,
- 'max', swap_stats.max_value,
- 'avg', swap_stats.avg_value
- ),
- 'anon_and_swap', AndroidMemoryMetric_Counter(
- 'min', anon_and_swap_stats.min_value,
- 'max', anon_and_swap_stats.max_value,
- 'avg', anon_and_swap_stats.avg_value
- )
+ 'anon_rss', anon_rss_stats_proto.proto,
+ 'file_rss', file_rss_stats_proto.proto,
+ 'swap', swap_stats_proto.proto,
+ 'anon_and_swap', anon_and_swap_stats_proto.proto,
+ 'java_heap', java_heap_stats_proto.proto
),
'priority_breakdown', (
SELECT RepeatedField(priority_breakdown_proto)
FROM process_priority_view AS ppv
- WHERE anon_rss_stats.process_name = ppv.process_name
+ WHERE anon_rss_stats_proto.process_name = ppv.process_name
)
) AS metric
FROM
- anon_rss_stats
- JOIN file_rss_stats USING (process_name)
- JOIN swap_stats USING (process_name)
- JOIN anon_and_swap_stats USING (process_name);
+ mem_all_processes
+ LEFT JOIN anon_rss_stats_proto USING (process_name)
+ LEFT JOIN file_rss_stats_proto USING (process_name)
+ LEFT JOIN swap_stats_proto USING (process_name)
+ LEFT JOIN anon_and_swap_stats_proto USING (process_name)
+ LEFT JOIN java_heap_stats_proto USING (process_name);
CREATE VIEW android_mem_output AS
SELECT
diff --git a/src/trace_processor/metrics/android/mem_stats_priority_breakdown.sql b/src/trace_processor/metrics/android/mem_stats_priority_breakdown.sql
index 8db50f4..f7ef71b 100644
--- a/src/trace_processor/metrics/android/mem_stats_priority_breakdown.sql
+++ b/src/trace_processor/metrics/android/mem_stats_priority_breakdown.sql
@@ -51,3 +51,16 @@
WHERE process.name IS NOT NULL
GROUP BY 1, 2
ORDER BY 1, 2;
+
+DROP VIEW IF EXISTS {{table_name}}_by_priority_stats_proto;
+
+CREATE VIEW {{table_name}}_by_priority_stats_proto AS
+SELECT
+ process_name,
+ priority,
+ AndroidMemoryMetric_Counter(
+ 'min', min_value,
+ 'max', max_value,
+ 'avg', avg_value
+ ) AS proto
+FROM {{table_name}}_by_priority_stats;
diff --git a/src/trace_processor/metrics/android/process_mem.sql b/src/trace_processor/metrics/android/process_mem.sql
index d6a8454..131e942 100644
--- a/src/trace_processor/metrics/android/process_mem.sql
+++ b/src/trace_processor/metrics/android/process_mem.sql
@@ -44,6 +44,17 @@
IFNULL(anon_rss_val, 0) + IFNULL(swap_val, 0) AS anon_and_swap_val
FROM anon_and_swap_join;
+-- If we have dalvik events enabled (for ART trace points) we can construct the java heap timeline.
+SELECT RUN_METRIC('android/upid_span_view.sql',
+ 'table_name', 'java_heap_kb',
+ 'counter_name', 'Heap size (KB)');
+
+DROP VIEW IF EXISTS java_heap_span;
+
+CREATE VIEW java_heap_span AS
+SELECT ts, dur, upid, java_heap_kb_val * 1024 AS java_heap_val
+FROM java_heap_kb_span;
+
-- Create a track for process OOM scores.
DROP VIEW IF EXISTS oom_score_span;
@@ -76,3 +87,8 @@
CREATE VIRTUAL TABLE anon_and_swap_by_oom_span
USING SPAN_JOIN(anon_and_swap_span PARTITIONED upid, oom_score_span PARTITIONED upid);
+
+DROP TABLE IF EXISTS java_heap_by_oom_span;
+
+CREATE VIRTUAL TABLE java_heap_by_oom_span
+USING SPAN_JOIN(java_heap_span PARTITIONED upid, oom_score_span PARTITIONED upid);
diff --git a/src/trace_processor/metrics/android/span_view_stats.sql b/src/trace_processor/metrics/android/span_view_stats.sql
index 52f6d15..ff85408 100644
--- a/src/trace_processor/metrics/android/span_view_stats.sql
+++ b/src/trace_processor/metrics/android/span_view_stats.sql
@@ -33,3 +33,15 @@
WHERE process.name IS NOT NULL
GROUP BY 1
ORDER BY 1;
+
+DROP VIEW IF EXISTS {{table_name}}_stats_proto;
+
+CREATE VIEW {{table_name}}_stats_proto AS
+SELECT
+ process_name,
+ AndroidMemoryMetric_Counter(
+ 'min', min_value,
+ 'max', max_value,
+ 'avg', avg_value
+ ) AS proto
+FROM {{table_name}}_stats;
diff --git a/src/trace_processor/metrics/metrics.descriptor.h b/src/trace_processor/metrics/metrics.descriptor.h
index d7e9337..19593fb 100644
--- a/src/trace_processor/metrics/metrics.descriptor.h
+++ b/src/trace_processor/metrics/metrics.descriptor.h
@@ -19,7 +19,7 @@
namespace perfetto {
-constexpr std::array<uint8_t, 8768> kMetricsDescriptor{
+constexpr std::array<uint8_t, 8843> kMetricsDescriptor{
{0x0a, 0x91, 0x03, 0x0a, 0x2a, 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,
@@ -98,12 +98,12 @@
0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
0x43, 0x70, 0x75, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x54, 0x68,
0x72, 0x65, 0x61, 0x64, 0x52, 0x07, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64,
- 0x73, 0x42, 0x02, 0x48, 0x03, 0x0a, 0xc1, 0x07, 0x0a, 0x29, 0x70, 0x65,
+ 0x73, 0x42, 0x02, 0x48, 0x03, 0x0a, 0x8c, 0x08, 0x0a, 0x29, 0x70, 0x65,
0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69,
0x63, 0x73, 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x6d,
0x65, 0x6d, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74,
- 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x22, 0xfe, 0x06, 0x0a,
+ 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x22, 0xc9, 0x07, 0x0a,
0x13, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x4d, 0x65, 0x6d, 0x6f,
0x72, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x5c, 0x0a, 0x0f,
0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6d, 0x65, 0x74, 0x72,
@@ -146,7 +146,7 @@
0x72, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x50, 0x72, 0x6f,
0x63, 0x65, 0x73, 0x73, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x43, 0x6f,
0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x52, 0x08, 0x63, 0x6f, 0x75, 0x6e,
- 0x74, 0x65, 0x72, 0x73, 0x1a, 0xbd, 0x02, 0x0a, 0x15, 0x50, 0x72, 0x6f,
+ 0x74, 0x65, 0x72, 0x73, 0x1a, 0x88, 0x03, 0x0a, 0x15, 0x50, 0x72, 0x6f,
0x63, 0x65, 0x73, 0x73, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x43, 0x6f,
0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x12, 0x47, 0x0a, 0x08, 0x61, 0x6e,
0x6f, 0x6e, 0x5f, 0x72, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
@@ -173,584 +173,590 @@
0x6f, 0x69, 0x64, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x74,
0x72, 0x69, 0x63, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x52,
0x0b, 0x61, 0x6e, 0x6f, 0x6e, 0x41, 0x6e, 0x64, 0x53, 0x77, 0x61, 0x70,
- 0x1a, 0x3f, 0x0a, 0x07, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x12,
- 0x10, 0x0a, 0x03, 0x6d, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01,
- 0x52, 0x03, 0x6d, 0x69, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x61, 0x78,
- 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x03, 0x6d, 0x61, 0x78, 0x12,
- 0x10, 0x0a, 0x03, 0x61, 0x76, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01,
- 0x52, 0x03, 0x61, 0x76, 0x67, 0x42, 0x02, 0x48, 0x03, 0x0a, 0x9d, 0x06,
- 0x0a, 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, 0x12, 0x0f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e,
- 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x22, 0xd4, 0x05, 0x0a, 0x1f, 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, 0x12, 0x65, 0x0a, 0x0e, 0x70, 0x72,
- 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73,
- 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3e, 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, 0x2e, 0x50, 0x72, 0x6f,
- 0x63, 0x65, 0x73, 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52, 0x0d,
- 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65,
- 0x73, 0x1a, 0x97, 0x01, 0x0a, 0x0d, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73,
- 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x70,
- 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18,
- 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x63, 0x65,
- 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x63, 0x0a, 0x0a, 0x6d, 0x65,
- 0x6d, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01,
- 0x28, 0x0b, 0x32, 0x44, 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, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73,
- 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73,
- 0x52, 0x09, 0x6d, 0x65, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x1a,
- 0xe3, 0x02, 0x0a, 0x13, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4d,
- 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12,
- 0x51, 0x0a, 0x08, 0x61, 0x6e, 0x6f, 0x6e, 0x5f, 0x72, 0x73, 0x73, 0x18,
- 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x70, 0x65, 0x72, 0x66,
+ 0x12, 0x49, 0x0a, 0x09, 0x6a, 0x61, 0x76, 0x61, 0x5f, 0x68, 0x65, 0x61,
+ 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x70, 0x65,
+ 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x4d, 0x65, 0x6d,
+ 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x43, 0x6f,
+ 0x75, 0x6e, 0x74, 0x65, 0x72, 0x52, 0x08, 0x6a, 0x61, 0x76, 0x61, 0x48,
+ 0x65, 0x61, 0x70, 0x1a, 0x3f, 0x0a, 0x07, 0x43, 0x6f, 0x75, 0x6e, 0x74,
+ 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x69, 0x6e, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x01, 0x52, 0x03, 0x6d, 0x69, 0x6e, 0x12, 0x10, 0x0a, 0x03,
+ 0x6d, 0x61, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x03, 0x6d,
+ 0x61, 0x78, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x76, 0x67, 0x18, 0x03, 0x20,
+ 0x01, 0x28, 0x01, 0x52, 0x03, 0x61, 0x76, 0x67, 0x42, 0x02, 0x48, 0x03,
+ 0x0a, 0x9d, 0x06, 0x0a, 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, 0x12, 0x0f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74,
+ 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x22, 0xd4, 0x05,
+ 0x0a, 0x1f, 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, 0x12, 0x65, 0x0a,
+ 0x0e, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x76, 0x61, 0x6c,
+ 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3e, 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, 0x2e,
+ 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65,
+ 0x73, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x56, 0x61,
+ 0x6c, 0x75, 0x65, 0x73, 0x1a, 0x97, 0x01, 0x0a, 0x0d, 0x50, 0x72, 0x6f,
+ 0x63, 0x65, 0x73, 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x21,
+ 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6e, 0x61,
+ 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72,
+ 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x63, 0x0a,
+ 0x0a, 0x6d, 0x65, 0x6d, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18,
+ 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x44, 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, 0x2e, 0x56, 0x61, 0x6c, 0x75,
- 0x65, 0x52, 0x07, 0x61, 0x6e, 0x6f, 0x6e, 0x52, 0x73, 0x73, 0x12, 0x51,
- 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x72, 0x73, 0x73, 0x18, 0x02,
- 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 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, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65,
- 0x52, 0x07, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x73, 0x73, 0x12, 0x4a, 0x0a,
- 0x04, 0x73, 0x77, 0x61, 0x70, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32,
- 0x36, 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, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x04, 0x73, 0x77, 0x61,
- 0x70, 0x12, 0x5a, 0x0a, 0x0d, 0x61, 0x6e, 0x6f, 0x6e, 0x5f, 0x61, 0x6e,
- 0x64, 0x5f, 0x73, 0x77, 0x61, 0x70, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b,
- 0x32, 0x36, 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, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0b, 0x61, 0x6e,
- 0x6f, 0x6e, 0x41, 0x6e, 0x64, 0x53, 0x77, 0x61, 0x70, 0x1a, 0x4a, 0x0a,
- 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x73,
- 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x74, 0x73, 0x12, 0x1b,
- 0x0a, 0x09, 0x6f, 0x6f, 0x6d, 0x5f, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x18,
- 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x6f, 0x6f, 0x6d, 0x53, 0x63,
- 0x6f, 0x72, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
- 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75,
- 0x65, 0x42, 0x02, 0x48, 0x03, 0x0a, 0x89, 0x04, 0x0a, 0x2d, 0x70, 0x65,
- 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69,
- 0x63, 0x73, 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x70,
- 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x6f, 0x77, 0x74,
- 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x70, 0x65, 0x72,
- 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
- 0x22, 0xc2, 0x03, 0x0a, 0x14, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
- 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x77, 0x74,
- 0x68, 0x12, 0x60, 0x0a, 0x10, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63,
- 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x01, 0x20,
- 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74,
+ 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x50, 0x72, 0x6f, 0x63,
+ 0x65, 0x73, 0x73, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x56, 0x61, 0x6c,
+ 0x75, 0x65, 0x73, 0x52, 0x09, 0x6d, 0x65, 0x6d, 0x56, 0x61, 0x6c, 0x75,
+ 0x65, 0x73, 0x1a, 0xe3, 0x02, 0x0a, 0x13, 0x50, 0x72, 0x6f, 0x63, 0x65,
+ 0x73, 0x73, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x56, 0x61, 0x6c, 0x75,
+ 0x65, 0x73, 0x12, 0x51, 0x0a, 0x08, 0x61, 0x6e, 0x6f, 0x6e, 0x5f, 0x72,
+ 0x73, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 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, 0x2e, 0x56,
+ 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x61, 0x6e, 0x6f, 0x6e, 0x52, 0x73,
+ 0x73, 0x12, 0x51, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x72, 0x73,
+ 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 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, 0x2e, 0x56, 0x61,
+ 0x6c, 0x75, 0x65, 0x52, 0x07, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x73, 0x73,
+ 0x12, 0x4a, 0x0a, 0x04, 0x73, 0x77, 0x61, 0x70, 0x18, 0x03, 0x20, 0x03,
+ 0x28, 0x0b, 0x32, 0x36, 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, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x04,
+ 0x73, 0x77, 0x61, 0x70, 0x12, 0x5a, 0x0a, 0x0d, 0x61, 0x6e, 0x6f, 0x6e,
+ 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x73, 0x77, 0x61, 0x70, 0x18, 0x04, 0x20,
+ 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74,
0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e,
- 0x64, 0x72, 0x6f, 0x69, 0x64, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73,
- 0x47, 0x72, 0x6f, 0x77, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61,
- 0x6e, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x0f,
- 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x72,
- 0x69, 0x63, 0x73, 0x1a, 0xc7, 0x02, 0x0a, 0x0f, 0x49, 0x6e, 0x73, 0x74,
- 0x61, 0x6e, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12,
- 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d,
- 0x52, 0x03, 0x70, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x6f,
- 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73,
- 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x19, 0x61, 0x6e, 0x6f, 0x6e,
- 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x73, 0x74,
- 0x61, 0x72, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20,
- 0x01, 0x28, 0x03, 0x52, 0x15, 0x61, 0x6e, 0x6f, 0x6e, 0x41, 0x6e, 0x64,
- 0x53, 0x77, 0x61, 0x70, 0x53, 0x74, 0x61, 0x72, 0x74, 0x56, 0x61, 0x6c,
- 0x75, 0x65, 0x12, 0x3a, 0x0a, 0x1a, 0x61, 0x6e, 0x6f, 0x6e, 0x5f, 0x61,
- 0x6e, 0x64, 0x5f, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x63, 0x68, 0x61, 0x6e,
- 0x67, 0x65, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01,
- 0x28, 0x03, 0x52, 0x16, 0x61, 0x6e, 0x6f, 0x6e, 0x41, 0x6e, 0x64, 0x53,
- 0x77, 0x61, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x42, 0x79, 0x74,
- 0x65, 0x73, 0x12, 0x3b, 0x0a, 0x1a, 0x6d, 0x61, 0x6c, 0x6c, 0x6f, 0x63,
- 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x5f, 0x63, 0x68, 0x61, 0x6e,
- 0x67, 0x65, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01,
- 0x28, 0x03, 0x52, 0x17, 0x6d, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x4d, 0x65,
- 0x6d, 0x6f, 0x72, 0x79, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x42, 0x79,
- 0x74, 0x65, 0x73, 0x12, 0x4c, 0x0a, 0x23, 0x6d, 0x61, 0x6c, 0x6c, 0x6f,
- 0x63, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x5f, 0x74, 0x6f, 0x74,
- 0x61, 0x6c, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, 0x64,
- 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03,
- 0x52, 0x1f, 0x6d, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x4d, 0x65, 0x6d, 0x6f,
- 0x72, 0x79, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x41, 0x6c, 0x6c, 0x6f, 0x63,
- 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x42, 0x02, 0x48,
- 0x03, 0x0a, 0xa8, 0x02, 0x0a, 0x29, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74,
- 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x61,
- 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x69, 0x6f, 0x6e, 0x5f, 0x6d,
- 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
- 0x0f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72,
- 0x6f, 0x74, 0x6f, 0x73, 0x22, 0xe5, 0x01, 0x0a, 0x10, 0x41, 0x6e, 0x64,
- 0x72, 0x6f, 0x69, 0x64, 0x49, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x72, 0x69,
- 0x63, 0x12, 0x40, 0x0a, 0x06, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x18,
- 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x70, 0x65, 0x72, 0x66,
- 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e,
+ 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, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52,
+ 0x0b, 0x61, 0x6e, 0x6f, 0x6e, 0x41, 0x6e, 0x64, 0x53, 0x77, 0x61, 0x70,
+ 0x1a, 0x4a, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x0e, 0x0a,
+ 0x02, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x74,
+ 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x6f, 0x6f, 0x6d, 0x5f, 0x73, 0x63, 0x6f,
+ 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x6f, 0x6f,
+ 0x6d, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61,
+ 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76,
+ 0x61, 0x6c, 0x75, 0x65, 0x42, 0x02, 0x48, 0x03, 0x0a, 0x89, 0x04, 0x0a,
+ 0x2d, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2f, 0x6d, 0x65,
+ 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69,
+ 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72,
+ 0x6f, 0x77, 0x74, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f,
+ 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x73, 0x22, 0xc2, 0x03, 0x0a, 0x14, 0x41, 0x6e, 0x64, 0x72,
+ 0x6f, 0x69, 0x64, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72,
+ 0x6f, 0x77, 0x74, 0x68, 0x12, 0x60, 0x0a, 0x10, 0x69, 0x6e, 0x73, 0x74,
+ 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73,
+ 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x70, 0x65, 0x72,
+ 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
+ 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x50, 0x72, 0x6f, 0x63,
+ 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x77, 0x74, 0x68, 0x2e, 0x49, 0x6e,
+ 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63,
+ 0x73, 0x52, 0x0f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x4d,
+ 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x1a, 0xc7, 0x02, 0x0a, 0x0f, 0x49,
+ 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69,
+ 0x63, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x0d, 0x52, 0x03, 0x70, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c,
+ 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x63,
+ 0x65, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x19, 0x61,
+ 0x6e, 0x6f, 0x6e, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x73, 0x77, 0x61, 0x70,
+ 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65,
+ 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x61, 0x6e, 0x6f, 0x6e,
+ 0x41, 0x6e, 0x64, 0x53, 0x77, 0x61, 0x70, 0x53, 0x74, 0x61, 0x72, 0x74,
+ 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3a, 0x0a, 0x1a, 0x61, 0x6e, 0x6f,
+ 0x6e, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x63,
+ 0x68, 0x61, 0x6e, 0x67, 0x65, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18,
+ 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x16, 0x61, 0x6e, 0x6f, 0x6e, 0x41,
+ 0x6e, 0x64, 0x53, 0x77, 0x61, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65,
+ 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x3b, 0x0a, 0x1a, 0x6d, 0x61, 0x6c,
+ 0x6c, 0x6f, 0x63, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x5f, 0x63,
+ 0x68, 0x61, 0x6e, 0x67, 0x65, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18,
+ 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x17, 0x6d, 0x61, 0x6c, 0x6c, 0x6f,
+ 0x63, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x43, 0x68, 0x61, 0x6e, 0x67,
+ 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x4c, 0x0a, 0x23, 0x6d, 0x61,
+ 0x6c, 0x6c, 0x6f, 0x63, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x5f,
+ 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61,
+ 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x06, 0x20,
+ 0x01, 0x28, 0x03, 0x52, 0x1f, 0x6d, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x4d,
+ 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x41, 0x6c,
+ 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73,
+ 0x42, 0x02, 0x48, 0x03, 0x0a, 0xa8, 0x02, 0x0a, 0x29, 0x70, 0x65, 0x72,
+ 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63,
+ 0x73, 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x69, 0x6f,
+ 0x6e, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x12, 0x0f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f,
+ 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x22, 0xe5, 0x01, 0x0a, 0x10,
0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x49, 0x6f, 0x6e, 0x4d, 0x65,
- 0x74, 0x72, 0x69, 0x63, 0x2e, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x52,
- 0x06, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x1a, 0x8e, 0x01, 0x0a, 0x06,
- 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61,
- 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,
- 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x61, 0x76, 0x67, 0x5f, 0x73, 0x69,
- 0x7a, 0x65, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01,
- 0x28, 0x01, 0x52, 0x0c, 0x61, 0x76, 0x67, 0x53, 0x69, 0x7a, 0x65, 0x42,
- 0x79, 0x74, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x6d, 0x69, 0x6e, 0x5f,
- 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03,
- 0x20, 0x01, 0x28, 0x01, 0x52, 0x0c, 0x6d, 0x69, 0x6e, 0x53, 0x69, 0x7a,
- 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x6d, 0x61,
- 0x78, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73,
- 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x53,
- 0x69, 0x7a, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x42, 0x02, 0x48, 0x03,
- 0x0a, 0x8e, 0x02, 0x0a, 0x29, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74,
+ 0x74, 0x72, 0x69, 0x63, 0x12, 0x40, 0x0a, 0x06, 0x62, 0x75, 0x66, 0x66,
+ 0x65, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 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, 0x2e, 0x42, 0x75, 0x66, 0x66,
+ 0x65, 0x72, 0x52, 0x06, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x1a, 0x8e,
+ 0x01, 0x0a, 0x06, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x12, 0x12, 0x0a,
+ 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x61, 0x76, 0x67,
+ 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18,
+ 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0c, 0x61, 0x76, 0x67, 0x53, 0x69,
+ 0x7a, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x6d,
+ 0x69, 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x62, 0x79, 0x74, 0x65,
+ 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0c, 0x6d, 0x69, 0x6e,
+ 0x53, 0x69, 0x7a, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x24, 0x0a,
+ 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x62, 0x79,
+ 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0c, 0x6d,
+ 0x61, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x42,
+ 0x02, 0x48, 0x03, 0x0a, 0x8e, 0x02, 0x0a, 0x29, 0x70, 0x65, 0x72, 0x66,
+ 0x65, 0x74, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73,
+ 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x6c, 0x6d, 0x6b,
+ 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x12, 0x0f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x22, 0xcb, 0x01, 0x0a, 0x10, 0x41,
+ 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x4c, 0x6d, 0x6b, 0x4d, 0x65, 0x74,
+ 0x72, 0x69, 0x63, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c,
+ 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05,
+ 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x43, 0x6f, 0x75, 0x6e, 0x74,
+ 0x12, 0x4e, 0x0a, 0x0c, 0x62, 0x79, 0x5f, 0x6f, 0x6f, 0x6d, 0x5f, 0x73,
+ 0x63, 0x6f, 0x72, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c,
+ 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
+ 0x4c, 0x6d, 0x6b, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x42, 0x79,
+ 0x4f, 0x6f, 0x6d, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x52, 0x0a, 0x62, 0x79,
+ 0x4f, 0x6f, 0x6d, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x1a, 0x46, 0x0a, 0x0a,
+ 0x42, 0x79, 0x4f, 0x6f, 0x6d, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x12, 0x22,
+ 0x0a, 0x0d, 0x6f, 0x6f, 0x6d, 0x5f, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x5f,
+ 0x61, 0x64, 0x6a, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x6f,
+ 0x6f, 0x6d, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x41, 0x64, 0x6a, 0x12, 0x14,
+ 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28,
+ 0x05, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x02, 0x48, 0x03,
+ 0x0a, 0xed, 0x02, 0x0a, 0x2e, 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,
+ 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, 0x12, 0x0f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74,
+ 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x22, 0xa5, 0x02, 0x0a,
+ 0x11, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x50, 0x6f, 0x77, 0x65,
+ 0x72, 0x52, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x4e, 0x0a, 0x0b, 0x70, 0x6f,
+ 0x77, 0x65, 0x72, 0x5f, 0x72, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x01, 0x20,
+ 0x03, 0x28, 0x0b, 0x32, 0x2d, 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, 0x2e, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x52, 0x61, 0x69,
+ 0x6c, 0x73, 0x52, 0x0a, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x52, 0x61, 0x69,
+ 0x6c, 0x73, 0x1a, 0x4e, 0x0a, 0x0a, 0x45, 0x6e, 0x65, 0x72, 0x67, 0x79,
+ 0x44, 0x61, 0x74, 0x61, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x69, 0x6d, 0x65,
+ 0x73, 0x74, 0x61, 0x6d, 0x70, 0x5f, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x03, 0x52, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
+ 0x70, 0x4d, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x6e, 0x65, 0x72, 0x67,
+ 0x79, 0x5f, 0x75, 0x77, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52,
+ 0x09, 0x65, 0x6e, 0x65, 0x72, 0x67, 0x79, 0x55, 0x77, 0x73, 0x1a, 0x70,
+ 0x0a, 0x0a, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x52, 0x61, 0x69, 0x6c, 0x73,
+ 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x4e, 0x0a, 0x0b,
+ 0x65, 0x6e, 0x65, 0x72, 0x67, 0x79, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18,
+ 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 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, 0x2e, 0x45, 0x6e, 0x65, 0x72, 0x67, 0x79,
+ 0x44, 0x61, 0x74, 0x61, 0x52, 0x0a, 0x65, 0x6e, 0x65, 0x72, 0x67, 0x79,
+ 0x44, 0x61, 0x74, 0x61, 0x42, 0x02, 0x48, 0x03, 0x0a, 0xa5, 0x0e, 0x0a,
+ 0x2d, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2f, 0x6d, 0x65,
+ 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69,
+ 0x64, 0x2f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x5f, 0x6d, 0x65,
0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f,
0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f,
- 0x74, 0x6f, 0x73, 0x22, 0xcb, 0x01, 0x0a, 0x10, 0x41, 0x6e, 0x64, 0x72,
- 0x6f, 0x69, 0x64, 0x4c, 0x6d, 0x6b, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63,
- 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x63, 0x6f,
- 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x74,
- 0x6f, 0x74, 0x61, 0x6c, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x4e, 0x0a,
- 0x0c, 0x62, 0x79, 0x5f, 0x6f, 0x6f, 0x6d, 0x5f, 0x73, 0x63, 0x6f, 0x72,
- 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x70, 0x65,
- 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
- 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x4c, 0x6d, 0x6b,
- 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x42, 0x79, 0x4f, 0x6f, 0x6d,
- 0x53, 0x63, 0x6f, 0x72, 0x65, 0x52, 0x0a, 0x62, 0x79, 0x4f, 0x6f, 0x6d,
- 0x53, 0x63, 0x6f, 0x72, 0x65, 0x1a, 0x46, 0x0a, 0x0a, 0x42, 0x79, 0x4f,
- 0x6f, 0x6d, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x12, 0x22, 0x0a, 0x0d, 0x6f,
- 0x6f, 0x6d, 0x5f, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x5f, 0x61, 0x64, 0x6a,
- 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x6f, 0x6f, 0x6d, 0x53,
- 0x63, 0x6f, 0x72, 0x65, 0x41, 0x64, 0x6a, 0x12, 0x14, 0x0a, 0x05, 0x63,
- 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05,
- 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x02, 0x48, 0x03, 0x0a, 0xed, 0x02,
- 0x0a, 0x2e, 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,
- 0x12, 0x0f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70,
- 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x22, 0xa5, 0x02, 0x0a, 0x11, 0x41, 0x6e,
- 0x64, 0x72, 0x6f, 0x69, 0x64, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x52, 0x61,
- 0x69, 0x6c, 0x73, 0x12, 0x4e, 0x0a, 0x0b, 0x70, 0x6f, 0x77, 0x65, 0x72,
- 0x5f, 0x72, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
- 0x32, 0x2d, 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,
- 0x2e, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x52, 0x61, 0x69, 0x6c, 0x73, 0x52,
- 0x0a, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x52, 0x61, 0x69, 0x6c, 0x73, 0x1a,
- 0x4e, 0x0a, 0x0a, 0x45, 0x6e, 0x65, 0x72, 0x67, 0x79, 0x44, 0x61, 0x74,
- 0x61, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
- 0x6d, 0x70, 0x5f, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52,
- 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, 0x73,
- 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x6e, 0x65, 0x72, 0x67, 0x79, 0x5f, 0x75,
- 0x77, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, 0x65, 0x6e,
- 0x65, 0x72, 0x67, 0x79, 0x55, 0x77, 0x73, 0x1a, 0x70, 0x0a, 0x0a, 0x50,
- 0x6f, 0x77, 0x65, 0x72, 0x52, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x12, 0x0a,
- 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
- 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x4e, 0x0a, 0x0b, 0x65, 0x6e, 0x65,
- 0x72, 0x67, 0x79, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x03,
- 0x28, 0x0b, 0x32, 0x2d, 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, 0x2e, 0x45, 0x6e, 0x65, 0x72, 0x67, 0x79, 0x44, 0x61, 0x74,
- 0x61, 0x52, 0x0a, 0x65, 0x6e, 0x65, 0x72, 0x67, 0x79, 0x44, 0x61, 0x74,
- 0x61, 0x42, 0x02, 0x48, 0x03, 0x0a, 0xa5, 0x0e, 0x0a, 0x2d, 0x70, 0x65,
- 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69,
- 0x63, 0x73, 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x73,
- 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69,
- 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x70, 0x65, 0x72,
- 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
- 0x22, 0xde, 0x0d, 0x0a, 0x14, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
- 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x4d, 0x65, 0x74, 0x72, 0x69,
- 0x63, 0x12, 0x47, 0x0a, 0x07, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70,
- 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x70, 0x65, 0x72,
- 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
- 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x53, 0x74, 0x61, 0x72,
- 0x74, 0x75, 0x70, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x53, 0x74,
- 0x61, 0x72, 0x74, 0x75, 0x70, 0x52, 0x07, 0x73, 0x74, 0x61, 0x72, 0x74,
- 0x75, 0x70, 0x1a, 0xe0, 0x01, 0x0a, 0x12, 0x54, 0x61, 0x73, 0x6b, 0x53,
- 0x74, 0x61, 0x74, 0x65, 0x42, 0x72, 0x65, 0x61, 0x6b, 0x64, 0x6f, 0x77,
- 0x6e, 0x12, 0x24, 0x0a, 0x0e, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67,
- 0x5f, 0x64, 0x75, 0x72, 0x5f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28,
- 0x03, 0x52, 0x0c, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x44, 0x75,
- 0x72, 0x4e, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x72, 0x75, 0x6e, 0x6e, 0x61,
- 0x62, 0x6c, 0x65, 0x5f, 0x64, 0x75, 0x72, 0x5f, 0x6e, 0x73, 0x18, 0x02,
- 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x72, 0x75, 0x6e, 0x6e, 0x61, 0x62,
- 0x6c, 0x65, 0x44, 0x75, 0x72, 0x4e, 0x73, 0x12, 0x3f, 0x0a, 0x1c, 0x75,
- 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, 0x70, 0x74, 0x69, 0x62,
- 0x6c, 0x65, 0x5f, 0x73, 0x6c, 0x65, 0x65, 0x70, 0x5f, 0x64, 0x75, 0x72,
- 0x5f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x19, 0x75,
- 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, 0x70, 0x74, 0x69, 0x62,
- 0x6c, 0x65, 0x53, 0x6c, 0x65, 0x65, 0x70, 0x44, 0x75, 0x72, 0x4e, 0x73,
- 0x12, 0x3b, 0x0a, 0x1a, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, 0x70,
+ 0x74, 0x6f, 0x73, 0x22, 0xde, 0x0d, 0x0a, 0x14, 0x41, 0x6e, 0x64, 0x72,
+ 0x6f, 0x69, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x4d, 0x65,
+ 0x74, 0x72, 0x69, 0x63, 0x12, 0x47, 0x0a, 0x07, 0x73, 0x74, 0x61, 0x72,
+ 0x74, 0x75, 0x70, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e,
+ 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x53,
+ 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63,
+ 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x52, 0x07, 0x73, 0x74,
+ 0x61, 0x72, 0x74, 0x75, 0x70, 0x1a, 0xe0, 0x01, 0x0a, 0x12, 0x54, 0x61,
+ 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x42, 0x72, 0x65, 0x61, 0x6b,
+ 0x64, 0x6f, 0x77, 0x6e, 0x12, 0x24, 0x0a, 0x0e, 0x72, 0x75, 0x6e, 0x6e,
+ 0x69, 0x6e, 0x67, 0x5f, 0x64, 0x75, 0x72, 0x5f, 0x6e, 0x73, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e,
+ 0x67, 0x44, 0x75, 0x72, 0x4e, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x72, 0x75,
+ 0x6e, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x64, 0x75, 0x72, 0x5f, 0x6e,
+ 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x72, 0x75, 0x6e,
+ 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x75, 0x72, 0x4e, 0x73, 0x12, 0x3f,
+ 0x0a, 0x1c, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, 0x70,
0x74, 0x69, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x6c, 0x65, 0x65, 0x70, 0x5f,
- 0x64, 0x75, 0x72, 0x5f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03,
- 0x52, 0x17, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, 0x70, 0x74, 0x69,
- 0x62, 0x6c, 0x65, 0x53, 0x6c, 0x65, 0x65, 0x70, 0x44, 0x75, 0x72, 0x4e,
- 0x73, 0x1a, 0x1e, 0x0a, 0x05, 0x53, 0x6c, 0x69, 0x63, 0x65, 0x12, 0x15,
- 0x0a, 0x06, 0x64, 0x75, 0x72, 0x5f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x03, 0x52, 0x05, 0x64, 0x75, 0x72, 0x4e, 0x73, 0x1a, 0xbb, 0x08,
- 0x0a, 0x0c, 0x54, 0x6f, 0x46, 0x69, 0x72, 0x73, 0x74, 0x46, 0x72, 0x61,
- 0x6d, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x64, 0x75, 0x72, 0x5f, 0x6e, 0x73,
- 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x64, 0x75, 0x72, 0x4e,
- 0x73, 0x12, 0x72, 0x0a, 0x19, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x74, 0x68,
- 0x72, 0x65, 0x61, 0x64, 0x5f, 0x62, 0x79, 0x5f, 0x74, 0x61, 0x73, 0x6b,
- 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
- 0x32, 0x38, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e,
- 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f,
- 0x69, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x4d, 0x65, 0x74,
- 0x72, 0x69, 0x63, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74,
- 0x65, 0x42, 0x72, 0x65, 0x61, 0x6b, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x15,
- 0x6d, 0x61, 0x69, 0x6e, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x42, 0x79,
- 0x54, 0x61, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x41, 0x0a,
- 0x1d, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65,
- 0x73, 0x73, 0x65, 0x73, 0x5f, 0x73, 0x70, 0x61, 0x77, 0x6e, 0x65, 0x64,
- 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d,
- 0x52, 0x1a, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x63, 0x65,
- 0x73, 0x73, 0x65, 0x73, 0x53, 0x70, 0x61, 0x77, 0x6e, 0x65, 0x64, 0x43,
- 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x5f, 0x0a, 0x15, 0x74, 0x69, 0x6d, 0x65,
- 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x5f, 0x6d, 0x61,
- 0x6e, 0x61, 0x67, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32,
- 0x2b, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70,
- 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69,
- 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x4d, 0x65, 0x74, 0x72,
- 0x69, 0x63, 0x2e, 0x53, 0x6c, 0x69, 0x63, 0x65, 0x52, 0x13, 0x74, 0x69,
- 0x6d, 0x65, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x4d, 0x61,
- 0x6e, 0x61, 0x67, 0x65, 0x72, 0x12, 0x66, 0x0a, 0x19, 0x74, 0x69, 0x6d,
- 0x65, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x5f, 0x74,
- 0x68, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x05,
- 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65,
- 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41,
- 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75,
- 0x70, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x53, 0x6c, 0x69, 0x63,
- 0x65, 0x52, 0x16, 0x74, 0x69, 0x6d, 0x65, 0x41, 0x63, 0x74, 0x69, 0x76,
- 0x69, 0x74, 0x79, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x4d, 0x61, 0x69,
- 0x6e, 0x12, 0x5f, 0x0a, 0x15, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x62, 0x69,
- 0x6e, 0x64, 0x5f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69,
- 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70,
- 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74,
- 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x53, 0x74,
- 0x61, 0x72, 0x74, 0x75, 0x70, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e,
- 0x53, 0x6c, 0x69, 0x63, 0x65, 0x52, 0x13, 0x74, 0x69, 0x6d, 0x65, 0x42,
- 0x69, 0x6e, 0x64, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69,
- 0x6f, 0x6e, 0x12, 0x5b, 0x0a, 0x13, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x61,
- 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x72,
- 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x65,
- 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
- 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x53, 0x74, 0x61,
- 0x72, 0x74, 0x75, 0x70, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x53,
- 0x6c, 0x69, 0x63, 0x65, 0x52, 0x11, 0x74, 0x69, 0x6d, 0x65, 0x41, 0x63,
- 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12,
- 0x5d, 0x0a, 0x14, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x61, 0x63, 0x74, 0x69,
- 0x76, 0x69, 0x74, 0x79, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x18,
- 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x65, 0x72, 0x66,
- 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e,
- 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74,
- 0x75, 0x70, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x53, 0x6c, 0x69,
- 0x63, 0x65, 0x52, 0x12, 0x74, 0x69, 0x6d, 0x65, 0x41, 0x63, 0x74, 0x69,
- 0x76, 0x69, 0x74, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x12, 0x5a,
- 0x0a, 0x12, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x68, 0x6f, 0x72, 0x65,
- 0x6f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01,
+ 0x64, 0x75, 0x72, 0x5f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03,
+ 0x52, 0x19, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, 0x70,
+ 0x74, 0x69, 0x62, 0x6c, 0x65, 0x53, 0x6c, 0x65, 0x65, 0x70, 0x44, 0x75,
+ 0x72, 0x4e, 0x73, 0x12, 0x3b, 0x0a, 0x1a, 0x69, 0x6e, 0x74, 0x65, 0x72,
+ 0x72, 0x75, 0x70, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x6c, 0x65,
+ 0x65, 0x70, 0x5f, 0x64, 0x75, 0x72, 0x5f, 0x6e, 0x73, 0x18, 0x04, 0x20,
+ 0x01, 0x28, 0x03, 0x52, 0x17, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75,
+ 0x70, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x53, 0x6c, 0x65, 0x65, 0x70, 0x44,
+ 0x75, 0x72, 0x4e, 0x73, 0x1a, 0x1e, 0x0a, 0x05, 0x53, 0x6c, 0x69, 0x63,
+ 0x65, 0x12, 0x15, 0x0a, 0x06, 0x64, 0x75, 0x72, 0x5f, 0x6e, 0x73, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x64, 0x75, 0x72, 0x4e, 0x73,
+ 0x1a, 0xbb, 0x08, 0x0a, 0x0c, 0x54, 0x6f, 0x46, 0x69, 0x72, 0x73, 0x74,
+ 0x46, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x64, 0x75, 0x72,
+ 0x5f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x64,
+ 0x75, 0x72, 0x4e, 0x73, 0x12, 0x72, 0x0a, 0x19, 0x6d, 0x61, 0x69, 0x6e,
+ 0x5f, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x62, 0x79, 0x5f, 0x74,
+ 0x61, 0x73, 0x6b, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74,
+ 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e,
+ 0x64, 0x72, 0x6f, 0x69, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70,
+ 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x53,
+ 0x74, 0x61, 0x74, 0x65, 0x42, 0x72, 0x65, 0x61, 0x6b, 0x64, 0x6f, 0x77,
+ 0x6e, 0x52, 0x15, 0x6d, 0x61, 0x69, 0x6e, 0x54, 0x68, 0x72, 0x65, 0x61,
+ 0x64, 0x42, 0x79, 0x54, 0x61, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65,
+ 0x12, 0x41, 0x0a, 0x1d, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f, 0x70, 0x72,
+ 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x5f, 0x73, 0x70, 0x61, 0x77,
+ 0x6e, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20,
+ 0x01, 0x28, 0x0d, 0x52, 0x1a, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x50, 0x72,
+ 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x53, 0x70, 0x61, 0x77, 0x6e,
+ 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x5f, 0x0a, 0x15, 0x74,
+ 0x69, 0x6d, 0x65, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79,
+ 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74,
0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64,
0x72, 0x6f, 0x69, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x4d,
0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x53, 0x6c, 0x69, 0x63, 0x65, 0x52,
- 0x11, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x6f, 0x72, 0x65, 0x6f, 0x67,
- 0x72, 0x61, 0x70, 0x68, 0x65, 0x72, 0x12, 0x66, 0x0a, 0x19, 0x74, 0x69,
- 0x6d, 0x65, 0x5f, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x5f, 0x73, 0x74,
- 0x61, 0x72, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18,
- 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x65, 0x72, 0x66,
+ 0x13, 0x74, 0x69, 0x6d, 0x65, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74,
+ 0x79, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x12, 0x66, 0x0a, 0x19,
+ 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74,
+ 0x79, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x6d, 0x61, 0x69,
+ 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x65,
+ 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x53, 0x74, 0x61,
+ 0x72, 0x74, 0x75, 0x70, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x53,
+ 0x6c, 0x69, 0x63, 0x65, 0x52, 0x16, 0x74, 0x69, 0x6d, 0x65, 0x41, 0x63,
+ 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64,
+ 0x4d, 0x61, 0x69, 0x6e, 0x12, 0x5f, 0x0a, 0x15, 0x74, 0x69, 0x6d, 0x65,
+ 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x2b, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69,
+ 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x4d, 0x65, 0x74, 0x72,
+ 0x69, 0x63, 0x2e, 0x53, 0x6c, 0x69, 0x63, 0x65, 0x52, 0x13, 0x74, 0x69,
+ 0x6d, 0x65, 0x42, 0x69, 0x6e, 0x64, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x5b, 0x0a, 0x13, 0x74, 0x69, 0x6d,
+ 0x65, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x5f, 0x73,
+ 0x74, 0x61, 0x72, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b,
+ 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
+ 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x4d, 0x65, 0x74, 0x72, 0x69,
+ 0x63, 0x2e, 0x53, 0x6c, 0x69, 0x63, 0x65, 0x52, 0x11, 0x74, 0x69, 0x6d,
+ 0x65, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x53, 0x74, 0x61,
+ 0x72, 0x74, 0x12, 0x5d, 0x0a, 0x14, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x61,
+ 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x5f, 0x72, 0x65, 0x73, 0x75,
+ 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70,
+ 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x53, 0x74,
+ 0x61, 0x72, 0x74, 0x75, 0x70, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e,
+ 0x53, 0x6c, 0x69, 0x63, 0x65, 0x52, 0x12, 0x74, 0x69, 0x6d, 0x65, 0x41,
+ 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6d,
+ 0x65, 0x12, 0x5a, 0x0a, 0x12, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x68,
+ 0x6f, 0x72, 0x65, 0x6f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x65, 0x72, 0x18,
+ 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x65, 0x72, 0x66,
0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e,
0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74,
0x75, 0x70, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x53, 0x6c, 0x69,
- 0x63, 0x65, 0x52, 0x16, 0x74, 0x69, 0x6d, 0x65, 0x42, 0x65, 0x66, 0x6f,
- 0x72, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x63, 0x65,
- 0x73, 0x73, 0x12, 0x66, 0x0a, 0x19, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x64,
- 0x75, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f,
- 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28,
- 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f,
- 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72,
- 0x6f, 0x69, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x4d, 0x65,
- 0x74, 0x72, 0x69, 0x63, 0x2e, 0x53, 0x6c, 0x69, 0x63, 0x65, 0x52, 0x16,
- 0x74, 0x69, 0x6d, 0x65, 0x44, 0x75, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x74,
- 0x61, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x4b,
- 0x0a, 0x23, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f, 0x70, 0x72, 0x6f, 0x63,
- 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76,
- 0x69, 0x74, 0x79, 0x5f, 0x63, 0x70, 0x75, 0x5f, 0x72, 0x61, 0x74, 0x69,
- 0x6f, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x01, 0x52, 0x1e, 0x6f, 0x74, 0x68,
- 0x65, 0x72, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x41,
- 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x43, 0x70, 0x75, 0x52, 0x61,
- 0x74, 0x69, 0x6f, 0x1a, 0xbb, 0x02, 0x0a, 0x07, 0x53, 0x74, 0x61, 0x72,
- 0x74, 0x75, 0x70, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74,
- 0x75, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52,
- 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x49, 0x64, 0x12, 0x21,
- 0x0a, 0x0c, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61,
- 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x61,
- 0x63, 0x6b, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a,
- 0x0c, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6e, 0x61, 0x6d,
- 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x6f,
- 0x63, 0x65, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2c, 0x0a, 0x12,
- 0x7a, 0x79, 0x67, 0x6f, 0x74, 0x65, 0x5f, 0x6e, 0x65, 0x77, 0x5f, 0x70,
- 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08,
- 0x52, 0x10, 0x7a, 0x79, 0x67, 0x6f, 0x74, 0x65, 0x4e, 0x65, 0x77, 0x50,
- 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x43, 0x0a, 0x1e, 0x61, 0x63,
- 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x69,
- 0x6e, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63,
- 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x1b,
- 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x48, 0x6f, 0x73, 0x74,
- 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f,
- 0x75, 0x6e, 0x74, 0x12, 0x58, 0x0a, 0x0e, 0x74, 0x6f, 0x5f, 0x66, 0x69,
- 0x72, 0x73, 0x74, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20,
- 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74,
- 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e,
- 0x64, 0x72, 0x6f, 0x69, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70,
- 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x54, 0x6f, 0x46, 0x69, 0x72,
- 0x73, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x52, 0x0c, 0x74, 0x6f, 0x46,
- 0x69, 0x72, 0x73, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x42, 0x02, 0x48,
- 0x03, 0x0a, 0xcb, 0x05, 0x0a, 0x3a, 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, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x70,
- 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74,
- 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x22, 0xf7, 0x04,
- 0x0a, 0x18, 0x48, 0x65, 0x61, 0x70, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c,
- 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x53, 0x74, 0x61,
- 0x74, 0x73, 0x12, 0x5e, 0x0a, 0x0e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e,
- 0x63, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03,
- 0x28, 0x0b, 0x32, 0x37, 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, 0x53, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x49, 0x6e,
- 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52,
- 0x0d, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61,
- 0x74, 0x73, 0x1a, 0x1b, 0x0a, 0x05, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x12,
- 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x1a, 0x51, 0x0a, 0x08, 0x43,
- 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x12, 0x45, 0x0a, 0x05, 0x66,
- 0x72, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f,
+ 0x63, 0x65, 0x52, 0x11, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x68, 0x6f, 0x72,
+ 0x65, 0x6f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x65, 0x72, 0x12, 0x66, 0x0a,
+ 0x19, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65,
+ 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65,
+ 0x73, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70,
+ 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x53, 0x74,
+ 0x61, 0x72, 0x74, 0x75, 0x70, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e,
+ 0x53, 0x6c, 0x69, 0x63, 0x65, 0x52, 0x16, 0x74, 0x69, 0x6d, 0x65, 0x42,
+ 0x65, 0x66, 0x6f, 0x72, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x50, 0x72,
+ 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x66, 0x0a, 0x19, 0x74, 0x69, 0x6d,
+ 0x65, 0x5f, 0x64, 0x75, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x74, 0x61,
+ 0x72, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x0b,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65,
+ 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41,
+ 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75,
+ 0x70, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x53, 0x6c, 0x69, 0x63,
+ 0x65, 0x52, 0x16, 0x74, 0x69, 0x6d, 0x65, 0x44, 0x75, 0x72, 0x69, 0x6e,
+ 0x67, 0x53, 0x74, 0x61, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73,
+ 0x73, 0x12, 0x4b, 0x0a, 0x23, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f, 0x70,
+ 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x5f, 0x61, 0x63,
+ 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x5f, 0x63, 0x70, 0x75, 0x5f, 0x72,
+ 0x61, 0x74, 0x69, 0x6f, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x01, 0x52, 0x1e,
+ 0x6f, 0x74, 0x68, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73,
+ 0x54, 0x6f, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x43, 0x70,
+ 0x75, 0x52, 0x61, 0x74, 0x69, 0x6f, 0x1a, 0xbb, 0x02, 0x0a, 0x07, 0x53,
+ 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74,
+ 0x61, 0x72, 0x74, 0x75, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x0d, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x49,
+ 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65,
+ 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x0b, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65,
+ 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f,
+ 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b,
+ 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12,
+ 0x2c, 0x0a, 0x12, 0x7a, 0x79, 0x67, 0x6f, 0x74, 0x65, 0x5f, 0x6e, 0x65,
+ 0x77, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20,
+ 0x01, 0x28, 0x08, 0x52, 0x10, 0x7a, 0x79, 0x67, 0x6f, 0x74, 0x65, 0x4e,
+ 0x65, 0x77, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x43, 0x0a,
+ 0x1e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x5f, 0x68, 0x6f,
+ 0x73, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73,
+ 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28,
+ 0x0d, 0x52, 0x1b, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x48,
+ 0x6f, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73,
+ 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x58, 0x0a, 0x0e, 0x74, 0x6f,
+ 0x5f, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65,
+ 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x70, 0x65, 0x72,
+ 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
+ 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x53, 0x74, 0x61, 0x72,
+ 0x74, 0x75, 0x70, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x54, 0x6f,
+ 0x46, 0x69, 0x72, 0x73, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x52, 0x0c,
+ 0x74, 0x6f, 0x46, 0x69, 0x72, 0x73, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65,
+ 0x42, 0x02, 0x48, 0x03, 0x0a, 0xcb, 0x05, 0x0a, 0x3a, 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, 0x5f, 0x73, 0x74, 0x61, 0x74,
+ 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x70, 0x65, 0x72,
+ 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
+ 0x22, 0xf7, 0x04, 0x0a, 0x18, 0x48, 0x65, 0x61, 0x70, 0x50, 0x72, 0x6f,
+ 0x66, 0x69, 0x6c, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65,
+ 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x5e, 0x0a, 0x0e, 0x69, 0x6e, 0x73,
+ 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18,
+ 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, 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, 0x53, 0x74, 0x61, 0x74, 0x73,
+ 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61,
+ 0x74, 0x73, 0x52, 0x0d, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65,
+ 0x53, 0x74, 0x61, 0x74, 0x73, 0x1a, 0x1b, 0x0a, 0x05, 0x46, 0x72, 0x61,
+ 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x1a, 0x51,
+ 0x0a, 0x08, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x12, 0x45,
+ 0x0a, 0x05, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28,
+ 0x0b, 0x32, 0x2f, 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, 0x53, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x46, 0x72, 0x61,
+ 0x6d, 0x65, 0x52, 0x05, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x1a, 0xe3, 0x01,
+ 0x0a, 0x0d, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x53, 0x74,
+ 0x61, 0x74, 0x73, 0x12, 0x4e, 0x0a, 0x08, 0x63, 0x61, 0x6c, 0x6c, 0x73,
+ 0x69, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 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, 0x53,
+ 0x74, 0x61, 0x74, 0x73, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74,
+ 0x65, 0x52, 0x08, 0x63, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x12,
+ 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x75,
+ 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x74, 0x6f,
+ 0x74, 0x61, 0x6c, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b,
+ 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18,
+ 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c,
+ 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x6c,
+ 0x74, 0x61, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01,
+ 0x28, 0x03, 0x52, 0x0a, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x43, 0x6f, 0x75,
+ 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f,
+ 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52,
+ 0x0a, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x42, 0x79, 0x74, 0x65, 0x73, 0x1a,
+ 0xa4, 0x01, 0x0a, 0x0d, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65,
+ 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64,
+ 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x70, 0x69, 0x64, 0x12,
+ 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6e,
+ 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70,
+ 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x5e,
+ 0x0a, 0x0e, 0x63, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x5f, 0x73,
+ 0x74, 0x61, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37,
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,
- 0x53, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x52,
- 0x05, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x1a, 0xe3, 0x01, 0x0a, 0x0d, 0x43,
- 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73,
- 0x12, 0x4e, 0x0a, 0x08, 0x63, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65,
- 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 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, 0x53, 0x74, 0x61, 0x74,
- 0x73, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x52, 0x08,
- 0x63, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x12, 0x1f, 0x0a, 0x0b,
- 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18,
- 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c,
- 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74,
- 0x61, 0x6c, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01,
- 0x28, 0x03, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, 0x79, 0x74,
- 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f,
- 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52,
- 0x0a, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12,
- 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x62, 0x79, 0x74,
- 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x64, 0x65,
- 0x6c, 0x74, 0x61, 0x42, 0x79, 0x74, 0x65, 0x73, 0x1a, 0xa4, 0x01, 0x0a,
- 0x0d, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61,
- 0x74, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x03, 0x20,
- 0x01, 0x28, 0x0d, 0x52, 0x03, 0x70, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c,
- 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65,
- 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x63,
- 0x65, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x5e, 0x0a, 0x0e, 0x63,
- 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74,
- 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, 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, 0x53, 0x74, 0x61,
- 0x74, 0x73, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x53,
- 0x74, 0x61, 0x74, 0x73, 0x52, 0x0d, 0x63, 0x61, 0x6c, 0x6c, 0x73, 0x69,
- 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x42, 0x02, 0x48, 0x03, 0x0a,
- 0x85, 0x02, 0x0a, 0x2b, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f,
+ 0x53, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x69,
+ 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x0d, 0x63, 0x61, 0x6c,
+ 0x6c, 0x73, 0x69, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x42, 0x02,
+ 0x48, 0x03, 0x0a, 0x85, 0x02, 0x0a, 0x2b, 0x70, 0x65, 0x72, 0x66, 0x65,
+ 0x74, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f,
+ 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x70, 0x61, 0x63, 0x6b,
+ 0x61, 0x67, 0x65, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x12, 0x0f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f,
+ 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x22, 0xc0, 0x01, 0x0a, 0x12,
+ 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x61,
+ 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x47, 0x0a, 0x08, 0x70, 0x61,
+ 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
+ 0x32, 0x2b, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f,
+ 0x69, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73,
+ 0x74, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x52, 0x08, 0x70,
+ 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x1a, 0x61, 0x0a, 0x07, 0x50,
+ 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x61,
+ 0x63, 0x6b, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67,
+ 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12,
+ 0x21, 0x0a, 0x0c, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x63,
+ 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x76,
+ 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x64, 0x65, 0x42, 0x02,
+ 0x48, 0x03, 0x0a, 0xf6, 0x0d, 0x0a, 0x1e, 0x70, 0x65, 0x72, 0x66, 0x65,
+ 0x74, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f,
+ 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x12, 0x0f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x1a, 0x2a, 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, 0x29, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f,
0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x61, 0x6e, 0x64,
- 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65,
- 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
- 0x0f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72,
- 0x6f, 0x74, 0x6f, 0x73, 0x22, 0xc0, 0x01, 0x0a, 0x12, 0x41, 0x6e, 0x64,
- 0x72, 0x6f, 0x69, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x4c,
- 0x69, 0x73, 0x74, 0x12, 0x47, 0x0a, 0x08, 0x70, 0x61, 0x63, 0x6b, 0x61,
- 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e,
- 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f,
- 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x50,
- 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x50,
- 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x52, 0x08, 0x70, 0x61, 0x63, 0x6b,
- 0x61, 0x67, 0x65, 0x73, 0x1a, 0x61, 0x0a, 0x07, 0x50, 0x61, 0x63, 0x6b,
- 0x61, 0x67, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x61, 0x63, 0x6b, 0x61,
- 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x0b, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x4e, 0x61,
- 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20,
- 0x01, 0x28, 0x03, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c,
- 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x64, 0x65,
- 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x76, 0x65, 0x72, 0x73,
- 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x64, 0x65, 0x42, 0x02, 0x48, 0x03, 0x0a,
- 0xf6, 0x0d, 0x0a, 0x1e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f,
- 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x6d, 0x65, 0x74,
- 0x72, 0x69, 0x63, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f,
- 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f,
- 0x74, 0x6f, 0x73, 0x1a, 0x2a, 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,
+ 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x63, 0x70, 0x75, 0x5f, 0x6d, 0x65, 0x74,
+ 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x29, 0x70,
+ 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x72,
+ 0x69, 0x63, 0x73, 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f,
+ 0x6d, 0x65, 0x6d, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x1a, 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, 0x2d, 0x70, 0x65, 0x72, 0x66, 0x65,
+ 0x74, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f,
+ 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x63,
+ 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x6f, 0x77, 0x74, 0x68, 0x2e, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x29, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74,
+ 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x61,
+ 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x69, 0x6f, 0x6e, 0x5f, 0x6d,
0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a,
0x29, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2f, 0x6d, 0x65,
0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69,
- 0x64, 0x2f, 0x63, 0x70, 0x75, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63,
- 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x29, 0x70, 0x65, 0x72, 0x66,
+ 0x64, 0x2f, 0x6c, 0x6d, 0x6b, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63,
+ 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2e, 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, 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, 0x2d, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f,
- 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x61, 0x6e, 0x64,
- 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73,
- 0x5f, 0x67, 0x72, 0x6f, 0x77, 0x74, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74,
- 0x6f, 0x1a, 0x29, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2f,
- 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x61, 0x6e, 0x64, 0x72,
- 0x6f, 0x69, 0x64, 0x2f, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x65, 0x74, 0x72,
- 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x29, 0x70, 0x65,
- 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69,
- 0x63, 0x73, 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x6c,
- 0x6d, 0x6b, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72,
- 0x6f, 0x74, 0x6f, 0x1a, 0x2e, 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, 0x2d, 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, 0x3a, 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, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f,
- 0x74, 0x6f, 0x1a, 0x2b, 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, 0x22,
- 0xd2, 0x01, 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,
+ 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, 0x2d, 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, 0x3a, 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, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2b, 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, 0x22, 0xd2, 0x01, 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, 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,
+ 0xe9, 0x07, 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, 0x5b, 0x0a, 0x16, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69,
+ 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72,
+ 0x6f, 0x77, 0x74, 0x68, 0x18, 0x0a, 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,
+ 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x77, 0x74,
+ 0x68, 0x52, 0x14, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x50, 0x72,
+ 0x6f, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x77, 0x74, 0x68, 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, 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, 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, 0xe9, 0x07, 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,
+ 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, 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,
- 0x5b, 0x0a, 0x16, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x5f, 0x70,
- 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x6f, 0x77, 0x74,
- 0x68, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70, 0x65,
+ 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, 0x68, 0x0a, 0x1b, 0x68, 0x65,
+ 0x61, 0x70, 0x5f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x63,
+ 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74,
+ 0x73, 0x18, 0x0e, 0x20, 0x01, 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, 0x50, 0x72, 0x6f,
- 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x77, 0x74, 0x68, 0x52, 0x14,
- 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x50, 0x72, 0x6f, 0x63, 0x65,
- 0x73, 0x73, 0x47, 0x72, 0x6f, 0x77, 0x74, 0x68, 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, 0x68, 0x0a, 0x1b, 0x68, 0x65, 0x61, 0x70, 0x5f,
- 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c,
- 0x73, 0x69, 0x74, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x0e,
- 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 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, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52,
- 0x18, 0x68, 0x65, 0x61, 0x70, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65,
- 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74,
- 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,
+ 0x73, 0x2e, 0x48, 0x65, 0x61, 0x70, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c,
+ 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x53, 0x74, 0x61,
+ 0x74, 0x73, 0x52, 0x18, 0x68, 0x65, 0x61, 0x70, 0x50, 0x72, 0x6f, 0x66,
+ 0x69, 0x6c, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x69, 0x74, 0x65, 0x53,
+ 0x74, 0x61, 0x74, 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,
- 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, 0x0d, 0x10, 0x0e, 0x42, 0x02, 0x48, 0x03}};
+ 0x52, 0x0d, 0x74, 0x72, 0x61, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64,
+ 0x61, 0x74, 0x61, 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, 0x0d, 0x10, 0x0e, 0x42, 0x02, 0x48, 0x03}};
} // namespace perfetto
diff --git a/src/trace_processor/proto_trace_parser.cc b/src/trace_processor/proto_trace_parser.cc
index 442153a..930fb13 100644
--- a/src/trace_processor/proto_trace_parser.cc
+++ b/src/trace_processor/proto_trace_parser.cc
@@ -48,6 +48,7 @@
#include "perfetto/trace/android/android_log.pbzero.h"
#include "perfetto/trace/android/packages_list.pbzero.h"
#include "perfetto/trace/chrome/chrome_benchmark_metadata.pbzero.h"
+#include "perfetto/trace/chrome/chrome_trace_event.pbzero.h"
#include "perfetto/trace/clock_snapshot.pbzero.h"
#include "perfetto/trace/ftrace/ftrace.pbzero.h"
#include "perfetto/trace/ftrace/ftrace_event.pbzero.h"
@@ -254,6 +255,8 @@
context->storage->InternString("task.posted_from.file_name")),
task_function_name_args_key_id_(
context->storage->InternString("task.posted_from.function_name")),
+ raw_chrome_metadata_event_id_(
+ context->storage->InternString("chrome_event.metadata")),
raw_legacy_event_id_(
context->storage->InternString("track_event.legacy_event")),
legacy_event_category_key_id_(
@@ -430,6 +433,10 @@
ParseChromeBenchmarkMetadata(packet.chrome_benchmark_metadata());
}
+ if (packet.has_chrome_events()) {
+ ParseChromeEvents(packet.chrome_events());
+ }
+
if (packet.has_perfetto_metatrace()) {
ParseMetatraceEvent(ts, packet.perfetto_metatrace());
}
@@ -1215,11 +1222,13 @@
int64_t clock_realtime = 0;
for (auto it = evt.clocks(); it; ++it) {
protos::pbzero::ClockSnapshot::Clock::Decoder clk(it->data(), it->size());
- if (clk.type() == protos::pbzero::ClockSnapshot::Clock::BOOTTIME) {
+ if (clk.clock_id() == protos::pbzero::ClockSnapshot::Clock::BOOTTIME) {
clock_boottime = static_cast<int64_t>(clk.timestamp());
- } else if (clk.type() == protos::pbzero::ClockSnapshot::Clock::REALTIME) {
+ } else if (clk.clock_id() ==
+ protos::pbzero::ClockSnapshot::Clock::REALTIME) {
clock_realtime = static_cast<int64_t>(clk.timestamp());
- } else if (clk.type() == protos::pbzero::ClockSnapshot::Clock::MONOTONIC) {
+ } else if (clk.clock_id() ==
+ protos::pbzero::ClockSnapshot::Clock::MONOTONIC) {
clock_monotonic = static_cast<int64_t>(clk.timestamp());
}
}
@@ -1549,8 +1558,8 @@
// TODO(eseckler): This legacy event field will eventually be replaced by
// fields in TrackEvent itself.
- if (PERFETTO_UNLIKELY(!legacy_event.has_phase())) {
- PERFETTO_ELOG("TrackEvent without phase");
+ if (PERFETTO_UNLIKELY(!event.type() && !legacy_event.has_phase())) {
+ PERFETTO_ELOG("TrackEvent without type or phase");
return;
}
@@ -1580,6 +1589,7 @@
sequence_state->GetInternedDataMap<protos::pbzero::EventCategory>();
auto cat_view_it = map->find(category_iids[0]);
if (cat_view_it == map->end()) {
+ context_->storage->IncrementStats(stats::track_event_tokenizer_errors);
PERFETTO_ELOG("Could not find category interning entry for ID %" PRIu64,
category_iids[0]);
} else {
@@ -1605,6 +1615,7 @@
for (uint64_t iid : category_iids) {
auto cat_view_it = map->find(iid);
if (cat_view_it == map->end()) {
+ context_->storage->IncrementStats(stats::track_event_tokenizer_errors);
PERFETTO_ELOG("Could not find category interning entry for ID %" PRIu64,
iid);
continue;
@@ -1628,6 +1639,7 @@
sequence_state->GetInternedDataMap<protos::pbzero::LegacyEventName>();
auto name_view_it = map->find(legacy_event.name_iid());
if (name_view_it == map->end()) {
+ context_->storage->IncrementStats(stats::track_event_tokenizer_errors);
PERFETTO_ELOG("Could not find event name interning entry for ID %" PRIu64,
legacy_event.name_iid());
} else {
@@ -1678,7 +1690,23 @@
id_scope = storage->InternString(legacy_event.id_scope());
}
- int32_t phase = legacy_event.phase();
+ int32_t phase = 0;
+ if (legacy_event.has_phase()) {
+ phase = legacy_event.phase();
+ } else {
+ switch (event.type()) {
+ case protos::pbzero::TrackEvent::TYPE_SLICE_BEGIN:
+ phase = 'B';
+ break;
+ case protos::pbzero::TrackEvent::TYPE_SLICE_END:
+ phase = 'E';
+ break;
+ default:
+ PERFETTO_FATAL("unexpected event type %d", event.type());
+ return;
+ }
+ }
+
switch (static_cast<char>(phase)) {
case 'B': { // TRACE_EVENT_PHASE_BEGIN.
auto opt_slice_id = slice_tracker->Begin(
@@ -1998,6 +2026,7 @@
sequence_state->GetInternedDataMap<protos::pbzero::DebugAnnotationName>();
auto name_view_it = map->find(iid);
if (name_view_it == map->end()) {
+ context_->storage->IncrementStats(stats::track_event_tokenizer_errors);
PERFETTO_ELOG(
"Could not find debug annotation name interning entry for ID %" PRIu64,
iid);
@@ -2127,6 +2156,7 @@
sequence_state->GetInternedDataMap<protos::pbzero::SourceLocation>();
auto location_view_it = map->find(iid);
if (location_view_it == map->end()) {
+ context_->storage->IncrementStats(stats::track_event_tokenizer_errors);
PERFETTO_ELOG(
"Could not find source location interning entry for ID %" PRIu64, iid);
return;
@@ -2204,6 +2234,39 @@
}
}
+void ProtoTraceParser::ParseChromeEvents(ConstBytes blob) {
+ TraceStorage* storage = context_->storage.get();
+ protos::pbzero::ChromeEventBundle::Decoder bundle(blob.data, blob.size);
+ if (bundle.has_metadata()) {
+ ArgsTracker args(context_);
+ RowId row_id = storage->mutable_raw_events()->AddRawEvent(
+ 0, raw_chrome_metadata_event_id_, 0, 0);
+
+ // Metadata is proxied via a special event in the raw table to JSON export.
+ for (auto it = bundle.metadata(); it; ++it) {
+ protos::pbzero::ChromeMetadata::Decoder metadata(it->as_bytes().data,
+ it->as_bytes().size);
+ StringId name_id = storage->InternString(metadata.name());
+ Variadic value;
+ if (metadata.has_string_value()) {
+ value =
+ Variadic::String(storage->InternString(metadata.string_value()));
+ } else if (metadata.has_int_value()) {
+ value = Variadic::Integer(metadata.int_value());
+ } else if (metadata.has_bool_value()) {
+ value = Variadic::Integer(metadata.bool_value());
+ } else if (metadata.has_json_value()) {
+ value = Variadic::Json(storage->InternString(metadata.json_value()));
+ } else {
+ PERFETTO_FATAL("Empty ChromeMetadata message");
+ }
+ args.AddArg(row_id, name_id, name_id, value);
+ }
+ }
+
+ // TODO(khokhlov): parse legacy_ftrace_output and legacy_json_trace.
+}
+
void ProtoTraceParser::ParseMetatraceEvent(int64_t ts, ConstBytes blob) {
protos::pbzero::PerfettoMetatrace::Decoder event(blob.data, blob.size);
auto utid = context_->process_tracker->GetOrCreateThread(event.thread_id());
diff --git a/src/trace_processor/proto_trace_parser.h b/src/trace_processor/proto_trace_parser.h
index d7399a7..43e3d6e 100644
--- a/src/trace_processor/proto_trace_parser.h
+++ b/src/trace_processor/proto_trace_parser.h
@@ -128,6 +128,7 @@
ArgsTracker* args_tracker,
RowId row);
void ParseChromeBenchmarkMetadata(ConstBytes);
+ void ParseChromeEvents(ConstBytes);
void ParseMetatraceEvent(int64_t ts, ConstBytes);
void ParseGpuCounterEvent(int64_t ts, ConstBytes);
void ParseGpuRenderStageEvent(int64_t ts, ConstBytes);
@@ -167,6 +168,7 @@
const StringId metatrace_id_;
const StringId task_file_name_args_key_id_;
const StringId task_function_name_args_key_id_;
+ const StringId raw_chrome_metadata_event_id_;
const StringId raw_legacy_event_id_;
const StringId legacy_event_category_key_id_;
const StringId legacy_event_name_key_id_;
diff --git a/src/trace_processor/proto_trace_parser_unittest.cc b/src/trace_processor/proto_trace_parser_unittest.cc
index c67e98a..5cbc108 100644
--- a/src/trace_processor/proto_trace_parser_unittest.cc
+++ b/src/trace_processor/proto_trace_parser_unittest.cc
@@ -33,6 +33,7 @@
#include "perfetto/common/sys_stats_counters.pbzero.h"
#include "perfetto/trace/android/packages_list.pbzero.h"
#include "perfetto/trace/chrome/chrome_benchmark_metadata.pbzero.h"
+#include "perfetto/trace/chrome/chrome_trace_event.pbzero.h"
#include "perfetto/trace/ftrace/ftrace.pbzero.h"
#include "perfetto/trace/ftrace/ftrace_event.pbzero.h"
#include "perfetto/trace/ftrace/ftrace_event_bundle.pbzero.h"
@@ -728,6 +729,71 @@
EXPECT_EQ(storage_->thread_slices().thread_duration_ns()[1], 5000);
}
+TEST_F(ProtoTraceParserTest, TrackEventWithoutInternedDataWithTypes) {
+ context_.sorter.reset(new TraceSorter(
+ &context_, std::numeric_limits<int64_t>::max() /*window size*/));
+
+ {
+ auto* packet = trace_.add_packet();
+ packet->set_trusted_packet_sequence_id(1);
+ packet->set_incremental_state_cleared(true);
+ auto* thread_desc = packet->set_thread_descriptor();
+ thread_desc->set_pid(15);
+ thread_desc->set_tid(16);
+ thread_desc->set_reference_timestamp_us(1000);
+ thread_desc->set_reference_thread_time_us(2000);
+ }
+ {
+ auto* packet = trace_.add_packet();
+ packet->set_trusted_packet_sequence_id(1);
+ auto* event = packet->set_track_event();
+ event->set_timestamp_delta_us(10); // absolute: 1010.
+ event->set_thread_time_delta_us(5); // absolute: 2005.
+ event->add_category_iids(1);
+ event->set_type(protos::pbzero::TrackEvent::TYPE_SLICE_BEGIN);
+ auto* legacy_event = event->set_legacy_event();
+ legacy_event->set_name_iid(1);
+ }
+ {
+ auto* packet = trace_.add_packet();
+ packet->set_trusted_packet_sequence_id(1);
+ auto* event = packet->set_track_event();
+ event->set_timestamp_delta_us(10); // absolute: 1020.
+ event->set_thread_time_delta_us(5); // absolute: 2010.
+ event->add_category_iids(1);
+ event->set_type(protos::pbzero::TrackEvent::TYPE_SLICE_END);
+ auto* legacy_event = event->set_legacy_event();
+ legacy_event->set_name_iid(1);
+ }
+
+ Tokenize();
+
+ EXPECT_CALL(*process_, UpdateThread(16, 15))
+ .Times(2)
+ .WillRepeatedly(Return(1));
+
+ MockArgsTracker args(&context_);
+
+ InSequence in_sequence; // Below slices should be sorted by timestamp.
+ EXPECT_CALL(*slice_, Begin(1010000, 1, RefType::kRefUtid, 0, 0, _))
+ .WillOnce(DoAll(
+ InvokeArgument<5>(
+ &args, TraceStorage::CreateRowId(TableId::kNestableSlices, 0u)),
+ Return(0u)));
+ EXPECT_CALL(*slice_, End(1020000, 1, RefType::kRefUtid, 0, 0, _))
+ .WillOnce(DoAll(
+ InvokeArgument<5>(
+ &args, TraceStorage::CreateRowId(TableId::kNestableSlices, 0u)),
+ Return(0u)));
+
+ context_.sorter->ExtractEventsForced();
+
+ EXPECT_EQ(storage_->thread_slices().slice_count(), 1u);
+ EXPECT_EQ(storage_->thread_slices().slice_ids()[0], 0u);
+ EXPECT_EQ(storage_->thread_slices().thread_timestamp_ns()[0], 2005000);
+ EXPECT_EQ(storage_->thread_slices().thread_duration_ns()[0], 5000);
+}
+
TEST_F(ProtoTraceParserTest, TrackEventWithInternedData) {
context_.sorter.reset(new TraceSorter(
&context_, std::numeric_limits<int64_t>::max() /*window size*/));
@@ -1671,6 +1737,44 @@
EXPECT_TRUE(HasArg(1u, 5u, Variadic::UnsignedInteger(10u)));
}
+TEST_F(ProtoTraceParserTest, ParseChromeMetadataEventIntoRawTable) {
+ static const char kStringName[] = "string_name";
+ static const char kStringValue[] = "string_value";
+ static const char kIntName[] = "int_name";
+ static const int kIntValue = 123;
+
+ context_.sorter.reset(new TraceSorter(
+ &context_, std::numeric_limits<int64_t>::max() /*window size*/));
+
+ {
+ auto* packet = trace_.add_packet();
+ packet->set_trusted_packet_sequence_id(1);
+ auto* bundle = packet->set_chrome_events();
+ auto* metadata = bundle->add_metadata();
+ metadata->set_name(kStringName);
+ metadata->set_string_value(kStringValue);
+ metadata = bundle->add_metadata();
+ metadata->set_name(kIntName);
+ metadata->set_int_value(kIntValue);
+ }
+
+ Tokenize();
+ context_.sorter->ExtractEventsForced();
+
+ // Verify raw_events and args contents.
+ const auto& raw_events = storage_->raw_events();
+ EXPECT_EQ(raw_events.raw_event_count(), 1u);
+ EXPECT_EQ(raw_events.name_ids()[0],
+ storage_->InternString("chrome_event.metadata"));
+ EXPECT_EQ(raw_events.arg_set_ids()[0], 1u);
+
+ EXPECT_EQ(storage_->args().args_count(), 2u);
+ EXPECT_TRUE(HasArg(1u, storage_->InternString(kStringName),
+ Variadic::String(storage_->InternString(kStringValue))));
+ EXPECT_TRUE(HasArg(1u, storage_->InternString(kIntName),
+ Variadic::Integer(kIntValue)));
+}
+
TEST_F(ProtoTraceParserTest, LoadChromeBenchmarkMetadata) {
static const char kName[] = "name";
static const char kTag1[] = "tag1";
diff --git a/src/trace_processor/proto_trace_tokenizer.cc b/src/trace_processor/proto_trace_tokenizer.cc
index fbbd9b4..1fd4b28 100644
--- a/src/trace_processor/proto_trace_tokenizer.cc
+++ b/src/trace_processor/proto_trace_tokenizer.cc
@@ -18,7 +18,10 @@
#include <string>
+#include <zlib.h>
+
#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/optional.h"
#include "perfetto/ext/base/utils.h"
#include "perfetto/protozero/proto_decoder.h"
#include "perfetto/protozero/proto_utils.h"
@@ -50,6 +53,9 @@
namespace {
+constexpr uint8_t kTracePacketTag =
+ MakeTagLengthDelimited(protos::pbzero::Trace::kPacketFieldNumber);
+
template <typename MessageType>
void InternMessage(TraceProcessorContext* context,
ProtoIncrementalState::PacketSequenceState* state,
@@ -82,6 +88,33 @@
message_size) == 0));
}
+TraceBlobView Decompress(TraceBlobView input) {
+ uint8_t out[4096];
+ std::string s;
+
+ z_stream stream{};
+ stream.next_in = const_cast<uint8_t*>(input.data());
+ stream.avail_in = static_cast<unsigned int>(input.length());
+
+ if (inflateInit(&stream) != Z_OK)
+ return TraceBlobView(nullptr, 0, 0);
+
+ int ret;
+ do {
+ stream.next_out = out;
+ stream.avail_out = sizeof(out);
+ ret = inflate(&stream, Z_NO_FLUSH);
+ if (ret != Z_STREAM_END && ret != Z_OK)
+ return TraceBlobView(nullptr, 0, 0);
+ s.append(reinterpret_cast<char*>(out), sizeof(out) - stream.avail_out);
+ } while (ret != Z_STREAM_END);
+ inflateEnd(&stream);
+
+ std::unique_ptr<uint8_t[]> output(new uint8_t[s.size()]);
+ memcpy(output.get(), s.data(), s.size());
+ return TraceBlobView(std::move(output), 0, s.size());
+}
+
} // namespace
ProtoTraceTokenizer::ProtoTraceTokenizer(TraceProcessorContext* ctx)
@@ -105,8 +138,6 @@
// At this point we have enough data in |partial_buf_| to read at least the
// field header and know the size of the next TracePacket.
- constexpr uint8_t kTracePacketTag =
- MakeTagLengthDelimited(protos::pbzero::Trace::kPacketFieldNumber);
const uint8_t* pos = &partial_buf_[0];
uint8_t proto_field_tag = *pos;
uint64_t field_size = 0;
@@ -221,6 +252,34 @@
return util::OkStatus();
}
+ if (decoder.has_compressed_packets()) {
+ protozero::ConstBytes field = decoder.compressed_packets();
+ const size_t field_off = packet.offset_of(field.data);
+ TraceBlobView compressed_packets = packet.slice(field_off, field.size);
+ TraceBlobView packets = Decompress(std::move(compressed_packets));
+
+ const uint8_t* start = packets.data();
+ const uint8_t* end = packets.data() + packets.length();
+ const uint8_t* ptr = start;
+ while ((end - ptr) > 2) {
+ const uint8_t* packet_start = ptr;
+ if (PERFETTO_UNLIKELY(*ptr != kTracePacketTag))
+ return util::ErrStatus("Expected TracePacket tag");
+ uint64_t packet_size = 0;
+ ptr = ParseVarInt(++ptr, end, &packet_size);
+ size_t packet_offset = static_cast<size_t>(ptr - start);
+ ptr += packet_size;
+ if (PERFETTO_UNLIKELY((ptr - packet_start) < 2 || ptr > end))
+ return util::ErrStatus("Invalid packet size");
+ util::Status status = ParsePacket(
+ packets.slice(packet_offset, static_cast<size_t>(packet_size)));
+ if (PERFETTO_UNLIKELY(!status.ok()))
+ return status;
+ }
+
+ return util::OkStatus();
+ }
+
if (decoder.has_trace_config()) {
auto config = decoder.trace_config();
protos::pbzero::TraceConfig::Decoder trace_config(config.data, config.size);
diff --git a/src/trace_processor/trace_processor_impl.cc b/src/trace_processor/trace_processor_impl.cc
index 710c770..70f18d2 100644
--- a/src/trace_processor/trace_processor_impl.cc
+++ b/src/trace_processor/trace_processor_impl.cc
@@ -33,9 +33,7 @@
#include "src/trace_processor/counter_definitions_table.h"
#include "src/trace_processor/counter_values_table.h"
#include "src/trace_processor/event_tracker.h"
-#include "src/trace_processor/fuchsia_trace_parser.h"
-#include "src/trace_processor/fuchsia_trace_tokenizer.h"
-#include "src/trace_processor/gzip_trace_parser.h"
+#include "src/trace_processor/forwarding_trace_parser.h"
#include "src/trace_processor/heap_profile_allocation_table.h"
#include "src/trace_processor/heap_profile_callsite_table.h"
#include "src/trace_processor/heap_profile_frame_table.h"
@@ -49,7 +47,6 @@
#include "src/trace_processor/metrics/sql_metrics.h"
#include "src/trace_processor/process_table.h"
#include "src/trace_processor/process_tracker.h"
-#include "src/trace_processor/proto_trace_parser.h"
#include "src/trace_processor/proto_trace_tokenizer.h"
#include "src/trace_processor/raw_table.h"
#include "src/trace_processor/sched_slice_table.h"
@@ -77,8 +74,6 @@
#if PERFETTO_BUILDFLAG(PERFETTO_STANDALONE_BUILD) || \
PERFETTO_BUILD_WITH_CHROMIUM
#include "src/trace_processor/export_json.h"
-#include "src/trace_processor/json_trace_parser.h"
-#include "src/trace_processor/json_trace_tokenizer.h"
#endif
// In Android and Chromium tree builds, we don't have the percentile module.
@@ -94,12 +89,6 @@
namespace trace_processor {
namespace {
-std::string RemoveWhitespace(const std::string& input) {
- std::string str(input);
- str.erase(std::remove_if(str.begin(), str.end(), ::isspace), str.end());
- return str;
-}
-
void InitializeSqlite(sqlite3* db) {
char* error = nullptr;
sqlite3_exec(db, "PRAGMA temp_store=2", 0, 0, &error);
@@ -265,48 +254,8 @@
}
}
-// Fuchsia traces have a magic number as documented here:
-// https://fuchsia.googlesource.com/fuchsia/+/HEAD/docs/development/tracing/trace-format/README.md#magic-number-record-trace-info-type-0
-constexpr uint64_t kFuchsiaMagicNumber = 0x0016547846040010;
-
} // namespace
-TraceType GuessTraceType(const uint8_t* data, size_t size) {
- if (size == 0)
- return kUnknownTraceType;
- std::string start(reinterpret_cast<const char*>(data),
- std::min<size_t>(size, 20));
- std::string start_minus_white_space = RemoveWhitespace(start);
- if (base::StartsWith(start_minus_white_space, "{\"traceEvents\":["))
- return kJsonTraceType;
- if (base::StartsWith(start_minus_white_space, "[{"))
- return kJsonTraceType;
- if (size >= 8) {
- uint64_t first_word = *reinterpret_cast<const uint64_t*>(data);
- if (first_word == kFuchsiaMagicNumber)
- return kFuchsiaTraceType;
- }
-
- // Systrace with header but no leading HTML.
- if (base::StartsWith(start, "# tracer"))
- return kSystraceTraceType;
-
- // Systrace with leading HTML.
- if (base::StartsWith(start, "<!DOCTYPE html>") ||
- base::StartsWith(start, "<html>"))
- return kSystraceTraceType;
-
- // Systrace with no header or leading HTML.
- if (base::StartsWith(start, " "))
- return kSystraceTraceType;
-
- // Ctrace is GZIPed systrace with no headers.
- if (base::StartsWith(start, "TRACE:"))
- return kCtraceTraceType;
-
- return kProtoTraceType;
-}
-
TraceProcessorImpl::TraceProcessorImpl(const Config& cfg) {
sqlite3* db = nullptr;
PERFETTO_CHECK(sqlite3_initialize() == SQLITE_OK);
@@ -368,58 +317,8 @@
if (unrecoverable_parse_error_)
return util::ErrStatus(
"Failed unrecoverably while parsing in a previous Parse call");
-
- // If this is the first Parse() call, guess the trace type and create the
- // appropriate parser.
- if (!context_.chunk_reader) {
- TraceType trace_type;
- {
- auto scoped_trace = context_.storage->TraceExecutionTimeIntoStats(
- stats::guess_trace_type_duration_ns);
- trace_type = GuessTraceType(data.get(), size);
- }
- switch (trace_type) {
- case kJsonTraceType: {
- PERFETTO_DLOG("Legacy JSON trace detected");
-#if PERFETTO_BUILDFLAG(PERFETTO_STANDALONE_BUILD) || \
- PERFETTO_BUILD_WITH_CHROMIUM
- context_.chunk_reader.reset(new JsonTraceTokenizer(&context_));
- // JSON traces have no guarantees about the order of events in them.
- int64_t window_size_ns = std::numeric_limits<int64_t>::max();
- context_.sorter.reset(new TraceSorter(&context_, window_size_ns));
- context_.parser.reset(new JsonTraceParser(&context_));
-#else
- PERFETTO_FATAL("JSON traces not supported.");
-#endif
- break;
- }
- case kProtoTraceType: {
- // This will be reduced once we read the trace config and we see flush
- // period being set.
- int64_t window_size_ns = std::numeric_limits<int64_t>::max();
- context_.chunk_reader.reset(new ProtoTraceTokenizer(&context_));
- context_.sorter.reset(new TraceSorter(&context_, window_size_ns));
- context_.parser.reset(new ProtoTraceParser(&context_));
- break;
- }
- case kFuchsiaTraceType: {
- // Fuschia traces can have massively out of order events.
- int64_t window_size_ns = std::numeric_limits<int64_t>::max();
- context_.chunk_reader.reset(new FuchsiaTraceTokenizer(&context_));
- context_.sorter.reset(new TraceSorter(&context_, window_size_ns));
- context_.parser.reset(new FuchsiaTraceParser(&context_));
- break;
- }
- case kSystraceTraceType:
- context_.chunk_reader.reset(new SystraceTraceParser(&context_));
- break;
- case kCtraceTraceType:
- context_.chunk_reader.reset(new GzipTraceParser(&context_));
- break;
- case kUnknownTraceType:
- return util::ErrStatus("Unknown trace type provided");
- }
- }
+ if (!context_.chunk_reader)
+ context_.chunk_reader.reset(new ForwardingTraceParser(&context_));
auto scoped_trace = context_.storage->TraceExecutionTimeIntoStats(
stats::parse_trace_duration_ns);
diff --git a/src/trace_processor/trace_processor_impl.h b/src/trace_processor/trace_processor_impl.h
index e9c3435..0ef2d7e 100644
--- a/src/trace_processor/trace_processor_impl.h
+++ b/src/trace_processor/trace_processor_impl.h
@@ -36,17 +36,6 @@
namespace trace_processor {
-enum TraceType {
- kUnknownTraceType,
- kProtoTraceType,
- kJsonTraceType,
- kFuchsiaTraceType,
- kSystraceTraceType,
- kCtraceTraceType,
-};
-
-TraceType GuessTraceType(const uint8_t* data, size_t size);
-
// Coordinates the loading of traces from an arbitrary source and allows
// execution of SQL queries on the events in these traces.
class TraceProcessorImpl : public TraceProcessor {
diff --git a/src/tracing/api_integrationtest.cc b/src/tracing/api_integrationtest.cc
index 7e6087f..c696582 100644
--- a/src/tracing/api_integrationtest.cc
+++ b/src/tracing/api_integrationtest.cc
@@ -88,6 +88,8 @@
MockDataSource* instance;
perfetto::DataSourceConfig config;
bool handle_stop_asynchronously = false;
+ std::function<void()> on_start_callback;
+ std::function<void()> on_stop_callback;
std::function<void()> async_stop_closure;
};
@@ -182,6 +184,8 @@
void MockDataSource::OnStart(const StartArgs&) {
EXPECT_NE(handle_, nullptr);
+ if (handle_->on_start_callback)
+ handle_->on_start_callback();
handle_->on_start.Notify();
}
@@ -189,6 +193,8 @@
EXPECT_NE(handle_, nullptr);
if (handle_->handle_stop_asynchronously)
handle_->async_stop_closure = args.HandleStopAsynchronously();
+ if (handle_->on_stop_callback)
+ handle_->on_stop_callback();
handle_->on_stop.Notify();
}
@@ -441,6 +447,61 @@
EXPECT_EQ(trace_lambda_calls, 1);
}
+// Regression test for b/139110180. Checks that GetDataSourceLocked() can be
+// called from OnStart() and OnStop() callbacks without deadlocking.
+TEST_F(PerfettoApiTest, GetDataSourceLockedFromCallbacks) {
+ auto* data_source = &data_sources_["my_data_source"];
+
+ // Setup the trace config.
+ perfetto::TraceConfig cfg;
+ cfg.set_duration_ms(1);
+ cfg.add_buffers()->set_size_kb(1024);
+ auto* ds_cfg = cfg.add_data_sources()->mutable_config();
+ ds_cfg->set_name("my_data_source");
+
+ // Create a new trace session.
+ auto* tracing_session = NewTrace(cfg);
+
+ data_source->on_start_callback = [] {
+ MockDataSource::Trace([](MockDataSource::TraceContext ctx) {
+ ctx.NewTracePacket()->set_for_testing()->set_str("on-start");
+ auto ds = ctx.GetDataSourceLocked();
+ ASSERT_TRUE(!!ds);
+ ctx.NewTracePacket()->set_for_testing()->set_str("on-start-locked");
+ });
+ };
+
+ data_source->on_stop_callback = [] {
+ MockDataSource::Trace([](MockDataSource::TraceContext ctx) {
+ ctx.NewTracePacket()->set_for_testing()->set_str("on-stop");
+ auto ds = ctx.GetDataSourceLocked();
+ ASSERT_TRUE(!!ds);
+ ctx.NewTracePacket()->set_for_testing()->set_str("on-stop-locked");
+ ctx.Flush();
+ });
+ };
+
+ tracing_session->get()->Start();
+ data_source->on_stop.Wait();
+ tracing_session->on_stop.Wait();
+
+ std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
+ ASSERT_GE(raw_trace.size(), 0u);
+
+ perfetto::protos::Trace trace;
+ ASSERT_TRUE(trace.ParseFromArray(raw_trace.data(), int(raw_trace.size())));
+ int packets_found = 0;
+ for (const auto& packet : trace.packet()) {
+ if (!packet.has_for_testing())
+ continue;
+ packets_found |= packet.for_testing().str() == "on-start" ? 1 : 0;
+ packets_found |= packet.for_testing().str() == "on-start-locked" ? 2 : 0;
+ packets_found |= packet.for_testing().str() == "on-stop" ? 4 : 0;
+ packets_found |= packet.for_testing().str() == "on-stop-locked" ? 8 : 0;
+ }
+ EXPECT_EQ(packets_found, 1 | 2 | 4 | 8);
+}
+
} // namespace
PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(MockDataSource);
diff --git a/src/tracing/core/shared_memory_arbiter_impl_unittest.cc b/src/tracing/core/shared_memory_arbiter_impl_unittest.cc
index bffe662..5905ef8 100644
--- a/src/tracing/core/shared_memory_arbiter_impl_unittest.cc
+++ b/src/tracing/core/shared_memory_arbiter_impl_unittest.cc
@@ -44,7 +44,9 @@
void ActivateTriggers(const std::vector<std::string>&) {}
SharedMemory* shared_memory() const override { return nullptr; }
size_t shared_buffer_page_size_kb() const override { return 0; }
- std::unique_ptr<TraceWriter> CreateTraceWriter(BufferID) override {
+ std::unique_ptr<TraceWriter> CreateTraceWriter(
+ BufferID,
+ BufferExhaustedPolicy) override {
return nullptr;
}
SharedMemoryArbiter* GetInProcessShmemArbiter() override { return nullptr; }
@@ -90,8 +92,7 @@
static constexpr size_t kTotChunks = kNumPages * 14;
SharedMemoryABI::Chunk chunks[kTotChunks];
for (size_t i = 0; i < 14 * 2 + 2; i++) {
- chunks[i] = arbiter_->GetNewChunk(
- {}, SharedMemoryArbiter::BufferExhaustedPolicy::kStall);
+ chunks[i] = arbiter_->GetNewChunk({}, BufferExhaustedPolicy::kStall);
ASSERT_TRUE(chunks[i].is_valid());
}
@@ -175,23 +176,21 @@
static constexpr size_t kTotChunks = kNumPages;
SharedMemoryABI::Chunk chunks[kTotChunks];
for (size_t i = 0; i < kTotChunks; i++) {
- chunks[i] = arbiter_->GetNewChunk(
- {}, SharedMemoryArbiter::BufferExhaustedPolicy::kDrop);
+ chunks[i] = arbiter_->GetNewChunk({}, BufferExhaustedPolicy::kDrop);
ASSERT_TRUE(chunks[i].is_valid());
}
// SMB is exhausted, thus GetNewChunk() should return an invalid chunk. In
// kStall mode, this would stall.
- SharedMemoryABI::Chunk invalid_chunk = arbiter_->GetNewChunk(
- {}, SharedMemoryArbiter::BufferExhaustedPolicy::kDrop);
+ SharedMemoryABI::Chunk invalid_chunk =
+ arbiter_->GetNewChunk({}, BufferExhaustedPolicy::kDrop);
ASSERT_FALSE(invalid_chunk.is_valid());
// Returning the chunk is not enough to be able to reacquire it.
PatchList ignored;
arbiter_->ReturnCompletedChunk(std::move(chunks[0]), 0, &ignored);
- invalid_chunk = arbiter_->GetNewChunk(
- {}, SharedMemoryArbiter::BufferExhaustedPolicy::kDrop);
+ invalid_chunk = arbiter_->GetNewChunk({}, BufferExhaustedPolicy::kDrop);
ASSERT_FALSE(invalid_chunk.is_valid());
// After releasing the chunk as free, we can reacquire it.
@@ -200,8 +199,7 @@
ASSERT_TRUE(chunks[0].is_valid());
arbiter_->shmem_abi_for_testing()->ReleaseChunkAsFree(std::move(chunks[0]));
- chunks[0] = arbiter_->GetNewChunk(
- {}, SharedMemoryArbiter::BufferExhaustedPolicy::kDrop);
+ chunks[0] = arbiter_->GetNewChunk({}, BufferExhaustedPolicy::kDrop);
ASSERT_TRUE(chunks[0].is_valid());
}
diff --git a/src/tracing/core/startup_trace_writer.cc b/src/tracing/core/startup_trace_writer.cc
index 8f24990..d89b9a1 100644
--- a/src/tracing/core/startup_trace_writer.cc
+++ b/src/tracing/core/startup_trace_writer.cc
@@ -36,12 +36,11 @@
static constexpr ChunkID kFirstChunkId = 0;
-SharedMemoryABI::Chunk NewChunk(
- SharedMemoryArbiterImpl* arbiter,
- WriterID writer_id,
- ChunkID chunk_id,
- bool fragmenting_packet,
- SharedMemoryArbiter::BufferExhaustedPolicy buffer_exhausted_policy) {
+SharedMemoryABI::Chunk NewChunk(SharedMemoryArbiterImpl* arbiter,
+ WriterID writer_id,
+ ChunkID chunk_id,
+ bool fragmenting_packet,
+ BufferExhaustedPolicy buffer_exhausted_policy) {
ChunkHeader::Packets packets = {};
if (fragmenting_packet) {
packets.count = 1;
@@ -133,15 +132,14 @@
// commit before continuing with the remaining data.
class LocalBufferCommitter {
public:
- LocalBufferCommitter(
- std::unique_ptr<LocalBufferReader> local_buffer_reader,
- std::unique_ptr<std::vector<uint32_t>> packet_sizes,
- base::WeakPtr<SharedMemoryArbiterImpl> arbiter,
- WriterID writer_id,
- BufferID target_buffer,
- size_t chunks_per_batch,
- SharedMemoryArbiter::BufferExhaustedPolicy buffer_exhausted_policy,
- SharedMemoryABI::Chunk first_chunk)
+ LocalBufferCommitter(std::unique_ptr<LocalBufferReader> local_buffer_reader,
+ std::unique_ptr<std::vector<uint32_t>> packet_sizes,
+ base::WeakPtr<SharedMemoryArbiterImpl> arbiter,
+ WriterID writer_id,
+ BufferID target_buffer,
+ size_t chunks_per_batch,
+ BufferExhaustedPolicy buffer_exhausted_policy,
+ SharedMemoryABI::Chunk first_chunk)
: local_buffer_reader_(std::move(local_buffer_reader)),
packet_sizes_(std::move(packet_sizes)),
arbiter_(arbiter),
@@ -340,7 +338,7 @@
const WriterID writer_id_;
const BufferID target_buffer_;
const size_t chunks_per_batch_;
- SharedMemoryArbiter::BufferExhaustedPolicy buffer_exhausted_policy_;
+ BufferExhaustedPolicy buffer_exhausted_policy_;
SharedMemoryABI::Chunk cur_chunk_;
// We receive the first chunk in the constructor, thus the next chunk will be
// the second one.
@@ -354,7 +352,7 @@
StartupTraceWriter::StartupTraceWriter(
std::shared_ptr<StartupTraceWriterRegistryHandle> registry_handle,
- SharedMemoryArbiter::BufferExhaustedPolicy buffer_exhausted_policy)
+ BufferExhaustedPolicy buffer_exhausted_policy)
: registry_handle_(std::move(registry_handle)),
buffer_exhausted_policy_(buffer_exhausted_policy),
memory_buffer_(new protozero::ScatteredHeapBuffer()),
diff --git a/src/tracing/core/startup_trace_writer_registry.cc b/src/tracing/core/startup_trace_writer_registry.cc
index f60101f..ddbf31c 100644
--- a/src/tracing/core/startup_trace_writer_registry.cc
+++ b/src/tracing/core/startup_trace_writer_registry.cc
@@ -54,7 +54,7 @@
std::unique_ptr<StartupTraceWriter>
StartupTraceWriterRegistry::CreateUnboundTraceWriter(
- SharedMemoryArbiter::BufferExhaustedPolicy buffer_exhausted_policy) {
+ BufferExhaustedPolicy buffer_exhausted_policy) {
std::lock_guard<std::mutex> lock(lock_);
PERFETTO_DCHECK(!arbiter_); // Should only be called while unbound.
std::unique_ptr<StartupTraceWriter> writer(
diff --git a/src/tracing/core/startup_trace_writer_unittest.cc b/src/tracing/core/startup_trace_writer_unittest.cc
index 2461aff..8383548 100644
--- a/src/tracing/core/startup_trace_writer_unittest.cc
+++ b/src/tracing/core/startup_trace_writer_unittest.cc
@@ -54,8 +54,8 @@
std::unique_ptr<StartupTraceWriter> CreateUnboundWriter() {
std::shared_ptr<StartupTraceWriterRegistryHandle> registry;
- return std::unique_ptr<StartupTraceWriter>(new StartupTraceWriter(
- registry, SharedMemoryArbiter::BufferExhaustedPolicy::kDrop));
+ return std::unique_ptr<StartupTraceWriter>(
+ new StartupTraceWriter(registry, BufferExhaustedPolicy::kDrop));
}
bool BindWriter(StartupTraceWriter* writer, size_t chunks_per_batch = 0) {
@@ -309,10 +309,10 @@
new StartupTraceWriterRegistry());
// Create unbound writers.
- auto writer1 = registry->CreateUnboundTraceWriter(
- SharedMemoryArbiter::BufferExhaustedPolicy::kDrop);
- auto writer2 = registry->CreateUnboundTraceWriter(
- SharedMemoryArbiter::BufferExhaustedPolicy::kDrop);
+ auto writer1 =
+ registry->CreateUnboundTraceWriter(BufferExhaustedPolicy::kDrop);
+ auto writer2 =
+ registry->CreateUnboundTraceWriter(BufferExhaustedPolicy::kDrop);
EXPECT_EQ(2u, GetUnboundWriterCount(*registry));
@@ -410,8 +410,7 @@
static constexpr size_t kTotChunks = kNumPages;
SharedMemoryABI::Chunk chunks[kTotChunks];
for (size_t i = 0; i < kTotChunks; i++) {
- chunks[i] = arbiter_->GetNewChunk(
- {}, SharedMemoryArbiter::BufferExhaustedPolicy::kDrop);
+ chunks[i] = arbiter_->GetNewChunk({}, BufferExhaustedPolicy::kDrop);
ASSERT_TRUE(chunks[i].is_valid());
}
diff --git a/src/tracing/core/trace_buffer.cc b/src/tracing/core/trace_buffer.cc
index d78781a..7bb4664 100644
--- a/src/tracing/core/trace_buffer.cc
+++ b/src/tracing/core/trace_buffer.cc
@@ -844,10 +844,10 @@
const uint8_t* next_packet = packet_data + packet_size;
if (PERFETTO_UNLIKELY(next_packet <= packet_begin ||
next_packet > record_end)) {
- // In SharedMemoryArbiter::BufferExhaustedPolicy::kDrop mode, TraceWriter
- // may abort a fragmented packet by writing an invalid size in the last
- // fragment's header. We should handle this case without recording an ABI
- // violation (since Android R).
+ // In BufferExhaustedPolicy::kDrop mode, TraceWriter may abort a fragmented
+ // packet by writing an invalid size in the last fragment's header. We
+ // should handle this case without recording an ABI violation (since Android
+ // R).
if (packet_size != SharedMemoryABI::kPacketSizeDropPacket) {
stats_.set_abi_violations(stats_.abi_violations() + 1);
PERFETTO_DCHECK(suppress_sanity_dchecks_for_testing_);
diff --git a/src/tracing/core/trace_config.cc b/src/tracing/core/trace_config.cc
index 88c90db..2cd12b3 100644
--- a/src/tracing/core/trace_config.cc
+++ b/src/tracing/core/trace_config.cc
@@ -67,7 +67,8 @@
(allow_user_build_tracing_ == other.allow_user_build_tracing_) &&
(unique_session_name_ == other.unique_session_name_) &&
(compression_type_ == other.compression_type_) &&
- (incident_report_config_ == other.incident_report_config_);
+ (incident_report_config_ == other.incident_report_config_) &&
+ (trace_uuid_ == other.trace_uuid_);
}
#pragma GCC diagnostic pop
@@ -192,6 +193,10 @@
static_cast<decltype(compression_type_)>(proto.compression_type());
incident_report_config_->FromProto(proto.incident_report_config());
+
+ static_assert(sizeof(trace_uuid_) == sizeof(proto.trace_uuid()),
+ "size mismatch");
+ trace_uuid_ = static_cast<decltype(trace_uuid_)>(proto.trace_uuid());
unknown_fields_ = proto.unknown_fields();
}
@@ -313,6 +318,11 @@
static_cast<decltype(proto->compression_type())>(compression_type_));
incident_report_config_->ToProto(proto->mutable_incident_report_config());
+
+ static_assert(sizeof(trace_uuid_) == sizeof(proto->trace_uuid()),
+ "size mismatch");
+ proto->set_trace_uuid(
+ static_cast<decltype(proto->trace_uuid())>(trace_uuid_));
*(proto->mutable_unknown_fields()) = unknown_fields_;
}
diff --git a/src/tracing/core/trace_writer_impl.cc b/src/tracing/core/trace_writer_impl.cc
index 18e951c..a8926ac 100644
--- a/src/tracing/core/trace_writer_impl.cc
+++ b/src/tracing/core/trace_writer_impl.cc
@@ -40,11 +40,10 @@
uint8_t g_garbage_chunk[1024];
} // namespace
-TraceWriterImpl::TraceWriterImpl(
- SharedMemoryArbiterImpl* shmem_arbiter,
- WriterID id,
- BufferID target_buffer,
- SharedMemoryArbiter::BufferExhaustedPolicy buffer_exhausted_policy)
+TraceWriterImpl::TraceWriterImpl(SharedMemoryArbiterImpl* shmem_arbiter,
+ WriterID id,
+ BufferID target_buffer,
+ BufferExhaustedPolicy buffer_exhausted_policy)
: shmem_arbiter_(shmem_arbiter),
id_(id),
target_buffer_(target_buffer),
diff --git a/src/tracing/core/trace_writer_impl.h b/src/tracing/core/trace_writer_impl.h
index 26afd95..7442b5e 100644
--- a/src/tracing/core/trace_writer_impl.h
+++ b/src/tracing/core/trace_writer_impl.h
@@ -18,6 +18,7 @@
#define SRC_TRACING_CORE_TRACE_WRITER_IMPL_H_
#include "perfetto/ext/tracing/core/basic_types.h"
+#include "perfetto/ext/tracing/core/buffer_exhausted_policy.h"
#include "perfetto/ext/tracing/core/shared_memory_abi.h"
#include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
#include "perfetto/ext/tracing/core/trace_writer.h"
@@ -38,7 +39,7 @@
TraceWriterImpl(SharedMemoryArbiterImpl*,
WriterID,
BufferID,
- SharedMemoryArbiter::BufferExhaustedPolicy);
+ BufferExhaustedPolicy);
~TraceWriterImpl() override;
// TraceWriter implementation. See documentation in trace_writer.h.
@@ -73,7 +74,7 @@
// Whether GetNewChunk() should stall or return an invalid chunk if the SMB is
// exhausted.
- const SharedMemoryArbiter::BufferExhaustedPolicy buffer_exhausted_policy_;
+ const BufferExhaustedPolicy buffer_exhausted_policy_;
// Monotonic (% wrapping) sequence id of the chunk. Together with the WriterID
// this allows the Service to reconstruct the linear sequence of packets.
diff --git a/src/tracing/core/trace_writer_impl_unittest.cc b/src/tracing/core/trace_writer_impl_unittest.cc
index 68daa33..32ae83c 100644
--- a/src/tracing/core/trace_writer_impl_unittest.cc
+++ b/src/tracing/core/trace_writer_impl_unittest.cc
@@ -154,8 +154,8 @@
task_runner_.get()));
const BufferID kBufId = 42;
- std::unique_ptr<TraceWriter> writer = arbiter_->CreateTraceWriter(
- kBufId, SharedMemoryArbiter::BufferExhaustedPolicy::kDrop);
+ std::unique_ptr<TraceWriter> writer =
+ arbiter_->CreateTraceWriter(kBufId, BufferExhaustedPolicy::kDrop);
// Write a small first packet, so that |writer| owns a chunk.
auto packet = writer->NewTracePacket();
@@ -166,8 +166,8 @@
// Grab all the remaining chunks in the SMB in new writers.
std::array<std::unique_ptr<TraceWriter>, kNumPages * 4 - 1> other_writers;
for (size_t i = 0; i < other_writers.size(); i++) {
- other_writers[i] = arbiter_->CreateTraceWriter(
- kBufId, SharedMemoryArbiter::BufferExhaustedPolicy::kDrop);
+ other_writers[i] =
+ arbiter_->CreateTraceWriter(kBufId, BufferExhaustedPolicy::kDrop);
auto other_writer_packet = other_writers[i]->NewTracePacket();
EXPECT_FALSE(reinterpret_cast<TraceWriterImpl*>(other_writers[i].get())
->drop_packets_for_testing());
diff --git a/src/tracing/core/tracing_service_impl.cc b/src/tracing/core/tracing_service_impl.cc
index 994e1da..985bfa1 100644
--- a/src/tracing/core/tracing_service_impl.cc
+++ b/src/tracing/core/tracing_service_impl.cc
@@ -2182,7 +2182,7 @@
!PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
struct {
clockid_t id;
- protos::ClockSnapshot::Clock::Type type;
+ protos::ClockSnapshot::Clock::BuiltinClocks type;
struct timespec ts;
} clocks[] = {
{CLOCK_BOOTTIME, protos::ClockSnapshot::Clock::BOOTTIME, {0, 0}},
@@ -2216,7 +2216,7 @@
static_cast<uint64_t>(base::FromPosixTimespec(clock.ts).count()));
}
protos::ClockSnapshot::Clock* c = clock_snapshot->add_clocks();
- c->set_type(clock.type);
+ c->set_clock_id(clock.type);
c->set_timestamp(
static_cast<uint64_t>(base::FromPosixTimespec(clock.ts).count()));
}
@@ -2225,7 +2225,7 @@
if (set_root_timestamp)
packet.set_timestamp(wall_time_ns);
protos::ClockSnapshot::Clock* c = clock_snapshot->add_clocks();
- c->set_type(protos::ClockSnapshot::Clock::MONOTONIC);
+ c->set_clock_id(protos::ClockSnapshot::Clock::MONOTONIC);
c->set_timestamp(wall_time_ns);
#endif // !PERFETTO_BUILDFLAG(PERFETTO_OS_MACOSX)
@@ -2771,8 +2771,11 @@
// Can be called on any thread.
std::unique_ptr<TraceWriter>
-TracingServiceImpl::ProducerEndpointImpl::CreateTraceWriter(BufferID buf_id) {
- return GetInProcessShmemArbiter()->CreateTraceWriter(buf_id);
+TracingServiceImpl::ProducerEndpointImpl::CreateTraceWriter(
+ BufferID buf_id,
+ BufferExhaustedPolicy buffer_exhausted_policy) {
+ return GetInProcessShmemArbiter()->CreateTraceWriter(buf_id,
+ buffer_exhausted_policy);
}
void TracingServiceImpl::ProducerEndpointImpl::NotifyFlushComplete(
diff --git a/src/tracing/core/tracing_service_impl.h b/src/tracing/core/tracing_service_impl.h
index 57f504e..0fd2c3a 100644
--- a/src/tracing/core/tracing_service_impl.h
+++ b/src/tracing/core/tracing_service_impl.h
@@ -89,7 +89,9 @@
void UnregisterTraceWriter(uint32_t writer_id) override;
void CommitData(const CommitDataRequest&, CommitDataCallback) override;
void SetSharedMemory(std::unique_ptr<SharedMemory>);
- std::unique_ptr<TraceWriter> CreateTraceWriter(BufferID) override;
+ std::unique_ptr<TraceWriter> CreateTraceWriter(
+ BufferID,
+ BufferExhaustedPolicy) override;
SharedMemoryArbiter* GetInProcessShmemArbiter() override;
void NotifyFlushComplete(FlushRequestID) override;
void NotifyDataSourceStarted(DataSourceInstanceID) override;
diff --git a/src/tracing/internal/tracing_muxer_impl.cc b/src/tracing/internal/tracing_muxer_impl.cc
index 5f8035a..38a2d7b 100644
--- a/src/tracing/internal/tracing_muxer_impl.cc
+++ b/src/tracing/internal/tracing_muxer_impl.cc
@@ -26,6 +26,7 @@
#include "perfetto/base/task_runner.h"
#include "perfetto/ext/base/thread_checker.h"
#include "perfetto/ext/base/waitable_event.h"
+#include "perfetto/ext/tracing/core/buffer_exhausted_policy.h"
#include "perfetto/ext/tracing/core/trace_packet.h"
#include "perfetto/ext/tracing/core/trace_writer.h"
#include "perfetto/ext/tracing/core/tracing_service.h"
@@ -488,7 +489,7 @@
auto* internal_state =
reinterpret_cast<DataSourceState*>(&static_state.instances[i]);
- std::lock_guard<std::mutex> guard(internal_state->lock);
+ std::lock_guard<std::recursive_mutex> guard(internal_state->lock);
static_assert(
std::is_same<decltype(internal_state->data_source_instance_id),
DataSourceInstanceID>::value,
@@ -527,7 +528,7 @@
return;
}
- std::lock_guard<std::mutex> guard(ds.internal_state->lock);
+ std::lock_guard<std::recursive_mutex> guard(ds.internal_state->lock);
ds.internal_state->trace_lambda_enabled = true;
ds.internal_state->data_source->OnStart(DataSourceBase::StartArgs{});
}
@@ -558,7 +559,7 @@
};
{
- std::lock_guard<std::mutex> guard(ds.internal_state->lock);
+ std::lock_guard<std::recursive_mutex> guard(ds.internal_state->lock);
ds.internal_state->data_source->OnStop(stop_args);
}
@@ -592,7 +593,7 @@
// a Trace() execution where it called GetDataSourceLocked() while we
// destroy it.
{
- std::lock_guard<std::mutex> guard(ds.internal_state->lock);
+ std::lock_guard<std::recursive_mutex> guard(ds.internal_state->lock);
ds.internal_state->trace_lambda_enabled = false;
ds.internal_state->data_source.reset();
}
@@ -804,7 +805,13 @@
std::unique_ptr<TraceWriterBase> TracingMuxerImpl::CreateTraceWriter(
DataSourceState* data_source) {
ProducerImpl* producer = backends_[data_source->backend_id].producer.get();
- return producer->service_->CreateTraceWriter(data_source->buffer_id);
+ // We choose BufferExhaustedPolicy::kDrop to avoid stalls when all SMB chunks
+ // are allocated, ensuring that the app keeps working even when tracing hits
+ // its SMB limit. Note that this means we will lose data in such a case
+ // (tracked in BufferStats::trace_writer_packet_loss). To reduce this data
+ // loss, apps should choose a large enough SMB size.
+ return producer->service_->CreateTraceWriter(data_source->buffer_id,
+ BufferExhaustedPolicy::kDrop);
}
// This is called via the public API Tracing::NewTrace().
diff --git a/src/tracing/ipc/producer/producer_ipc_client_impl.cc b/src/tracing/ipc/producer/producer_ipc_client_impl.cc
index 28f1085..bee2026 100644
--- a/src/tracing/ipc/producer/producer_ipc_client_impl.cc
+++ b/src/tracing/ipc/producer/producer_ipc_client_impl.cc
@@ -19,6 +19,7 @@
#include <inttypes.h>
#include <string.h>
+#include "perfetto/base/logging.h"
#include "perfetto/base/task_runner.h"
#include "perfetto/ext/ipc/client.h"
#include "perfetto/ext/tracing/core/commit_data_request.h"
@@ -107,6 +108,14 @@
protos::InitializeConnectionRequest::SMB_SCRAPING_DISABLED);
break;
}
+
+#if PERFETTO_DCHECK_IS_ON()
+ req.set_build_flags(
+ protos::InitializeConnectionRequest::BUILD_FLAGS_DCHECKS_ON);
+#else
+ req.set_build_flags(
+ protos::InitializeConnectionRequest::BUILD_FLAGS_DCHECKS_OFF);
+#endif
producer_port_.InitializeConnection(req, std::move(on_init));
// Create the back channel to receive commands from the Service.
@@ -347,10 +356,12 @@
}
std::unique_ptr<TraceWriter> ProducerIPCClientImpl::CreateTraceWriter(
- BufferID target_buffer) {
+ BufferID target_buffer,
+ BufferExhaustedPolicy buffer_exhausted_policy) {
// This method can be called by different threads. |shared_memory_arbiter_| is
// thread-safe but be aware of accessing any other state in this function.
- return shared_memory_arbiter_->CreateTraceWriter(target_buffer);
+ return shared_memory_arbiter_->CreateTraceWriter(target_buffer,
+ buffer_exhausted_policy);
}
SharedMemoryArbiter* ProducerIPCClientImpl::GetInProcessShmemArbiter() {
diff --git a/src/tracing/ipc/producer/producer_ipc_client_impl.h b/src/tracing/ipc/producer/producer_ipc_client_impl.h
index 0028330..2034994 100644
--- a/src/tracing/ipc/producer/producer_ipc_client_impl.h
+++ b/src/tracing/ipc/producer/producer_ipc_client_impl.h
@@ -74,7 +74,8 @@
void ActivateTriggers(const std::vector<std::string>&) override;
std::unique_ptr<TraceWriter> CreateTraceWriter(
- BufferID target_buffer) override;
+ BufferID target_buffer,
+ BufferExhaustedPolicy) override;
SharedMemoryArbiter* GetInProcessShmemArbiter() override;
void NotifyFlushComplete(FlushRequestID) override;
SharedMemory* shared_memory() const override;
diff --git a/src/tracing/ipc/service/producer_ipc_service.cc b/src/tracing/ipc/service/producer_ipc_service.cc
index 99b51dd..96acf71 100644
--- a/src/tracing/ipc/service/producer_ipc_service.cc
+++ b/src/tracing/ipc/service/producer_ipc_service.cc
@@ -78,6 +78,21 @@
break;
}
+ bool dcheck_mismatch = false;
+#if PERFETTO_DCHECK_IS_ON()
+ dcheck_mismatch =
+ req.build_flags() ==
+ protos::InitializeConnectionRequest::BUILD_FLAGS_DCHECKS_OFF;
+#else
+ dcheck_mismatch = req.build_flags() ==
+ protos::InitializeConnectionRequest::BUILD_FLAGS_DCHECKS_ON;
+#endif
+ if (dcheck_mismatch) {
+ PERFETTO_LOG(
+ "The producer and the service binaries are built using different "
+ "DEBUG/NDEBUG flags. This will likely cause crashes.");
+ }
+
// ConnectProducer will call OnConnect() on the next task.
producer->service_endpoint = core_service_->ConnectProducer(
producer.get(), client_info.uid(), req.producer_name(),
@@ -86,8 +101,10 @@
req.shared_memory_page_size_hint_bytes());
// Could happen if the service has too many producers connected.
- if (!producer->service_endpoint)
+ if (!producer->service_endpoint) {
response.Reject();
+ return;
+ }
producers_.emplace(ipc_client_id, std::move(producer));
// Because of the std::move() |producer| is invalid after this point.
diff --git a/src/tracing/test/fake_producer_endpoint.h b/src/tracing/test/fake_producer_endpoint.h
index f6fb5b9..fc364cf 100644
--- a/src/tracing/test/fake_producer_endpoint.h
+++ b/src/tracing/test/fake_producer_endpoint.h
@@ -39,7 +39,9 @@
void ActivateTriggers(const std::vector<std::string>&) override {}
SharedMemory* shared_memory() const override { return nullptr; }
size_t shared_buffer_page_size_kb() const override { return 0; }
- std::unique_ptr<TraceWriter> CreateTraceWriter(BufferID) override {
+ std::unique_ptr<TraceWriter> CreateTraceWriter(
+ BufferID,
+ BufferExhaustedPolicy) override {
return nullptr;
}
SharedMemoryArbiter* GetInProcessShmemArbiter() override { return nullptr; }
diff --git a/test/ci/fuzzer_tests.sh b/test/ci/fuzzer_tests.sh
index b569ee9..6736857 100755
--- a/test/ci/fuzzer_tests.sh
+++ b/test/ci/fuzzer_tests.sh
@@ -29,6 +29,9 @@
tools/gn gen ${OUT_PATH} --args="${PERFETTO_TEST_GN_ARGS}" --check
tools/ninja -C ${OUT_PATH} ${PERFETTO_TEST_NINJA_ARGS} fuzzers
+# Check the amalgamated build here to avoid slowing down all the Linux bots.
+tools/test_gen_amalgamated.py
+
# Run a single iteration each to make sure they are not crashing.
for fuzzer in $(find ${OUT_PATH} -name '*_fuzzer' -executable); do
$fuzzer -runs=1
diff --git a/test/ci/linux_tests.sh b/test/ci/linux_tests.sh
index 4c293f9..c610844 100755
--- a/test/ci/linux_tests.sh
+++ b/test/ci/linux_tests.sh
@@ -35,8 +35,13 @@
${OUT_PATH}/perfetto_integrationtests
BENCHMARK_FUNCTIONAL_TEST_ONLY=true ${OUT_PATH}/perfetto_benchmarks
+mkdir -p /ci/artifacts/perf-test-metrics.tmp
tools/diff_test_trace_processor.py \
- --test-type=queries ${OUT_PATH}/trace_processor_shell
-
+ --test-type=queries \
+ --perf-file=/ci/artifacts/perf-test-metrics.tmp/tp-perf-queries.json \
+ ${OUT_PATH}/trace_processor_shell
tools/diff_test_trace_processor.py \
- --test-type=metrics ${OUT_PATH}/trace_processor_shell
+ --test-type=metrics \
+ --perf-file=/ci/artifacts/perf-test-metrics.tmp/tp-perf-metrics.json \
+ ${OUT_PATH}/trace_processor_shell
+mv /ci/artifacts/perf-test-metrics.tmp /ci/artifacts/perf-test-metrics
\ No newline at end of file
diff --git a/test/metrics/android_mem_counters.out b/test/metrics/android_mem_counters.out
index 7469f1f..c729120 100644
--- a/test/metrics/android_mem_counters.out
+++ b/test/metrics/android_mem_counters.out
@@ -2347,6 +2347,11 @@
max: 32796672
avg: 32765771.09452733
}
+ java_heap {
+ min: 1374208
+ max: 1427456
+ avg: 1419596.8920014114
+ }
}
}
process_metrics {
@@ -2372,6 +2377,11 @@
max: 31100928
avg: 30828073.014492534
}
+ java_heap {
+ min: 1193984
+ max: 1193984
+ avg: 1193984
+ }
}
}
process_metrics {
@@ -2397,6 +2407,11 @@
max: 38170624
avg: 37379428.70679906
}
+ java_heap {
+ min: 1499136
+ max: 4316160
+ avg: 2972808.7655181894
+ }
}
}
process_metrics {
@@ -2447,6 +2462,11 @@
max: 43556864
avg: 37778954.5579197
}
+ java_heap {
+ min: 3152896
+ max: 7367680
+ avg: 5624331.5376309063
+ }
}
}
process_metrics {
@@ -2522,6 +2542,11 @@
max: 32333824
avg: 32312115.023602
}
+ java_heap {
+ min: 1345536
+ max: 1395712
+ avg: 1378703.0378377116
+ }
}
}
process_metrics {
@@ -2572,6 +2597,11 @@
max: 51023872
avg: 50602448.04672049
}
+ java_heap {
+ min: 2658304
+ max: 3159040
+ avg: 2933014.4999347096
+ }
}
}
process_metrics {
@@ -2597,6 +2627,11 @@
max: 39768064
avg: 38817213.791344121
}
+ java_heap {
+ min: 1519616
+ max: 4826112
+ avg: 2558538.0852529262
+ }
}
}
process_metrics {
@@ -2647,6 +2682,11 @@
max: 36679680
avg: 36364002.255620666
}
+ java_heap {
+ min: 3202048
+ max: 4088832
+ avg: 4043650.9270121339
+ }
}
}
process_metrics {
@@ -2672,6 +2712,11 @@
max: 35635200
avg: 35418527.859008193
}
+ java_heap {
+ min: 3026944
+ max: 3207168
+ avg: 3204534.0849129637
+ }
}
}
process_metrics {
@@ -2822,6 +2867,11 @@
max: 71012352
avg: 68351542.715876162
}
+ java_heap {
+ min: 6224896
+ max: 10747904
+ avg: 6949136.10971856
+ }
}
}
process_metrics {
@@ -2997,6 +3047,11 @@
max: 82853888
avg: 68519057.186817423
}
+ java_heap {
+ min: 8163328
+ max: 14021632
+ avg: 11450919.918936323
+ }
}
}
process_metrics {
diff --git a/test/trace_processor/compressed_smoke.out b/test/trace_processor/compressed_smoke.out
new file mode 100644
index 0000000..422aaec
--- /dev/null
+++ b/test/trace_processor/compressed_smoke.out
@@ -0,0 +1,11 @@
+"ts","cpu","dur","end_state","priority","tid"
+170601497673450,2,53646,"DK",120,6790
+170601497691210,7,22917,"R",120,0
+170601497714127,7,29167,"D",120,6732
+170601497727096,2,55156,"S",120,62
+170601497743294,7,862656,"R",120,0
+170601497766106,3,13594,"S",120,8
+170601497779700,3,31094,"D",120,6790
+170601497782252,2,875313,"R",120,0
+170601497810794,3,824635,"R",120,0
+170601498605950,7,158333,"D",120,6732
diff --git a/test/trace_processor/index b/test/trace_processor/index
index f4a1805..5b0e49d 100644
--- a/test/trace_processor/index
+++ b/test/trace_processor/index
@@ -2,6 +2,7 @@
../data/sfgate.json smoke.sql sfgate_smoke.out
../data/sfgate.json smoke_slices.sql sfgate_smoke_slices.out
../data/android_sched_and_ps.pb smoke.sql android_sched_and_ps_smoke.out
+../data/compressed.pb smoke.sql compressed_smoke.out
synth_1.py smoke.sql synth_1_smoke.out
../data/fuchsia_trace.fxt smoke.sql fuchsia_smoke.out
../data/fuchsia_trace.fxt smoke_slices.sql fuchsia_smoke_slices.out
diff --git a/tools/diff_test_trace_processor.py b/tools/diff_test_trace_processor.py
index 251de30..627bc7d 100755
--- a/tools/diff_test_trace_processor.py
+++ b/tools/diff_test_trace_processor.py
@@ -23,11 +23,19 @@
import sys
import tempfile
+from itertools import chain
from google.protobuf import descriptor, descriptor_pb2, message_factory
from google.protobuf import reflection, text_format
ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+class PerfResult(object):
+ def __init__(self, trace_name, query_or_metric, ingest_time, real_time):
+ self.trace_name = trace_name
+ self.query_or_metric = query_or_metric
+ self.ingest_time = ingest_time
+ self.real_time = real_time
+
def create_metrics_message_factory(metrics_descriptor_path):
with open(metrics_descriptor_path, 'r') as metrics_descriptor_file:
metrics_descriptor_content = metrics_descriptor_file.read()
@@ -218,8 +226,9 @@
trace_shortpath = os.path.relpath(trace_path, test_dir)
assert len(perf_numbers) == 2
- perf_data.append((trace_shortpath, query_fname_or_metric,
- perf_numbers[0], perf_numbers[1]))
+ perf_result = PerfResult(trace_shortpath, query_fname_or_metric,
+ perf_numbers[0], perf_numbers[1])
+ perf_data.append(perf_result)
else:
sys.stderr.write(
'Expected did not match actual for trace {} and {} {}\n'
@@ -235,19 +244,35 @@
print('All tests passed successfully')
if args.perf_file:
- output_data = {
- 'benchmarks': [
+ metrics = [
+ [
{
- 'name': '{}|{}'.format(perf_args[0], perf_args[1]),
- 'trace_name': perf_args[0],
- 'query_name': perf_args[1],
- 'ingest_time': perf_args[2],
- 'real_time': perf_args[3],
- 'time_unit': 'ns',
- 'test_type': args.test_type,
+ 'metric': 'tp_perf_test_ingest_time',
+ 'value': float(perf_args.ingest_time) / 1.0e9,
+ 'unit': 's',
+ 'tags': {
+ 'test_name': '{}-{}'.format(perf_args.trace_name,
+ perf_args.query_or_metric),
+ 'test_type': args.test_type,
+ },
+ 'labels': {},
+ },
+ {
+ 'metric': 'perf_test_real_time',
+ 'value': float(perf_args.real_time) / 1.0e9,
+ 'unit': 's',
+ 'tags': {
+ 'test_name': '{}-{}'.format(perf_args.trace_name,
+ perf_args.query_or_metric),
+ 'test_type': args.test_type,
+ },
+ 'labels': {},
}
- for perf_args in sorted(perf_data)
]
+ for perf_args in sorted(perf_data)
+ ]
+ output_data = {
+ 'metrics': list(chain.from_iterable(metrics))
}
with open(args.perf_file, 'w+') as perf_file:
perf_file.write(json.dumps(output_data, indent=2))
diff --git a/tools/gen_all b/tools/gen_all
index dc5021c..3b50478 100755
--- a/tools/gen_all
+++ b/tools/gen_all
@@ -29,7 +29,7 @@
def call(cmd, *args):
path = os.path.join('tools', cmd)
command = [path] + list(args)
- print 'Running ', ' '.join(command)
+ print 'Running', ' '.join(command)
try:
subprocess.check_call(command, cwd=ROOT_DIR)
except subprocess.CalledProcessError as e:
@@ -51,7 +51,6 @@
call('gen_merged_protos')
call('gen_binary_descriptors', '--protoc', protoc_path(out))
call('gen_tracing_cpp_headers_from_protos', out)
- call('gen_amalgamated', '--check', '--quiet') # Keep last
except AssertionError as e:
if not str(e):
diff --git a/tools/gen_amalgamated b/tools/gen_amalgamated
index ce9ce82..57eed7c 100755
--- a/tools/gen_amalgamated
+++ b/tools/gen_amalgamated
@@ -181,13 +181,16 @@
class AmalgamatedProject(object):
"""In-memory representation of an amalgamated source/header pair."""
- def __init__(self, desc, source_deps):
+ def __init__(self, desc, source_deps, compute_deps_only=False):
"""Constructor.
Args:
desc: JSON build description.
source_deps: A map of (source file, [dependency header]) which is
to detect which header files are included by each source file.
+ compute_deps_only: If True, the project will only be used to compute
+ dependency information. Use |get_source_files()| to retrieve
+ the result.
"""
self.desc = desc
self.source_deps = source_deps
@@ -204,6 +207,7 @@
self._processed_headers = set()
self._processed_source_headers = set() # Header files included from .cc
self._include_re = re.compile(r'#include "(.*)"')
+ self._compute_deps_only = compute_deps_only
def add_target(self, target_name):
"""Include |target_name| in the amalgamated result."""
@@ -309,6 +313,8 @@
self._process_source_includes(
include_dirs, allowed_files, f))
return
+ if self._compute_deps_only:
+ return
msg = 'Looked in %s' % ', '.join('"%s"' % d for d in include_dirs)
raise Error('Header file %s not found. %s' % (header_name, msg))
@@ -343,6 +349,8 @@
self.header.extend(
self._process_header_includes(include_dirs, f))
return
+ if self._compute_deps_only:
+ return
msg = 'Looked in %s' % ', '.join('"%s"' % d for d in include_dirs)
raise Error('Header file %s not found. %s' % (header_name, msg))
@@ -352,6 +360,8 @@
self._processed_headers.add(header_name)
include_dirs = self._get_include_dirs(target_name)
if not os.path.exists(header_name):
+ if self._compute_deps_only:
+ return
raise Error('Header file %s not found' % source_name)
with open(header_name) as f:
self.header.append(
@@ -411,6 +421,7 @@
Call save() to persist the result.
"""
+ assert not self._compute_deps_only
self.source_defines.append('// %s: predefined macros' % tool_name)
def add_define(name):
# Valued macros aren't supported for now.
@@ -420,7 +431,13 @@
self.source_defines.append('#endif')
for name in self.defines:
add_define(name)
+ for target_name, source_name in self.get_source_files():
+ self._add_source(target_name, source_name)
+ def get_source_files(self):
+ """Return a list of (target, [source file]) that describes the source
+ files pulled in by each target which is a dependency of this project.
+ """
source_files = []
for node in self._dependency_tree.iterate_depth_first():
target = self.desc[node.target_name]
@@ -429,8 +446,7 @@
sources = [(node.target_name, gn_utils.label_to_path(s))
for s in target['sources'] if s.endswith('.cc')]
source_files.extend(sources)
- for target_name, source_name in source_files:
- self._add_source(target_name, source_name)
+ return source_files
def _get_nice_path(self, prefix, format):
basename = os.path.basename(prefix)
@@ -477,16 +493,6 @@
return build_cmd
-
-def create_amalgamated_project_for_targets(desc, targets, source_deps):
- """Generate an amalgamated project for a list of GN targets."""
- project = AmalgamatedProject(desc, source_deps)
- for target in targets:
- project.add_target(target)
- project.generate()
- return project
-
-
def main():
parser = argparse.ArgumentParser(
description='Generate an amalgamated header/source pair from a GN '
@@ -510,6 +516,10 @@
parser.add_argument('--quiet', help='Only report errors',
action='store_true')
parser.add_argument(
+ '--dump-deps',
+ help='List all source files that the amalgamated output depends on',
+ action='store_true')
+ parser.add_argument(
'targets',
nargs=argparse.REMAINDER,
help='Targets to include in the output (e.g., "//:libperfetto")')
@@ -526,12 +536,26 @@
out = gn_utils.prepare_out_directory(
args.gn_args, 'tmp.gen_amalgamated')
desc = gn_utils.load_build_description(out)
+
# We need to build everything first so that the necessary header
- # dependencies get generated.
- gn_utils.build_targets(out, targets)
+ # dependencies get generated. However if we are just dumping dependency
+ # information this can be skipped, allowing cross-platform operation.
+ if not args.dump_deps:
+ gn_utils.build_targets(out, targets)
source_deps = gn_utils.compute_source_dependencies(out)
- project = create_amalgamated_project_for_targets(
- desc, targets, source_deps)
+ project = AmalgamatedProject(
+ desc, source_deps, compute_deps_only=args.dump_deps)
+
+ for target in targets:
+ project.add_target(target)
+
+ if args.dump_deps:
+ source_files = [
+ source_file for _, source_file in project.get_source_files()]
+ print('\n'.join(sorted(set(source_files))))
+ return
+
+ project.generate()
result = project.save(output)
if not args.quiet:
print(result)
diff --git a/tools/gen_merged_protos b/tools/gen_merged_protos
index d187e13..74f6d53 100755
--- a/tools/gen_merged_protos
+++ b/tools/gen_merged_protos
@@ -46,6 +46,7 @@
TRACE_PROTOS = (
'protos/perfetto/common/trace_stats.proto', # only referenced by trace protos
'protos/perfetto/trace/android/android_log.proto',
+ 'protos/perfetto/trace/android/graphics_frame_event.proto',
'protos/perfetto/trace/android/packages_list.proto',
'protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto',
"protos/perfetto/trace/chrome/chrome_metadata.proto",
@@ -85,6 +86,7 @@
'protos/perfetto/trace/system_info.proto',
'protos/perfetto/trace/trace.proto',
'protos/perfetto/trace/trace_packet.proto',
+ 'protos/perfetto/trace/trace_packet_defaults.proto',
'protos/perfetto/trace/track_event/debug_annotation.proto',
'protos/perfetto/trace/track_event/log_message.proto',
'protos/perfetto/trace/track_event/process_descriptor.proto',
diff --git a/tools/heap_profile b/tools/heap_profile
index 5fc693e..3938b64 100755
--- a/tools/heap_profile
+++ b/tools/heap_profile
@@ -30,8 +30,8 @@
import urllib
TRACE_TO_TEXT_SHAS = {
- 'linux': 'b91fd044422c5276f314728dca52a1d1cf43df69',
- 'mac': 'd00c9ba443c93c18ed9e712d3e699ddda72a8bd8',
+ 'linux': '74cb40d9413d7ad756e327e09e46a8adde90db92',
+ 'mac': '47045bc6abd4f9113969211f37fdd2259b0c1cc3',
}
TRACE_TO_TEXT_PATH = tempfile.gettempdir()
TRACE_TO_TEXT_BASE_URL = (
diff --git a/tools/install-build-deps b/tools/install-build-deps
index 9ad78b3..e66cdff 100755
--- a/tools/install-build-deps
+++ b/tools/install-build-deps
@@ -195,8 +195,8 @@
# Example traces for regression tests.
('buildtools/test_data.zip',
- 'https://storage.googleapis.com/perfetto/test-data-20190710-183108.zip',
- 'a37e5e7153ae5f0ade0a413add1404b184c57fcc',
+ 'https://storage.googleapis.com/perfetto/test-data-20190807-125643.zip',
+ 'abd9bc3e9f9e74ec6810b5c9bd1f15713a9a58ec',
'all',
),
diff --git a/tools/test_gen_amalgamated.py b/tools/test_gen_amalgamated.py
new file mode 100755
index 0000000..1a43d67
--- /dev/null
+++ b/tools/test_gen_amalgamated.py
@@ -0,0 +1,56 @@
+#!/usr/bin/env python
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+import subprocess
+
+ROOT_DIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
+
+
+def call(cmd, *args):
+ path = os.path.join('tools', cmd)
+ command = [path] + list(args)
+ print 'Running', ' '.join(command)
+ try:
+ return subprocess.check_output(command, cwd=ROOT_DIR)
+ except subprocess.CalledProcessError as e:
+ assert False, 'Command: {} failed'.format(' '.join(command))
+
+
+def check_amalgamated_output():
+ call('gen_amalgamated', '--check', '--quiet')
+
+
+def check_amalgamated_dependencies():
+ os_deps = {}
+ for os_name in ['android', 'linux', 'mac']:
+ os_deps[os_name] = call(
+ 'gen_amalgamated', '--gn_args', 'target_os="%s"' % os_name,
+ '--dump-deps', '--quiet').split('\n')
+ for os_name, deps in os_deps.items():
+ for dep in deps:
+ for other_os, other_deps in os_deps.items():
+ if not dep in other_deps:
+ raise AssertionError('Discrepancy in amalgamated build dependencies: '
+ '%s is missing on %s.' % (dep, other_os))
+
+
+def main():
+ check_amalgamated_output()
+ check_amalgamated_dependencies()
+
+
+if __name__ == '__main__':
+ exit(main())
diff --git a/tools/trace_to_text/main.cc b/tools/trace_to_text/main.cc
index b26fc97..d098e45 100644
--- a/tools/trace_to_text/main.cc
+++ b/tools/trace_to_text/main.cc
@@ -35,7 +35,7 @@
int Usage(const char* argv0) {
printf(
- "Usage: %s systrace|json|text|profile [--truncate] [trace.pb] "
+ "Usage: %s systrace|json|text|profile [--truncate start|end] [trace.pb] "
"[trace.txt]\n",
argv0);
return 1;
@@ -44,17 +44,26 @@
} // namespace
int main(int argc, char** argv) {
- uint64_t file_size_limit = std::numeric_limits<uint64_t>::max();
std::vector<const char*> positional_args;
- bool should_truncate_trace = false;
+ perfetto::trace_to_text::Keep truncate_keep =
+ perfetto::trace_to_text::Keep::kAll;
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0) {
printf("%s\n", PERFETTO_GET_GIT_REVISION());
return 0;
} else if (strcmp(argv[i], "-t") == 0 ||
strcmp(argv[i], "--truncate") == 0) {
- should_truncate_trace = true;
- file_size_limit = 1024u * 1024u * 50u;
+ i++;
+ if (i <= argc && strcmp(argv[i], "start") == 0) {
+ truncate_keep = perfetto::trace_to_text::Keep::kStart;
+ } else if (i <= argc && strcmp(argv[i], "end") == 0) {
+ truncate_keep = perfetto::trace_to_text::Keep::kEnd;
+ } else {
+ PERFETTO_ELOG(
+ "--truncate must specify whether to keep the end or the "
+ "start of the trace.");
+ return Usage(argv[0]);
+ }
} else {
positional_args.push_back(argv[i]);
}
@@ -97,13 +106,13 @@
if (format == "json")
return perfetto::trace_to_text::TraceToSystrace(input_stream, output_stream,
- file_size_limit,
+ truncate_keep,
/*wrap_in_json=*/true);
if (format == "systrace")
return perfetto::trace_to_text::TraceToSystrace(input_stream, output_stream,
- file_size_limit,
+ truncate_keep,
/*wrap_in_json=*/false);
- if (should_truncate_trace) {
+ if (truncate_keep != perfetto::trace_to_text::Keep::kAll) {
PERFETTO_ELOG(
"--truncate is unsupported for text|profile|symbolize format.");
return 1;
diff --git a/tools/trace_to_text/trace_symbol_table.cc b/tools/trace_to_text/trace_symbol_table.cc
index e1ea600..1767cad 100644
--- a/tools/trace_to_text/trace_symbol_table.cc
+++ b/tools/trace_to_text/trace_symbol_table.cc
@@ -22,7 +22,6 @@
#include <string>
#include <vector>
-#include <elf.h>
#include <inttypes.h>
#include <sys/mman.h>
#include <sys/stat.h>
diff --git a/tools/trace_to_text/trace_to_profile.cc b/tools/trace_to_text/trace_to_profile.cc
index a4c5b14..cb34eca 100644
--- a/tools/trace_to_text/trace_to_profile.cc
+++ b/tools/trace_to_text/trace_to_profile.cc
@@ -23,6 +23,7 @@
#include "tools/trace_to_text/local_symbolizer.h" // nogncheck
#endif
#include "tools/trace_to_text/pprof_builder.h"
+#include "tools/trace_to_text/symbolizer.h"
#include "tools/trace_to_text/utils.h"
#include "perfetto/base/logging.h"
diff --git a/tools/trace_to_text/trace_to_systrace.cc b/tools/trace_to_text/trace_to_systrace.cc
index 820ce69..e67ef09 100644
--- a/tools/trace_to_text/trace_to_systrace.cc
+++ b/tools/trace_to_text/trace_to_systrace.cc
@@ -174,7 +174,7 @@
int TraceToSystrace(std::istream* input,
std::ostream* output,
- uint64_t file_size_limit,
+ Keep truncate_keep,
bool wrap_in_json) {
trace_processor::Config config;
std::unique_ptr<trace_processor::TraceProcessor> tp =
@@ -192,7 +192,7 @@
#endif
uint64_t file_size = 0;
- for (int i = 0; file_size < file_size_limit; i++) {
+ for (int i = 0;; i++) {
if (i % kStderrRate == 0) {
fprintf(stderr, "Loading trace %.2f MB" PROGRESS_CHAR, file_size / 1.0e6);
fflush(stderr);
@@ -269,7 +269,14 @@
fprintf(stderr, "Converting trace events" PROGRESS_CHAR);
fflush(stderr);
- static const char kRawSql[] = "select to_ftrace(id) from raw";
+ static const char kEstimatSql[] = "select count(1) from raw";
+ uint32_t raw_events = 0;
+ auto e_callback = [&raw_events](Iterator* it, base::StringWriter*) {
+ raw_events = static_cast<uint32_t>(it->Get(0).long_value);
+ };
+ if (!q_writer.RunQuery(kEstimatSql, e_callback))
+ return 1;
+
auto raw_callback = [wrap_in_json](Iterator* it, base::StringWriter* writer) {
const char* line = it->Get(0 /* col */).string_value;
if (wrap_in_json) {
@@ -309,8 +316,30 @@
writer->AppendChar('\n');
}
};
- if (!q_writer.RunQuery(kRawSql, raw_callback))
- return 1;
+
+ // An estimate of 130b per ftrace event, allowing some space for the processes
+ // and threads.
+ const uint32_t max_ftrace_events = (140 * 1024 * 1024) / 130;
+
+ char kEndTrunc[100];
+ sprintf(kEndTrunc,
+ "select to_ftrace(id) from raw limit %d "
+ "offset %d",
+ max_ftrace_events, raw_events - max_ftrace_events);
+ char kStartTruncate[100];
+ sprintf(kStartTruncate, "select to_ftrace(id) from raw limit %d",
+ max_ftrace_events);
+
+ if (truncate_keep == Keep::kEnd && raw_events > max_ftrace_events) {
+ if (!q_writer.RunQuery(kEndTrunc, raw_callback))
+ return 1;
+ } else if (truncate_keep == Keep::kStart) {
+ if (!q_writer.RunQuery(kStartTruncate, raw_callback))
+ return 1;
+ } else {
+ if (!q_writer.RunQuery("select to_ftrace(id) from raw", raw_callback))
+ return 1;
+ }
if (wrap_in_json)
*output << kTraceFooter;
diff --git a/tools/trace_to_text/trace_to_systrace.h b/tools/trace_to_text/trace_to_systrace.h
index 366d10c..c1c4659 100644
--- a/tools/trace_to_text/trace_to_systrace.h
+++ b/tools/trace_to_text/trace_to_systrace.h
@@ -22,9 +22,11 @@
namespace perfetto {
namespace trace_to_text {
+enum class Keep { kStart = 0, kEnd, kAll };
+
int TraceToSystrace(std::istream* input,
std::ostream* output,
- uint64_t file_size_limit,
+ Keep truncate_keep,
bool wrap_in_json);
} // namespace trace_to_text
diff --git a/ui/BUILD.gn b/ui/BUILD.gn
index f4ba00b..2641265 100644
--- a/ui/BUILD.gn
+++ b/ui/BUILD.gn
@@ -291,6 +291,7 @@
"src/assets/topbar.scss",
"src/assets/record.scss",
"src/assets/common.scss",
+ "src/assets/modal.scss",
]
# Build css.
diff --git a/ui/index.html b/ui/index.html
index ad3d369..c375f93 100644
--- a/ui/index.html
+++ b/ui/index.html
@@ -10,7 +10,10 @@
<link rel="preload" href="trace_processor.wasm" as="fetch">
</head>
<body>
- <div class="full-page-loading-screen"></div>
+ <main>
+ <div class="full-page-loading-screen"></div>
+ </main>
+ <div id="main-modal" aria-hidden="true" class="modal micromodal-slide"></div>
</body>
</html>
<script src="frontend_bundle.js"></script>
diff --git a/ui/package-lock.json b/ui/package-lock.json
index c92b6a2..1d3b02d 100644
--- a/ui/package-lock.json
+++ b/ui/package-lock.json
@@ -2288,6 +2288,11 @@
"integrity": "sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg=",
"dev": true
},
+ "events": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz",
+ "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA=="
+ },
"exec-sh": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.2.2.tgz",
@@ -2603,7 +2608,8 @@
"ansi-regex": {
"version": "2.1.1",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"aproba": {
"version": "1.2.0",
@@ -2624,12 +2630,14 @@
"balanced-match": {
"version": "1.0.0",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -2644,17 +2652,20 @@
"code-point-at": {
"version": "1.1.0",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"core-util-is": {
"version": "1.0.2",
@@ -2771,7 +2782,8 @@
"inherits": {
"version": "2.0.3",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"ini": {
"version": "1.3.5",
@@ -2783,6 +2795,7 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@@ -2797,6 +2810,7 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@@ -2804,12 +2818,14 @@
"minimist": {
"version": "0.0.8",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"minipass": {
"version": "2.3.5",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@@ -2828,6 +2844,7 @@
"version": "0.5.1",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"minimist": "0.0.8"
}
@@ -2908,7 +2925,8 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"object-assign": {
"version": "4.1.1",
@@ -2920,6 +2938,7 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"wrappy": "1"
}
@@ -3005,7 +3024,8 @@
"safe-buffer": {
"version": "5.1.2",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"safer-buffer": {
"version": "2.1.2",
@@ -3041,6 +3061,7 @@
"version": "1.0.2",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -3060,6 +3081,7 @@
"version": "3.0.1",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@@ -3103,12 +3125,14 @@
"wrappy": {
"version": "1.0.2",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"yallist": {
"version": "3.0.3",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
}
}
},
@@ -4875,6 +4899,11 @@
"regex-cache": "^0.4.2"
}
},
+ "micromodal": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/micromodal/-/micromodal-0.4.0.tgz",
+ "integrity": "sha512-YDku9Fi57S4Sm6oitSy3sr786qSp5L6NbatuH2kEeXf0jStvZgZk4bLBKaoSONBaq3BEvFz3hAaoUa7/pV1Kgg=="
+ },
"mime": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
@@ -5160,6 +5189,11 @@
}
}
},
+ "noice-json-rpc": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/noice-json-rpc/-/noice-json-rpc-1.2.0.tgz",
+ "integrity": "sha512-Wm+otW+drKzdqlSPoSwj34tUEq/Xj1gX6Cr2avrykvTW4IY7d3ngLmP+PErALzS0s9nYRokXvYDM54sbFvLlDA=="
+ },
"nopt": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
@@ -6437,26 +6471,26 @@
}
},
"rollup": {
- "version": "1.12.2",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.12.2.tgz",
- "integrity": "sha512-ePehZfVMIE4eO0/LV6VaMY8kp0D9sbziUabpBeJbHAHa2WJPxuS0lYLmiLamb02e098RIRyq1F2yjM4O08dQVA==",
+ "version": "1.17.0",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.17.0.tgz",
+ "integrity": "sha512-k/j1m0NIsI4SYgCJR4MWPstGJOWfJyd6gycKoMhyoKPVXxm+L49XtbUwZyFsrSU2YXsOkM4u1ll9CS/ZgJBUpw==",
"dev": true,
"requires": {
"@types/estree": "0.0.39",
- "@types/node": "^12.0.2",
- "acorn": "^6.1.1"
+ "@types/node": "^12.6.2",
+ "acorn": "^6.2.0"
},
"dependencies": {
"@types/node": {
- "version": "12.0.2",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.2.tgz",
- "integrity": "sha512-5tabW/i+9mhrfEOUcLDu2xBPsHJ+X5Orqy9FKpale3SjDA17j5AEpYq5vfy3oAeAHGcvANRCO3NV3d2D6q3NiA==",
+ "version": "12.6.8",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-12.6.8.tgz",
+ "integrity": "sha512-aX+gFgA5GHcDi89KG5keey2zf0WfZk/HAQotEamsK2kbey+8yGKcson0hbK8E+v0NArlCJQCqMP161YhV6ZXLg==",
"dev": true
},
"acorn": {
- "version": "6.1.1",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz",
- "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==",
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.2.1.tgz",
+ "integrity": "sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q==",
"dev": true
}
}
diff --git a/ui/package.json b/ui/package.json
index 30b66cf..c1f09a8 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -18,8 +18,11 @@
"@types/uuid": "^3.4.4",
"color-convert": "^2.0.0",
"devtools-protocol": "0.0.681549",
+ "events": "^3.0.0",
"immer": "^1.12.1",
+ "micromodal": "^0.4.0",
"mithril": "^1.1.6",
+ "noice-json-rpc": "^1.2.0",
"pako": "^1.0.10",
"protobufjs": "^6.8.8",
"uuid": "^3.3.2"
@@ -32,7 +35,7 @@
"lite-server": "^2.4.0",
"node-sass": "^4.12.0",
"puppeteer": "^1.16.0",
- "rollup": "^1.12.2",
+ "rollup": "^1.17.0",
"rollup-plugin-commonjs": "^9.3.4",
"rollup-plugin-node-resolve": "^4.2.4",
"sorcery": "^0.10.0",
diff --git a/ui/rollup.config.js b/ui/rollup.config.js
index 3cd838c..e4795c4 100644
--- a/ui/rollup.config.js
+++ b/ui/rollup.config.js
@@ -8,6 +8,7 @@
nodeResolve({
mainFields: ['browser'],
browser: true,
+ preferBuiltins: false,
}),
// emscripten conditionally executes require('fs') (likewise for
@@ -21,5 +22,5 @@
'crypto',
]
}),
- ]
+ ],
}
diff --git a/ui/src/assets/common.scss b/ui/src/assets/common.scss
index 061d3dd..fb9f3ba 100644
--- a/ui/src/assets/common.scss
+++ b/ui/src/assets/common.scss
@@ -65,7 +65,8 @@
}
html,
-body {
+body,
+body>main {
height: 100%;
width: 100%;
padding: 0;
@@ -86,13 +87,13 @@
user-select: text;
}
-body {
+body>main {
display: grid;
grid-template-areas:
"sidebar topbar"
"sidebar alerts"
"sidebar page";
- grid-template-rows: var(--topbar-height) auto 1fr;
+ grid-template-rows: auto auto 1fr;
grid-template-columns: auto 1fr;
color: #121212;
}
diff --git a/ui/src/assets/modal.scss b/ui/src/assets/modal.scss
new file mode 100644
index 0000000..8879e18
--- /dev/null
+++ b/ui/src/assets/modal.scss
@@ -0,0 +1,169 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**************************\
+ Basic Modal Styles
+\**************************/
+.modal {
+ font-family: 'Raleway';
+}
+
+.modal-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: rgba(0,0,0,0.6);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ z-index: 4;
+}
+
+.modal-container {
+ background-color: #fff;
+ padding: 30px;
+ max-width: 550px;
+ max-height: 100vh;
+ border-radius: 4px;
+ overflow-y: auto;
+ box-sizing: border-box;
+}
+
+.modal-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+
+.modal-title {
+ margin-top: 0;
+ margin-bottom: 0;
+ font-family: 'Raleway';
+ font-weight: 600;
+ font-size: 1.25rem;
+ line-height: 1.25;
+ color: #262f3c;
+ box-sizing: border-box;
+}
+
+.modal-close {
+ background: transparent;
+ border: 0;
+}
+
+.modal-header .modal-close:before { content: "\2715"; }
+
+.modal-content {
+ margin-top: 2rem;
+ margin-bottom: 2rem;
+ line-height: 1.5;
+ color: rgba(0,0,0,.8);
+}
+
+.modal-btn {
+ font-size: .875rem;
+ padding-left: 1rem;
+ padding-right: 1rem;
+ padding-top: .5rem;
+ padding-bottom: .5rem;
+ background-color: #e6e6e6;
+ color: rgba(0,0,0,.8);
+ border-radius: .25rem;
+ border-style: none;
+ border-width: 0;
+ cursor: pointer;
+ -webkit-appearance: button;
+ text-transform: none;
+ overflow: visible;
+ line-height: 1.15;
+ margin: 5px;
+ will-change: transform;
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-backface-visibility: hidden;
+ backface-visibility: hidden;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ transition: -webkit-transform .25s ease-out;
+ transition: transform .25s ease-out;
+ transition: transform .25s ease-out,-webkit-transform .25s ease-out;
+}
+
+.modal-btn:focus, .modal-btn:hover {
+ -webkit-transform: scale(1.05);
+ transform: scale(1.05);
+}
+
+.modal-btn-primary {
+ background-color: #262f3c;
+ color: #fff;
+}
+
+.modal-footer {
+ display: flex;
+ justify-content: space-around;
+}
+
+/**************************\
+ Demo Animation Style
+\**************************/
+@keyframes mmfadeIn {
+ from { opacity: 0; }
+ to { opacity: 1; }
+}
+
+@keyframes mmfadeOut {
+ from { opacity: 1; }
+ to { opacity: 0; }
+}
+
+@keyframes mmslideIn {
+ from { transform: translateY(15%); }
+ to { transform: translateY(0); }
+}
+
+@keyframes mmslideOut {
+ from { transform: translateY(0); }
+ to { transform: translateY(-10%); }
+}
+
+.micromodal-slide {
+ display: none;
+}
+
+.micromodal-slide.is-open {
+ display: block;
+}
+
+.micromodal-slide[aria-hidden="false"] .modal-overlay {
+ animation: mmfadeIn .3s cubic-bezier(0.0, 0.0, 0.2, 1);
+}
+
+.micromodal-slide[aria-hidden="false"] .modal-container {
+ animation: mmslideIn .3s cubic-bezier(0, 0, .2, 1);
+}
+
+.micromodal-slide[aria-hidden="true"] .modal-overlay {
+ animation: mmfadeOut .3s cubic-bezier(0.0, 0.0, 0.2, 1);
+}
+
+.micromodal-slide[aria-hidden="true"] .modal-container {
+ animation: mmslideOut .3s cubic-bezier(0, 0, .2, 1);
+}
+
+.micromodal-slide .modal-container,
+.micromodal-slide .modal-overlay {
+ will-change: transform;
+}
\ No newline at end of file
diff --git a/ui/src/assets/perfetto.scss b/ui/src/assets/perfetto.scss
index 059a98a..ca03a81 100644
--- a/ui/src/assets/perfetto.scss
+++ b/ui/src/assets/perfetto.scss
@@ -17,3 +17,4 @@
@import 'sidebar';
@import 'topbar';
@import 'record';
+@import 'modal';
diff --git a/ui/src/assets/topbar.scss b/ui/src/assets/topbar.scss
index 6c4bf3a..c346488 100644
--- a/ui/src/assets/topbar.scss
+++ b/ui/src/assets/topbar.scss
@@ -23,7 +23,10 @@
overflow: visible;
background-color: hsl(215, 1%, 95%);
box-shadow: 0px -3px 14px 2px #bbb;
- line-height: var(--topbar-height);
+ min-height: var(--topbar-height);
+ display: flex;
+ justify-content: center;
+ align-items: center;
.omnibox {
@include omnibox-width();
@include transition(0.25s);
@@ -33,13 +36,10 @@
border-radius: 20px;
background-color: #fcfcfc;
border: 0;
- margin: 6px auto 0 auto;
- height: 36px;
line-height: 36px;
&:before {
@include material-icon('search');
vertical-align: middle;
- font-size: 32px;
margin: 5px;
color: #aaa;
grid-area: icon;
@@ -130,10 +130,8 @@
bottom: 0;
height: 1px;
width: 100%;
- background-color: #f2f2f2;
- }
-
- .progress-anim {
+ }
+ .progress-anim {
&:before {
content: '';
position: absolute;
diff --git a/ui/src/chrome_extension/chrome_tracing_controller.ts b/ui/src/chrome_extension/chrome_tracing_controller.ts
index d4ea29e..0ba2314 100644
--- a/ui/src/chrome_extension/chrome_tracing_controller.ts
+++ b/ui/src/chrome_extension/chrome_tracing_controller.ts
@@ -1,167 +1,173 @@
-import Protocol from 'devtools-protocol';
-// TODO(nicomazz): Use noice-json-rpc.
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import {Protocol} from 'devtools-protocol';
+import {ProtocolProxyApi} from 'devtools-protocol/types/protocol-proxy-api';
+import * as rpc from 'noice-json-rpc';
import {TraceConfig} from '../common/protos';
+import {
+ GetTraceStatsResponse,
+ ReadBuffersResponse
+} from '../controller/consumer_port_types';
+import {perfetto} from '../gen/protos';
+
+import {DevToolsSocket} from './devtools_socket';
const CHUNK_SIZE: number = 1024 * 1024 * 64;
-export class ChromeTraceController {
- recordingTarget: chrome.debugger.Debuggee|null = null;
- streamHandle: string|undefined = undefined;
- startTracingSendResponse: Function|null = null;
- dataBuffer = '';
+export class ChromeTracingController {
+ private streamHandle: string|undefined = undefined;
+ private uiPort: chrome.runtime.Port;
+ private api: ProtocolProxyApi.ProtocolApi;
+ private devtoolsSocket: DevToolsSocket;
+ private lastBufferUsageEvent: Protocol.Tracing.BufferUsageEvent|undefined;
- constructor() {
- chrome.debugger.onEvent.addListener(this.onEvent.bind(this));
- chrome.debugger.onDetach.addListener(this.onDetach.bind(this));
+ constructor(port: chrome.runtime.Port) {
+ this.uiPort = port;
+ this.devtoolsSocket = new DevToolsSocket();
+ this.devtoolsSocket.on('close', () => this.resetState());
+ const rpcClient = new rpc.Client(this.devtoolsSocket);
+ this.api = rpcClient.api();
+ this.api.Tracing.on('tracingComplete', this.onTracingComplete.bind(this));
+ this.api.Tracing.on('bufferUsage', this.onBufferUsage.bind(this));
}
- onMessage(
- request: {method: string, traceConfig: Uint8Array},
- _sender: chrome.runtime.MessageSender, sendResponse: Function) {
- console.log('OnMessage: ', request);
+ sendMessage(message: object) {
+ this.uiPort.postMessage(message);
+ }
+
+ sendErrorMessage(error: string) {
+ this.uiPort.postMessage({type: 'ErrorResponse', result: {error}});
+ }
+
+ onMessage(request: {method: string, traceConfig: Uint8Array}) {
switch (request.method) {
case 'EnableTracing':
- this.cleanState();
- this.startTracingSendResponse = sendResponse;
- const traceConfig =
- TraceConfig.decode(new Uint8Array(request.traceConfig));
- this.handleStartTracing(traceConfig);
- break;
- case 'StartTracing':
- sendResponse({
- answer: 'no-op, start tracing happens when enable tracing is called.'
- });
+ this.enableTracing(request);
break;
case 'FreeBuffers':
- sendResponse({answer: 'Freeing buffers'});
- this.handleFreeBuffers();
+ this.freeBuffers();
break;
case 'ReadBuffers':
- this.handleReadBuffers(sendResponse);
+ this.readBuffers();
break;
- case 'StopTracing':
- this.startTracingSendResponse = sendResponse;
- this.handleStopTracing();
+ case 'DisableTracing':
+ this.disableTracing();
+ break;
+ case 'GetTraceStats':
+ this.getTraceStats();
break;
default:
- sendResponse({error: 'Action not recognised'});
+ this.sendErrorMessage('Action not recognised');
console.log('Received not recognized message');
break;
}
}
- cleanState() {
- this.recordingTarget = null;
- this.streamHandle = undefined;
- this.startTracingSendResponse = null;
- this.dataBuffer = '';
+ enableTracing(request: {method: string, traceConfig: Uint8Array}) {
+ this.resetState();
+ const traceConfig = TraceConfig.decode(new Uint8Array(request.traceConfig));
+ const chromeConfig = this.extractChromeConfig(traceConfig);
+ this.handleStartTracing(chromeConfig);
}
- onEvent(_source: chrome.debugger.Debuggee, method: string, params?: object) {
- if (method === 'Tracing.tracingComplete' && params) {
- this.streamHandle =
- (params as Protocol.Tracing.TracingCompleteEvent).stream;
- this.notifyFrontendStreamReady();
+ extractChromeConfig(perfettoConfig: TraceConfig):
+ Protocol.Tracing.TraceConfig {
+ for (const ds of perfettoConfig.dataSources) {
+ if (ds.config && ds.config.name === 'org.chromium.trace_event' &&
+ ds.config.chromeConfig && ds.config.chromeConfig.traceConfig) {
+ const chromeConfigJsonString = ds.config.chromeConfig.traceConfig;
+ return JSON.parse(chromeConfigJsonString) as
+ Protocol.Tracing.TraceConfig;
+ }
}
+ return {};
}
- notifyFrontendStreamReady() {
- // TODO(nicomazz): Send the response in a separate way.
- if (this.startTracingSendResponse) {
- this.startTracingSendResponse({recordingReady: 1});
+ freeBuffers() {
+ this.devtoolsSocket.detach();
+ this.sendMessage({type: 'FreeBuffersResponse'});
+ }
+
+ async readBuffers(offset = 0) {
+ // TODO(nicomazz): Add error handling also in the frontend.
+ if (!this.devtoolsSocket.isAttached() || this.streamHandle === undefined) {
+ this.sendErrorMessage('No tracing session to read from');
+ return;
}
- }
- handleStartTracing(traceConfig: TraceConfig) {
- const args: Protocol.Tracing.StartRequest = {
- traceConfig: {includedCategories: []},
- streamFormat: 'proto',
- transferMode: 'ReturnAsStream',
- streamCompression: 'gzip'
+ const res = await this.api.IO.read(
+ {handle: this.streamHandle, offset, size: CHUNK_SIZE});
+ if (res === undefined) return;
+
+ const chunk = res.base64Encoded ? atob(res.data) : res.data;
+ // TODO(nicomazz): remove the conversion to unknown when we stream each
+ // chunk to the trace processor.
+ const response: ReadBuffersResponse = {
+ type: 'ReadBuffersResponse',
+ slices:
+ [{data: chunk as unknown as Uint8Array, lastSliceForPacket: res.eof}]
};
- this.findAndAttachTarget(t => {
- chrome.debugger.sendCommand(t, 'Tracing.start', args, results => {
- console.log('tracing started with config:', traceConfig, results);
- // For initial testing, the recording is stopped after 3 seconds.
- setTimeout(() => {
- this.handleStopTracing();
- }, 3000);
- });
- });
+ this.sendMessage(response);
+ if (res.eof) return;
+ this.readBuffers(offset + res.data.length);
}
- findTarget(then: (target: chrome.debugger.Debuggee) => void) {
- chrome.debugger.getTargets(targets => {
- const perfettoTab =
- targets.find((target) => target.title.includes('Perfetto'));
- if (perfettoTab === undefined) {
- console.log('No perfetto tab found');
- return;
- }
- const t: chrome.debugger.Debuggee = {targetId: perfettoTab.id};
- this.recordingTarget = t;
- then(t);
- });
+ async disableTracing() {
+ await this.api.Tracing.end();
+ this.sendMessage({type: 'DisableTracingResponse'});
}
- findAndAttachTarget(then: (target: chrome.debugger.Debuggee) => void) {
- this.findTarget(t => {
- chrome.debugger.attach(t, /*requiredVersion=*/ '1.3', () => {
- then(t);
- });
- });
- }
-
- handleStopTracing() {
- if (this.recordingTarget === null) {
- console.log('No recordings in progress');
- return;
+ getTraceStats() {
+ let percentFull = 0; // If the statistics are not available yet, it is 0.
+ if (this.lastBufferUsageEvent && this.lastBufferUsageEvent.percentFull) {
+ percentFull = this.lastBufferUsageEvent.percentFull;
}
- chrome.debugger.sendCommand(
- this.recordingTarget, 'Tracing.end', undefined, _ => {});
+ const stats: perfetto.protos.ITraceStats = {
+ bufferStats:
+ [{bufferSize: 1000, bytesWritten: Math.round(percentFull * 1000)}]
+ };
+ const response: GetTraceStatsResponse = {
+ type: 'GetTraceStatsResponse',
+ traceStats: stats
+ };
+ this.sendMessage(response);
}
- handleFreeBuffers() {
- if (this.recordingTarget !== null) {
- chrome.debugger.detach(this.recordingTarget, () => {
- this.recordingTarget = null;
- });
- }
- }
-
- handleReadBuffers(sendResponse: Function, offset = 0) {
- // TODO(nicomazz): Send back the response each time a chunk is readed.
- if (this.recordingTarget === null || this.streamHandle === undefined) {
- return;
- }
- this.readBuffer(this.streamHandle, offset, res => {
- if (res === undefined) return;
- const chunk = res.base64Encoded ? atob(res.data) : res.data;
- this.dataBuffer += chunk;
- if (res.eof) {
- sendResponse({traceData: this.dataBuffer});
- return;
- }
- this.handleReadBuffers(sendResponse, offset + res.data.length);
- });
- }
-
- readBuffer(
- handle: string, offset: number,
- then: (res: Protocol.IO.ReadResponse) => void) {
- if (this.recordingTarget === null) return;
- const readRequest:
- Protocol.IO.ReadRequest = {handle, offset, size: CHUNK_SIZE};
- chrome.debugger.sendCommand(
- this.recordingTarget,
- 'IO.read',
- readRequest,
- res => then(res as Protocol.IO.ReadResponse));
- }
-
- onDetach(source: chrome.debugger.Debuggee, reason: string) {
- console.log('source detached: ', source, 'reason: ', reason);
- this.recordingTarget = null;
+ resetState() {
+ this.devtoolsSocket.detach();
this.streamHandle = undefined;
}
-}
\ No newline at end of file
+
+ onTracingComplete(params: Protocol.Tracing.TracingCompleteEvent) {
+ this.streamHandle = params.stream;
+ this.sendMessage({type: 'EnableTracingResponse'});
+ }
+
+ onBufferUsage(params: Protocol.Tracing.BufferUsageEvent) {
+ this.lastBufferUsageEvent = params;
+ }
+
+ handleStartTracing(traceConfig: Protocol.Tracing.TraceConfig) {
+ this.devtoolsSocket.findAndAttachTarget(async _ => {
+ await this.api.Tracing.start({
+ traceConfig,
+ streamFormat: 'proto',
+ transferMode: 'ReturnAsStream',
+ streamCompression: 'gzip',
+ bufferUsageReportingInterval: 200
+ });
+ });
+ }
+}
diff --git a/ui/src/chrome_extension/devtools_socket.ts b/ui/src/chrome_extension/devtools_socket.ts
new file mode 100644
index 0000000..aa23f8f
--- /dev/null
+++ b/ui/src/chrome_extension/devtools_socket.ts
@@ -0,0 +1,107 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import * as rpc from 'noice-json-rpc';
+
+// To really understand how this works it is useful to see the implementation
+// of noice-json-rpc.
+export class DevToolsSocket implements rpc.LikeSocket {
+ private messageCallback: Function = (_: string) => {};
+ private openCallback: Function = () => {};
+ private closeCallback: Function = () => {};
+ private target: chrome.debugger.Debuggee|undefined;
+
+ constructor() {
+ chrome.debugger.onDetach.addListener(this.onDetach.bind(this));
+ chrome.debugger.onEvent.addListener((_source, method, params) => {
+ if (this.messageCallback) {
+ const msg: rpc.JsonRpc2.Notification = {method, params};
+ this.messageCallback(JSON.stringify(msg));
+ }
+ });
+ }
+
+ send(message: string): void {
+ if (this.target === undefined) return;
+
+ const msg: rpc.JsonRpc2.Request = JSON.parse(message);
+ chrome.debugger.sendCommand(
+ this.target, msg.method, msg.params, (result) => {
+ if (result === undefined) result = {};
+ const response: rpc.JsonRpc2.Response = {id: msg.id, result};
+ this.messageCallback(JSON.stringify(response));
+ });
+ }
+
+ // This method will be called once for each event soon after the creation of
+ // this object. To understand better what happens, checking the implementation
+ // of noice-json-rpc is very useful.
+ // While the events "message" and "open" are for implementing the LikeSocket,
+ // "close" is a callback set from ChromeTracingController, to reset the state
+ // after a detach.
+ on(event: string, cb: Function) {
+ if (event === 'message') {
+ this.messageCallback = cb;
+ } else if (event === 'open') {
+ this.openCallback = cb;
+ } else if (event === 'close') {
+ this.closeCallback = cb;
+ }
+ }
+
+ removeListener(_event: string, _cb: Function) {
+ throw new Error('Call unexpected');
+ }
+
+ findTarget(then: (target: chrome.debugger.Debuggee) => void) {
+ chrome.debugger.getTargets(targets => {
+ const perfettoTab =
+ targets.find(target => target.title.includes('Perfetto'));
+ if (perfettoTab === undefined) {
+ console.log('No perfetto tab found');
+ return;
+ }
+ this.target = {targetId: perfettoTab.id};
+ then(this.target);
+ });
+ }
+
+ findAndAttachTarget(then: (target: chrome.debugger.Debuggee) => void) {
+ this.findTarget(t => {
+ chrome.debugger.attach(t, /*requiredVersion=*/ '1.3', () => {
+ this.openCallback();
+ then(t);
+ });
+ });
+ }
+
+ detach() {
+ if (this.target === undefined) return;
+
+ chrome.debugger.detach(this.target, () => {
+ this.target = undefined;
+ });
+ }
+
+ onDetach(_source: chrome.debugger.Debuggee, _reason: string) {
+ if (_source === this.target) {
+ this.target = undefined;
+ this.closeCallback();
+ }
+ }
+
+ isAttached(): boolean {
+ return this.target !== undefined;
+ }
+}
diff --git a/ui/src/chrome_extension/index.ts b/ui/src/chrome_extension/index.ts
index 95f20c5..468857b 100644
--- a/ui/src/chrome_extension/index.ts
+++ b/ui/src/chrome_extension/index.ts
@@ -1,34 +1,55 @@
-// import {TraceConfig} from '../common/protos';
-import {ChromeTraceController} from './chrome_tracing_controller';
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
-const chromeTraceController = new ChromeTraceController();
+import {ChromeTracingController} from './chrome_tracing_controller';
+
+let chromeTraceController: ChromeTracingController|undefined = undefined;
chrome.runtime.onInstalled.addListener(() => {
enableOnlyOnPerfettoHost();
// Listen for messages from the perfetto ui.
- chrome.runtime.onMessageExternal.addListener(onMessage);
+ chrome.runtime.onConnectExternal.addListener(port => {
+ chromeTraceController = new ChromeTracingController(port);
+ port.onMessage.addListener(onUIMessage);
+ });
});
-function onMessage(
- request: {method: string, traceConfig: Uint8Array},
- _sender: chrome.runtime.MessageSender,
- sendResponse: Function) {
- if (request.method === 'ExtensionVersion') {
- sendResponse({version: chrome.runtime.getManifest().version});
+function onUIMessage(
+ message: {method: string, traceConfig: Uint8Array},
+ port: chrome.runtime.Port) {
+ if (message.method === 'ExtensionVersion') {
+ port.postMessage({version: chrome.runtime.getManifest().version});
return;
}
- // In the future more targets will be supported.
- chromeTraceController.onMessage(request, _sender, sendResponse);
+ // In the future, more targets will be supported.
+ if (chromeTraceController) chromeTraceController.onMessage(message);
}
function enableOnlyOnPerfettoHost() {
- chrome.declarativeContent.onPageChanged.removeRules(undefined, () => {
- chrome.declarativeContent.onPageChanged.addRules([{
+ function enableOnHostWithSuffix(suffix: string) {
+ return {
conditions: [new chrome.declarativeContent.PageStateMatcher({
- // TODO(nicomazz): Also enable on ui.perfetto.dev once we're ready.
- pageUrl: {hostContains: 'perfetto.local'},
+ pageUrl: {hostSuffix: suffix},
})],
actions: [new chrome.declarativeContent.ShowPageAction()]
- }]);
+ };
+ }
+ chrome.declarativeContent.onPageChanged.removeRules(undefined, () => {
+ chrome.declarativeContent.onPageChanged.addRules([
+ enableOnHostWithSuffix('.perfetto.local'),
+ enableOnHostWithSuffix('.perfetto.dev'),
+ enableOnHostWithSuffix('-dot-perfetto-ui.appspot.com'),
+ ]);
});
}
diff --git a/ui/src/chrome_extension/manifest.json b/ui/src/chrome_extension/manifest.json
index ce0caa4..3b48556 100644
--- a/ui/src/chrome_extension/manifest.json
+++ b/ui/src/chrome_extension/manifest.json
@@ -19,6 +19,10 @@
"persistent": false
},
"externally_connectable": {
- "matches": ["*://*.perfetto.local/*"]
+ "matches": [
+ "*://*.perfetto.local/*",
+ "*://*.perfetto.dev/*",
+ "*://*-dot-perfetto-ui.appspot.com/*"
+ ]
}
}
\ No newline at end of file
diff --git a/ui/src/common/actions.ts b/ui/src/common/actions.ts
index 7f561d7..f37ae0a 100644
--- a/ui/src/common/actions.ts
+++ b/ui/src/common/actions.ts
@@ -83,10 +83,10 @@
state.videoEnabled = true;
},
- convertTraceToJson(_: StateDraft, args: {file: File, truncate: boolean}):
- void {
- ConvertTrace(args.file, args.truncate);
- },
+ convertTraceToJson(
+ _: StateDraft, args: {file: File, truncate?: 'start'|'end'}): void {
+ ConvertTrace(args.file, args.truncate);
+ },
openTraceFromUrl(state: StateDraft, args: {url: string}): void {
clearTraceState(state);
@@ -325,6 +325,10 @@
}
},
+ setVideoOffset(state: StateDraft, args: {offset: number}): void {
+ state.videoOffset = args.offset;
+ },
+
changeNoteColor(state: StateDraft, args: {id: string, newColor: string}):
void {
const note = state.notes[args.id];
@@ -403,7 +407,11 @@
setExtensionAvailable(state: StateDraft, args: {available: boolean}): void {
state.extensionInstalled = args.available;
- }
+ },
+
+ updateBufferUsage(state: StateDraft, args: {percentage: number}): void {
+ state.bufferUsage = args.percentage;
+ },
};
diff --git a/ui/src/common/state.ts b/ui/src/common/state.ts
index bc86c7c..be59fe9 100644
--- a/ui/src/common/state.ts
+++ b/ui/src/common/state.ts
@@ -160,10 +160,10 @@
video: string | null;
videoEnabled: boolean;
+ videoOffset: number;
+ videoNoteIds: string[];
scrubbingEnabled: boolean;
flagPauseEnabled: boolean;
- videoNoteIds: string[];
-
/**
* Trace recording
*/
@@ -316,10 +316,10 @@
video: null,
videoEnabled: false,
+ videoOffset: 0,
+ videoNoteIds: [],
scrubbingEnabled: false,
flagPauseEnabled: false,
- videoNoteIds: [],
-
recordingInProgress: false,
extensionInstalled: false,
};
diff --git a/ui/src/common/time.ts b/ui/src/common/time.ts
index 33e13b8..58e2eda 100644
--- a/ui/src/common/time.ts
+++ b/ui/src/common/time.ts
@@ -31,6 +31,17 @@
return ns / 1e9;
}
+export function toNsFloor(seconds: number) {
+ return Math.floor(seconds * 1e9);
+}
+
+export function toNsCeil(seconds: number) {
+ return Math.ceil(seconds * 1e9);
+}
+
+export function toNs(seconds: number) {
+ return Math.round(seconds * 1e9);
+}
// 1000000023ns -> "1.000 000 023"
export function formatTimestamp(sec: number) {
diff --git a/ui/src/controller/consumer_port_types.ts b/ui/src/controller/consumer_port_types.ts
new file mode 100644
index 0000000..0e9bc0c
--- /dev/null
+++ b/ui/src/controller/consumer_port_types.ts
@@ -0,0 +1,41 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import {perfetto} from '../gen/protos';
+
+interface Typed {
+ type: string;
+}
+
+export interface ReadBuffersResponse extends
+ Typed, perfetto.protos.IReadBuffersResponse {}
+export interface EnableTracingResponse extends
+ Typed, perfetto.protos.IEnableTracingResponse {}
+export interface GetTraceStatsResponse extends
+ Typed, perfetto.protos.IGetTraceStatsResponse {}
+
+
+export function isReadBuffersResponse(obj: Typed): obj is ReadBuffersResponse {
+ return obj.type === 'ReadBuffersResponse';
+}
+
+export function isEnableTracingResponse(obj: Typed):
+ obj is EnableTracingResponse {
+ return obj.type === 'EnableTracingResponse';
+}
+
+export function isGetTraceStatsResponse(obj: Typed):
+ obj is GetTraceStatsResponse {
+ return obj.type === 'GetTraceStatsResponse';
+}
\ No newline at end of file
diff --git a/ui/src/controller/globals.ts b/ui/src/controller/globals.ts
index 5ff94f5..c5f5c18 100644
--- a/ui/src/controller/globals.ts
+++ b/ui/src/controller/globals.ts
@@ -104,7 +104,7 @@
// TODO: this needs to be cleaned up.
publish(
what: 'OverviewData'|'TrackData'|'Threads'|'QueryResult'|'LegacyTrace'|
- 'SliceDetails'|'Loading',
+ 'SliceDetails'|'Loading'|'BufferUsage',
data: {}, transferList?: Transferable[]) {
assertExists(this._frontend)
.send<void>(`publish${what}`, [data], transferList);
diff --git a/ui/src/controller/logs_controller.ts b/ui/src/controller/logs_controller.ts
index 6e7735e..3d6e9ea 100644
--- a/ui/src/controller/logs_controller.ts
+++ b/ui/src/controller/logs_controller.ts
@@ -20,15 +20,15 @@
LogEntriesKey,
LogExistsKey
} from '../common/logs';
-import {fromNs, TimeSpan} from '../common/time';
+import {fromNs, TimeSpan, toNsCeil, toNsFloor} from '../common/time';
import {Controller} from './controller';
import {App} from './globals';
async function updateLogBounds(
engine: Engine, span: TimeSpan): Promise<LogBounds> {
- const vizStartNs = Math.floor(span.start * 1e9);
- const vizEndNs = Math.ceil(span.end * 1e9);
+ const vizStartNs = toNsFloor(span.start);
+ const vizEndNs = toNsCeil(span.end);
const countResult = await engine.queryOneRow(`
select min(ts), max(ts), count(ts)
@@ -63,8 +63,8 @@
async function updateLogEntries(
engine: Engine, span: TimeSpan, pagination: Pagination):
Promise<LogEntries> {
- const vizStartNs = Math.floor(span.start * 1e9);
- const vizEndNs = Math.ceil(span.end * 1e9);
+ const vizStartNs = toNsFloor(span.start);
+ const vizEndNs = toNsCeil(span.end);
const vizSqlBounds = `ts >= ${vizStartNs} and ts <= ${vizEndNs}`;
const rowsResult =
diff --git a/ui/src/controller/record_controller.ts b/ui/src/controller/record_controller.ts
index 3a0ec65..c73fa56 100644
--- a/ui/src/controller/record_controller.ts
+++ b/ui/src/controller/record_controller.ts
@@ -32,6 +32,14 @@
import {MeminfoCounters, VmstatCounters} from '../common/protos';
import {MAX_TIME, RecordConfig} from '../common/state';
+import {
+ EnableTracingResponse,
+ GetTraceStatsResponse,
+ isEnableTracingResponse,
+ isGetTraceStatsResponse,
+ isReadBuffersResponse,
+ ReadBuffersResponse
+} from './consumer_port_types';
import {Controller} from './controller';
import {App, globals} from './globals';
@@ -298,6 +306,10 @@
protoCfg.dataSources.push(metadataDs);
}
+ if (uiCfg.screenRecord) {
+ atraceCats.add('gfx');
+ }
+
// Keep these last. The stages above can enrich them.
if (sysStatsCfg !== undefined) {
@@ -395,8 +407,10 @@
private app: App;
private config: RecordConfig|null = null;
private extensionPort: MessagePort;
- private recordingInProgress: boolean|null = null;
+ private recordingInProgress = false;
private consumerPort: ConsumerPort;
+ private traceBuffer = '';
+ private bufferUpdateInterval: ReturnType<typeof setTimeout>|undefined;
constructor(args: {app: App, extensionPort: MessagePort}) {
super('main');
@@ -406,50 +420,6 @@
this.extensionPort.onmessage = this.onExtensionMessage.bind(this);
}
- requestRecording() {
- console.log('Requesting recording');
- if (this.extensionPort) {
- this.extensionPort.postMessage({method: 'ReadBuffers'});
- }
- }
-
- // TODO(nicomazz): Create different data types for each extension response,
- // like "TraceCompleteEvent", "ReadBufferResponse"
- onExtensionMessage(message: {
- data: {recordingReady: number, traceData: string, readProgress: number}
- }) {
- const data = message.data;
- console.log('message received from the extension:', data);
- if (data === undefined) return;
-
- if (data.recordingReady === 1) {
- this.requestRecording();
- return;
- }
- if (data.traceData !== undefined) {
- // The trace is gzipped.
- const compressedTraceProto = this.stringToArrayBuffer(data.traceData);
- const uncompressedTrace = ungzip(compressedTraceProto);
-
- // Open trace in UI.
- globals.dispatch(
- Actions.openTraceFromBuffer({buffer: uncompressedTrace.buffer}));
- return;
- }
- if (data.readProgress) {
- // TODO(nicomazz): update loading state
- }
- }
-
- stringToArrayBuffer(str: string): Uint8Array {
- const buf = new ArrayBuffer(str.length);
- const bufView = new Uint8Array(buf);
- for (let i = 0, strLen = str.length; i < strLen; i++) {
- bufView[i] = str.charCodeAt(i);
- }
- return bufView;
- }
-
run() {
if (this.app.state.recordConfig === this.config &&
this.app.state.recordingInProgress === this.recordingInProgress) {
@@ -485,11 +455,74 @@
}
startRecordTrace(traceConfig: TraceConfig) {
+ this.scheduleBufferUpdateRequests();
this.consumerPort.enableTracing({traceConfig});
}
stopRecordTrace() {
- // TODO(nicomazz): Implement stopping trace & retrieving trace data.
+ if (this.bufferUpdateInterval) clearInterval(this.bufferUpdateInterval);
+ this.consumerPort.disableTracing({});
+ }
+
+ scheduleBufferUpdateRequests() {
+ if (this.bufferUpdateInterval) clearInterval(this.bufferUpdateInterval);
+ this.bufferUpdateInterval = setInterval(() => {
+ this.consumerPort.getTraceStats({});
+ }, 200);
+ }
+
+ readBuffers() {
+ if (this.extensionPort) this.consumerPort.readBuffers({});
+ }
+
+ onExtensionMessage(message: {
+ data: EnableTracingResponse|ReadBuffersResponse|GetTraceStatsResponse
+ }) {
+ const data = message.data;
+ if (data === undefined) return;
+
+ // TODO(nicomazz): Add error handling.
+ if (isReadBuffersResponse(data)) {
+ if (!data.slices) return;
+ this.traceBuffer += data.slices[0].data;
+ // TODO(nicomazz): Stream the chunks directly in the trace processor.
+ if (data.slices[0].lastSliceForPacket) this.openTraceInUI();
+ } else if (isEnableTracingResponse(data)) {
+ this.readBuffers();
+ } else if (isGetTraceStatsResponse(data)) {
+ const percentage = this.getBufferUsagePercentage(data);
+ if (percentage) {
+ globals.publish('BufferUsage', {percentage});
+ }
+ }
+ }
+
+ openTraceInUI() {
+ this.consumerPort.freeBuffers({});
+ const trace = ungzip(this.stringToArrayBuffer(this.traceBuffer));
+ globals.dispatch(Actions.openTraceFromBuffer({buffer: trace.buffer}));
+ this.traceBuffer = '';
+ }
+
+ stringToArrayBuffer(str: string): Uint8Array {
+ const buf = new ArrayBuffer(str.length);
+ const bufView = new Uint8Array(buf);
+ for (let i = 0, strLen = str.length; i < strLen; i++) {
+ bufView[i] = str.charCodeAt(i);
+ }
+ return bufView;
+ }
+
+
+ getBufferUsagePercentage(data: GetTraceStatsResponse): number {
+ if (!data.traceStats || !data.traceStats.bufferStats) return 0.0;
+ let used = 0.0, total = 0.0;
+ for (const buffer of data.traceStats.bufferStats) {
+ used += buffer.bytesWritten as number;
+ total += buffer.bufferSize as number;
+ }
+ if (total === 0.0) return 0;
+ return used / total;
}
// This forwards the messages that have to be sent to the extension to the
diff --git a/ui/src/controller/trace_controller.ts b/ui/src/controller/trace_controller.ts
index 9ac9d78..eedb6a5 100644
--- a/ui/src/controller/trace_controller.ts
+++ b/ui/src/controller/trace_controller.ts
@@ -25,6 +25,7 @@
import {Engine} from '../common/engine';
import {NUM, NUM_NULL, rawQueryToRows, STR_NULL} from '../common/protos';
import {SCROLLING_TRACK_GROUP} from '../common/state';
+import {toNs, toNsCeil, toNsFloor} from '../common/time';
import {TimeSpan} from '../common/time';
import {QuantizedLoad, ThreadDesc} from '../frontend/globals';
import {ANDROID_LOGS_TRACK_KIND} from '../tracks/android_log/common';
@@ -571,9 +572,9 @@
'Loading overview ' +
`${Math.round((step + 1) / numSteps * 1000) / 10}%`);
const startSec = traceTime.start + step * stepSec;
- const startNs = Math.floor(startSec * 1e9);
+ const startNs = toNsFloor(startSec);
const endSec = startSec + stepSec;
- const endNs = Math.ceil(endSec * 1e9);
+ const endNs = toNsCeil(endSec);
// Sched overview.
const schedRows = await engine.query(
@@ -595,8 +596,8 @@
}
// Slices overview.
- const traceStartNs = traceTime.start * 1e9;
- const stepSecNs = stepSec * 1e9;
+ const traceStartNs = toNs(traceTime.start);
+ const stepSecNs = toNs(stepSec);
const sliceSummaryQuery = await engine.query(
`select bucket, upid, sum(utid_sum) / cast(${stepSecNs} as float) ` +
`as upid_sum from thread inner join ` +
diff --git a/ui/src/controller/trace_converter.ts b/ui/src/controller/trace_converter.ts
index d45970b..5941cb4 100644
--- a/ui/src/controller/trace_converter.ts
+++ b/ui/src/controller/trace_converter.ts
@@ -17,7 +17,7 @@
import {globals} from './globals';
-export function ConvertTrace(trace: Blob, truncate: boolean) {
+export function ConvertTrace(trace: Blob, truncate?: 'start'|'end') {
const mod = trace_to_text({
noInitialRun: true,
locateFile: (s: string) => s,
@@ -26,10 +26,11 @@
onRuntimeInitialized: () => {
updateStatus('Converting trace');
const outPath = '/trace.json';
- if (truncate) {
- mod.callMain(['json', '--truncate', '/fs/trace.proto', outPath]);
- } else {
+ if (truncate === undefined) {
mod.callMain(['json', '/fs/trace.proto', outPath]);
+ } else {
+ mod.callMain(
+ ['json', '--truncate', truncate, '/fs/trace.proto', outPath]);
}
updateStatus('Trace conversion completed');
const fsNode = mod.FS.lookupPath(outPath).node;
diff --git a/ui/src/frontend/globals.ts b/ui/src/frontend/globals.ts
index 0e979c0..e6c2a9b 100644
--- a/ui/src/frontend/globals.ts
+++ b/ui/src/frontend/globals.ts
@@ -67,6 +67,7 @@
private _threadMap?: ThreadMap = undefined;
private _sliceDetails?: SliceDetails = undefined;
private _isLoading = false;
+ private _bufferUsage?: number = undefined;
initialize(dispatch: Dispatch, controllerWorker: Worker) {
this._dispatch = dispatch;
@@ -136,6 +137,14 @@
return this._isLoading;
}
+ get bufferUsage() {
+ return this._bufferUsage;
+ }
+
+ setBufferUsage(bufferUsage: number) {
+ this._bufferUsage = bufferUsage;
+ }
+
setTrackData(id: string, data: {}) {
this.trackDataStore.set(id, data);
}
diff --git a/ui/src/frontend/index.ts b/ui/src/frontend/index.ts
index 1106113..c68aefe 100644
--- a/ui/src/frontend/index.ts
+++ b/ui/src/frontend/index.ts
@@ -15,8 +15,10 @@
import '../tracks/all_frontend';
import {applyPatches, Patch} from 'immer';
+import * as MicroModal from 'micromodal';
import * as m from 'mithril';
+import {assertExists} from '../base/logging';
import {forwardRemoteCalls} from '../base/remote';
import {Actions} from '../common/actions';
import {
@@ -119,6 +121,11 @@
openBufferWithLegacyTraceViewer('trace.json', str, 0);
}
+ publishBufferUsage(args: {percentage: number}) {
+ globals.setBufferUsage(args.percentage);
+ this.redraw();
+ }
+
private redraw(): void {
if (globals.state.route &&
globals.state.route !== this.router.getRouteFromHash()) {
@@ -129,26 +136,15 @@
}
}
-function checkExtensionAvailability() {
- function setAvailable(available: boolean) {
- globals.dispatch(Actions.setExtensionAvailable({
- available,
- }));
- }
- // Check if the extension is installed.
- if (chrome.runtime === undefined) {
- setAvailable(false);
- return;
- }
-
- chrome.runtime.sendMessage(
- EXTENSION_ID, {method: 'ExtensionVersion'}, resp => {
- setAvailable(
- chrome.runtime.lastError === undefined && resp !== undefined &&
- resp.version !== null);
- });
+function setExtensionAvailability(available: boolean) {
+ if (available) console.log('Extension available!');
+ globals.dispatch(Actions.setExtensionAvailable({
+ available,
+ }));
}
+
+
function main() {
const controller = new Worker('controller_bundle.js');
controller.onerror = e => {
@@ -156,14 +152,20 @@
};
const frontendChannel = new MessageChannel();
const controllerChannel = new MessageChannel();
- const extensionChannel = new MessageChannel();
+ const extensionLocalChannel = new MessageChannel();
+
+
controller.postMessage(
{
frontendPort: frontendChannel.port1,
controllerPort: controllerChannel.port1,
- extensionPort: extensionChannel.port1
+ extensionPort: extensionLocalChannel.port1
},
- [frontendChannel.port1, controllerChannel.port1, extensionChannel.port1]);
+ [
+ frontendChannel.port1,
+ controllerChannel.port1,
+ extensionLocalChannel.port1
+ ]);
const dispatch =
controllerChannel.port2.postMessage.bind(controllerChannel.port2);
@@ -180,15 +182,28 @@
// We proxy messages between the extension and the controller because the
// controller's worker can't access chrome.runtime.
- extensionChannel.port2.onmessage = ({data}) => {
- chrome.runtime.sendMessage(EXTENSION_ID, data, (response) => {
- extensionChannel.port2.postMessage(response);
- });
+ const extensionPort = chrome.runtime !== undefined ?
+ chrome.runtime.connect(EXTENSION_ID) :
+ undefined; // Will be null if the extension is not installed.
+ setExtensionAvailability(extensionPort !== undefined);
+ if (extensionPort) {
+ // This forwards the messages from the extension to the controller.
+ extensionPort.onMessage.addListener(
+ (message: object, _port: chrome.runtime.Port) => {
+ extensionLocalChannel.port2.postMessage(message);
+ });
+ }
+
+ // This forwards the messages from the controller to the extension
+ extensionLocalChannel.port2.onmessage = ({data}) => {
+ if (extensionPort) extensionPort.postMessage(data);
};
- checkExtensionAvailability();
+
+
+ const main = assertExists(document.body.querySelector('main'));
globals.rafScheduler.domRedraw = () =>
- m.render(document.body, m(router.resolve(globals.state.route)));
+ m.render(main, m(router.resolve(globals.state.route)));
// Add support for opening traces from postMessage().
window.addEventListener('message', postMessageHandler, {passive: true});
@@ -211,6 +226,8 @@
}, {passive: false});
router.navigateToCurrentHash();
+
+ MicroModal.init();
}
main();
diff --git a/ui/src/frontend/modal.ts b/ui/src/frontend/modal.ts
new file mode 100644
index 0000000..8791e58
--- /dev/null
+++ b/ui/src/frontend/modal.ts
@@ -0,0 +1,67 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import * as MicroModal from 'micromodal';
+import * as m from 'mithril';
+
+// We need any here so we can accept vnodes with arbitrary attrs.
+// tslint:disable-next-line:no-any
+export type AnyAttrsVnode = m.Vnode<any, {}>;
+
+interface ModalDefinition {
+ title: string;
+ content: AnyAttrsVnode;
+ buttons: Button[];
+}
+
+export interface Button {
+ text: string;
+ primary: boolean;
+ id: string;
+ action: () => void;
+}
+
+export async function showModal(attrs: ModalDefinition): Promise<void> {
+ const modal = document.querySelector('#main-modal') as HTMLElement;
+ m.render(
+ modal,
+ m('.modal-overlay[data-micromodal-close]',
+ {tabindex: -1},
+ m('.modal-container[aria-labelledby=mm-title][aria-model][role=dialog]',
+ m('header.modal-header',
+ m('h2.modal-title', {id: 'mm-title'}, attrs.title),
+ m('button.modal-close[aria-label=Close Modal]' +
+ '[data-micromodal-close]')),
+ m('main.modal-content', attrs.content),
+ m('footer.modal-footer', ...makeButtons(attrs.buttons)))));
+ return new Promise(resolve => {
+ MicroModal.show(
+ 'main-modal', {onClose: () => resolve, awaitCloseAnimation: true});
+ });
+}
+
+function makeButtons(buttonDefinition: Button[]): Array<m.Vnode<Button>> {
+ const buttons: Array<m.Vnode<Button>> = [];
+ buttonDefinition.forEach(button => {
+ buttons.push(
+ m('button[data-micromodal-close].modal-btn',
+ {
+ class: button.primary ? 'modal-btn-primary' : '',
+ id: button.id,
+ onclick: button.action
+ },
+ button.text));
+ });
+ return buttons;
+}
diff --git a/ui/src/frontend/record_page.ts b/ui/src/frontend/record_page.ts
index 829d420..4480127 100644
--- a/ui/src/frontend/record_page.ts
+++ b/ui/src/frontend/record_page.ts
@@ -520,19 +520,18 @@
img: null,
descr: `Records the screen along with running a trace. Max
time of recording is 3 minutes (180 seconds).`,
- setEnabled: (cfg, val) => cfg.screenRecord = val,
- isEnabled: (cfg) => cfg.screenRecord,
- } as ProbeAttrs,
- m(Slider, {
- title: 'Max duration',
- icon: 'timer',
- values: [S(10), S(15), S(30), S(60), M(2), M(3)],
- isTime: true,
- unit: 'm:s',
- set: (cfg, val) => cfg.durationMs = val,
- get: (cfg) => cfg.durationMs,
- } as SliderAttrs)) :
- null);
+ setEnabled: (cfg, val) => cfg.screenRecord = val,
+ isEnabled: (cfg) => cfg.screenRecord,
+ } as ProbeAttrs,
+ m(Slider, {
+ title: 'Max duration',
+ icon: 'timer',
+ values: [S(10), S(15), S(30), S(60), M(2), M(3)],
+ isTime: true,
+ unit: 'm:s',
+ set: (cfg, val) => cfg.durationMs = val,
+ get: (cfg) => cfg.durationMs,
+ } as SliderAttrs),) : null);
}
function Instructions(cssClass: string) {
@@ -550,8 +549,10 @@
const pbtx = data ? data.pbtxt : '';
let cmd = '';
if (cfg.screenRecord) {
- cmd += `adb shell screenrecord --time-limit ${time}`;
- cmd += ' "/sdcard/tracescr.mp4" &\\\n';
+ // Half-second delay to ensure Perfetto starts tracing before screenrecord
+ // starts recording
+ cmd += `(sleep 0.5 && adb shell screenrecord --time-limit ${time}`;
+ cmd += ' "/sdcard/tracescr.mp4") &\\\n';
}
cmd += 'adb shell perfetto \\\n';
cmd += ' -c - --txt \\\n';
@@ -607,6 +608,9 @@
globals.dispatch(Actions.setRecordConfig({config: traceCfg}));
};
+ const bufferUsagePercentage =
+ ((globals.bufferUsage ? globals.bufferUsage : 0.0) * 100).toFixed(1);
+
return m(
`.record-section.instructions${cssClass}`,
m('header', 'Instructions'),
@@ -623,11 +627,21 @@
globals.state.extensionInstalled ?
[
m('button',
- {onclick: () => globals.dispatch(Actions.startRecording({}))},
+ {
+ onclick: () => globals.dispatch(Actions.startRecording({})),
+ disabled: globals.state.recordingInProgress
+ },
'Start Recording'),
m('button',
- {onclick: () => globals.dispatch(Actions.stopRecording({}))},
- 'Stop Recording')
+ {
+ onclick: () => globals.dispatch(Actions.stopRecording({})),
+ disabled: !globals.state.recordingInProgress
+ },
+ 'Stop Recording'),
+ m('label',
+ globals.state.recordingInProgress ?
+ 'Buffer usage: ' + bufferUsagePercentage + '%' :
+ '')
] :
[]);
}
diff --git a/ui/src/frontend/sidebar.ts b/ui/src/frontend/sidebar.ts
index d0d0fc6..0d1dbcd 100644
--- a/ui/src/frontend/sidebar.ts
+++ b/ui/src/frontend/sidebar.ts
@@ -15,12 +15,14 @@
import * as m from 'mithril';
import {Actions} from '../common/actions';
+import {QueryResponse} from '../common/queries';
import {globals} from './globals';
import {
isLegacyTrace,
openFileWithLegacyTraceViewer,
} from './legacy_trace_viewer';
+import {showModal} from './modal';
const ALL_PROCESSES_QUERY = 'select name, pid from process order by name;';
@@ -90,7 +92,7 @@
}
const EXAMPLE_ANDROID_TRACE_URL =
- 'https://storage.googleapis.com/perfetto-misc/example_android_trace_30s_1';
+ 'https://storage.googleapis.com/perfetto-misc/example_android_trace_15s';
const EXAMPLE_CHROME_TRACE_URL =
'https://storage.googleapis.com/perfetto-misc/example_chrome_trace_4s_1.json';
@@ -102,6 +104,11 @@
expanded: true,
items: [
{t: 'Open trace file', a: popupFileSelectionDialog, i: 'folder_open'},
+ {
+ t: 'Open with legacy UI',
+ a: popupFileSelectionDialogOldUI,
+ i: 'filter_none'
+ },
{t: 'Record new trace', a: navigateRecord, i: 'fiber_smart_record'},
{t: 'Show timeline', a: navigateViewer, i: 'line_style'},
{
@@ -119,23 +126,6 @@
],
},
{
- title: 'Legacy UI',
- expanded: true,
- summary: 'Open trace with legacy UI',
- items: [
- {
- t: 'Open with legacy UI',
- a: popupFileSelectionDialogOldUI,
- i: 'folder_open'
- },
- {
- t: 'Truncate and open',
- a: popupFileSelectionDialogOldUITruncate,
- i: 'flip'
- },
- ],
- },
- {
title: 'Example Traces',
expanded: true,
summary: 'Open an example trace',
@@ -224,26 +214,16 @@
e.preventDefault();
delete getFileElement().dataset['useCatapultLegacyUi'];
delete getFileElement().dataset['video'];
- delete getFileElement().dataset['truncate'];
getFileElement().click();
}
function popupFileSelectionDialogOldUI(e: Event) {
e.preventDefault();
delete getFileElement().dataset['video'];
- delete getFileElement().dataset['truncate'];
getFileElement().dataset['useCatapultLegacyUi'] = '1';
getFileElement().click();
}
-function popupFileSelectionDialogOldUITruncate(e: Event) {
- e.preventDefault();
- delete getFileElement().dataset['video'];
- getFileElement().dataset['useCatapultLegacyUi'] = '1';
- getFileElement().dataset['truncate'] = '1';
- getFileElement().click();
-}
-
function popupVideoSelectionDialog(e: Event) {
e.preventDefault();
delete getFileElement().dataset['useCatapultLegacyUi'];
@@ -274,30 +254,89 @@
// Switch back to the old catapult UI.
if (isLegacyTrace(file.name)) {
openFileWithLegacyTraceViewer(file);
- } else {
- if (e.target.dataset['truncate'] === '1') {
- globals.dispatch(Actions.convertTraceToJson({file, truncate: true}));
- return;
- } else if (file.size > 1024 * 1024 * 50) {
- const size = Math.round(file.size / (1024 * 1024));
- const result = confirm(
- `This trace is ${size}mb, opening it in ` +
- `the legacy UI may fail.\nPress 'OK' to attempt to open this ` +
- `trace or press 'Cancel' and use the 'Truncate' button ` +
- `to load just the first 50mb.\nMore options can be found at ` +
- `go/opening-large-traces.`);
- if (!result) return;
- }
- globals.dispatch(Actions.convertTraceToJson({file, truncate: false}));
+ return;
}
+
+ // Perfetto traces smaller than 50mb can be safely opened in the legacy UI.
+ if (file.size < 1024 * 1024 * 50) {
+ globals.dispatch(Actions.convertTraceToJson({file}));
+ return;
+ }
+
+ // Give the user the option to truncate larger perfetto traces.
+ const size = Math.round(file.size / (1024 * 1024));
+ showModal({
+ title: 'Legacy UI may fail to open this trace',
+ content:
+ m('div',
+ m('p',
+ `This trace is ${size}mb, opening it in the legacy UI ` +
+ `may fail.`),
+ m('p',
+ 'More options can be found at ',
+ m('a',
+ {
+ href: 'https://goto.google.com/opening-large-traces',
+ target: '_blank'
+ },
+ 'go/opening-large-traces'),
+ '.')),
+ buttons: [
+ {
+ text: 'Open full trace (not recommended)',
+ primary: false,
+ id: 'open',
+ action: () => {
+ globals.dispatch(Actions.convertTraceToJson({file}));
+ }
+ },
+ {
+ text: 'Open beginning of trace',
+ primary: true,
+ id: 'truncate-start',
+ action: () => {
+ globals.dispatch(
+ Actions.convertTraceToJson({file, truncate: 'start'}));
+ }
+ },
+ {
+ text: 'Open end of trace',
+ primary: true,
+ id: 'truncate-end',
+ action: () => {
+ globals.dispatch(
+ Actions.convertTraceToJson({file, truncate: 'end'}));
+ }
+ }
+
+ ]
+ });
return;
}
if (e.target.dataset['video'] === '1') {
+ // TODO(hjd): Update this to use a controller and publish.
+ globals.dispatch(Actions.executeQuery({
+ engineId: '0', queryId: 'command',
+ query: `select ts from slices where name = 'first_frame' union ` +
+ `select start_ts from trace_bounds`}));
+ setTimeout(() => {
+ const resp = globals.queryResults.get('command') as QueryResponse;
+ // First value is screenrecord trace event timestamp
+ // and second value is trace boundary's start timestamp
+ const offset = (parseInt(resp.rows[1]['ts'].toString()) -
+ parseInt(resp.rows[0]['ts'].toString())) / 1e9;
+ globals.queryResults.delete('command');
+ globals.rafScheduler.scheduleFullRedraw();
+ globals.dispatch(Actions.deleteQuery({queryId: 'command'}));
+ globals.dispatch(Actions.setVideoOffset({offset}));
+ }, 1000);
globals.dispatch(Actions.openVideoFromFile({file}));
- } else {
- globals.dispatch(Actions.openTraceFromFile({file}));
+ return;
}
+
+ globals.dispatch(Actions.openTraceFromFile({file}));
+
}
function navigateRecord(e: Event) {
@@ -420,22 +459,23 @@
class: globals.frontendLocalState.sidebarVisible ? 'show-sidebar' :
'hide-sidebar'
},
- m('header',
- 'Perfetto',
- m(
- '.sidebar-button',
- m('button',
- m('i.material-icons',
- {
- title: globals.frontendLocalState.sidebarVisible ?
- 'Hide menu' :
- 'Show menu',
- onclick: () => {
- globals.frontendLocalState.toggleSidebar();
- },
- },
- 'menu')),
- )),
+ m(
+ 'header',
+ 'Perfetto',
+ m('button.sidebar-button',
+ {
+ onclick: () => {
+ globals.frontendLocalState.toggleSidebar();
+ },
+ },
+ m('i.material-icons',
+ {
+ title: globals.frontendLocalState.sidebarVisible ?
+ 'Hide menu' :
+ 'Show menu',
+ },
+ 'menu')),
+ ),
m('input[type=file]', {onchange: onInputElementFileSelectionChanged}),
m('.sidebar-content', ...vdomSections));
}
diff --git a/ui/src/frontend/topbar.ts b/ui/src/frontend/topbar.ts
index 36319b4..d6f7db8 100644
--- a/ui/src/frontend/topbar.ts
+++ b/ui/src/frontend/topbar.ts
@@ -22,24 +22,26 @@
const QUERY_ID = 'quicksearch';
+const SEARCH = Symbol('search');
+const COMMAND = Symbol('command');
+type Mode = typeof SEARCH|typeof COMMAND;
+
+const PLACEHOLDER = {
+ [SEARCH]: 'Search',
+ [COMMAND]: 'e.g. select * from sched left join thread using(utid) limit 10'
+};
+
let selResult = 0;
let numResults = 0;
-let mode: 'search'|'command' = 'search';
+let mode: Mode = SEARCH;
let omniboxValue = '';
-function enterCommandMode() {
- if (mode === 'search') {
- mode = 'command';
- globals.rafScheduler.scheduleFullRedraw();
- }
-}
-
function clearOmniboxResults(e: Event) {
globals.queryResults.delete(QUERY_ID);
globals.dispatch(Actions.deleteQuery({queryId: QUERY_ID}));
const txt = (e.target as HTMLInputElement);
if (txt.value.length <= 0) {
- mode = 'search';
+ mode = SEARCH;
globals.rafScheduler.scheduleFullRedraw();
}
}
@@ -47,6 +49,7 @@
function onKeyDown(e: Event) {
e.stopPropagation();
const key = (e as KeyboardEvent).key;
+ const txt = (e.target as HTMLInputElement);
// Avoid that the global 'a', 'd', 'w', 's' handler sees these keystrokes.
// TODO: this seems a bug in the pan_and_zoom_handler.ts.
@@ -54,7 +57,20 @@
e.preventDefault();
return;
}
- const txt = (e.target as HTMLInputElement);
+
+ if (mode === SEARCH && txt.value === '' && key === ':') {
+ e.preventDefault();
+ mode = COMMAND;
+ globals.rafScheduler.scheduleFullRedraw();
+ return;
+ }
+
+ if (mode === COMMAND && txt.value === '' && key === 'Backspace') {
+ mode = SEARCH;
+ globals.rafScheduler.scheduleFullRedraw();
+ return;
+ }
+
omniboxValue = txt.value;
}
@@ -71,17 +87,17 @@
globals.rafScheduler.scheduleFullRedraw();
return;
}
- if (txt.value.length <= 0 || key === 'Escape') {
+
+ if (key === 'Escape') {
globals.queryResults.delete(QUERY_ID);
- globals.dispatch(Actions.deleteQuery({queryId: QUERY_ID}));
- mode = 'search';
+ globals.dispatch(Actions.deleteQuery({queryId: 'command'}));
+ mode = SEARCH;
txt.value = '';
- omniboxValue = txt.value;
txt.blur();
globals.rafScheduler.scheduleFullRedraw();
return;
}
- if (mode === 'command' && key === 'Enter') {
+ if (mode === COMMAND && key === 'Enter') {
globals.dispatch(Actions.executeQuery(
{engineId: '0', queryId: 'command', query: txt.value}));
}
@@ -90,8 +106,6 @@
class Omnibox implements m.ClassComponent {
oncreate(vnode: m.VnodeDOM) {
const txt = vnode.dom.querySelector('input') as HTMLInputElement;
- txt.addEventListener('focus', enterCommandMode);
- txt.addEventListener('click', enterCommandMode);
txt.addEventListener('blur', clearOmniboxResults);
txt.addEventListener('keydown', onKeyDown);
txt.addEventListener('keyup', onKeyUp);
@@ -124,15 +138,11 @@
results.push(m(`div${clazz}`, resp.rows[i][resp.columns[0]]));
}
}
- const placeholder = {
- search: 'Click to enter command mode',
- command: 'e.g. select * from sched left join thread using(utid) limit 10'
- };
-
- const commandMode = mode === 'command';
+ const commandMode = mode === COMMAND;
return m(
`.omnibox${commandMode ? '.command-mode' : ''}`,
- m(`input[placeholder=${placeholder[mode]}]`, {
+ m('input', {
+ placeholder: PLACEHOLDER[mode],
onchange: m.withAttr('value', v => omniboxValue = v),
value: omniboxValue,
}),
@@ -166,9 +176,9 @@
const engine: EngineConfig = globals.state.engines['0'];
if (globals.state.queries[QUERY_ID] !== undefined ||
(engine !== undefined && !engine.ready) || globals.isLoading) {
- this.progressBar.setAttribute('class', 'progress progress-anim');
+ this.progressBar.classList.add('progress-anim');
} else {
- this.progressBar.setAttribute('class', 'progress');
+ this.progressBar.classList.remove('progress-anim');
}
}
}
diff --git a/ui/src/frontend/video_panel.ts b/ui/src/frontend/video_panel.ts
index d3f3bbd..9957e37 100644
--- a/ui/src/frontend/video_panel.ts
+++ b/ui/src/frontend/video_panel.ts
@@ -21,7 +21,7 @@
export class VideoPanel implements m.ClassComponent {
view() {
const vidSections = [];
- const offset = globals.state.traceTime.startSec;
+ const offset = globals.state.traceTime.startSec + globals.state.videoOffset;
vidSections.push(
m('video', {
class: 'video-panel',
@@ -67,7 +67,7 @@
makeMsg(globals.state.flagPauseEnabled, 'message', pEnabled, pDisabled),
makeMsg(globals.state.scrubbingEnabled, 'setting',
tSetting.concat('Enabled'), tSetting.concat('Disabled')),
- makeMsg(globals.state.scrubbingEnabled, 'message', tEnabled, tDisabled))
+ makeMsg(globals.state.scrubbingEnabled, 'message', tEnabled, tDisabled));
vidSections.push(vidMessages);
return m('.video-panel', vidSections);
}
diff --git a/ui/src/tracks/android_log/controller.ts b/ui/src/tracks/android_log/controller.ts
index 170875c..fba13d7 100644
--- a/ui/src/tracks/android_log/controller.ts
+++ b/ui/src/tracks/android_log/controller.ts
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {fromNs} from '../../common/time';
+import {fromNs, toNsCeil, toNsFloor} from '../../common/time';
import {LIMIT} from '../../common/track_data';
import {
TrackController,
@@ -26,11 +26,11 @@
async onBoundsChange(start: number, end: number, resolution: number):
Promise<Data> {
- const startNs = Math.floor(start * 1e9);
- const endNs = Math.ceil(end * 1e9);
+ const startNs = toNsFloor(start);
+ const endNs = toNsCeil(end);
// |resolution| is in s/px the frontend wants.
- const quantNs = Math.ceil(resolution * 1e9);
+ const quantNs = toNsCeil(resolution);
const rawResult = await this.query(`
select
diff --git a/ui/src/tracks/chrome_slices/controller.ts b/ui/src/tracks/chrome_slices/controller.ts
index 6b55d64..8e7ac98 100644
--- a/ui/src/tracks/chrome_slices/controller.ts
+++ b/ui/src/tracks/chrome_slices/controller.ts
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {fromNs} from '../../common/time';
+import {fromNs, toNs} from '../../common/time';
import {LIMIT} from '../../common/track_data';
import {
TrackController,
@@ -27,10 +27,10 @@
async onBoundsChange(start: number, end: number, resolution: number):
Promise<Data> {
- const startNs = Math.round(start * 1e9);
- const endNs = Math.round(end * 1e9);
+ const startNs = toNs(start);
+ const endNs = toNs(end);
// Ns in 1px width. We want all slices smaller than 1px to be grouped.
- const minNs = Math.round(resolution * 1e9);
+ const minNs = toNs(resolution);
if (!this.setup) {
await this.query(
diff --git a/ui/src/tracks/counter/controller.ts b/ui/src/tracks/counter/controller.ts
index 13146bb..2ef24af 100644
--- a/ui/src/tracks/counter/controller.ts
+++ b/ui/src/tracks/counter/controller.ts
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {fromNs} from '../../common/time';
+import {fromNs, toNs} from '../../common/time';
import {LIMIT} from '../../common/track_data';
import {
@@ -34,8 +34,8 @@
async onBoundsChange(start: number, end: number, resolution: number):
Promise<Data> {
- const startNs = Math.round(start * 1e9);
- const endNs = Math.round(end * 1e9);
+ const startNs = toNs(start);
+ const endNs = toNs(end);
if (!this.setup) {
const result = await this.query(`
diff --git a/ui/src/tracks/cpu_freq/controller.ts b/ui/src/tracks/cpu_freq/controller.ts
index a1c2149..190a3d9 100644
--- a/ui/src/tracks/cpu_freq/controller.ts
+++ b/ui/src/tracks/cpu_freq/controller.ts
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {fromNs} from '../../common/time';
+import {fromNs, toNs} from '../../common/time';
import {LIMIT} from '../../common/track_data';
import {
@@ -33,8 +33,8 @@
async onBoundsChange(start: number, end: number, resolution: number):
Promise<Data> {
- const startNs = Math.round(start * 1e9);
- const endNs = Math.round(end * 1e9);
+ const startNs = toNs(start);
+ const endNs = toNs(end);
if (!this.setup) {
const result = await this.query(`
diff --git a/ui/src/tracks/cpu_slices/controller.ts b/ui/src/tracks/cpu_slices/controller.ts
index 2e858c4..278450e 100644
--- a/ui/src/tracks/cpu_slices/controller.ts
+++ b/ui/src/tracks/cpu_slices/controller.ts
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {fromNs} from '../../common/time';
+import {fromNs, toNs} from '../../common/time';
import {LIMIT} from '../../common/track_data';
import {
@@ -34,8 +34,8 @@
async onBoundsChange(start: number, end: number, resolution: number):
Promise<Data> {
- const startNs = Math.round(start * 1e9);
- const endNs = Math.round(end * 1e9);
+ const startNs = toNs(start);
+ const endNs = toNs(end);
if (this.setup === false) {
await this.query(
@@ -72,8 +72,8 @@
private async computeSummary(
start: number, end: number, resolution: number,
bucketSizeNs: number): Promise<SummaryData> {
- const startNs = Math.round(start * 1e9);
- const endNs = Math.round(end * 1e9);
+ const startNs = toNs(start);
+ const endNs = toNs(end);
const numBuckets = Math.ceil((endNs - startNs) / bucketSizeNs);
const query = `select
diff --git a/ui/src/tracks/gpu_freq/controller.ts b/ui/src/tracks/gpu_freq/controller.ts
index 57c503f..6fa2e39 100644
--- a/ui/src/tracks/gpu_freq/controller.ts
+++ b/ui/src/tracks/gpu_freq/controller.ts
@@ -12,9 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {fromNs} from '../../common/time';
+import {fromNs, toNs} from '../../common/time';
import {LIMIT} from '../../common/track_data';
-
import {
TrackController,
trackControllerRegistry
@@ -22,8 +21,8 @@
import {
Config,
- GPU_FREQ_TRACK_KIND,
Data,
+ GPU_FREQ_TRACK_KIND,
} from './common';
class GpuFreqTrackController extends TrackController<Config, Data> {
@@ -33,8 +32,8 @@
async onBoundsChange(start: number, end: number, resolution: number):
Promise<Data> {
- const startNs = Math.round(start * 1e9);
- const endNs = Math.round(end * 1e9);
+ const startNs = toNs(start);
+ const endNs = toNs(end);
if (!this.setup) {
const result = await this.query(`
diff --git a/ui/src/tracks/process_scheduling/controller.ts b/ui/src/tracks/process_scheduling/controller.ts
index ea9cf00..e0816a5 100644
--- a/ui/src/tracks/process_scheduling/controller.ts
+++ b/ui/src/tracks/process_scheduling/controller.ts
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {fromNs} from '../../common/time';
+import {fromNs, toNs} from '../../common/time';
import {LIMIT} from '../../common/track_data';
import {
@@ -42,8 +42,8 @@
throw new Error('Upid not set.');
}
- const startNs = Math.round(start * 1e9);
- const endNs = Math.round(end * 1e9);
+ const startNs = toNs(start);
+ const endNs = toNs(end);
if (this.setup === false) {
await this.query(
@@ -85,8 +85,8 @@
private async computeSummary(
start: number, end: number, resolution: number,
bucketSizeNs: number): Promise<SummaryData> {
- const startNs = Math.round(start * 1e9);
- const endNs = Math.round(end * 1e9);
+ const startNs = toNs(start);
+ const endNs = toNs(end);
const numBuckets = Math.ceil((endNs - startNs) / bucketSizeNs);
// cpu < numCpus improves perfomance a lot since the window table can
diff --git a/ui/src/tracks/process_summary/controller.ts b/ui/src/tracks/process_summary/controller.ts
index 2600dc2..d18cb6b 100644
--- a/ui/src/tracks/process_summary/controller.ts
+++ b/ui/src/tracks/process_summary/controller.ts
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {fromNs} from '../../common/time';
+import {fromNs, toNs} from '../../common/time';
import {LIMIT} from '../../common/track_data';
import {
@@ -35,8 +35,8 @@
async onBoundsChange(start: number, end: number, resolution: number):
Promise<Data> {
- const startNs = Math.round(start * 1e9);
- const endNs = Math.round(end * 1e9);
+ const startNs = toNs(start);
+ const endNs = toNs(end);
if (this.setup === false) {
await this.query(
@@ -81,8 +81,8 @@
private async computeSummary(
start: number, end: number, resolution: number,
bucketSizeNs: number): Promise<Data> {
- const startNs = Math.round(start * 1e9);
- const endNs = Math.round(end * 1e9);
+ const startNs = toNs(start);
+ const endNs = toNs(end);
const numBuckets = Math.ceil((endNs - startNs) / bucketSizeNs);
const query = `select
diff --git a/ui/src/tracks/thread_state/controller.ts b/ui/src/tracks/thread_state/controller.ts
index a6ebd2c..043d134 100644
--- a/ui/src/tracks/thread_state/controller.ts
+++ b/ui/src/tracks/thread_state/controller.ts
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {fromNs} from '../../common/time';
+import {fromNs, toNs} from '../../common/time';
import {LIMIT} from '../../common/track_data';
import {
@@ -33,12 +33,12 @@
async onBoundsChange(start: number, end: number, resolution: number):
Promise<Data> {
- const startNs = Math.round(start * 1e9);
- const endNs = Math.round(end * 1e9);
+ const startNs = toNs(start);
+ const endNs = toNs(end);
let minNs = 0;
if (groupBusyStates(resolution)) {
// Ns for 1px (the smallest state to display)
- minNs = Math.round(resolution * 1 * 1e9);
+ minNs = Math.round(resolution * 1e9);
}
if (this.setup === false) {
diff --git a/ui/tsconfig.json b/ui/tsconfig.json
index 314b2d4..7f4d790 100644
--- a/ui/tsconfig.json
+++ b/ui/tsconfig.json
@@ -9,6 +9,10 @@
"dom", // Need to be explicitly mentioned now since we're overriding default included libs.
"es2018", // Need this to use Object.values.
],
+ "baseUrl": ".",
+ "paths": {
+ "*" : ["*", "./types/*"]
+ },
"target": "es6",
"module": "commonjs",
"moduleResolution": "node",
diff --git a/ui/types/micromodal/index.d.ts b/ui/types/micromodal/index.d.ts
new file mode 100644
index 0000000..d16ff3e
--- /dev/null
+++ b/ui/types/micromodal/index.d.ts
@@ -0,0 +1,73 @@
+// Type definitions for micromodal 0.3
+// Project: https://github.com/ghosh/micromodal#readme
+// Definitions by: Wayne Carson <https://github.com/wcarson>
+// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
+
+
+/**
+ * MicroModal controller
+ */
+declare namespace MicroModal {
+ /**
+ * MicroModal configuration options
+ */
+ export interface MicroModalConfig {
+ /** This is fired when the modal is opening. */
+ onShow?: (modal?: HTMLElement) => void;
+
+ /** This is fired when the modal is closing. */
+ onClose?: (modal?: HTMLElement) => void;
+
+ /**
+ * Custom data attribute to open modal. Default is data-micromodal-trigger.
+ */
+ openTrigger?: string;
+
+ /**
+ * Custom data attribute to close modal. Default is data-micromodal-close.
+ */
+ closeTrigger?: string;
+
+ /**
+ * This disables scrolling on the page while the modal is open. The default
+ * value is false.
+ */
+ disableScroll?: boolean;
+
+ /** Disable auto focus on first focusable element. Default is false */
+ disableFocus?: boolean;
+
+ /**
+ * Set this to true if using css animations to hide the modal. This allows
+ * it to wait for the animation to finish before removing it from the DOM.
+ * Default is false
+ */
+ awaitCloseAnimation?: boolean;
+
+ /**
+ * This option suppresses the console warnings if passed as true. The
+ * default value is false.
+ */
+ debugMode?: boolean;
+ }
+
+ /**
+ * Binds click handlers to all modal triggers
+ * @param config configuration options
+ */
+ function init(config?: MicroModalConfig): void;
+
+ /**
+ * Shows a particular modal
+ * @param targetModal The id of the modal to display
+ * @param config configuration options
+ */
+ function show(targetModal: string, config?: MicroModalConfig): void;
+
+ /**
+ * Closes the active modal
+ */
+ function close(): void;
+}
+
+export = MicroModal;