Files
android/libwvdrmengine/mediadrm/aidl_src/wv_metrics_adapter.cpp
Edwin Wong a7aa1c5013 Revert "Rename aidl_ include and src directories."
This reverts commit 5400741601.

Reason for revert: broke hidl build

Change-Id: I3954a1c0d6c0d7a663bd2a1c8c8888cae37cee80
2022-09-02 17:17:20 +00:00

596 lines
25 KiB
C++

//
// Copyright 2021 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine License
// Agreement.
//
#include "wv_metrics_adapter.h"
#include "wv_metrics.pb.h"
namespace wvcdm {
using ::aidl::android::hardware::drm::DrmMetric;
using ::aidl::android::hardware::drm::DrmMetricGroup;
using ::aidl::android::hardware::drm::DrmMetricNamedValue;
using ::aidl::android::hardware::drm::DrmMetricValue;
using drm_metrics::CounterMetric;
using drm_metrics::DistributionMetric;
using google::protobuf::RepeatedPtrField;
namespace {
const char kAttributeErrorCode[] = "error_code";
const char kAttributeErrorCodeBool[] = "error_code_bool";
const char kAttributeCdmSecurityLevel[] = "cdm_security_level";
const char kAttributeSecurityLevel[] = "security_level";
const char kAttributeLength[] = "length";
const char kAttributeEncryptionAlgorithm[] = "encryption_algorithm";
const char kAttributeSigningAlgorithm[] = "signing_algorithm";
const char kAttributeOemCryptoResult[] = "oem_crypto_result";
const char kAttributeKeyStatusType[] = "key_status_type";
const char kAttributeEventType[] = "event_type";
const char kAttributeKeyRequestType[] = "key_request_type";
const char kAttributeLicenseType[] = "license_type";
template <typename T>
void SetValue(const T& value, DrmMetricNamedValue* attribute);
template <>
void SetValue(const int& value, DrmMetricNamedValue* attribute) {
attribute->value = DrmMetricValue::make<DrmMetricValue::int64Value>(value);
}
template <>
void SetValue(const bool& value, DrmMetricNamedValue* attribute) {
attribute->value = DrmMetricValue::make<DrmMetricValue::int64Value>(value);
}
template <>
void SetValue(const float& value, DrmMetricNamedValue* attribute) {
attribute->value = DrmMetricValue::make<DrmMetricValue::doubleValue>(value);
}
template <>
void SetValue(const double& value, DrmMetricNamedValue* attribute) {
attribute->value = DrmMetricValue::make<DrmMetricValue::doubleValue>(value);
}
template <>
__attribute__((unused)) void SetValue(const long& value,
DrmMetricNamedValue* attribute) {
attribute->value = DrmMetricValue::make<DrmMetricValue::int64Value>(value);
}
template <>
__attribute__((unused)) void SetValue(const long long& value,
DrmMetricNamedValue* attribute) {
attribute->value = DrmMetricValue::make<DrmMetricValue::int64Value>(value);
}
template <>
void SetValue(const std::string& value, DrmMetricNamedValue* attribute) {
attribute->value = DrmMetricValue::make<DrmMetricValue::stringValue>(value);
}
template <>
void SetValue(const unsigned int& value, DrmMetricNamedValue* attribute) {
attribute->value = DrmMetricValue::make<DrmMetricValue::int64Value>(value);
}
template <>
__attribute__((unused)) void SetValue(const unsigned long& value,
DrmMetricNamedValue* attribute) {
attribute->value = DrmMetricValue::make<DrmMetricValue::int64Value>(value);
}
template <>
__attribute__((unused)) void SetValue(const unsigned long long& value,
DrmMetricNamedValue* attribute) {
attribute->value = DrmMetricValue::make<DrmMetricValue::int64Value>(value);
}
template <typename T>
void AddAttribute(const std::string& name, T value,
std::vector<DrmMetricNamedValue>* attribute_vector) {
// Set the default values.
DrmMetricNamedValue attribute;
attribute.name = name;
SetValue(value, &attribute);
attribute_vector->push_back(attribute);
}
} // anonymous namespace
void WvMetricsGroupBuilder::AddDistributions(
const std::string& name,
const RepeatedPtrField<drm_metrics::DistributionMetric>& distributions) {
for (const auto& metric : distributions) {
AddDistribution(name, metric);
}
}
void WvMetricsGroupBuilder::AddCounters(
const std::string& name,
const RepeatedPtrField<drm_metrics::CounterMetric>& counters) {
for (const auto& counter : counters) {
AddCounter(name, counter);
}
}
void WvMetricsGroupBuilder::AddDistribution(
const std::string& name,
const drm_metrics::DistributionMetric& distribution) {
DrmMetric metric;
metric.name = name;
AddAttributes(distribution.attributes(), &(metric.attributes));
DrmMetricNamedValue mean, count;
mean.name = "mean";
SetValue(distribution.mean(), &mean);
count.name = "count";
SetValue(distribution.operation_count(), &count);
if (distribution.operation_count() == 1) {
metric.values.resize(2);
metric.values[0] = mean;
metric.values[1] = count;
} else {
DrmMetricNamedValue min, max, variance;
min.name = "min";
SetValue(distribution.min(), &min);
max.name = "max";
SetValue(distribution.max(), &max);
variance.name = "variance";
SetValue(distribution.variance(), &variance);
metric.values.resize(5);
metric.values[0] = mean;
metric.values[1] = count;
metric.values[2] = min;
metric.values[3] = max;
metric.values[4] = variance;
}
metrics_.push_back(metric);
}
void WvMetricsGroupBuilder::AddCounter(
const std::string& name, const drm_metrics::CounterMetric& counter) {
DrmMetric metric;
metric.name = name;
AddAttributes(counter.attributes(), &(metric.attributes));
DrmMetricNamedValue count;
count.name = "count";
SetValue(counter.count(), &count);
metric.values.resize(1);
metric.values[0] = count;
metrics_.push_back(metric);
}
void WvMetricsGroupBuilder::AddValue(
const std::string& name, const drm_metrics::ValueMetric& value_or_error) {
DrmMetric metric;
DrmMetricNamedValue value;
metric.name = name;
if (value_or_error.has_error_code()) {
value.name = "error_code";
SetValue(value_or_error.error_code(), &value);
} else if (value_or_error.has_int_value()) {
value.name = "value";
SetValue(value_or_error.int_value(), &value);
} else if (value_or_error.has_double_value()) {
value.name = "value";
SetValue(value_or_error.double_value(), &value);
} else if (value_or_error.has_string_value()) {
value.name = "value";
SetValue(value_or_error.string_value(), &value);
} else {
value.name = "error";
SetValue(std::string("Unexpected value type"), &value);
}
metric.values.resize(1);
metric.values[0] = value;
metrics_.push_back(metric);
}
void WvMetricsGroupBuilder::AddAttributes(
const drm_metrics::Attributes& attributes_proto,
std::vector<DrmMetricNamedValue>* attributes) {
std::vector<DrmMetricNamedValue> attribute_vector;
if (attributes_proto.has_error_code()) {
AddAttribute(kAttributeErrorCode, attributes_proto.error_code(),
&attribute_vector);
}
if (attributes_proto.has_error_code_bool()) {
AddAttribute(kAttributeErrorCodeBool, attributes_proto.error_code_bool(),
&attribute_vector);
}
if (attributes_proto.has_cdm_security_level()) {
AddAttribute(kAttributeCdmSecurityLevel,
attributes_proto.cdm_security_level(), &attribute_vector);
}
if (attributes_proto.has_security_level()) {
AddAttribute(kAttributeSecurityLevel, attributes_proto.security_level(),
&attribute_vector);
}
if (attributes_proto.has_length()) {
AddAttribute(kAttributeLength, attributes_proto.length(),
&attribute_vector);
}
if (attributes_proto.has_encryption_algorithm()) {
AddAttribute(kAttributeEncryptionAlgorithm,
attributes_proto.encryption_algorithm(), &attribute_vector);
}
if (attributes_proto.has_signing_algorithm()) {
AddAttribute(kAttributeSigningAlgorithm,
attributes_proto.signing_algorithm(), &attribute_vector);
}
if (attributes_proto.has_oem_crypto_result()) {
AddAttribute(kAttributeOemCryptoResult,
attributes_proto.oem_crypto_result(), &attribute_vector);
}
if (attributes_proto.has_key_status_type()) {
AddAttribute(kAttributeKeyStatusType, attributes_proto.key_status_type(),
&attribute_vector);
}
if (attributes_proto.has_event_type()) {
AddAttribute(kAttributeEventType, attributes_proto.event_type(),
&attribute_vector);
}
if (attributes_proto.has_key_request_type()) {
AddAttribute(kAttributeKeyRequestType, attributes_proto.key_request_type(),
&attribute_vector);
}
if (attributes_proto.has_license_type()) {
AddAttribute(kAttributeLicenseType, attributes_proto.license_type(),
&attribute_vector);
}
*attributes = attribute_vector;
}
DrmMetricGroup WvMetricsGroupBuilder::Build() {
DrmMetricGroup metric_group;
metric_group.metrics = metrics_;
return metric_group;
}
WvMetricsGroupBuilder::WvMetricsGroupBuilder() {}
WvMetricsAdapter::WvMetricsAdapter() {}
WvMetricsAdapter::~WvMetricsAdapter() {}
void WvMetricsAdapter::AddEngineMetrics(
const drm_metrics::WvCdmMetrics::EngineMetrics& proto_metrics) {
WvMetricsGroupBuilder group_builder;
AddCryptoMetrics(proto_metrics.crypto_metrics(), &group_builder);
if (proto_metrics.has_oemcrypto_initialization_mode()) {
group_builder.AddValue("oemcrypto_initialization_mode",
proto_metrics.oemcrypto_initialization_mode());
}
if (proto_metrics.has_oemcrypto_l1_api_version()) {
group_builder.AddValue("oemcrypto_l1_api_version",
proto_metrics.oemcrypto_l1_api_version());
}
if (proto_metrics.has_oemcrypto_l1_min_api_version()) {
group_builder.AddValue("oemcrypto_l1_min_api_version",
proto_metrics.oemcrypto_l1_min_api_version());
}
if (proto_metrics.has_app_package_name()) {
group_builder.AddValue("app_package_name",
proto_metrics.app_package_name());
}
group_builder.AddDistributions("cdm_engine_add_key_time_us",
proto_metrics.cdm_engine_add_key_time_us());
if (proto_metrics.has_cdm_engine_cdm_version()) {
group_builder.AddValue("cdm_engine_cdm_version",
proto_metrics.cdm_engine_cdm_version());
}
group_builder.AddCounters("cdm_engine_close_session",
proto_metrics.cdm_engine_close_session());
if (proto_metrics.has_cdm_engine_creation_time_millis()) {
group_builder.AddValue("cdm_engine_creation_time_millis",
proto_metrics.cdm_engine_creation_time_millis());
}
group_builder.AddDistributions("cdm_engine_decrypt_time_us",
proto_metrics.cdm_engine_decrypt_time_us());
group_builder.AddCounters("cdm_engine_find_session_for_key",
proto_metrics.cdm_engine_find_session_for_key());
group_builder.AddDistributions(
"cdm_engine_generate_key_request_time_us",
proto_metrics.cdm_engine_generate_key_request_time_us());
group_builder.AddDistributions(
"cdm_engine_get_provisioning_request_time_us",
proto_metrics.cdm_engine_get_provisioning_request_time_us());
group_builder.AddCounters("cdm_engine_get_secure_stop_ids",
proto_metrics.cdm_engine_get_secure_stop_ids());
group_builder.AddDistributions(
"cdm_engine_get_usage_info_time_us",
proto_metrics.cdm_engine_get_usage_info_time_us());
group_builder.AddDistributions(
"cdm_engine_handle_provisioning_response_time_us",
proto_metrics.cdm_engine_handle_provisioning_response_time_us());
if (proto_metrics.has_cdm_engine_life_span_ms()) {
group_builder.AddValue("cdm_engine_life_span_ms",
proto_metrics.cdm_engine_life_span_ms());
}
group_builder.AddCounters("cdm_engine_open_key_set_session",
proto_metrics.cdm_engine_open_key_set_session());
group_builder.AddCounters("cdm_engine_open_session",
proto_metrics.cdm_engine_open_session());
group_builder.AddDistributions(
"cdm_engine_query_key_status_time_us",
proto_metrics.cdm_engine_query_key_status_time_us());
group_builder.AddCounters("cdm_engine_release_all_usage_info",
proto_metrics.cdm_engine_release_all_usage_info());
group_builder.AddCounters("cdm_engine_release_usage_info",
proto_metrics.cdm_engine_release_usage_info());
group_builder.AddCounters("cdm_engine_remove_all_usage_info",
proto_metrics.cdm_engine_remove_all_usage_info());
group_builder.AddCounters("cdm_engine_remove_keys",
proto_metrics.cdm_engine_remove_keys());
group_builder.AddCounters("cdm_engine_remove_usage_info",
proto_metrics.cdm_engine_remove_usage_info());
group_builder.AddDistributions(
"cdm_engine_restore_key_time_us",
proto_metrics.cdm_engine_restore_key_time_us());
group_builder.AddCounters("cdm_engine_unprovision",
proto_metrics.cdm_engine_unprovision());
if (proto_metrics.has_level3_oemcrypto_initialization_error()) {
group_builder.AddValue(
"level3_oemcrypto_initialization_error",
proto_metrics.level3_oemcrypto_initialization_error());
}
if (proto_metrics.has_previous_oemcrypto_initialization_failure()) {
group_builder.AddValue(
"previous_oemcrypto_initialization_failure",
proto_metrics.previous_oemcrypto_initialization_failure());
}
group_vector_.emplace_back(group_builder.Build());
}
void WvMetricsAdapter::AddSessionMetrics(
const drm_metrics::WvCdmMetrics::SessionMetrics& proto_metrics) {
WvMetricsGroupBuilder group_builder;
AddCryptoMetrics(proto_metrics.crypto_metrics(), &group_builder);
if (proto_metrics.has_session_id()) {
group_builder.AddValue("session_id", proto_metrics.session_id());
}
if (proto_metrics.has_cdm_session_life_span_ms()) {
group_builder.AddValue("cdm_session_life_span_ms",
proto_metrics.cdm_session_life_span_ms());
}
group_builder.AddDistributions("cdm_session_renew_key_time_us",
proto_metrics.cdm_session_renew_key_time_us());
group_builder.AddCounters(
"cdm_session_restore_offline_session",
proto_metrics.cdm_session_restore_offline_session());
group_builder.AddCounters("cdm_session_restore_usage_session",
proto_metrics.cdm_session_restore_usage_session());
group_builder.AddDistributions(
"cdm_session_license_request_latency_ms",
proto_metrics.cdm_session_license_request_latency_ms());
if (proto_metrics.has_oemcrypto_build_info()) {
group_builder.AddValue("oemcrypto_build_info",
proto_metrics.oemcrypto_build_info());
}
if (proto_metrics.has_license_sdk_version()) {
group_builder.AddValue("license_sdk_version",
proto_metrics.license_sdk_version());
}
if (proto_metrics.has_license_service_version()) {
group_builder.AddValue("license_service_version",
proto_metrics.license_service_version());
}
if (proto_metrics.has_playback_id()) {
group_builder.AddValue("playback_id", proto_metrics.playback_id());
}
group_vector_.emplace_back(group_builder.Build());
}
void WvMetricsAdapter::AddCryptoMetrics(
const drm_metrics::WvCdmMetrics::CryptoMetrics& proto_metrics,
WvMetricsGroupBuilder* group_builder) {
if (proto_metrics.has_crypto_session_security_level()) {
group_builder->AddValue("crypto_session_security_level",
proto_metrics.crypto_session_security_level());
}
group_builder->AddCounters(
"crypto_session_delete_all_usage_reports",
proto_metrics.crypto_session_delete_all_usage_reports());
group_builder->AddCounters(
"crypto_session_delete_multiple_usage_information",
proto_metrics.crypto_session_delete_multiple_usage_information());
group_builder->AddDistributions(
"crypto_session_generic_decrypt_time_us",
proto_metrics.crypto_session_generic_decrypt_time_us());
group_builder->AddDistributions(
"crypto_session_generic_encrypt_time_us",
proto_metrics.crypto_session_generic_encrypt_time_us());
group_builder->AddDistributions(
"crypto_session_generic_sign_time_us",
proto_metrics.crypto_session_generic_sign_time_us());
group_builder->AddDistributions(
"crypto_session_generic_verify_time_us",
proto_metrics.crypto_session_generic_verify_time_us());
group_builder->AddCounters(
"crypto_session_get_device_unique_id",
proto_metrics.crypto_session_get_device_unique_id());
group_builder->AddCounters("crypto_session_get_token",
proto_metrics.crypto_session_get_token());
if (proto_metrics.has_crypto_session_life_span()) {
group_builder->AddValue("crypto_session_life_span",
proto_metrics.crypto_session_life_span());
}
group_builder->AddDistributions(
"crypto_session_load_certificate_private_key_time_us",
proto_metrics.crypto_session_load_certificate_private_key_time_us());
group_builder->AddDistributions("crypto_session_open_time_us",
proto_metrics.crypto_session_open_time_us());
if (proto_metrics.has_crypto_session_system_id()) {
group_builder->AddValue("crypto_session_system_id",
proto_metrics.crypto_session_system_id());
}
group_builder->AddDistributions(
"crypto_session_update_usage_information_time_us",
proto_metrics.crypto_session_update_usage_information_time_us());
if (proto_metrics.has_crypto_session_usage_information_support()) {
group_builder->AddValue(
"crypto_session_usage_information_support",
proto_metrics.crypto_session_usage_information_support());
}
if (proto_metrics.has_usage_table_header_initial_size()) {
group_builder->AddValue("usage_table_header_initial_size",
proto_metrics.usage_table_header_initial_size());
}
group_builder->AddCounters("usage_table_header_add_entry",
proto_metrics.usage_table_header_add_entry());
group_builder->AddCounters("usage_table_header_delete_entry",
proto_metrics.usage_table_header_delete_entry());
group_builder->AddDistributions(
"usage_table_header_update_entry_time_us",
proto_metrics.usage_table_header_update_entry_time_us());
group_builder->AddCounters("usage_table_header_load_entry",
proto_metrics.usage_table_header_load_entry());
if (proto_metrics.has_oemcrypto_api_version()) {
group_builder->AddValue("oemcrypto_api_version",
proto_metrics.oemcrypto_api_version());
}
group_builder->AddCounters("oemcrypto_close_session",
proto_metrics.oemcrypto_close_session());
group_builder->AddDistributions(
"oemcrypto_copy_buffer_time_us",
proto_metrics.oemcrypto_copy_buffer_time_us());
if (proto_metrics.has_oemcrypto_current_hdcp_capability()) {
group_builder->AddValue("oemcrypto_current_hdcp_capability",
proto_metrics.oemcrypto_current_hdcp_capability());
}
group_builder->AddCounters("oemcrypto_deactivate_usage_entry",
proto_metrics.oemcrypto_deactivate_usage_entry());
group_builder->AddDistributions(
"oemcrypto_decrypt_cenc_time_us",
proto_metrics.oemcrypto_decrypt_cenc_time_us());
group_builder->AddCounters("oemcrypto_delete_usage_entry",
proto_metrics.oemcrypto_delete_usage_entry());
group_builder->AddCounters("oemcrypto_delete_usage_table",
proto_metrics.oemcrypto_delete_usage_table());
group_builder->AddDistributions(
"oemcrypto_derive_keys_from_session_key_time_us",
proto_metrics.oemcrypto_derive_keys_from_session_key_time_us());
group_builder->AddCounters(
"oemcrypto_force_delete_usage_entry",
proto_metrics.oemcrypto_force_delete_usage_entry());
group_builder->AddDistributions(
"oemcrypto_generate_derived_keys_time_us",
proto_metrics.oemcrypto_generate_derived_keys_time_us());
group_builder->AddCounters("oemcrypto_generate_nonce",
proto_metrics.oemcrypto_generate_nonce());
group_builder->AddDistributions(
"oemcrypto_generate_rsa_signature_time_us",
proto_metrics.oemcrypto_generate_rsa_signature_time_us());
group_builder->AddDistributions(
"oemcrypto_generate_signature_time_us",
proto_metrics.oemcrypto_generate_signature_time_us());
group_builder->AddDistributions(
"oemcrypto_generic_decrypt_time_us",
proto_metrics.oemcrypto_generic_decrypt_time_us());
group_builder->AddDistributions(
"oemcrypto_generic_encrypt_time_us",
proto_metrics.oemcrypto_generic_encrypt_time_us());
group_builder->AddDistributions(
"oemcrypto_generic_sign_time_us",
proto_metrics.oemcrypto_generic_sign_time_us());
group_builder->AddDistributions(
"oemcrypto_generic_verify_time_us",
proto_metrics.oemcrypto_generic_verify_time_us());
group_builder->AddCounters("oemcrypto_get_device_id",
proto_metrics.oemcrypto_get_device_id());
group_builder->AddDistributions(
"oemcrypto_get_key_data_time_us",
proto_metrics.oemcrypto_get_key_data_time_us());
group_builder->AddCounters(
"oemcrypto_get_oem_public_certificate",
proto_metrics.oemcrypto_get_oem_public_certificate());
group_builder->AddCounters("oemcrypto_get_random",
proto_metrics.oemcrypto_get_random());
group_builder->AddDistributions("oemcrypto_initialize_time_us",
proto_metrics.oemcrypto_initialize_time_us());
if (proto_metrics.has_oemcrypto_is_anti_rollback_hw_present()) {
group_builder->AddValue(
"oemcrypto_is_anti_rollback_hw_present",
proto_metrics.oemcrypto_is_anti_rollback_hw_present());
}
if (proto_metrics.has_oemcrypto_is_keybox_valid()) {
group_builder->AddValue("oemcrypto_is_keybox_valid",
proto_metrics.oemcrypto_is_keybox_valid());
}
group_builder->AddDistributions(
"oemcrypto_load_device_drm_key_time_us",
proto_metrics.oemcrypto_load_device_drm_key_time_us());
group_builder->AddDistributions(
"oemcrypto_load_entitled_keys_time_us",
proto_metrics.oemcrypto_load_entitled_keys_time_us());
group_builder->AddDistributions("oemcrypto_load_keys_time_us",
proto_metrics.oemcrypto_load_keys_time_us());
if (proto_metrics.has_oemcrypto_max_hdcp_capability()) {
group_builder->AddValue("oemcrypto_max_hdcp_capability",
proto_metrics.oemcrypto_max_hdcp_capability());
}
if (proto_metrics.has_oemcrypto_max_number_of_sessions()) {
group_builder->AddValue("oemcrypto_max_number_of_sessions",
proto_metrics.oemcrypto_max_number_of_sessions());
}
if (proto_metrics.has_oemcrypto_number_of_open_sessions()) {
group_builder->AddValue("oemcrypto_number_of_open_sessions",
proto_metrics.oemcrypto_number_of_open_sessions());
}
if (proto_metrics.has_oemcrypto_provisioning_method()) {
group_builder->AddValue("oemcrypto_provisioning_method",
proto_metrics.oemcrypto_provisioning_method());
}
group_builder->AddDistributions(
"oemcrypto_refresh_keys_time_us",
proto_metrics.oemcrypto_refresh_keys_time_us());
group_builder->AddCounters("oemcrypto_report_usage",
proto_metrics.oemcrypto_report_usage());
group_builder->AddDistributions(
"oemcrypto_rewrap_device_rsa_key_time_us",
proto_metrics.oemcrypto_rewrap_device_rsa_key_time_us());
group_builder->AddDistributions(
"oemcrypto_rewrap_device_rsa_key_30_time_us",
proto_metrics.oemcrypto_rewrap_device_rsa_key_30_time_us());
if (proto_metrics.has_oemcrypto_security_patch_level()) {
group_builder->AddValue("oemcrypto_security_patch_level",
proto_metrics.oemcrypto_security_patch_level());
}
group_builder->AddDistributions("oemcrypto_select_key_time_us",
proto_metrics.oemcrypto_select_key_time_us());
if (proto_metrics.has_oemcrypto_usage_table_support()) {
group_builder->AddValue("oemcrypto_usage_table_support",
proto_metrics.oemcrypto_usage_table_support());
}
group_builder->AddCounters("oemcrypto_update_usage_table",
proto_metrics.oemcrypto_update_usage_table());
group_builder->AddCounters("oemcrypto_update_usage_entry",
proto_metrics.oemcrypto_update_usage_entry());
}
const std::vector<DrmMetricGroup> WvMetricsAdapter::GetWvGroupVector() {
return group_vector_;
}
void WvMetricsAdapter::ToWvMetrics(
const drm_metrics::WvCdmMetrics& proto_metrics,
std::vector<DrmMetricGroup>* wv_metrics) {
// Convert the engine level metrics
wvcdm::WvMetricsAdapter adapter;
if (proto_metrics.has_engine_metrics()) {
adapter.AddEngineMetrics(proto_metrics.engine_metrics());
}
for (const auto& session_metrics : proto_metrics.session_metrics()) {
adapter.AddSessionMetrics(session_metrics);
}
*wv_metrics = adapter.GetWvGroupVector();
}
} // namespace wvcdm