diff --git a/libwvdrmengine/cdm/core/include/cdm_engine.h b/libwvdrmengine/cdm/core/include/cdm_engine.h index 1c9f47a3..e3cb89dc 100644 --- a/libwvdrmengine/cdm/core/include/cdm_engine.h +++ b/libwvdrmengine/cdm/core/include/cdm_engine.h @@ -97,6 +97,9 @@ class CdmEngine { // process the response. Should be empty if a release response. // |key_data| is the license, renewal, release response or service // certificate response. + // |license_type| must not be null. If the result is KEY_ADDED, this out + // parameter indicates the type of license containd in + // key_data. For any other return code, no value is provided. // |key_set_id| should be non-null and specified if license release. // If offline license or streaming license associated with // a secure stop, |key_set_id| should be non-null and will @@ -107,6 +110,7 @@ class CdmEngine { // (not associated with a secure stop). virtual CdmResponseType AddKey(const CdmSessionId& session_id, const CdmKeyResponse& key_data, + CdmLicenseType* license_type, CdmKeySetId* key_set_id); virtual CdmResponseType RestoreKey(const CdmSessionId& session_id, diff --git a/libwvdrmengine/cdm/core/include/wv_cdm_types.h b/libwvdrmengine/cdm/core/include/wv_cdm_types.h index 2c17d203..46dd5bb3 100644 --- a/libwvdrmengine/cdm/core/include/wv_cdm_types.h +++ b/libwvdrmengine/cdm/core/include/wv_cdm_types.h @@ -5,6 +5,7 @@ #ifndef WVCDM_CORE_WV_CDM_TYPES_H_ #define WVCDM_CORE_WV_CDM_TYPES_H_ +#include #include #include #include diff --git a/libwvdrmengine/cdm/core/src/cdm_engine.cpp b/libwvdrmengine/cdm/core/src/cdm_engine.cpp index 879c410e..e4e24865 100644 --- a/libwvdrmengine/cdm/core/src/cdm_engine.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_engine.cpp @@ -311,8 +311,13 @@ CdmResponseType CdmEngine::GenerateKeyRequest( CdmResponseType CdmEngine::AddKey(const CdmSessionId& session_id, const CdmKeyResponse& key_data, + CdmLicenseType* license_type, CdmKeySetId* key_set_id) { LOGI("CdmEngine::AddKey"); + if (license_type == nullptr) { + LOGE("CdmEngine::AddKey: license_type cannot be null."); + return PARAMETER_NULL; + } CdmSessionId id = session_id; bool license_type_release = session_id.empty(); @@ -349,7 +354,21 @@ CdmResponseType CdmEngine::AddKey(const CdmSessionId& session_id, return EMPTY_KEY_DATA_1; } - CdmResponseType sts = session->AddKey(key_data); + + CdmResponseType sts = (session->AddKey(key_data)); + + if (sts == KEY_ADDED) { + if (session->is_release()) { + *license_type = kLicenseTypeRelease; + } else if (session->is_temporary()) { + *license_type = kLicenseTypeTemporary; + } else if (session->is_offline()) { + *license_type = kLicenseTypeOffline; + } else { + *license_type = kLicenseTypeStreaming; + } + } + if (key_set_id) { if ((session->is_offline() || session->has_provider_session_token()) && !license_type_release) { diff --git a/libwvdrmengine/cdm/core/test/cdm_engine_test.cpp b/libwvdrmengine/cdm/core/test/cdm_engine_test.cpp index 0efea6b2..50b45b8a 100644 --- a/libwvdrmengine/cdm/core/test/cdm_engine_test.cpp +++ b/libwvdrmengine/cdm/core/test/cdm_engine_test.cpp @@ -159,6 +159,12 @@ class WvCdmEngineTest : public WvCdmEnginePreProvTest { protected: void GenerateKeyRequest(const std::string& key_id, const std::string& init_data_type_string) { + GenerateKeyRequest(key_id, init_data_type_string, kLicenseTypeStreaming); + } + + void GenerateKeyRequest(const std::string& key_id, + const std::string& init_data_type_string, + CdmLicenseType license_type) { CdmAppParameterMap app_parameters; CdmKeySetId key_set_id; @@ -167,7 +173,7 @@ class WvCdmEngineTest : public WvCdmEnginePreProvTest { CdmKeyRequest key_request; CdmResponseType result = cdm_engine_.GenerateKeyRequest( - session_id_, key_set_id, init_data, kLicenseTypeStreaming, + session_id_, key_set_id, init_data, license_type, app_parameters, &key_request); EXPECT_EQ(KEY_MESSAGE, result); @@ -234,9 +240,19 @@ class WvCdmEngineTest : public WvCdmEnginePreProvTest { void VerifyNewKeyResponse(const std::string& server_url, const std::string& client_auth) { + VerifyNewKeyResponse(server_url, client_auth, kLicenseTypeStreaming); + } + void VerifyNewKeyResponse(const std::string& server_url, + const std::string& client_auth, + CdmLicenseType expected_license_type) { std::string resp = GetKeyRequestResponse(server_url, client_auth); CdmKeySetId key_set_id; - EXPECT_EQ(KEY_ADDED, cdm_engine_.AddKey(session_id_, resp, &key_set_id)); + CdmLicenseType license_type; + CdmResponseType status = + cdm_engine_.AddKey(session_id_, resp, &license_type, &key_set_id); + + EXPECT_EQ(KEY_ADDED, status); + EXPECT_EQ(expected_license_type, license_type); VerifyLicenseRequestLatency(kKeyRequestTypeInitial, *cdm_engine_.GetMetrics()); } @@ -335,6 +351,13 @@ TEST_F(WvCdmEngineTest, NormalDecryptionIsoBmff) { VerifyNewKeyResponse(config_.license_server(), config_.client_auth()); } +// TODO(blueeyes): Add tests for different license types. +TEST_F(WvCdmEngineTest, ReturnsLicenseTypeDetailStreaming) { + GenerateKeyRequest(binary_key_id(), kCencMimeType, kLicenseTypeStreaming); + VerifyNewKeyResponse(config_.license_server(), config_.client_auth(), + kLicenseTypeStreaming); +} + // TODO(juce): Set up with correct test data. TEST_F(WvCdmEngineTest, DISABLED_NormalDecryptionWebm) { // Extract the key ID from the PSSH box. diff --git a/libwvdrmengine/cdm/core/test/test_base.cpp b/libwvdrmengine/cdm/core/test/test_base.cpp index f0341bb0..349cec5c 100644 --- a/libwvdrmengine/cdm/core/test/test_base.cpp +++ b/libwvdrmengine/cdm/core/test/test_base.cpp @@ -610,8 +610,10 @@ void TestLicenseHolder::SignAndLoadLicense() { signed_response.SerializeToString(&response_data); CdmKeySetId key_set_id; + CdmLicenseType license_type; // Required for AddKey. Result value ignored. EXPECT_EQ(KEY_ADDED, - cdm_engine_->AddKey(session_id_, response_data, &key_set_id)); + cdm_engine_->AddKey(session_id_, response_data, + &license_type, &key_set_id)); } void TestLicenseHolder::DeriveKeysFromSessionKey() { diff --git a/libwvdrmengine/cdm/metrics/include/metrics_collections.h b/libwvdrmengine/cdm/metrics/include/metrics_collections.h index a65b6e74..8eb1bfc5 100644 --- a/libwvdrmengine/cdm/metrics/include/metrics_collections.h +++ b/libwvdrmengine/cdm/metrics/include/metrics_collections.h @@ -85,6 +85,8 @@ const int kEventTypeFieldNumber = ::drm_metrics::Attributes::kEventTypeFieldNumber; const int kKeyRequestTypeFieldNumber = ::drm_metrics::Attributes::kKeyRequestTypeFieldNumber; +const int kLicenseTypeFieldNumber = + ::drm_metrics::Attributes::kLicenseTypeFieldNumber; } // anonymous namespace @@ -374,7 +376,8 @@ class EngineMetrics { void SetAppPackageName(const std::string &app_package_name); // Metrics recorded at the engine level. - EventMetric cdm_engine_add_key_; + EventMetric cdm_engine_add_key_; ValueMetric cdm_engine_cdm_version_; CounterMetric cdm_engine_close_session_; @@ -384,7 +387,8 @@ class EngineMetrics { cdm_engine_decrypt_; CounterMetric cdm_engine_find_session_for_key_; - EventMetric + EventMetric cdm_engine_generate_key_request_; EventMetric cdm_engine_get_provisioning_request_; diff --git a/libwvdrmengine/cdm/metrics/src/attribute_handler.cpp b/libwvdrmengine/cdm/metrics/src/attribute_handler.cpp index 8de1a641..70d00aa8 100644 --- a/libwvdrmengine/cdm/metrics/src/attribute_handler.cpp +++ b/libwvdrmengine/cdm/metrics/src/attribute_handler.cpp @@ -80,6 +80,14 @@ void SetAttributeFieldset_key_request_type(key_request_type); } +template <> +void SetAttributeField( + const CdmLicenseType &license_type, + drm_metrics::Attributes *attributes) { + attributes->set_license_type(license_type); +} + template <> void SetAttributeField<0, util::Unused>(const util::Unused &, drm_metrics::Attributes *) { diff --git a/libwvdrmengine/cdm/metrics/src/metrics.proto b/libwvdrmengine/cdm/metrics/src/metrics.proto index 6fa787dd..2f749968 100644 --- a/libwvdrmengine/cdm/metrics/src/metrics.proto +++ b/libwvdrmengine/cdm/metrics/src/metrics.proto @@ -46,6 +46,8 @@ message Attributes { optional uint32 event_type = 15; // Contains the CdmKeyRequestType defined in wv_cdm_types.h. optional uint32 key_request_type = 16; + // Contains the CdmLicenseType defined in wv_cdm_types.h. + optional uint32 license_type = 17; } // The Counter message is used to store a count value with an associated diff --git a/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp b/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp index 3cf2de23..99538d16 100644 --- a/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp +++ b/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp @@ -122,7 +122,8 @@ CdmResponseType WvContentDecryptionModule::GenerateKeyRequest( M_TIME(sts = cdm_engine->GenerateKeyRequest(session_id, key_set_id, initialization_data, license_type, app_parameters, key_request), - cdm_engine->GetMetrics(), cdm_engine_generate_key_request_, sts); + cdm_engine->GetMetrics(), cdm_engine_generate_key_request_, + sts, license_type); switch (license_type) { case kLicenseTypeRelease: if (sts != KEY_MESSAGE) { @@ -149,9 +150,12 @@ CdmResponseType WvContentDecryptionModule::AddKey( release_key_set_id = *key_set_id; } CdmResponseType sts; - M_TIME(sts = cdm_engine->AddKey(session_id, key_data, key_set_id), - cdm_engine->GetMetrics(), cdm_engine_add_key_, sts); - if (sts == KEY_ADDED && session_id.empty()) { // license type release + CdmLicenseType license_type; + M_TIME(sts = cdm_engine->AddKey(session_id, key_data, + &license_type, key_set_id), + cdm_engine->GetMetrics(), cdm_engine_add_key_, sts, license_type); + // Empty session id indicates license type release. + if (sts == KEY_ADDED && session_id.empty()) { cdm_engine->CloseKeySetSession(release_key_set_id); cdm_by_session_id_.erase(release_key_set_id); } diff --git a/libwvdrmengine/mediadrm/src_hidl/hidl_metrics_adapter.cpp b/libwvdrmengine/mediadrm/src_hidl/hidl_metrics_adapter.cpp index d5ebf643..f00ae387 100644 --- a/libwvdrmengine/mediadrm/src_hidl/hidl_metrics_adapter.cpp +++ b/libwvdrmengine/mediadrm/src_hidl/hidl_metrics_adapter.cpp @@ -30,6 +30,7 @@ const char kAttributeOemCryptoResult[] = "oem_crypto_result"; const char kAttributeKeyStatusType[] = "key_status_type"; const char kAttributeEventType[] = "event_type"; const char kAttributeKeyRequestType[] = "key_request_type"; +const char kAttributeLicenseType[] = "license_type"; template void SetValue(const T& value, DrmMetricGroup::Attribute* attribute); @@ -237,6 +238,12 @@ void HidlMetricsGroupBuilder::AddAttributes( DrmMetricGroup::ValueType::INT64_TYPE, attributes_proto.key_request_type(), &attribute_vector); } + if (attributes_proto.has_license_type()) { + AddAttribute( + kAttributeLicenseType, + DrmMetricGroup::ValueType::INT64_TYPE, + attributes_proto.license_type(), &attribute_vector); + } *attributes = attribute_vector; } diff --git a/libwvdrmengine/mediadrm/test/hidl_metrics_adapter_unittest.cpp b/libwvdrmengine/mediadrm/test/hidl_metrics_adapter_unittest.cpp index cdfe0e14..f79b8bce 100644 --- a/libwvdrmengine/mediadrm/test/hidl_metrics_adapter_unittest.cpp +++ b/libwvdrmengine/mediadrm/test/hidl_metrics_adapter_unittest.cpp @@ -281,6 +281,7 @@ TEST(HidlMetricsAdapterTest, AddAllAttrbitues) { attributes->set_key_status_type(43); attributes->set_event_type(47); attributes->set_key_request_type(53); + attributes->set_license_type(59); DrmMetricGroup::Metric expected_counter_metric = { "crypto_session_get_token", @@ -302,7 +303,9 @@ TEST(HidlMetricsAdapterTest, AddAllAttrbitues) { DrmMetricGroup::ValueType::INT64_TYPE, 43, 0, "" }, { "event_type", DrmMetricGroup::ValueType::INT64_TYPE, 47, 0, "" }, { "key_request_type", - DrmMetricGroup::ValueType::INT64_TYPE, 53, 0, "" } }, + DrmMetricGroup::ValueType::INT64_TYPE, 53, 0, "" }, + { "license_type", + DrmMetricGroup::ValueType::INT64_TYPE, 59, 0, "" } }, { { "count", DrmMetricGroup::ValueType::INT64_TYPE, 13, 0, "" } } }; // Confirm that all of the attributes exist in the hidl data.