MediaDrm throws an exception when Secure Stops are requested
Our recommendation to OEMs is that they support a table of at least 50 usage entries in OEMCrypto. If more usage entries are stored, the PSTs get added to the CDM but are LRU'ed out of the OEMCrypto usage table. When the CDM queries those usage entries, OEMCrypto will return a OEMCrypto_ERROR_INVALID_CONTEXT. Rather than return an error and have MediaDrm throw an exception, CDM should delete this PST and return the next usage entry, when queried. [ Merge of https://widevine-internal-review.googlesource.com/#/c/11457/ from Widevine cdm repo ] b/17994711 Change-Id: I00e3f93000096fb434d94333e22958de795a4bb5
This commit is contained in:
@@ -1200,6 +1200,68 @@ TEST_F(WvCdmRequestLicenseTest, RemoveKeys) {
|
||||
ASSERT_EQ(NO_ERROR, decryptor_.CloseSession(session_id_));
|
||||
}
|
||||
|
||||
TEST_F(WvCdmRequestLicenseTest, UsageInfoRetryTest) {
|
||||
Unprovision();
|
||||
Provision(kLevelDefault);
|
||||
|
||||
CdmSecurityLevel security_level = GetDefaultSecurityLevel();
|
||||
std::string app_id = "";
|
||||
DeviceFiles handle;
|
||||
EXPECT_TRUE(handle.Init(security_level));
|
||||
File file;
|
||||
handle.SetTestFile(&file);
|
||||
EXPECT_TRUE(handle.DeleteAllUsageInfoForApp(app_id));
|
||||
|
||||
SubSampleInfo* data = &usage_info_sub_samples_icp[0];
|
||||
decryptor_.OpenSession(g_key_system, NULL, &session_id_);
|
||||
std::string key_id = a2bs_hex(
|
||||
"000000427073736800000000" // blob size and pssh
|
||||
"EDEF8BA979D64ACEA3C827DCD51D21ED00000022" // Widevine system id
|
||||
"08011a0d7769646576696e655f74657374220f73" // pssh data
|
||||
"747265616d696e675f636c697033");
|
||||
|
||||
GenerateKeyRequest(key_id, kLicenseTypeStreaming, NULL);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
|
||||
|
||||
std::vector<uint8_t> 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;
|
||||
EXPECT_EQ(NO_ERROR, decryptor_.Decrypt(session_id_, data->validate_key_id,
|
||||
decryption_parameters));
|
||||
|
||||
EXPECT_TRUE(std::equal(data->decrypt_data.begin(), data->decrypt_data.end(),
|
||||
decrypt_buffer.begin()));
|
||||
decryptor_.CloseSession(session_id_);
|
||||
|
||||
uint32_t num_usage_info = 0;
|
||||
CdmUsageInfo usage_info;
|
||||
CdmUsageInfoReleaseMessage release_msg;
|
||||
CdmResponseType status = decryptor_.GetUsageInfo(app_id, &usage_info);
|
||||
EXPECT_EQ(usage_info.empty() ? NO_ERROR : KEY_MESSAGE, status);
|
||||
|
||||
// Discard and retry to verify usage reports can be generated multiple times
|
||||
// before release.
|
||||
status = decryptor_.GetUsageInfo(app_id, &usage_info);
|
||||
EXPECT_EQ(usage_info.empty() ? NO_ERROR : KEY_MESSAGE, status);
|
||||
while (usage_info.size() > 0) {
|
||||
for (size_t i = 0; i < usage_info.size(); ++i) {
|
||||
release_msg =
|
||||
GetUsageInfoResponse(g_license_server, g_client_auth, usage_info[i]);
|
||||
EXPECT_EQ(NO_ERROR, decryptor_.ReleaseUsageInfo(release_msg));
|
||||
}
|
||||
status = decryptor_.GetUsageInfo(app_id, &usage_info);
|
||||
switch (status) {
|
||||
case KEY_MESSAGE: EXPECT_FALSE(usage_info.empty()); break;
|
||||
case NO_ERROR: EXPECT_TRUE(usage_info.empty()); break;
|
||||
default: FAIL() << "GetUsageInfo failed with error "
|
||||
<< static_cast<int>(status) ; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class WvCdmUsageInfoTest
|
||||
: public WvCdmRequestLicenseTest,
|
||||
public ::testing::WithParamInterface<UsageInfoSubSampleInfo*> {};
|
||||
|
||||
Reference in New Issue
Block a user