From e7edb5d2e2a559a892c0196ccf9099b5560d4f22 Mon Sep 17 00:00:00 2001 From: Adam Stone Date: Mon, 2 Apr 2018 17:29:42 -0700 Subject: [PATCH] Fix API support for Widevine vendor metrics This fixes Widevine's getMetrics call so that it will return vendor metrics through the Drm plugin 1.1 interface. Bug: 73724453 Test: New and existing unit tests. Updated and existing GTS. Google Play manual. Change-Id: Ie35128dc80bd6eabf9e1f3b9c1800256af77bc51 --- libwvdrmengine/mediadrm/Android.mk | 1 + .../mediadrm/include_hidl/WVDrmPlugin.h | 5 +- .../include_hidl/hidl_metrics_adapter.h | 113 ++++ .../mediadrm/src_hidl/WVDrmPlugin.cpp | 25 + .../src_hidl/hidl_metrics_adapter.cpp | 593 ++++++++++++++++++ libwvdrmengine/mediadrm/test/Android.mk | 60 ++ .../test/hidl_metrics_adapter_unittest.cpp | 442 +++++++++++++ 7 files changed, 1235 insertions(+), 4 deletions(-) create mode 100644 libwvdrmengine/mediadrm/include_hidl/hidl_metrics_adapter.h create mode 100644 libwvdrmengine/mediadrm/src_hidl/hidl_metrics_adapter.cpp create mode 100644 libwvdrmengine/mediadrm/test/hidl_metrics_adapter_unittest.cpp diff --git a/libwvdrmengine/mediadrm/Android.mk b/libwvdrmengine/mediadrm/Android.mk index e6b40a23..89f040c5 100644 --- a/libwvdrmengine/mediadrm/Android.mk +++ b/libwvdrmengine/mediadrm/Android.mk @@ -43,6 +43,7 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES := \ src_hidl/WVDrmPlugin.cpp \ src_hidl/WVGenericCryptoInterface.cpp \ + src_hidl/hidl_metrics_adapter.cpp \ LOCAL_C_INCLUDES := \ frameworks/av/include \ diff --git a/libwvdrmengine/mediadrm/include_hidl/WVDrmPlugin.h b/libwvdrmengine/mediadrm/include_hidl/WVDrmPlugin.h index 60d6f6a1..c4218762 100644 --- a/libwvdrmengine/mediadrm/include_hidl/WVDrmPlugin.h +++ b/libwvdrmengine/mediadrm/include_hidl/WVDrmPlugin.h @@ -125,10 +125,7 @@ struct WVDrmPlugin : public IDrmPlugin, IDrmPluginListener, Return releaseSecureStop( const hidl_vec& secureStopId) override; - Return getMetrics(getMetrics_cb _hidl_cb) { - _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, hidl_vec()); - return Void(); - } + Return getMetrics(getMetrics_cb _hidl_cb); Return getSecureStopIds(getSecureStopIds_cb _hidl_cb) override; diff --git a/libwvdrmengine/mediadrm/include_hidl/hidl_metrics_adapter.h b/libwvdrmengine/mediadrm/include_hidl/hidl_metrics_adapter.h new file mode 100644 index 00000000..eda3160f --- /dev/null +++ b/libwvdrmengine/mediadrm/include_hidl/hidl_metrics_adapter.h @@ -0,0 +1,113 @@ +// +// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine Master +// License Agreement. +// + +#ifndef CDM_HIDL_METRICS_ADAPTER_H_ +#define CDM_HIDL_METRICS_ADAPTER_H_ + +#include + +#include + +#include "metrics.pb.h" + +namespace wvcdm { + +// Convenience alias. Used only in the declaration of HidlMetricsGroup. +namespace internal { +using DrmMetricGroup = android::hardware::drm::V1_1::DrmMetricGroup; +} // namespace internal + +class HidlMetricsAdapter; + +// This class is used to convert from the metrics.proto format for metrics +// to the format specified in the android.hardware.drm@1.1 DrmMetricGroup +// type. This class converts the common metric types into a single group. +// +// Example: +// drm_metrics::DistributionMetric distribution; +// distribution.set_operation_count(1); +// HidlMetricsGroupBuilder builder; +// builder.AddDistributions("test distribution", { distribution }); +// +// DrmMetricGroup group = builder.Build(); +class HidlMetricsGroupBuilder { + public: + // Adds a group of distributions with the given base name. + void AddDistributions( + const std::string& name, + const google::protobuf::RepeatedPtrField< + drm_metrics::DistributionMetric>& distributions); + + // Adds a group of counter metrics with the given base name. + void AddCounters( + const std::string& name, + const google::protobuf::RepeatedPtrField< + drm_metrics::CounterMetric>& counters); + + // Adds a value metric. + void AddValue(const std::string& name, + const drm_metrics::ValueMetric& value_or_error); + + // Builds the metric group containing all of the previously added metrics. + internal::DrmMetricGroup Build(); + + private: + friend class HidlMetricsAdapter; + std::vector metrics_; + + HidlMetricsGroupBuilder(); + // Adds a distribution with the given name and distribution values. + void AddDistribution(const std::string& name, + const drm_metrics::DistributionMetric& distribution); + // Adds a counter metric + void AddCounter(const std::string& name, + const drm_metrics::CounterMetric& counter); + void AddAttributes( + const drm_metrics::Attributes& attributes_proto, + ::android::hardware::hidl_vec* + attributes); +}; + +// This class handles adding the engine and session metric collections. This +// will generate one DrmMetricGroup for each EngineMetric added and one for +// each SessionMetric added. This class also supports a static utility method to +// convert a WvCdmMetrics proto to a vector of DrmMetricGroup instances. +class HidlMetricsAdapter { + public: + // Utility method to quickly convert a WvCdmMetrics proto to a DrmMetricGroup + // vector. + static void ToHidlMetrics( + const drm_metrics::WvCdmMetrics& proto_metrics, + android::hardware::hidl_vec* hidl_metrics); + + HidlMetricsAdapter(); + ~HidlMetricsAdapter(); + + // Adds the EngineMetrics instance to the Adapter. It will be converted and + // stored. The converted metrics can be fetched via GetHidlGroupVector. + void AddEngineMetrics( + const drm_metrics::WvCdmMetrics::EngineMetrics& proto_metrics); + + // Adds the SessionMetrics instance to the Adapter. It will be converted and + // stored. The converted metrics can be fetched via GetHidlGroupVector. + void AddSessionMetrics( + const drm_metrics::WvCdmMetrics::SessionMetrics& proto_metrics); + + // Returns the converted DrmMetricGroup vector containing all of the + // previously added engine and session metrics collections. + const android::hardware::hidl_vec + GetHidlGroupVector(); + + private: + void AddCryptoMetrics( + const drm_metrics::WvCdmMetrics::CryptoMetrics& proto_metrics, + HidlMetricsGroupBuilder* group_builder); + std::vector group_vector_; +}; + +} // namespace wvcdm + +#endif // CDM_HIDL_METRICS_ADAPTER_H_ diff --git a/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp b/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp index eb790f5b..2ce0973f 100644 --- a/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp +++ b/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp @@ -14,6 +14,7 @@ #include "WVDrmPlugin.h" #include "TypeConvert.h" +#include "hidl_metrics_adapter.h" #include "mapErrors-inl.h" #include "media/stagefright/MediaErrors.h" #include "metrics.pb.h" @@ -41,6 +42,7 @@ using ::android::hardware::drm::V1_0::KeyRequestType; using ::android::hardware::drm::V1_0::KeyStatusType; using ::android::hardware::drm::V1_0::KeyType; using ::android::hardware::drm::V1_0::Status; +using ::android::hardware::drm::V1_1::DrmMetricGroup; using ::android::hardware::drm::V1_1::SecurityLevel; using ::android::hardware::drm::V1_1::widevine::toHidlVec; using ::android::hardware::drm::V1_1::widevine::toVector; @@ -757,6 +759,29 @@ Return WVDrmPlugin::releaseSecureStop( return mapCdmResponseType(res); } +Return WVDrmPlugin::getMetrics(getMetrics_cb _hidl_cb) { + hidl_vec hidl_metrics; + CdmIdentifier identifier; + Status status = mCdmIdentifierBuilder.getCdmIdentifier(&identifier); + if (status != Status::OK) { + _hidl_cb(status, hidl_metrics); + return Void(); + } + + drm_metrics::WvCdmMetrics proto_metrics; + CdmResponseType result = mCDM->GetMetrics(identifier, &proto_metrics); + if (result != wvcdm::NO_ERROR) { + status = mapCdmResponseType(result); + _hidl_cb(status, hidl_metrics); + return Void(); + } + + ::wvcdm::HidlMetricsAdapter adapter; + ::wvcdm::HidlMetricsAdapter::ToHidlMetrics(proto_metrics, &hidl_metrics); + _hidl_cb(Status::OK, hidl_metrics); + return Void(); +} + Return WVDrmPlugin::getSecureStopIds(getSecureStopIds_cb _hidl_cb) { std::vector secureStopIds; diff --git a/libwvdrmengine/mediadrm/src_hidl/hidl_metrics_adapter.cpp b/libwvdrmengine/mediadrm/src_hidl/hidl_metrics_adapter.cpp new file mode 100644 index 00000000..e1b418bc --- /dev/null +++ b/libwvdrmengine/mediadrm/src_hidl/hidl_metrics_adapter.cpp @@ -0,0 +1,593 @@ +// +// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine Master +// License Agreement. +// + +#include "hidl_metrics_adapter.h" + +#include +#include "metrics.pb.h" + +using android::hardware::hidl_vec; +using android::hardware::drm::V1_1::DrmMetricGroup; +using drm_metrics::CounterMetric; +using drm_metrics::DistributionMetric; +using google::protobuf::RepeatedPtrField; + +namespace wvcdm { + +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"; + +template +void SetValue(const T& value, DrmMetricGroup::Attribute* attribute); + +template<> +void SetValue(const int& value, DrmMetricGroup::Attribute* attribute) { + attribute->int64Value = value; +} +template<> +void SetValue(const bool& value, DrmMetricGroup::Attribute* attribute) { + attribute->int64Value = value; +} +template<> +void SetValue(const unsigned int& value, + DrmMetricGroup::Attribute* attribute) { + attribute->int64Value = value; +} +template<> +void SetValue(const unsigned long long& value, + DrmMetricGroup::Attribute* attribute) { + attribute->int64Value = value; +} + +template +void AddAttribute( + const std::string& name, DrmMetricGroup::ValueType vt, T value, + std::vector* attribute_vector) { + // Set the default values. + DrmMetricGroup::Attribute attribute = { name, vt, 0, 0, "" }; + SetValue(value, &attribute); + attribute_vector->push_back(attribute); +} + +} // anonymous namespace + +void HidlMetricsGroupBuilder::AddDistributions( + const std::string& name, + const RepeatedPtrField& distributions) { + for (const auto& metric : distributions) { + AddDistribution(name, metric); + } +} + +void HidlMetricsGroupBuilder::AddCounters( + const std::string& name, + const RepeatedPtrField& counters) { + for (const auto& counter : counters) { + AddCounter(name, counter); + } +} + +void HidlMetricsGroupBuilder::AddDistribution( + const std::string& name, const drm_metrics::DistributionMetric& distribution) { + DrmMetricGroup::Metric metric; + metric.name = name; + AddAttributes(distribution.attributes(), &(metric.attributes)); + + DrmMetricGroup::Value mean = { + "mean", DrmMetricGroup::ValueType::DOUBLE_TYPE, + 0, distribution.mean(), "" }; + DrmMetricGroup::Value count = { + "count", DrmMetricGroup::ValueType::INT64_TYPE, + (int64_t) distribution.operation_count(), 0, "" }; + + if (distribution.operation_count() == 1) { + metric.values.resize(2); + metric.values[0] = mean; + metric.values[1] = count; + } else { + DrmMetricGroup::Value min = { + "min", DrmMetricGroup::ValueType::DOUBLE_TYPE, + 0, distribution.min(), "" }; + DrmMetricGroup::Value max = { + "max", DrmMetricGroup::ValueType::DOUBLE_TYPE, + 0, distribution.max(), "" }; + DrmMetricGroup::Value variance { + "variance", DrmMetricGroup::ValueType::DOUBLE_TYPE, + 0, distribution.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 HidlMetricsGroupBuilder::AddCounter( + const std::string& name, const drm_metrics::CounterMetric& counter) { + DrmMetricGroup::Metric metric; + metric.name = name; + AddAttributes(counter.attributes(), &(metric.attributes)); + + DrmMetricGroup::Value value = { + "count", DrmMetricGroup::ValueType::INT64_TYPE, counter.count(), 0, "" }; + metric.values.resize(1); + metric.values[0] = value; + metrics_.push_back(metric); +} + +void HidlMetricsGroupBuilder::AddValue( + const std::string& name, const drm_metrics::ValueMetric& value_or_error) { + DrmMetricGroup::Metric metric; + DrmMetricGroup::Value value; + + metric.name = name; + if (value_or_error.has_error_code()) { + value = { "error_code", DrmMetricGroup::ValueType::INT64_TYPE, + value_or_error.error_code(), 0, "" }; + } else if (value_or_error.has_int_value()) { + value = { "value", DrmMetricGroup::ValueType::INT64_TYPE, + value_or_error.int_value(), 0, "" }; + } else if (value_or_error.has_double_value()) { + value = { "value", DrmMetricGroup::ValueType::DOUBLE_TYPE, + 0, value_or_error.double_value(), "" }; + } else if (value_or_error.has_string_value()) { + value = { "value", DrmMetricGroup::ValueType::STRING_TYPE, + 0, 0, value_or_error.string_value() }; + } else { + value = { "error", DrmMetricGroup::ValueType::STRING_TYPE, + 0, 0, "Unexpected value type." }; + } + metric.values.resize(1); + metric.values[0] = value; + metrics_.push_back(metric); +} + +void HidlMetricsGroupBuilder::AddAttributes( + const drm_metrics::Attributes& attributes_proto, + hidl_vec* + attributes) { + std::vector + attribute_vector; + if (attributes_proto.has_error_code()) { + AddAttribute( + kAttributeErrorCode, + DrmMetricGroup::ValueType::INT64_TYPE, + attributes_proto.error_code(), &attribute_vector); + } + if (attributes_proto.has_error_code_bool()) { + AddAttribute( + kAttributeErrorCodeBool, + DrmMetricGroup::ValueType::INT64_TYPE, + attributes_proto.error_code_bool(), &attribute_vector); + } + if (attributes_proto.has_cdm_security_level()) { + AddAttribute( + kAttributeCdmSecurityLevel, + DrmMetricGroup::ValueType::INT64_TYPE, + attributes_proto.cdm_security_level(), &attribute_vector); + } + if (attributes_proto.has_security_level()) { + AddAttribute( + kAttributeSecurityLevel, + DrmMetricGroup::ValueType::INT64_TYPE, + attributes_proto.security_level(), &attribute_vector); + } + if (attributes_proto.has_length()) { + AddAttribute( + kAttributeLength, + DrmMetricGroup::ValueType::INT64_TYPE, + attributes_proto.length(), &attribute_vector); + } + if (attributes_proto.has_encryption_algorithm()) { + AddAttribute( + kAttributeEncryptionAlgorithm, + DrmMetricGroup::ValueType::INT64_TYPE, + attributes_proto.encryption_algorithm(), &attribute_vector); + } + if (attributes_proto.has_signing_algorithm()) { + AddAttribute( + kAttributeSigningAlgorithm, + DrmMetricGroup::ValueType::INT64_TYPE, + attributes_proto.signing_algorithm(), &attribute_vector); + } + if (attributes_proto.has_oem_crypto_result()) { + AddAttribute( + kAttributeOemCryptoResult, + DrmMetricGroup::ValueType::INT64_TYPE, + attributes_proto.oem_crypto_result(), &attribute_vector); + } + if (attributes_proto.has_key_status_type()) { + AddAttribute( + kAttributeKeyStatusType, + DrmMetricGroup::ValueType::INT64_TYPE, + attributes_proto.key_status_type(), &attribute_vector); + } + if (attributes_proto.has_event_type()) { + AddAttribute( + kAttributeEventType, + DrmMetricGroup::ValueType::INT64_TYPE, + attributes_proto.event_type(), &attribute_vector); + } + if (attributes_proto.has_key_request_type()) { + AddAttribute( + kAttributeKeyRequestType, + DrmMetricGroup::ValueType::INT64_TYPE, + attributes_proto.key_request_type(), &attribute_vector); + } + + *attributes = attribute_vector; +} + +DrmMetricGroup HidlMetricsGroupBuilder::Build() { + DrmMetricGroup metric_group; + metric_group.metrics = metrics_; + return metric_group; +} + +HidlMetricsGroupBuilder::HidlMetricsGroupBuilder() {} + +HidlMetricsAdapter::HidlMetricsAdapter() {} +HidlMetricsAdapter::~HidlMetricsAdapter() {} + +void HidlMetricsAdapter::AddEngineMetrics( + const drm_metrics::WvCdmMetrics::EngineMetrics& proto_metrics) { + HidlMetricsGroupBuilder 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()); + + group_vector_.emplace_back(group_builder.Build()); +} + +void HidlMetricsAdapter::AddSessionMetrics( + const drm_metrics::WvCdmMetrics::SessionMetrics& proto_metrics) { + HidlMetricsGroupBuilder 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()); + group_vector_.emplace_back(group_builder.Build()); +} + +void HidlMetricsAdapter::AddCryptoMetrics( + const drm_metrics::WvCdmMetrics::CryptoMetrics& proto_metrics, + HidlMetricsGroupBuilder* 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()); + group_builder->AddDistributions( + "crypto_session_update_usage_entry_time_us", + proto_metrics.crypto_session_update_usage_entry_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_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_rsa_key_time_us", + proto_metrics.oemcrypto_load_device_rsa_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 android::hardware::hidl_vec< + DrmMetricGroup> +HidlMetricsAdapter::GetHidlGroupVector() { + return group_vector_; +} + +void HidlMetricsAdapter::ToHidlMetrics( + const drm_metrics::WvCdmMetrics& proto_metrics, + hidl_vec* hidl_metrics) { + // Convert the engine level metrics + HidlMetricsAdapter 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); + } + + *hidl_metrics = adapter.GetHidlGroupVector(); +} + +} // namespace wvcdm diff --git a/libwvdrmengine/mediadrm/test/Android.mk b/libwvdrmengine/mediadrm/test/Android.mk index c5bc46b0..10c413ba 100644 --- a/libwvdrmengine/mediadrm/test/Android.mk +++ b/libwvdrmengine/mediadrm/test/Android.mk @@ -120,3 +120,63 @@ LOCAL_MODULE_TARGET_ARCH := arm x86 mips endif include $(BUILD_EXECUTABLE) + +# ----------------------------------------------------------------------------- +# Builds hidl_metrics_adapter_unittest +# +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + hidl_metrics_adapter_unittest.cpp \ + +LOCAL_C_INCLUDES := \ + vendor/widevine/libwvdrmengine/cdm/core/include \ + vendor/widevine/libwvdrmengine/cdm/include \ + vendor/widevine/libwvdrmengine/cdm/metrics/include \ + vendor/widevine/libwvdrmengine/include_hidl \ + vendor/widevine/libwvdrmengine/include \ + vendor/widevine/libwvdrmengine/mediadrm/include_hidl \ + vendor/widevine/libwvdrmengine/mediadrm/include \ + vendor/widevine/libwvdrmengine/oemcrypto/include \ + +LOCAL_STATIC_LIBRARIES := \ + libcdm \ + libcdm_protos \ + libcdm_utils \ + libgtest \ + libgtest_main \ + libwvdrmdrmplugin_hidl \ + libcrypto \ + libjsmn \ + libwvlevel3 \ + libwvdrmdrmplugin_hidl \ + +LOCAL_SHARED_LIBRARIES := \ + android.hardware.drm@1.0 \ + android.hardware.drm@1.1 \ + android.hidl.memory@1.0 \ + libhidlbase \ + libhidlmemory \ + libhidltransport \ + liblog \ + libprotobuf-cpp-lite \ + +LOCAL_C_INCLUDES += \ + external/protobuf/src \ + +LOCAL_MODULE := hidl_metrics_adapter_unittest + +LOCAL_MODULE_TAGS := tests + +LOCAL_MODULE_OWNER := widevine +LOCAL_PROPRIETARY_MODULE := true + +# When built, explicitly put it in the DATA/bin directory. +LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/bin + +ifneq ($(TARGET_ENABLE_MEDIADRM_64), true) +LOCAL_MODULE_TARGET_ARCH := arm x86 mips +endif + +include $(BUILD_EXECUTABLE) + diff --git a/libwvdrmengine/mediadrm/test/hidl_metrics_adapter_unittest.cpp b/libwvdrmengine/mediadrm/test/hidl_metrics_adapter_unittest.cpp new file mode 100644 index 00000000..50855ae5 --- /dev/null +++ b/libwvdrmengine/mediadrm/test/hidl_metrics_adapter_unittest.cpp @@ -0,0 +1,442 @@ +// +// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine Master +// License Agreement. +// + +// This file contains unit tests for the HidlMetricsAdapter. + +#include "hidl_metrics_adapter.h" + +#include +#include +#include + +#include "gtest/gtest.h" +#include "metrics.pb.h" + +using android::hardware::hidl_vec; +using android::hardware::drm::V1_1::DrmMetricGroup; +using drm_metrics::CounterMetric; +using drm_metrics::DistributionMetric; + +namespace { + +template +std::string ToString(const T& attribute_or_value) { + std::ostringstream os; + switch (attribute_or_value.type) { + case DrmMetricGroup::ValueType::DOUBLE_TYPE: + os << "DOUBLE_TYPE. value: " << attribute_or_value.doubleValue; + break; + case DrmMetricGroup::ValueType::INT64_TYPE: + os << "INT64_TYPE. value: " << attribute_or_value.int64Value; + break; + case DrmMetricGroup::ValueType::STRING_TYPE: + os << "STRING_TYPE. value: " << attribute_or_value.stringValue; + break; + default: + os << "UNKNOWN TYPE!!: " << (int64_t) attribute_or_value.type; + break; + } + os << " (" << attribute_or_value.int64Value << "," + << attribute_or_value.doubleValue << ",\"" + << attribute_or_value.stringValue << "\")"; + return os.str(); +} + +std::string ToString(const DrmMetricGroup::Metric& metric) { + std::ostringstream os; + os << "metric: " << metric.name << std::endl; + os << " attributes:" << std::endl; + for (unsigned a = 0; a < metric.attributes.size(); a++) { + os << " " << metric.attributes[a].name << ". " + << ToString(metric.attributes[a]) << std::endl; + } + os << " values:" << std::endl; + for (unsigned v = 0; v < metric.values.size(); v++) { + os << " " << metric.values[v].componentName << ". " + << ToString(metric.values[v]) << std::endl; + } + return os.str(); +} + +std::string ToString(const hidl_vec& metrics_vector) { + std::ostringstream os; + os << "hidl metrics..." << std::endl; + os << "group count: " << metrics_vector.size() << std::endl; + for (unsigned g = 0; g < metrics_vector.size(); g++) { + os << "group " << g << ". metric count: " + << metrics_vector[g].metrics.size() << std::endl; + for (unsigned m = 0; m < metrics_vector[g].metrics.size(); m++) { + const DrmMetricGroup::Metric metric = metrics_vector[g].metrics[m]; + os << ToString(metric); + } + } + return os.str(); +} + +bool HasMetric(const DrmMetricGroup::Metric& expected, + const DrmMetricGroup& actual_metrics) { + DrmMetricGroup::Metric metric; + auto it = std::find(actual_metrics.metrics.begin(), + actual_metrics.metrics.end(), expected); + if (it == actual_metrics.metrics.end()) { + ALOGE("COULDN'T FIND THE METRIC! %s", ToString(expected).c_str()); + for (auto it = actual_metrics.metrics.begin(); + it < actual_metrics.metrics.end(); it++) { + if (expected.name == it->name) { + ALOGE("Names match."); + } + if (expected.attributes == it->attributes) { + ALOGE("attributes match."); + } + if (expected.values == it->values) { + ALOGE("values match."); + } else { + ALOGE("values length match? %d, %d", + expected.values.size(), it->values.size()); + if (expected.values.size() == it->values.size()) { + for (unsigned int i = 0; i < expected.values.size(); i++) { + ALOGE("value %d match? %d", i, expected.values[i] == it->values[i]); + if (expected.values[i] != it->values[i]) { + ALOGE("value component mismatch. %d. %s, %s", + i, expected.values[i].componentName.c_str(), + it->values[i].componentName.c_str()); + } + } + } + } + } + } else { + ALOGE("Found metric: %s", ToString(*it).c_str()); + } + return it != actual_metrics.metrics.end(); +} + +} // anonymous namespace + +namespace wvcdm { + +TEST(HidlMetricsAdapterTest, EmptyMetrics) { + drm_metrics::WvCdmMetrics metrics_proto; + hidl_vec hidl_metrics; + + HidlMetricsAdapter::ToHidlMetrics(metrics_proto, &hidl_metrics); + ASSERT_EQ(0U, hidl_metrics.size()) << ToString(hidl_metrics); +} + +// Adds a metric from each type - Value, counter and distribution. +TEST(HidlMetricsAdapterTest, AllMetricTypes) { + drm_metrics::WvCdmMetrics metrics_proto; + + // Value metric - error. + metrics_proto + .mutable_engine_metrics() + ->mutable_crypto_metrics() + ->mutable_crypto_session_security_level() + ->set_error_code(7); + DrmMetricGroup::Metric expected_value_metric_1 = { + "crypto_session_security_level", + {}, + { { "error_code", DrmMetricGroup::ValueType::INT64_TYPE, 7, 0, "" } } + }; + + // Value metric - integer. + metrics_proto + .mutable_engine_metrics() + ->mutable_oemcrypto_initialization_mode() + ->set_int_value(11); + DrmMetricGroup::Metric expected_value_metric_2 = { + "oemcrypto_initialization_mode", + {}, + { { "value", DrmMetricGroup::ValueType::INT64_TYPE, 11, 0, "" } } + }; + + // Value metric - double. + metrics_proto + .mutable_engine_metrics() + ->mutable_cdm_engine_life_span_ms() + ->set_double_value(3.14159); + DrmMetricGroup::Metric expected_value_metric_3 = { + "cdm_engine_life_span_ms", + {}, + { { "value", DrmMetricGroup::ValueType::DOUBLE_TYPE, 0, 3.14159, "" } } + }; + + // Value metric - string. + metrics_proto + .mutable_engine_metrics() + ->mutable_cdm_engine_cdm_version() + ->set_string_value("test"); + DrmMetricGroup::Metric expected_value_metric_4 = { + "cdm_engine_cdm_version", + {}, + { { "value", DrmMetricGroup::ValueType::STRING_TYPE, 0, 0, "test" } } + }; + + // Counter metric + CounterMetric* counter = metrics_proto.mutable_engine_metrics() + ->mutable_crypto_metrics()->add_crypto_session_get_token(); + counter->set_count(13); + counter->mutable_attributes()->set_error_code(17); + DrmMetricGroup::Metric expected_counter_metric_1 = { + "crypto_session_get_token", + { { "error_code", DrmMetricGroup::ValueType::INT64_TYPE, 17, 0, "" } }, + { { "count", DrmMetricGroup::ValueType::INT64_TYPE, 13, 0, "" } } + }; + // Add a second counter. + counter = metrics_proto.mutable_engine_metrics() + ->mutable_crypto_metrics()->add_crypto_session_get_token(); + counter->set_count(19); + counter->mutable_attributes()->set_error_code(23); + DrmMetricGroup::Metric expected_counter_metric_2 = { + "crypto_session_get_token", + { { "error_code", DrmMetricGroup::ValueType::INT64_TYPE, 23, 0, "" } }, + { { "count", DrmMetricGroup::ValueType::INT64_TYPE, 19, 0, "" } } + }; + + // Distribution metric + DistributionMetric* distribution = metrics_proto.mutable_engine_metrics() + ->mutable_crypto_metrics()->add_crypto_session_open_time_us(); + distribution->set_min(1.0); + distribution->set_max(1.2); + distribution->set_mean(1.1); + distribution->set_variance(.01); + distribution->set_operation_count(2); + distribution->mutable_attributes()->set_error_code(0); + DrmMetricGroup::Metric expected_distribution_metric_1 = { + "crypto_session_open_time_us", + { { "error_code", DrmMetricGroup::ValueType::INT64_TYPE, 0, 0, "" } }, + { { "mean", DrmMetricGroup::ValueType::DOUBLE_TYPE, 0, 1.1f, "" }, + { "count", DrmMetricGroup::ValueType::INT64_TYPE, 2, 0, "" }, + { "min", DrmMetricGroup::ValueType::DOUBLE_TYPE, 0, 1.0, "" }, + { "max", DrmMetricGroup::ValueType::DOUBLE_TYPE, 0, 1.2f, "" }, + { "variance", DrmMetricGroup::ValueType::DOUBLE_TYPE, 0, 0.01, "" } } + }; + // Add a second distribution + distribution = metrics_proto.mutable_engine_metrics() + ->mutable_crypto_metrics()->add_crypto_session_open_time_us(); + distribution->set_mean(0.7); + distribution->set_operation_count(1); + distribution->mutable_attributes()->set_error_code(27); + DrmMetricGroup::Metric expected_distribution_metric_2 = { + "crypto_session_open_time_us", + { { "error_code", DrmMetricGroup::ValueType::INT64_TYPE, 27, 0, "" } }, + { { "mean", DrmMetricGroup::ValueType::DOUBLE_TYPE, 0, 0.7f, "" }, + { "count", DrmMetricGroup::ValueType::INT64_TYPE, 1, 0, "" } } + }; + + hidl_vec hidl_metrics; + + HidlMetricsAdapter::ToHidlMetrics(metrics_proto, &hidl_metrics); + ASSERT_EQ(1U, hidl_metrics.size()); + ASSERT_EQ(8U, hidl_metrics[0].metrics.size()) << ToString(hidl_metrics); + + EXPECT_TRUE(HasMetric(expected_value_metric_1, hidl_metrics[0])) + << "Missing value_metric_1. " << ToString(expected_value_metric_1) + << std::endl << "In metrics: " << ToString(hidl_metrics); + EXPECT_TRUE(HasMetric(expected_value_metric_2, hidl_metrics[0])) + << "Missing value_metric_2. " << ToString(expected_value_metric_2) + << std::endl << "In metrics: " << ToString(hidl_metrics); + EXPECT_TRUE(HasMetric(expected_value_metric_3, hidl_metrics[0])) + << "Missing value_metric_3." << ToString(expected_value_metric_3) + << std::endl << "In metrics: " << ToString(hidl_metrics); + EXPECT_TRUE(HasMetric(expected_value_metric_4, hidl_metrics[0])) + << "Missing value_metric_4. " << ToString(expected_value_metric_4) + << std::endl << "In metrics: " << ToString(hidl_metrics); + EXPECT_TRUE(HasMetric(expected_counter_metric_1, hidl_metrics[0])) + << "Missing counter_metric_1. " << ToString(expected_counter_metric_1) + << std::endl << "In metrics: " << ToString(hidl_metrics); + EXPECT_TRUE(HasMetric(expected_counter_metric_2, hidl_metrics[0])) + << "Missing counter_metric_2. " << ToString(expected_counter_metric_2) + << std::endl << "In metrics: " << ToString(hidl_metrics); + EXPECT_TRUE(HasMetric(expected_distribution_metric_1, hidl_metrics[0])) + << "Missing distribution_metric_1. " + << ToString(expected_distribution_metric_1) << std::endl + << "In metrics: " << ToString(hidl_metrics); + EXPECT_TRUE(HasMetric(expected_distribution_metric_2, hidl_metrics[0])) + << "Missing distribution_metric_2. " + << ToString(expected_distribution_metric_2) << std::endl + << "In metrics: " << ToString(hidl_metrics); +} + +// Add a single metric with all attributes to confirm that all attributes +// can be converted. +TEST(HidlMetricsAdapterTest, AddAllAttrbitues) { + // Create a test attribute proto with all attributes set. + drm_metrics::WvCdmMetrics metrics_proto; + CounterMetric* counter = metrics_proto.mutable_engine_metrics() + ->mutable_crypto_metrics()->add_crypto_session_get_token(); + counter->set_count(13); + drm_metrics::Attributes* attributes = counter->mutable_attributes(); + attributes->set_error_code(17); + attributes->set_error_code_bool(true); + attributes->set_cdm_security_level(19); + attributes->set_security_level(23); + attributes->set_length(29); + attributes->set_encryption_algorithm(31); + attributes->set_signing_algorithm(37); + attributes->set_oem_crypto_result(41); + attributes->set_key_status_type(43); + attributes->set_event_type(47); + attributes->set_key_request_type(53); + + DrmMetricGroup::Metric expected_counter_metric = { + "crypto_session_get_token", + { { "error_code", DrmMetricGroup::ValueType::INT64_TYPE, 17, 0, "" }, + { "error_code_bool", + DrmMetricGroup::ValueType::INT64_TYPE, true, 0, "" }, + { "cdm_security_level", + DrmMetricGroup::ValueType::INT64_TYPE, 19, 0, "" }, + { "security_level", + DrmMetricGroup::ValueType::INT64_TYPE, 23, 0, "" }, + { "length", DrmMetricGroup::ValueType::INT64_TYPE, 29, 0, "" }, + { "encryption_algorithm", + DrmMetricGroup::ValueType::INT64_TYPE, 31, 0, "" }, + { "signing_algorithm", + DrmMetricGroup::ValueType::INT64_TYPE, 37, 0, "" }, + { "oem_crypto_result", + DrmMetricGroup::ValueType::INT64_TYPE, 41, 0, "" }, + { "key_status_type", + DrmMetricGroup::ValueType::INT64_TYPE, 43, 0, "" }, + { "event_type", DrmMetricGroup::ValueType::INT64_TYPE, 47, 0, "" }, + { "key_request_type", + DrmMetricGroup::ValueType::INT64_TYPE, 53, 0, "" } }, + { { "count", DrmMetricGroup::ValueType::INT64_TYPE, 13, 0, "" } } }; + + // Confirm that all of the attributes exist in the hidl data. + hidl_vec hidl_metrics; + HidlMetricsAdapter::ToHidlMetrics(metrics_proto, &hidl_metrics); + EXPECT_TRUE(HasMetric(expected_counter_metric, hidl_metrics[0])) + << "Missing expected_counter_metrc. " + << ToString(expected_counter_metric) << std::endl + << "In metrics: " << ToString(hidl_metrics); +} + +// Add all session and engine metrics to cofirm that all are converted. +// Only check the counts since other tests confirm that metrics are converted +// properly. +TEST(HidlMetricsAdapterTest, EngineAndSessionAllMetrics) { + // Set all CryptoSession metrics. + drm_metrics::WvCdmMetrics::CryptoMetrics crypto_metrics; + crypto_metrics.mutable_crypto_session_security_level()->set_int_value(1); + crypto_metrics.add_crypto_session_delete_all_usage_reports()->set_count(13); + crypto_metrics.add_crypto_session_delete_multiple_usage_information + ()->set_count(13); + crypto_metrics.add_crypto_session_generic_decrypt_time_us()->set_min(1.0f); + crypto_metrics.add_crypto_session_generic_encrypt_time_us()->set_min(1.0f); + crypto_metrics.add_crypto_session_generic_sign_time_us()->set_min(1.0f); + crypto_metrics.add_crypto_session_generic_verify_time_us()->set_min(1.0f); + crypto_metrics.add_crypto_session_get_device_unique_id()->set_count(13); + crypto_metrics.add_crypto_session_get_token()->set_count(13); + crypto_metrics.mutable_crypto_session_life_span()->set_int_value(1); + crypto_metrics.add_crypto_session_load_certificate_private_key_time_us + ()->set_min(1.0f); + crypto_metrics.add_crypto_session_open_time_us()->set_min(1.0f); + crypto_metrics.mutable_crypto_session_system_id()->set_int_value(1); + crypto_metrics.add_crypto_session_update_usage_information_time_us + ()->set_min(1.0f); + crypto_metrics.add_crypto_session_update_usage_entry_time_us()->set_min(1.0f); + crypto_metrics.mutable_crypto_session_usage_information_support + ()->set_int_value(1); + // OemCrypto metrics. + crypto_metrics.mutable_oemcrypto_api_version()->set_int_value(1); + crypto_metrics.add_oemcrypto_close_session()->set_count(13); + crypto_metrics.add_oemcrypto_copy_buffer_time_us()->set_min(1.0f); + crypto_metrics.mutable_oemcrypto_current_hdcp_capability()->set_int_value(1); + crypto_metrics.add_oemcrypto_deactivate_usage_entry()->set_count(13); + crypto_metrics.add_oemcrypto_decrypt_cenc_time_us()->set_min(1.0f); + crypto_metrics.add_oemcrypto_delete_usage_entry()->set_count(13); + crypto_metrics.add_oemcrypto_delete_usage_table()->set_count(13); + crypto_metrics.add_oemcrypto_derive_keys_from_session_key_time_us + ()->set_min(1.0f); + crypto_metrics.add_oemcrypto_force_delete_usage_entry()->set_count(13); + crypto_metrics.add_oemcrypto_generate_derived_keys_time_us()->set_min(1.0f); + crypto_metrics.add_oemcrypto_generate_nonce()->set_count(13); + crypto_metrics.add_oemcrypto_generate_rsa_signature_time_us()->set_min(1.0f); + crypto_metrics.add_oemcrypto_generate_signature_time_us()->set_min(1.0f); + crypto_metrics.add_oemcrypto_generic_decrypt_time_us()->set_min(1.0f); + crypto_metrics.add_oemcrypto_generic_encrypt_time_us()->set_min(1.0f); + crypto_metrics.add_oemcrypto_generic_sign_time_us()->set_min(1.0f); + crypto_metrics.add_oemcrypto_generic_verify_time_us()->set_min(1.0f); + crypto_metrics.add_oemcrypto_get_device_id()->set_count(13); + crypto_metrics.add_oemcrypto_get_key_data_time_us()->set_min(1.0f); + crypto_metrics.add_oemcrypto_get_oem_public_certificate()->set_count(13); + crypto_metrics.add_oemcrypto_get_random()->set_count(13); + crypto_metrics.add_oemcrypto_initialize_time_us()->set_min(1.0f); + crypto_metrics.mutable_oemcrypto_is_anti_rollback_hw_present + ()->set_int_value(1); + crypto_metrics.mutable_oemcrypto_is_keybox_valid()->set_int_value(1); + crypto_metrics.add_oemcrypto_load_device_rsa_key_time_us()->set_min(1.0f); + crypto_metrics.add_oemcrypto_load_entitled_keys_time_us()->set_min(1.0f); + crypto_metrics.add_oemcrypto_load_keys_time_us()->set_min(1.0f); + crypto_metrics.mutable_oemcrypto_max_hdcp_capability()->set_int_value(1); + crypto_metrics.mutable_oemcrypto_max_number_of_sessions()->set_int_value(1); + crypto_metrics.mutable_oemcrypto_number_of_open_sessions()->set_int_value(1); + crypto_metrics.mutable_oemcrypto_provisioning_method()->set_int_value(1); + crypto_metrics.add_oemcrypto_refresh_keys_time_us()->set_min(1.0f); + crypto_metrics.add_oemcrypto_report_usage()->set_count(13); + crypto_metrics.add_oemcrypto_rewrap_device_rsa_key_time_us()->set_min(1.0f); + crypto_metrics.add_oemcrypto_rewrap_device_rsa_key_30_time_us() + ->set_min(1.0f); + crypto_metrics.mutable_oemcrypto_security_patch_level()->set_int_value(1); + crypto_metrics.add_oemcrypto_select_key_time_us()->set_min(1.0f); + crypto_metrics.mutable_oemcrypto_usage_table_support()->set_int_value(1); + crypto_metrics.add_oemcrypto_update_usage_table()->set_count(13); + crypto_metrics.add_oemcrypto_update_usage_entry()->set_count(13); + + drm_metrics::WvCdmMetrics::SessionMetrics session_metrics; + session_metrics.mutable_session_id()->set_string_value("test"); + *(session_metrics.mutable_crypto_metrics()) = crypto_metrics; + session_metrics.mutable_cdm_session_life_span_ms()->set_double_value(1.0f); + session_metrics.add_cdm_session_renew_key_time_us()->set_min(1.0f); + session_metrics.add_cdm_session_restore_offline_session()->set_count(13); + session_metrics.add_cdm_session_restore_usage_session()->set_count(13); + session_metrics.add_cdm_session_license_request_latency_ms()->set_min(1.0); + + drm_metrics::WvCdmMetrics::EngineMetrics engine_metrics; + *(engine_metrics.mutable_crypto_metrics()) = crypto_metrics; + // OEMCrypto Initialize Metrics. + engine_metrics.mutable_oemcrypto_initialization_mode()->set_int_value(1); + engine_metrics.mutable_oemcrypto_l1_api_version()->set_int_value(1); + engine_metrics.mutable_oemcrypto_l1_min_api_version()->set_int_value(1); + // CdmEngine Metrics. + engine_metrics.mutable_app_package_name()->set_int_value(1); + engine_metrics.add_cdm_engine_add_key_time_us()->set_min(1.0f); + engine_metrics.mutable_cdm_engine_cdm_version()->set_int_value(1); + engine_metrics.add_cdm_engine_close_session()->set_count(13); + engine_metrics.mutable_cdm_engine_creation_time_millis()->set_int_value(1); + engine_metrics.add_cdm_engine_decrypt_time_us()->set_min(1.0f); + engine_metrics.add_cdm_engine_find_session_for_key()->set_count(13); + engine_metrics.add_cdm_engine_generate_key_request_time_us()->set_min(1.0f); + engine_metrics.add_cdm_engine_get_provisioning_request_time_us() + ->set_min(1.0f); + engine_metrics.add_cdm_engine_get_secure_stop_ids()->set_count(13); + engine_metrics.add_cdm_engine_get_usage_info_time_us()->set_min(1.0f); + engine_metrics.add_cdm_engine_handle_provisioning_response_time_us() + ->set_min(1.0f); + engine_metrics.mutable_cdm_engine_life_span_ms()->set_int_value(1); + engine_metrics.add_cdm_engine_open_key_set_session()->set_count(13); + engine_metrics.add_cdm_engine_open_session()->set_count(13); + engine_metrics.add_cdm_engine_query_key_status_time_us()->set_min(1.0f); + engine_metrics.add_cdm_engine_release_all_usage_info()->set_count(13); + engine_metrics.add_cdm_engine_release_usage_info()->set_count(13); + engine_metrics.add_cdm_engine_remove_all_usage_info()->set_count(13); + engine_metrics.add_cdm_engine_remove_keys()->set_count(13); + engine_metrics.add_cdm_engine_remove_usage_info()->set_count(13); + engine_metrics.add_cdm_engine_restore_key_time_us()->set_min(1.0f); + engine_metrics.add_cdm_engine_unprovision()->set_count(13); + + drm_metrics::WvCdmMetrics metrics_proto; + *(metrics_proto.add_session_metrics()) = session_metrics; + *(metrics_proto.mutable_engine_metrics()) = engine_metrics; + + hidl_vec hidl_metrics; + HidlMetricsAdapter::ToHidlMetrics(metrics_proto, &hidl_metrics); + ASSERT_EQ(2U, hidl_metrics.size()); + EXPECT_EQ(83U, hidl_metrics[0].metrics.size()); + EXPECT_EQ(63U, hidl_metrics[1].metrics.size()); +} + +} // namespace wvcdm