diff --git a/libwvdrmengine/cdm/core/src/license.cpp b/libwvdrmengine/cdm/core/src/license.cpp index 20591e5f..da15a28f 100644 --- a/libwvdrmengine/cdm/core/src/license.cpp +++ b/libwvdrmengine/cdm/core/src/license.cpp @@ -549,8 +549,6 @@ CdmResponseType CdmLicense::HandleKeyResponse( server_url_ = license.policy().renewal_server_url(); } - policy_engine_->SetLicense(license); - if (license.policy().has_renew_with_client_id()) { renew_with_client_id_ = license.policy().renew_with_client_id(); } @@ -565,6 +563,7 @@ CdmResponseType CdmLicense::HandleKeyResponse( it != key_array.end(); ++it) { loaded_keys_.insert(it->key_id()); } + policy_engine_->SetLicense(license); } return resp; } @@ -626,8 +625,6 @@ CdmResponseType CdmLicense::HandleKeyUpdateResponse( return LICENSE_ID_NOT_FOUND; } - policy_engine_->UpdateLicense(license); - if (license.policy().has_renew_with_client_id()) { renew_with_client_id_ = license.policy().renew_with_client_id(); } @@ -651,6 +648,8 @@ CdmResponseType CdmLicense::HandleKeyUpdateResponse( if (session_->RefreshKeys(signed_response.msg(), signed_response.signature(), key_array.size(), &key_array[0])) { + policy_engine_->UpdateLicense(license); + return KEY_ADDED; } else { return REFRESH_KEYS_ERROR; diff --git a/libwvdrmengine/cdm/test/request_license_test.cpp b/libwvdrmengine/cdm/test/request_license_test.cpp index 68a070ab..602b6aa5 100644 --- a/libwvdrmengine/cdm/test/request_license_test.cpp +++ b/libwvdrmengine/cdm/test/request_license_test.cpp @@ -30,6 +30,7 @@ using ::testing::AllOf; using ::testing::AtLeast; using ::testing::Contains; using ::testing::Each; +using ::testing::Invoke; using ::testing::IsEmpty; using ::testing::Not; using ::testing::Pair; @@ -811,7 +812,6 @@ class TestWvCdmClientPropertySet : public CdmClientPropertySet { class TestWvCdmEventListener : public WvCdmEventListener { public: TestWvCdmEventListener() : WvCdmEventListener() {} - MOCK_METHOD1(OnSessionRenewalNeeded, void(const CdmSessionId& session_id)); MOCK_METHOD3(OnSessionKeysChange, void(const CdmSessionId& session_id, const CdmKeyStatusMap& keys_status, @@ -820,6 +820,36 @@ class TestWvCdmEventListener : public WvCdmEventListener { int64_t new_expiry_time_seconds)); }; +class DecryptCallbackTester { + public: + DecryptCallbackTester(wvcdm::WvContentDecryptionModule* decryptor, + SubSampleInfo* sub_sample_info) + : decryptor_(decryptor), + sub_sample_info_(sub_sample_info) {} + + void Decrypt(const CdmSessionId& session_id, + const CdmKeyStatusMap& /* keys_status */, + bool /* has_new_usable_key */) { + EXPECT_TRUE(decryptor_ != NULL); + EXPECT_TRUE(sub_sample_info_ != NULL); + + std::vector decrypt_buffer(sub_sample_info_->encrypt_data.size()); + CdmDecryptionParameters decryption_parameters( + &sub_sample_info_->key_id, &sub_sample_info_->encrypt_data.front(), + sub_sample_info_->encrypt_data.size(), &sub_sample_info_->iv, + sub_sample_info_->block_offset, &decrypt_buffer[0]); + decryption_parameters.is_encrypted = sub_sample_info_->is_encrypted; + decryption_parameters.is_secure = sub_sample_info_->is_secure; + EXPECT_EQ(NO_ERROR, decryptor_->Decrypt(session_id, + sub_sample_info_->validate_key_id, + decryption_parameters)); + + } + private: + wvcdm::WvContentDecryptionModule* decryptor_; + SubSampleInfo* sub_sample_info_; +}; + class TestWvCdmHlsEventListener : public WvCdmEventListener { public: TestWvCdmHlsEventListener() : WvCdmEventListener() {} @@ -2644,6 +2674,7 @@ TEST_F(WvCdmRequestLicenseTest, QueryStatusL3) { EXPECT_TRUE(ss.eof()); EXPECT_LE(10u, api_version); } + TEST_F(WvCdmRequestLicenseTest, QueryKeyControlInfo) { Unprovision(); Provision(kLevelDefault); @@ -3106,6 +3137,33 @@ TEST_F(WvCdmRequestLicenseTest, DecryptionKeyExpiredTest) { decryptor_.CloseSession(session_id_); } +TEST_F(WvCdmRequestLicenseTest, SessionKeyChangeNotificationTest) { + StrictMock listener; + DecryptCallbackTester decrypt_callback( + &decryptor_, + &single_encrypted_sub_sample_short_expiry); + decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, &listener, + &session_id_); + EXPECT_CALL( + listener, + OnSessionKeysChange( + session_id_, + AllOf(Each(Pair(_, kKeyStatusUsable)), Not(IsEmpty())), true)) + .WillOnce(Invoke(&decrypt_callback, &DecryptCallbackTester::Decrypt)); +; + EXPECT_CALL(listener, OnExpirationUpdate(session_id_, _)); + + const std::string kCpKeyId = a2bs_hex( + "000000347073736800000000" // blob size and pssh + "EDEF8BA979D64ACEA3C827DCD51D21ED00000014" // Widevine system id + "0801121030313233343536373839616263646566"); // pssh data + + GenerateKeyRequest(kCpKeyId, kLicenseTypeStreaming); + VerifyKeyRequestResponse(g_license_server, g_client_auth, false); + + decryptor_.CloseSession(session_id_); +} + class WvCdmDecryptionTest : public WvCdmRequestLicenseTest, public ::testing::WithParamInterface {};