From 8ea1ab7f5e50b9f7192fdbd05092e6dd9eefe348 Mon Sep 17 00:00:00 2001 From: Kongqun Yang Date: Tue, 24 Mar 2015 17:15:53 -0700 Subject: [PATCH] Report key request type in GenerateKeyRequest Bug: 19771299 Merged from Widevine CDM repo: https://widevine-internal-review.googlesource.com/#/c/13830/ Change-Id: Id9b4547febcabbb73a4be5dbb2e4c63b1c3eacd3 --- libwvdrmengine/cdm/core/include/cdm_engine.h | 8 ++++- libwvdrmengine/cdm/core/include/cdm_session.h | 3 +- .../cdm/core/include/wv_cdm_types.h | 7 ++++ libwvdrmengine/cdm/core/src/cdm_engine.cpp | 9 ++--- libwvdrmengine/cdm/core/src/cdm_session.cpp | 6 +++- .../cdm/core/test/cdm_engine_test.cpp | 10 +++--- .../include/wv_content_decryption_module.h | 1 + .../cdm/src/wv_content_decryption_module.cpp | 21 +++++------- .../cdm/test/cdm_extended_duration_test.cpp | 31 ++++++++++------- .../cdm/test/request_license_test.cpp | 10 ++++-- libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp | 33 ++++++++++++------ .../mediadrm/test/WVDrmPlugin_test.cpp | 34 +++++++++++-------- 12 files changed, 108 insertions(+), 65 deletions(-) diff --git a/libwvdrmengine/cdm/core/include/cdm_engine.h b/libwvdrmengine/cdm/core/include/cdm_engine.h index 5c6c767f..0de009c5 100644 --- a/libwvdrmengine/cdm/core/include/cdm_engine.h +++ b/libwvdrmengine/cdm/core/include/cdm_engine.h @@ -57,6 +57,9 @@ class CdmEngine { // and renewal requests. // key_request: This must be non-null and point to a CdmKeyMessage. The buffer // will have its contents replaced with the key request. + // key_request_type: May be null. If it is non-null, it will be filled with + // key request type, whether it is an initial request, + // renewal request or release request etc. // server_url: This must be non-null and point to a string. The string will // have its contents replaced with the default URL (if one is // known) to send this key request to. @@ -64,11 +67,14 @@ class CdmEngine { // will have its contents replaced with the key set ID of the // session. Note that for non-offline license requests, the // key set ID is empty, so the CdmKeySetId will be cleared. + // TODO(kqyang): Consider refactor GenerateKeyRequest to reduce the number of + // parameters. virtual CdmResponseType GenerateKeyRequest( const CdmSessionId& session_id, const CdmKeySetId& key_set_id, const InitializationData& init_data, const CdmLicenseType license_type, CdmAppParameterMap& app_parameters, CdmKeyMessage* key_request, - std::string* server_url, CdmKeySetId* key_set_id_out); + CdmKeyRequestType* key_request_type, std::string* server_url, + CdmKeySetId* key_set_id_out); // Accept license response and extract key info. virtual CdmResponseType AddKey(const CdmSessionId& session_id, diff --git a/libwvdrmengine/cdm/core/include/cdm_session.h b/libwvdrmengine/cdm/core/include/cdm_session.h index 64e60a67..593eb191 100644 --- a/libwvdrmengine/cdm/core/include/cdm_session.h +++ b/libwvdrmengine/cdm/core/include/cdm_session.h @@ -37,7 +37,8 @@ class CdmSession { virtual CdmResponseType GenerateKeyRequest( const InitializationData& init_data, const CdmLicenseType license_type, const CdmAppParameterMap& app_parameters, CdmKeyMessage* key_request, - std::string* server_url, CdmKeySetId* key_set_id); + CdmKeyRequestType* key_request_type, std::string* server_url, + CdmKeySetId* key_set_id); // AddKey() - Accept license response and extract key info. virtual CdmResponseType AddKey(const CdmKeyResponse& key_response, diff --git a/libwvdrmengine/cdm/core/include/wv_cdm_types.h b/libwvdrmengine/cdm/core/include/wv_cdm_types.h index daf97151..bed8ec53 100644 --- a/libwvdrmengine/cdm/core/include/wv_cdm_types.h +++ b/libwvdrmengine/cdm/core/include/wv_cdm_types.h @@ -29,6 +29,13 @@ typedef std::string CdmUsageInfoReleaseMessage; typedef std::string CdmProvisioningRequest; typedef std::string CdmProvisioningResponse; +enum CdmKeyRequestType { + kKeyRequestTypeUnknown, + kKeyRequestTypeInitial, + kKeyRequestTypeRenewal, + kKeyRequestTypeRelease, +}; + enum CdmResponseType { NO_ERROR, UNKNOWN_ERROR, diff --git a/libwvdrmengine/cdm/core/src/cdm_engine.cpp b/libwvdrmengine/cdm/core/src/cdm_engine.cpp index 1e21f4b6..0fdc331a 100644 --- a/libwvdrmengine/cdm/core/src/cdm_engine.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_engine.cpp @@ -166,7 +166,8 @@ CdmResponseType CdmEngine::GenerateKeyRequest( const CdmSessionId& session_id, const CdmKeySetId& key_set_id, const InitializationData& init_data, const CdmLicenseType license_type, CdmAppParameterMap& app_parameters, CdmKeyMessage* key_request, - std::string* server_url, CdmKeySetId* key_set_id_out) { + CdmKeyRequestType* key_request_type, std::string* server_url, + CdmKeySetId* key_set_id_out) { LOGI("CdmEngine::GenerateKeyRequest"); CdmSessionId id = session_id; @@ -217,9 +218,9 @@ CdmResponseType CdmEngine::GenerateKeyRequest( } } - sts = - iter->second->GenerateKeyRequest(init_data, license_type, app_parameters, - key_request, server_url, key_set_id_out); + sts = iter->second->GenerateKeyRequest( + init_data, license_type, app_parameters, key_request, key_request_type, + server_url, key_set_id_out); if (KEY_MESSAGE != sts) { if (sts == NEED_PROVISIONING) { diff --git a/libwvdrmengine/cdm/core/src/cdm_session.cpp b/libwvdrmengine/cdm/core/src/cdm_session.cpp index 016e7a97..f0804965 100644 --- a/libwvdrmengine/cdm/core/src/cdm_session.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_session.cpp @@ -154,7 +154,8 @@ CdmResponseType CdmSession::RestoreUsageSession( CdmResponseType CdmSession::GenerateKeyRequest( const InitializationData& init_data, const CdmLicenseType license_type, const CdmAppParameterMap& app_parameters, CdmKeyMessage* key_request, - std::string* server_url, CdmKeySetId* key_set_id) { + CdmKeyRequestType* key_request_type, std::string* server_url, + CdmKeySetId* key_set_id) { if (crypto_session_.get() == NULL) { LOGW("CdmSession::GenerateKeyRequest: Invalid crypto session"); return UNKNOWN_ERROR; @@ -182,10 +183,13 @@ CdmResponseType CdmSession::GenerateKeyRequest( } if (is_release_) { + if (key_request_type) *key_request_type = kKeyRequestTypeRelease; return GenerateReleaseRequest(key_request, server_url); } else if (license_received_) { // renewal + if (key_request_type) *key_request_type = kKeyRequestTypeRenewal; return GenerateRenewalRequest(key_request, server_url); } else { + if (key_request_type) *key_request_type = kKeyRequestTypeInitial; if (!init_data.is_supported()) { LOGW("CdmSession::GenerateKeyRequest: unsupported init data type (%s)", init_data.type().c_str()); diff --git a/libwvdrmengine/cdm/core/test/cdm_engine_test.cpp b/libwvdrmengine/cdm/core/test/cdm_engine_test.cpp index 0ba413e1..1e72e293 100644 --- a/libwvdrmengine/cdm/core/test/cdm_engine_test.cpp +++ b/libwvdrmengine/cdm/core/test/cdm_engine_test.cpp @@ -85,10 +85,12 @@ class WvCdmEngineTest : public testing::Test { InitializationData init_data(init_data_type_string, key_id); - EXPECT_EQ(KEY_MESSAGE, - cdm_engine_.GenerateKeyRequest( - session_id_, key_set_id, init_data, kLicenseTypeStreaming, - app_parameters, &key_msg_, &server_url, NULL)); + CdmKeyRequestType key_request_type; + EXPECT_EQ(KEY_MESSAGE, cdm_engine_.GenerateKeyRequest( + session_id_, key_set_id, init_data, + kLicenseTypeStreaming, app_parameters, &key_msg_, + &key_request_type, &server_url, NULL)); + EXPECT_EQ(kKeyRequestTypeInitial, key_request_type); } void GenerateRenewalRequest() { diff --git a/libwvdrmengine/cdm/include/wv_content_decryption_module.h b/libwvdrmengine/cdm/include/wv_content_decryption_module.h index 1b0bfe1d..5c6825e6 100644 --- a/libwvdrmengine/cdm/include/wv_content_decryption_module.h +++ b/libwvdrmengine/cdm/include/wv_content_decryption_module.h @@ -41,6 +41,7 @@ class WvContentDecryptionModule : public TimerHandler { CdmAppParameterMap& app_parameters, CdmClientPropertySet* property_set, CdmKeyMessage* key_request, + CdmKeyRequestType* key_request_type, std::string* server_url); // Accept license response and extract key info. diff --git a/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp b/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp index 58b09c28..4aecab5a 100644 --- a/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp +++ b/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp @@ -58,25 +58,20 @@ CdmResponseType WvContentDecryptionModule::CloseSession( } CdmResponseType WvContentDecryptionModule::GenerateKeyRequest( - const CdmSessionId& session_id, - const CdmKeySetId& key_set_id, - const std::string& init_data_type, - const CdmInitData& init_data, - const CdmLicenseType license_type, - CdmAppParameterMap& app_parameters, - CdmClientPropertySet* property_set, - CdmKeyMessage* key_request, - std::string* server_url) { + const CdmSessionId& session_id, const CdmKeySetId& key_set_id, + const std::string& init_data_type, const CdmInitData& init_data, + const CdmLicenseType license_type, CdmAppParameterMap& app_parameters, + CdmClientPropertySet* property_set, CdmKeyMessage* key_request, + CdmKeyRequestType* key_request_type, std::string* server_url) { CdmResponseType sts; if (license_type == kLicenseTypeRelease) { sts = cdm_engine_->OpenKeySetSession(key_set_id, property_set, NULL); if (sts != NO_ERROR) return sts; } InitializationData initialization_data(init_data_type, init_data); - sts = cdm_engine_->GenerateKeyRequest(session_id, key_set_id, - initialization_data, license_type, - app_parameters, key_request, - server_url, NULL); + sts = cdm_engine_->GenerateKeyRequest( + session_id, key_set_id, initialization_data, license_type, app_parameters, + key_request, key_request_type, server_url, NULL); switch(license_type) { case kLicenseTypeRelease: diff --git a/libwvdrmengine/cdm/test/cdm_extended_duration_test.cpp b/libwvdrmengine/cdm/test/cdm_extended_duration_test.cpp index 8956131b..9a00b325 100644 --- a/libwvdrmengine/cdm/test/cdm_extended_duration_test.cpp +++ b/libwvdrmengine/cdm/test/cdm_extended_duration_test.cpp @@ -270,10 +270,12 @@ class WvCdmExtendedDurationTest : public testing::Test { CdmLicenseType license_type) { wvcdm::CdmAppParameterMap app_parameters; std::string server_url; - EXPECT_EQ(wvcdm::KEY_MESSAGE, - decryptor_.GenerateKeyRequest( - session_id_, key_set_id_, "video/mp4", init_data, - license_type, app_parameters, NULL, &key_msg_, &server_url)); + CdmKeyRequestType key_request_type; + EXPECT_EQ(wvcdm::KEY_MESSAGE, decryptor_.GenerateKeyRequest( + session_id_, key_set_id_, "video/mp4", + init_data, license_type, app_parameters, + NULL, &key_msg_, &key_request_type, &server_url)); + EXPECT_EQ(kKeyRequestTypeInitial, key_request_type); EXPECT_EQ(0u, server_url.size()); } @@ -283,10 +285,13 @@ class WvCdmExtendedDurationTest : public testing::Test { // when appropriate. std::string init_data; wvcdm::CdmAppParameterMap app_parameters; - EXPECT_EQ(wvcdm::KEY_MESSAGE, - decryptor_.GenerateKeyRequest( - session_id_, key_set_id_, "video/mp4", init_data, - license_type, app_parameters, NULL, &key_msg_, server_url)); + CdmKeyRequestType key_request_type; + EXPECT_EQ( + wvcdm::KEY_MESSAGE, + decryptor_.GenerateKeyRequest( + session_id_, key_set_id_, "video/mp4", init_data, license_type, + app_parameters, NULL, &key_msg_, &key_request_type, server_url)); + EXPECT_EQ(kKeyRequestTypeRenewal, key_request_type); // TODO(edwinwong, rfrias): Add tests cases for when license server url // is empty on renewal. Need appropriate key id at the server. EXPECT_NE(0u, server_url->size()); @@ -297,11 +302,13 @@ class WvCdmExtendedDurationTest : public testing::Test { CdmInitData init_data; wvcdm::CdmAppParameterMap app_parameters; std::string server_url; + CdmKeyRequestType key_request_type; EXPECT_EQ(wvcdm::KEY_MESSAGE, - decryptor_.GenerateKeyRequest( - session_id, key_set_id, "video/mp4", init_data, - kLicenseTypeRelease, app_parameters, NULL, &key_msg_, - &server_url)); + decryptor_.GenerateKeyRequest(session_id, key_set_id, "video/mp4", + init_data, kLicenseTypeRelease, + app_parameters, NULL, &key_msg_, + &key_request_type, &server_url)); + EXPECT_EQ(kKeyRequestTypeRelease, key_request_type); } void LogResponseError(const std::string& message, int http_status_code) { diff --git a/libwvdrmengine/cdm/test/request_license_test.cpp b/libwvdrmengine/cdm/test/request_license_test.cpp index d7fa3e48..4b8f6da2 100644 --- a/libwvdrmengine/cdm/test/request_license_test.cpp +++ b/libwvdrmengine/cdm/test/request_license_test.cpp @@ -484,7 +484,7 @@ class WvCdmRequestLicenseTest : public testing::Test { EXPECT_EQ(wvcdm::KEY_MESSAGE, decryptor_.GenerateKeyRequest( session_id_, key_set_id, "video/mp4", init_data, license_type, - app_parameters, property_set, &key_msg_, &server_url)); + app_parameters, property_set, &key_msg_, NULL, &server_url)); EXPECT_EQ(0u, server_url.size()); } @@ -500,11 +500,13 @@ class WvCdmRequestLicenseTest : public testing::Test { // when appropriate. std::string init_data; wvcdm::CdmAppParameterMap app_parameters; + wvcdm::CdmKeyRequestType key_request_type; EXPECT_EQ(wvcdm::KEY_MESSAGE, decryptor_.GenerateKeyRequest( session_id_, key_set_id_, "video/mp4", init_data, license_type, app_parameters, property_set, &key_msg_, - server_url)); + &key_request_type, server_url)); + EXPECT_EQ(kKeyRequestTypeRenewal, key_request_type); // TODO(edwinwong, rfrias): Add tests cases for when license server url // is empty on renewal. Need appropriate key id at the server. EXPECT_NE(0u, server_url->size()); @@ -519,12 +521,14 @@ class WvCdmRequestLicenseTest : public testing::Test { CdmSessionId session_id; CdmInitData init_data; wvcdm::CdmAppParameterMap app_parameters; + wvcdm::CdmKeyRequestType key_request_type; std::string server_url; EXPECT_EQ(wvcdm::KEY_MESSAGE, decryptor_.GenerateKeyRequest( session_id, key_set_id, "video/mp4", init_data, kLicenseTypeRelease, app_parameters, property_set, &key_msg_, - &server_url)); + &key_request_type, &server_url)); + EXPECT_EQ(kKeyRequestTypeRelease, key_request_type); } void LogResponseError(const std::string& message, int http_status_code) { diff --git a/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp b/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp index d9b2f092..e33dffe4 100644 --- a/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp +++ b/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp @@ -32,6 +32,22 @@ using namespace android; using namespace std; using namespace wvcdm; +namespace { +DrmPlugin::KeyRequestType ConvertFromCdmKeyRequestType( + CdmKeyRequestType keyRequestType) { + switch (keyRequestType) { + case kKeyRequestTypeInitial: + return DrmPlugin::kKeyRequestType_Initial; + case kKeyRequestTypeRenewal: + return DrmPlugin::kKeyRequestType_Renewal; + case kKeyRequestTypeRelease: + return DrmPlugin::kKeyRequestType_Release; + default: + return DrmPlugin::kKeyRequestType_Unknown; + } +} +} // namespace + WVDrmPlugin::WVDrmPlugin(WvContentDecryptionModule* cdm, WVGenericCryptoInterface* crypto) : mCDM(cdm), mCrypto(crypto), mCryptoSessionsMutex(), mCryptoSessions() {} @@ -138,11 +154,6 @@ status_t WVDrmPlugin::getKeyRequest( return android::ERROR_DRM_CANNOT_HANDLE; } - // TODO: set *keyRequestType properly, this is - // just a stub implementation to allow the framework - // changes to build and run - *keyRequestType = kKeyRequestType_Initial; - string cdmInitDataType = initDataType.string(); // Provide backwards-compatibility for apps that pass non-EME-compatible MIME // types. @@ -195,13 +206,13 @@ status_t WVDrmPlugin::getKeyRequest( } CdmKeyMessage keyRequest; + CdmKeyRequestType cdmKeyRequestType; string cdmDefaultUrl; - CdmResponseType res = mCDM->GenerateKeyRequest(cdmSessionId, cdmKeySetId, - cdmInitDataType, - processedInitData, - cdmLicenseType, cdmParameters, - &mPropertySet, &keyRequest, - &cdmDefaultUrl); + CdmResponseType res = mCDM->GenerateKeyRequest( + cdmSessionId, cdmKeySetId, cdmInitDataType, processedInitData, + cdmLicenseType, cdmParameters, &mPropertySet, &keyRequest, + &cdmKeyRequestType, &cdmDefaultUrl); + *keyRequestType = ConvertFromCdmKeyRequestType(cdmKeyRequestType); if (isCdmResponseTypeSuccess(res)) { defaultUrl.clear(); diff --git a/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp b/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp index 5aa11d8b..1c4be2ec 100644 --- a/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp +++ b/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp @@ -33,14 +33,12 @@ class MockCDM : public WvContentDecryptionModule { MOCK_METHOD1(CloseSession, CdmResponseType(const CdmSessionId&)); - MOCK_METHOD9(GenerateKeyRequest, CdmResponseType(const CdmSessionId&, - const CdmKeySetId&, - const std::string&, - const CdmInitData&, - const CdmLicenseType, - CdmAppParameterMap&, - CdmClientPropertySet*, - CdmKeyMessage*, string*)); + MOCK_METHOD10(GenerateKeyRequest, + CdmResponseType(const CdmSessionId&, const CdmKeySetId&, + const std::string&, const CdmInitData&, + const CdmLicenseType, CdmAppParameterMap&, + CdmClientPropertySet*, CdmKeyMessage*, + CdmKeyRequestType*, string*)); MOCK_METHOD3(AddKey, CdmResponseType(const CdmSessionId&, const CdmKeyResponse&, @@ -269,23 +267,26 @@ TEST_F(WVDrmPluginTest, GeneratesKeyRequests) { EXPECT_CALL(cdm, GenerateKeyRequest(cdmSessionId, "", mimeType, initData, kLicenseTypeOffline, cdmParameters, _, - _, _)) + _, _, _)) .WillOnce(DoAll(SetArgPointee<7>(cdmRequest), - SetArgPointee<8>(kDefaultUrl), + SetArgPointee<8>(kKeyRequestTypeInitial), + SetArgPointee<9>(kDefaultUrl), Return(wvcdm::KEY_MESSAGE))); EXPECT_CALL(cdm, GenerateKeyRequest(cdmSessionId, "", mimeType, initData, - kLicenseTypeStreaming, cdmParameters, _, - _, _)) + kLicenseTypeStreaming, cdmParameters, + _, _, _, _)) .WillOnce(DoAll(SetArgPointee<7>(cdmRequest), - SetArgPointee<8>(kDefaultUrl), + SetArgPointee<8>(kKeyRequestTypeRenewal), + SetArgPointee<9>(kDefaultUrl), Return(wvcdm::KEY_MESSAGE))); EXPECT_CALL(cdm, GenerateKeyRequest("", cdmKeySetId, mimeType, initData, kLicenseTypeRelease, cdmParameters, - NotNull(), _, _)) + NotNull(), _, _, _)) .WillOnce(DoAll(SetArgPointee<7>(cdmRequest), - SetArgPointee<8>(kDefaultUrl), + SetArgPointee<8>(kKeyRequestTypeRelease), + SetArgPointee<9>(kDefaultUrl), Return(wvcdm::KEY_MESSAGE))); } } @@ -306,6 +307,7 @@ TEST_F(WVDrmPluginTest, GeneratesKeyRequests) { &keyRequestType); ASSERT_EQ(OK, res); EXPECT_THAT(request, ElementsAreArray(requestRaw, kRequestSize)); + EXPECT_EQ(DrmPlugin::kKeyRequestType_Initial, keyRequestType); EXPECT_STREQ(kDefaultUrl, defaultUrl.string()); res = plugin.getKeyRequest(sessionId, initData, mimeType, @@ -313,6 +315,7 @@ TEST_F(WVDrmPluginTest, GeneratesKeyRequests) { request, defaultUrl, &keyRequestType); ASSERT_EQ(OK, res); EXPECT_THAT(request, ElementsAreArray(requestRaw, kRequestSize)); + EXPECT_EQ(DrmPlugin::kKeyRequestType_Renewal, keyRequestType); EXPECT_STREQ(kDefaultUrl, defaultUrl.string()); res = plugin.getKeyRequest(keySetId, initData, mimeType, @@ -320,6 +323,7 @@ TEST_F(WVDrmPluginTest, GeneratesKeyRequests) { request, defaultUrl, &keyRequestType); ASSERT_EQ(OK, res); EXPECT_THAT(request, ElementsAreArray(requestRaw, kRequestSize)); + EXPECT_EQ(DrmPlugin::kKeyRequestType_Release, keyRequestType); EXPECT_STREQ(kDefaultUrl, defaultUrl.string()); } }