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
This commit is contained in:
Adam Stone
2018-04-02 17:29:42 -07:00
parent 81ce8b4601
commit e7edb5d2e2
7 changed files with 1235 additions and 4 deletions

View File

@@ -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 \

View File

@@ -125,10 +125,7 @@ struct WVDrmPlugin : public IDrmPlugin, IDrmPluginListener,
Return<Status> releaseSecureStop(
const hidl_vec<uint8_t>& secureStopId) override;
Return<void> getMetrics(getMetrics_cb _hidl_cb) {
_hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, hidl_vec<DrmMetricGroup>());
return Void();
}
Return<void> getMetrics(getMetrics_cb _hidl_cb);
Return<void> getSecureStopIds(getSecureStopIds_cb _hidl_cb) override;

View File

@@ -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 <vector>
#include <android/hardware/drm/1.1/types.h>
#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<internal::DrmMetricGroup::Metric> 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<internal::DrmMetricGroup::Attribute>*
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<internal::DrmMetricGroup>* 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<internal::DrmMetricGroup>
GetHidlGroupVector();
private:
void AddCryptoMetrics(
const drm_metrics::WvCdmMetrics::CryptoMetrics& proto_metrics,
HidlMetricsGroupBuilder* group_builder);
std::vector<internal::DrmMetricGroup> group_vector_;
};
} // namespace wvcdm
#endif // CDM_HIDL_METRICS_ADAPTER_H_

View File

@@ -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<Status> WVDrmPlugin::releaseSecureStop(
return mapCdmResponseType(res);
}
Return<void> WVDrmPlugin::getMetrics(getMetrics_cb _hidl_cb) {
hidl_vec<DrmMetricGroup> 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<void> WVDrmPlugin::getSecureStopIds(getSecureStopIds_cb _hidl_cb) {
std::vector<SecureStopId> secureStopIds;

View File

@@ -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 <android/hardware/drm/1.1/types.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;
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<typename T>
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<typename T>
void AddAttribute(
const std::string& name, DrmMetricGroup::ValueType vt, T value,
std::vector<DrmMetricGroup::Attribute>* 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<drm_metrics::DistributionMetric>& distributions) {
for (const auto& metric : distributions) {
AddDistribution(name, metric);
}
}
void HidlMetricsGroupBuilder::AddCounters(
const std::string& name,
const RepeatedPtrField<drm_metrics::CounterMetric>& 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<DrmMetricGroup::Attribute>*
attributes) {
std::vector<DrmMetricGroup::Attribute>
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<DrmMetricGroup>* 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

View File

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

View File

@@ -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 <android/hardware/drm/1.1/types.h>
#include <sstream>
#include <utils/Log.h>
#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<typename T>
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<DrmMetricGroup>& 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<DrmMetricGroup> 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<DrmMetricGroup> 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<DrmMetricGroup> 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<DrmMetricGroup> 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