diff --git a/libwvdrmengine/cdm/core/src/usage_table_header.cpp b/libwvdrmengine/cdm/core/src/usage_table_header.cpp index 92f4bf45..1fe88e92 100644 --- a/libwvdrmengine/cdm/core/src/usage_table_header.cpp +++ b/libwvdrmengine/cdm/core/src/usage_table_header.cpp @@ -500,7 +500,8 @@ CdmResponseType UsageTableHeader::StoreEntry(uint32_t usage_entry_number, CdmResponseType UsageTableHeader::Shrink( metrics::CryptoMetrics* metrics, uint32_t number_of_usage_entries_to_delete) { - LOGI("UsageTableHeader::Shrink: %d", number_of_usage_entries_to_delete); + LOGI("UsageTableHeader::Shrink: %d (of %d)", + number_of_usage_entries_to_delete, usage_entry_info_.size()); if (usage_entry_info_.empty()) { LOGE("UsageTableHeader::Shrink: usage entry info table unexpectedly empty"); return NO_USAGE_ENTRIES; diff --git a/libwvdrmengine/cdm/test/request_license_test.cpp b/libwvdrmengine/cdm/test/request_license_test.cpp index ad089154..a5efbffe 100644 --- a/libwvdrmengine/cdm/test/request_license_test.cpp +++ b/libwvdrmengine/cdm/test/request_license_test.cpp @@ -1632,6 +1632,28 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase { key_set_id_.size() > 0); } + bool VerifyDecryption(const CdmSessionId& session_id, + const SubSampleInfo& data) { + std::vector decrypt_buffer(data.encrypt_data.size()); + CdmDecryptionParameters decryption_parameters( + &data.key_id, &data.encrypt_data.front(), data.encrypt_data.size(), + &data.iv, data.block_offset, &decrypt_buffer[0]); + decryption_parameters.is_encrypted = data.is_encrypted; + decryption_parameters.is_secure = data.is_secure; + decryption_parameters.subsample_flags = data.subsample_flags; + CdmResponseType status = decryptor_.Decrypt(session_id, + data.validate_key_id, + decryption_parameters); + EXPECT_EQ(NO_ERROR, status); + if (status != NO_ERROR) + return false; + + bool result = std::equal(data.decrypt_data.begin(), data.decrypt_data.end(), + decrypt_buffer.begin()); + EXPECT_TRUE(result); + return result; + } + void Unprovision() { EXPECT_EQ(NO_ERROR, decryptor_.Unprovision(kSecurityLevelL1, kDefaultCdmIdentifier)); @@ -3196,6 +3218,96 @@ TEST_F(WvCdmRequestLicenseTest, UsageInfoRetryTest) { } } +TEST_F(WvCdmRequestLicenseTest, UsageInfo_ReleaseThreeRecords) { + Unprovision(); + Provision(kLevelDefault); + + CdmSecurityLevel security_level = GetDefaultSecurityLevel(); + std::string app_id = ""; + FileSystem file_system; + DeviceFiles handle(&file_system); + EXPECT_TRUE(handle.Init(security_level)); + std::vector psts; + EXPECT_TRUE(handle.DeleteAllUsageInfoForApp( + DeviceFiles::GetUsageInfoFileName(app_id), + &psts)); + + std::string session_id_clip3, session_id_clip4, session_id_clip7; + + // Open session for streaming_clip3 and verify decryption is successful + decryptor_.OpenSession(config_.key_system(), NULL, kDefaultCdmIdentifier, + NULL, &session_id_clip3); + + session_id_ = session_id_clip3; + GenerateKeyRequest(kPsshStreamingClip3, kLicenseTypeStreaming, NULL); + VerifyUsageKeyRequestResponse(config_.license_server(), + config_.client_auth()); + + EXPECT_TRUE(VerifyDecryption(session_id_clip3, + usage_info_sub_samples_icp[0])); + + // Open session for streaming_clip4 and verify decryption is successful + decryptor_.OpenSession(config_.key_system(), NULL, kDefaultCdmIdentifier, + NULL, &session_id_clip4); + + session_id_ = session_id_clip4; + GenerateKeyRequest(kPsshStreamingClip4, kLicenseTypeStreaming, NULL); + VerifyUsageKeyRequestResponse(config_.license_server(), + config_.client_auth()); + + EXPECT_TRUE(VerifyDecryption(session_id_clip4, + usage_info_sub_samples_icp[1])); + + // Open session for streaming_clip7 and verify decryption is successful + decryptor_.OpenSession(config_.key_system(), NULL, kDefaultCdmIdentifier, + NULL, &session_id_clip7); + + session_id_ = session_id_clip7; + GenerateKeyRequest(kPsshStreamingClip7, kLicenseTypeStreaming, NULL); + VerifyUsageKeyRequestResponse(config_.license_server(), + config_.client_auth()); + + EXPECT_TRUE(VerifyDecryption(session_id_clip7, + usage_info_sub_samples_icp[4])); + + // Close session for streaming_clip4 and release usage information + decryptor_.CloseSession(session_id_clip4); + + CdmUsageInfo usage_info; + CdmUsageInfoReleaseMessage release_msg; + CdmResponseType status = decryptor_.GetUsageInfo( + app_id, kProviderSessionTokenStreamingClip4, kDefaultCdmIdentifier, + &usage_info); + EXPECT_EQ(KEY_MESSAGE, status); + EXPECT_EQ(1, usage_info.size()); + release_msg = GetUsageInfoResponse(config_.license_server(), + config_.client_auth(), usage_info[0]); + EXPECT_EQ(NO_ERROR, + decryptor_.ReleaseUsageInfo(release_msg, kDefaultCdmIdentifier)); + + decryptor_.CloseSession(session_id_clip7); + + status = decryptor_.GetUsageInfo(app_id, kProviderSessionTokenStreamingClip7, + kDefaultCdmIdentifier, &usage_info); + EXPECT_EQ(KEY_MESSAGE, status); + EXPECT_EQ(1, usage_info.size()); + release_msg = GetUsageInfoResponse(config_.license_server(), + config_.client_auth(), usage_info[0]); + EXPECT_EQ(NO_ERROR, + decryptor_.ReleaseUsageInfo(release_msg, kDefaultCdmIdentifier)); + + decryptor_.CloseSession(session_id_clip3); + + status = decryptor_.GetUsageInfo(app_id, kProviderSessionTokenStreamingClip3, + kDefaultCdmIdentifier, &usage_info); + EXPECT_EQ(KEY_MESSAGE, status); + EXPECT_EQ(1, usage_info.size()); + release_msg = GetUsageInfoResponse(config_.license_server(), + config_.client_auth(), usage_info[0]); + EXPECT_EQ(NO_ERROR, + decryptor_.ReleaseUsageInfo(release_msg, kDefaultCdmIdentifier)); +} + class WvCdmUsageInfoTest : public WvCdmRequestLicenseTest, public ::testing::WithParamInterface {};