// Copyright 2016 Google Inc. All Rights Reserved. #include "metrics_collections.h" #include #include "log.h" #include "metrics.pb.h" using drm_metrics::MetricsGroup; using wvcdm::metrics::MetricSerializer; namespace { // Helper struct for comparing session ids. struct CompareSessionIds { const std::string& target_; CompareSessionIds(const wvcdm::CdmSessionId& target) : target_(target) {}; bool operator()(const wvcdm::metrics::SessionMetrics* metrics) const { return metrics->GetSessionId() == target_; } }; // Local class used to serialize to the MetricsGroup proto message. class ProtoMetricSerializer : public wvcdm::metrics::MetricSerializer { public: ProtoMetricSerializer(MetricsGroup* metric_group) : metric_group_(metric_group) {} virtual void SetString(const std::string& metric_id, const std::string& value) { MetricsGroup::Metric* metric = metric_group_->add_metric(); metric->set_name(metric_id); metric->mutable_value()->set_string_value(value); } virtual void SetInt32(const std::string& metric_id, int32_t value) { MetricsGroup::Metric* metric = metric_group_->add_metric(); metric->set_name(metric_id); metric->mutable_value()->set_int_value(value); } virtual void SetInt64(const std::string& metric_id, int64_t value) { MetricsGroup::Metric* metric = metric_group_->add_metric(); metric->set_name(metric_id); metric->mutable_value()->set_int_value(value); } virtual void SetDouble(const std::string& metric_id, double value) { MetricsGroup::Metric* metric = metric_group_->add_metric(); metric->set_name(metric_id); metric->mutable_value()->set_double_value(value); } private: MetricsGroup* metric_group_; }; } // anonymous namespace namespace wvcdm { namespace metrics { CryptoMetrics::CryptoMetrics() : crypto_session_security_level_( "/drm/widevine/crypto_session/security_level"), crypto_session_delete_all_usage_reports_( "/drm/widevine/crypto_session/delete_all_usage_reports", "error"), crypto_session_delete_multiple_usage_information_( "/drm/widevine/crypto_session/delete_multiple_usage_information", "error"), crypto_session_generic_decrypt_( "/drm/widevine/crypto_session/generic_decrypt/time", "error", "length", "encryption_algorithm"), crypto_session_generic_encrypt_( "/drm/widevine/crypto_session/generic_encrypt/time", "error", "length", "encryption_algorithm"), crypto_session_generic_sign_( "/drm/widevine/crypto_session/generic_sign/time", "error", "length", "signing_algorithm"), crypto_session_generic_verify_( "/drm/widevine/crypto_session/generic_verify/time", "error", "length", "signing_algorithm"), crypto_session_get_device_unique_id_( "/drm/widevine/crypto_session/get_device_unique_id", "success"), crypto_session_get_token_( "/drm/widevine/crypto_session/get_token", "success"), crypto_session_life_span_( "/drm/widevine/crypto_session/life_span"), crypto_session_load_certificate_private_key_( "/drm/widevine/crypto_session/load_certificate_private_key/time", "success"), crypto_session_open_( "/drm/widevine/crypto_session/open/time", "error", "requested_security_level"), crypto_session_system_id_( "/drm/widevine/crypto_session/system_id"), crypto_session_update_usage_information_( "/drm/widevine/crypto_session/update_usage_information/time", "error"), crypto_session_usage_information_support_( "/drm/widevine/crypto_session/usage_information_support"), oemcrypto_api_version_( "/drm/widevine/oemcrypto/api_version"), oemcrypto_close_session_( "/drm/widevine/oemcrypto/close_session", "oemcrypto_error"), oemcrypto_copy_buffer_( "/drm/widevine/oemcrypto/copy_buffer/time", "oemcrypto_error", "length"), oemcrypto_current_hdcp_capability_( "/drm/widevine/oemcrypto/current_hdcp_capability"), oemcrypto_deactivate_usage_entry_( "/drm/widevine/oemcrypto/deactivate_usage_entry", "oemcrypto_error"), oemcrypto_decrypt_cenc_( "/drm/widevine/oemcrypto/decrypt_cenc/time", "oemcrypto_error", "length"), oemcrypto_delete_usage_entry_( "/drm/widevine/oemcrypto/delete_usage_entry", "oemcrypto_error"), oemcrypto_delete_usage_table_( "/drm/widevine/oemcrypto/delete_usage_table", "oemcrypto_error"), oemcrypto_derive_keys_from_session_key_( "/drm/widevine/oemcrypto/derive_keys_from_session_key/time", "oemcrypto_error"), oemcrypto_force_delete_usage_entry_( "/drm/widevine/oemcrypto/force_delete_usage_entry", "oemcrypto_error"), oemcrypto_generate_derived_keys_( "/drm/widevine/oemcrypto/generate_derived_keys/time", "oemcrypto_error"), oemcrypto_generate_nonce_( "/drm/widevine/oemcrypto/generate_nonce", "oemcrypto_error"), oemcrypto_generate_rsa_signature_( "/drm/widevine/oemcrypto/generate_rsa_signature/time", "oemcrypto_error", "length"), oemcrypto_generate_signature_( "/drm/widevine/oemcrypto/generate_signature/time", "oemcrypto_error", "length"), oemcrypto_generic_decrypt_( "/drm/widevine/oemcrypto/generic_decrypt/time", "oemcrypto_error", "length"), oemcrypto_generic_encrypt_( "/drm/widevine/oemcrypto/generic_encrypt/time", "oemcrypto_error", "length"), oemcrypto_generic_sign_( "/drm/widevine/oemcrypto/generic_sign/time", "oemcrypto_error", "length"), oemcrypto_generic_verify_( "/drm/widevine/oemcrypto/generic_verify/time", "oemcrypto_error", "length"), oemcrypto_get_device_id_( "/drm/widevine/oemcrypto/get_device_id", "oemcrypto_error"), oemcrypto_get_key_data_( "/drm/widevine/oemcrypto/get_key_data/time", "oemcrypto_error", "length"), oemcrypto_get_oem_public_certificate_( "/drm/widevine/oemcrypto/get_oem_public_certificate", "oemcrypto_error"), oemcrypto_get_random_( "/drm/widevine/oemcrypto/get_random", "oemcrypto_error"), oemcrypto_initialize_( "/drm/widevine/oemcrypto/initialize/time", "oemcrypto_error"), oemcrypto_is_anti_rollback_hw_present_( "/drm/widevine/oemcrypto/is_anti_rollback_hw_present"), oemcrypto_is_keybox_valid_( "/drm/widevine/oemcrypto/is_keybox_valid"), oemcrypto_load_device_rsa_key_( "/drm/widevine/oemcrypto/load_device_rsa_key/time", "oemcrypto_error"), oemcrypto_load_entitled_keys_( "/drm/widevine/oemcrypto/load_entitled_keys/time", "oemcrypto_error"), oemcrypto_load_keys_( "/drm/widevine/oemcrypto/load_keys/time", "oemcrypto_error"), oemcrypto_max_hdcp_capability_( "/drm/widevine/oemcrypto/max_hdcp_capability"), oemcrypto_max_number_of_sessions_( "/drm/widevine/oemcrypto/max_number_of_sessions"), oemcrypto_number_of_open_sessions_( "/drm/widevine/oemcrypto/number_of_open_sessions"), oemcrypto_provisioning_method_( "/drm/widevine/oemcrypto/provisioning_method"), oemcrypto_refresh_keys_( "/drm/widevine/oemcrypto/refresh_keys/time", "oemcrypto_error"), oemcrypto_report_usage_( "/drm/widevine/oemcrypto/report_usage", "oemcrypto_error"), oemcrypto_rewrap_device_rsa_key_( "/drm/widevine/oemcrypto/rewrap_device_rsa_key/time", "oemcrypto_error"), oemcrypto_rewrap_device_rsa_key_30_( "/drm/widevine/oemcrypto/rewrap_device_rsa_key_30/time", "oemcrypto_error"), oemcrypto_security_patch_level_( "/drm/widevine/oemcrypto/security_patch_level"), oemcrypto_select_key_( "/drm/widevine/oemcrypto/select_key/time", "oemcrypto_error"), oemcrypto_usage_table_support_( "/drm/widevine/oemcrypto/usage_table_support"), oemcrypto_update_usage_table_( "/drm/widevine/oemcrypto/update_usage_table", "oemcrypto_error") { } void CryptoMetrics::Serialize(MetricsGroup* metrics) { ProtoMetricSerializer serializer(metrics); /* CRYPTO SESSION */ crypto_session_security_level_.Serialize(&serializer); crypto_session_delete_all_usage_reports_.Serialize(&serializer); crypto_session_delete_multiple_usage_information_.Serialize(&serializer); crypto_session_generic_decrypt_.Serialize(&serializer); crypto_session_generic_encrypt_.Serialize(&serializer); crypto_session_generic_sign_.Serialize(&serializer); crypto_session_generic_verify_.Serialize(&serializer); crypto_session_get_device_unique_id_.Serialize(&serializer); crypto_session_get_token_.Serialize(&serializer); crypto_session_life_span_.Serialize(&serializer); crypto_session_load_certificate_private_key_.Serialize(&serializer); crypto_session_open_.Serialize(&serializer); crypto_session_system_id_.Serialize(&serializer); crypto_session_update_usage_information_.Serialize(&serializer); crypto_session_usage_information_support_.Serialize(&serializer); /* OEMCRYPTO */ oemcrypto_api_version_.Serialize(&serializer); oemcrypto_close_session_.Serialize(&serializer); oemcrypto_copy_buffer_.Serialize(&serializer); oemcrypto_current_hdcp_capability_.Serialize(&serializer); oemcrypto_deactivate_usage_entry_.Serialize(&serializer); oemcrypto_decrypt_cenc_.Serialize(&serializer); oemcrypto_delete_usage_entry_.Serialize(&serializer); oemcrypto_delete_usage_table_.Serialize(&serializer); oemcrypto_derive_keys_from_session_key_.Serialize(&serializer); oemcrypto_force_delete_usage_entry_.Serialize(&serializer); oemcrypto_generate_derived_keys_.Serialize(&serializer); oemcrypto_generate_nonce_.Serialize(&serializer); oemcrypto_generate_rsa_signature_.Serialize(&serializer); oemcrypto_generate_signature_.Serialize(&serializer); oemcrypto_generic_decrypt_.Serialize(&serializer); oemcrypto_generic_encrypt_.Serialize(&serializer); oemcrypto_generic_sign_.Serialize(&serializer); oemcrypto_generic_verify_.Serialize(&serializer); oemcrypto_get_device_id_.Serialize(&serializer); oemcrypto_get_key_data_.Serialize(&serializer); oemcrypto_get_oem_public_certificate_.Serialize(&serializer); oemcrypto_get_random_.Serialize(&serializer); oemcrypto_initialize_.Serialize(&serializer); oemcrypto_is_anti_rollback_hw_present_.Serialize(&serializer); oemcrypto_is_keybox_valid_.Serialize(&serializer); oemcrypto_load_device_rsa_key_.Serialize(&serializer); oemcrypto_load_entitled_keys_.Serialize(&serializer); oemcrypto_load_keys_.Serialize(&serializer); oemcrypto_max_hdcp_capability_.Serialize(&serializer); oemcrypto_max_number_of_sessions_.Serialize(&serializer); oemcrypto_number_of_open_sessions_.Serialize(&serializer); oemcrypto_provisioning_method_.Serialize(&serializer); oemcrypto_refresh_keys_.Serialize(&serializer); oemcrypto_report_usage_.Serialize(&serializer); oemcrypto_rewrap_device_rsa_key_.Serialize(&serializer); oemcrypto_rewrap_device_rsa_key_30_.Serialize(&serializer); oemcrypto_security_patch_level_.Serialize(&serializer); oemcrypto_select_key_.Serialize(&serializer); oemcrypto_usage_table_support_.Serialize(&serializer); oemcrypto_update_usage_table_.Serialize(&serializer); } SessionMetrics::SessionMetrics() : cdm_session_life_span_( "/drm/widevine/cdm_session/life_span"), cdm_session_renew_key_( "/drm/widevine/cdm_session/renew_key/time", "error"), cdm_session_restore_offline_session_( "/drm/widevine/cdm_session/restore_offline_session", "error"), cdm_session_restore_usage_session_( "/drm/widevine/cdm_session/restore_usage_session", "error"), completed_(false) { } void SessionMetrics::Serialize(MetricsGroup* metric_group) { SerializeSessionMetrics(metric_group); crypto_metrics_.Serialize(metric_group); } void SessionMetrics::SerializeSessionMetrics(MetricsGroup* metric_group) { ProtoMetricSerializer serializer(metric_group); // Add the session id as a single-valued metric. serializer.SetString("/drm/widevine/cdm_session/session_id", session_id_); cdm_session_life_span_.Serialize(&serializer); cdm_session_renew_key_.Serialize(&serializer); cdm_session_restore_offline_session_.Serialize(&serializer); cdm_session_restore_usage_session_.Serialize(&serializer); } OemCryptoDynamicAdapterMetrics::OemCryptoDynamicAdapterMetrics() : oemcrypto_initialization_mode_( "/drm/widevine/oemcrypto/initialization_mode"), oemcrypto_l1_api_version_( "/drm/widevine/oemcrypto/l1_api_version"), oemcrypto_l1_min_api_version_( "/drm/widevine/oemcrypto/l1_min_api_version") { } void OemCryptoDynamicAdapterMetrics::SetInitializationMode( OEMCryptoInitializationMode mode) { AutoLock lock(adapter_lock_); oemcrypto_initialization_mode_.Record(mode); } void OemCryptoDynamicAdapterMetrics::SetL1ApiVersion(uint32_t version) { AutoLock lock(adapter_lock_); oemcrypto_l1_api_version_.Record(version); } void OemCryptoDynamicAdapterMetrics::SetL1MinApiVersion(uint32_t version) { AutoLock lock(adapter_lock_); oemcrypto_l1_min_api_version_.Record(version); } void OemCryptoDynamicAdapterMetrics::Serialize( drm_metrics::MetricsGroup* metric_group) { AutoLock lock(adapter_lock_); ProtoMetricSerializer serializer(metric_group); oemcrypto_initialization_mode_.Serialize(&serializer); oemcrypto_l1_api_version_.Serialize(&serializer); oemcrypto_l1_min_api_version_.Serialize(&serializer); } void OemCryptoDynamicAdapterMetrics::Clear() { AutoLock lock(adapter_lock_); oemcrypto_initialization_mode_.Clear(); oemcrypto_l1_api_version_.Clear(); oemcrypto_l1_min_api_version_.Clear(); } // This method returns a reference. This means that the destructor is never // executed for the returned object. OemCryptoDynamicAdapterMetrics& GetDynamicAdapterMetricsInstance() { // This is safe in C++ 11 since the initialization is guaranteed to run // only once regardless of multi-threaded access. static OemCryptoDynamicAdapterMetrics* adapter_metrics = new OemCryptoDynamicAdapterMetrics(); return *adapter_metrics; } EngineMetrics::EngineMetrics() : cdm_engine_add_key_( "/drm/widevine/cdm_engine/add_key/time", "error"), cdm_engine_cdm_version_( "/drm/widevine/cdm_engine/version"), cdm_engine_close_session_( "/drm/widevine/cdm_engine/close_session", "error"), cdm_engine_creation_time_millis_( "/drm/widevine/cdm_engine/creation_time_millis"), cdm_engine_decrypt_( "/drm/widevine/cdm_engine/decrypt/time", "error", "length"), cdm_engine_find_session_for_key_( "/drm/widevine/cdm_engine/find_session_for_key", "success"), cdm_engine_generate_key_request_( "/drm/widevine/cdm_engine/generate_key_request/time", "error"), cdm_engine_get_provisioning_request_( "/drm/widevine/cdm_engine/get_provisioning_request/time", "error"), cdm_engine_get_usage_info_( "/drm/widevine/cdm_engine/get_usage_info/time", "error"), cdm_engine_handle_provisioning_response_( "/drm/widevine/cdm_engine/handle_provisioning_response/time", "error"), cdm_engine_life_span_( "/drm/widevine/cdm_engine/life_span"), cdm_engine_open_key_set_session_( "/drm/widevine/cdm_engine/open_key_set_session", "error"), cdm_engine_open_session_( "/drm/widevine/cdm_engine/open_session", "error"), cdm_engine_query_key_status_( "/drm/widevine/cdm_engine/query_key_status/time", "error"), cdm_engine_remove_all_usage_info_( "/drm/widevine/cdm_engine/remove_all_usage_info", "error"), cdm_engine_remove_usage_info_( "/drm/widevine/cdm_engine/remove_usage_info", "error"), cdm_engine_release_usage_info_( "/drm/widevine/cdm_engine/release_usage_info", "error"), cdm_engine_get_secure_stop_ids_( "/drm/widevine/cdm_engine/get_secure_stop_ids", "error"), cdm_engine_remove_keys_( "/drm/widevine/cdm_engine/remove_keys", "error"), cdm_engine_restore_key_( "/drm/widevine/cdm_engine/restore_key/time", "error"), cdm_engine_unprovision_( "/drm/widevine/cdm_engine/unprovision", "error", "security_level"), app_package_name_("") { } EngineMetrics::~EngineMetrics() { AutoLock lock(session_metrics_lock_); std::vector::iterator i; if (!session_metrics_list_.empty()) { LOGV("EngineMetrics::~EngineMetrics. Session count: %d", session_metrics_list_.size()); } for (i = session_metrics_list_.begin(); i != session_metrics_list_.end(); i++) { delete *i; } session_metrics_list_.clear(); } SessionMetrics* EngineMetrics::AddSession() { AutoLock lock(session_metrics_lock_); SessionMetrics* metrics = new SessionMetrics(); session_metrics_list_.push_back(metrics); return metrics; } void EngineMetrics::RemoveSession(wvcdm::CdmSessionId session_id) { AutoLock lock(session_metrics_lock_); session_metrics_list_.erase( std::remove_if(session_metrics_list_.begin(), session_metrics_list_.end(), CompareSessionIds(session_id)), session_metrics_list_.end()); } void EngineMetrics::Serialize(drm_metrics::MetricsGroup* metric_group, bool completed_only, bool clear_serialized_sessions) { AutoLock lock(session_metrics_lock_); // Serialize the most recent metrics from the OemCyrpto dynamic adapter. OemCryptoDynamicAdapterMetrics& adapter_metrics = GetDynamicAdapterMetricsInstance(); adapter_metrics.Serialize(metric_group); if (!app_package_name_.empty()) { metric_group->set_app_package_name(app_package_name_); } SerializeEngineMetrics(metric_group); std::vector::iterator i; for (i = session_metrics_list_.begin(); i != session_metrics_list_.end(); /* no increment */) { bool serialized = false; if (!completed_only || (*i)->IsCompleted()) { MetricsGroup* metric_sub_group = metric_group->add_metric_sub_group(); if (!app_package_name_.empty()) { metric_sub_group->set_app_package_name(app_package_name_); } (*i)->Serialize(metric_sub_group); serialized = true; } // Clear the serialized session metrics if requested. if (serialized && clear_serialized_sessions) { session_metrics_list_.erase(i); } else { i++; } } } void EngineMetrics::SetAppPackageName(const std::string& app_package_name) { app_package_name_ = app_package_name; } void EngineMetrics::SerializeEngineMetrics(MetricsGroup* metric_group) { ProtoMetricSerializer serializer(metric_group); cdm_engine_add_key_.Serialize(&serializer); cdm_engine_cdm_version_.Serialize(&serializer); cdm_engine_close_session_.Serialize(&serializer); cdm_engine_creation_time_millis_.Serialize(&serializer); cdm_engine_decrypt_.Serialize(&serializer); cdm_engine_find_session_for_key_.Serialize(&serializer); cdm_engine_generate_key_request_.Serialize(&serializer); cdm_engine_get_provisioning_request_.Serialize(&serializer); cdm_engine_get_usage_info_.Serialize(&serializer); cdm_engine_handle_provisioning_response_.Serialize(&serializer); cdm_engine_life_span_.Serialize(&serializer); cdm_engine_open_key_set_session_.Serialize(&serializer); cdm_engine_open_session_.Serialize(&serializer); cdm_engine_query_key_status_.Serialize(&serializer); cdm_engine_remove_all_usage_info_.Serialize(&serializer); cdm_engine_remove_usage_info_.Serialize(&serializer); cdm_engine_release_usage_info_.Serialize(&serializer); cdm_engine_get_secure_stop_ids_.Serialize(&serializer); cdm_engine_remove_keys_.Serialize(&serializer); cdm_engine_restore_key_.Serialize(&serializer); cdm_engine_unprovision_.Serialize(&serializer); crypto_metrics_.Serialize(metric_group); } } // metrics } // wvcdm