am dffa3ca9: Merge "MediaDrm throws an exception when Secure Stops are requested" into lmp-mr1-dev
* commit 'dffa3ca991c64035e1852543a215f99935b58c7f': MediaDrm throws an exception when Secure Stops are requested
This commit is contained in:
@@ -100,6 +100,8 @@ class CdmSession {
|
|||||||
is_usage_update_needed_ = false;
|
is_usage_update_needed_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DeleteLicense();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Internal constructor
|
// Internal constructor
|
||||||
void Create(CdmLicense* license_parser, CryptoSession* crypto_session,
|
void Create(CdmLicense* license_parser, CryptoSession* crypto_session,
|
||||||
@@ -112,7 +114,6 @@ class CdmSession {
|
|||||||
|
|
||||||
CdmResponseType StoreLicense();
|
CdmResponseType StoreLicense();
|
||||||
bool StoreLicense(DeviceFiles::LicenseState state);
|
bool StoreLicense(DeviceFiles::LicenseState state);
|
||||||
bool DeleteLicense();
|
|
||||||
|
|
||||||
// instance variables
|
// instance variables
|
||||||
bool initialized_;
|
bool initialized_;
|
||||||
|
|||||||
@@ -108,7 +108,9 @@ class DeviceFiles {
|
|||||||
FRIEND_TEST(DeviceFilesUsageInfoTest, Store);
|
FRIEND_TEST(DeviceFilesUsageInfoTest, Store);
|
||||||
FRIEND_TEST(WvCdmRequestLicenseTest, UnprovisionTest);
|
FRIEND_TEST(WvCdmRequestLicenseTest, UnprovisionTest);
|
||||||
FRIEND_TEST(WvCdmRequestLicenseTest, ForceL3Test);
|
FRIEND_TEST(WvCdmRequestLicenseTest, ForceL3Test);
|
||||||
|
FRIEND_TEST(WvCdmRequestLicenseTest, UsageInfoRetryTest);
|
||||||
FRIEND_TEST(WvCdmUsageInfoTest, UsageInfo);
|
FRIEND_TEST(WvCdmUsageInfoTest, UsageInfo);
|
||||||
|
FRIEND_TEST(WvCdmExtendedDurationTest, UsageOverflowTest);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
scoped_ptr<File> file_;
|
scoped_ptr<File> file_;
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ class CdmLicense {
|
|||||||
const CdmSessionId& session_id,
|
const CdmSessionId& session_id,
|
||||||
CdmKeyMessage* signed_request,
|
CdmKeyMessage* signed_request,
|
||||||
std::string* server_url);
|
std::string* server_url);
|
||||||
virtual bool PrepareKeyUpdateRequest(bool is_renewal, CdmKeyMessage* signed_request,
|
virtual CdmResponseType PrepareKeyUpdateRequest(
|
||||||
std::string* server_url);
|
bool is_renewal, CdmKeyMessage* signed_request, std::string* server_url);
|
||||||
virtual CdmResponseType HandleKeyResponse(const CdmKeyResponse& license_response);
|
virtual CdmResponseType HandleKeyResponse(const CdmKeyResponse& license_response);
|
||||||
virtual CdmResponseType HandleKeyUpdateResponse(
|
virtual CdmResponseType HandleKeyUpdateResponse(
|
||||||
bool is_renewal, const CdmKeyResponse& license_response);
|
bool is_renewal, const CdmKeyResponse& license_response);
|
||||||
|
|||||||
@@ -654,16 +654,22 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
|
|||||||
CdmUsageInfo* usage_info) {
|
CdmUsageInfo* usage_info) {
|
||||||
// Return a random usage report from a random security level
|
// Return a random usage report from a random security level
|
||||||
SecurityLevel security_level = ((rand() % 2) == 0) ? kLevelDefault : kLevel3;
|
SecurityLevel security_level = ((rand() % 2) == 0) ? kLevelDefault : kLevel3;
|
||||||
CdmResponseType status = GetUsageInfo(app_id, security_level, usage_info);
|
CdmResponseType status = UNKNOWN_ERROR;
|
||||||
|
do {
|
||||||
|
status = GetUsageInfo(app_id, security_level, usage_info);
|
||||||
|
|
||||||
|
if (KEY_MESSAGE == status && !usage_info->empty())
|
||||||
|
return status;
|
||||||
|
} while (KEY_CANCELED == status);
|
||||||
|
|
||||||
if (KEY_MESSAGE == status && !usage_info->empty())
|
|
||||||
return status;
|
|
||||||
|
|
||||||
security_level = (kLevel3 == security_level) ? kLevelDefault : kLevel3;
|
security_level = (kLevel3 == security_level) ? kLevelDefault : kLevel3;
|
||||||
status = GetUsageInfo(app_id, security_level, usage_info);
|
do {
|
||||||
if (NEED_PROVISIONING == status)
|
status = GetUsageInfo(app_id, security_level, usage_info);
|
||||||
return NO_ERROR; // Valid scenario that one of the security
|
if (NEED_PROVISIONING == status)
|
||||||
// levels has not been provisioned
|
return NO_ERROR; // Valid scenario that one of the security
|
||||||
|
// levels has not been provisioned
|
||||||
|
} while (KEY_CANCELED == status);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -716,13 +722,20 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
|
|||||||
|
|
||||||
status = usage_session_->GenerateReleaseRequest(&(*usage_info)[0], &server_url);
|
status = usage_session_->GenerateReleaseRequest(&(*usage_info)[0], &server_url);
|
||||||
|
|
||||||
if (KEY_MESSAGE != status) {
|
switch (status) {
|
||||||
LOGE("CdmEngine::GetUsageInfo: generate release request error: %d",
|
case KEY_MESSAGE:
|
||||||
status);
|
break;
|
||||||
usage_info->clear();
|
case KEY_CANCELED: // usage information not present in
|
||||||
return status;
|
usage_session_->DeleteLicense(); // OEMCrypto, delete and try again
|
||||||
|
usage_info->clear();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOGE("CdmEngine::GetUsageInfo: generate release request error: %d",
|
||||||
|
status);
|
||||||
|
usage_info->clear();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return KEY_MESSAGE;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
CdmResponseType CdmEngine::ReleaseAllUsageInfo(const std::string& app_id) {
|
CdmResponseType CdmEngine::ReleaseAllUsageInfo(const std::string& app_id) {
|
||||||
|
|||||||
@@ -385,11 +385,11 @@ CdmResponseType CdmSession::Decrypt(const CdmDecryptionParameters& params) {
|
|||||||
// session keys.
|
// session keys.
|
||||||
CdmResponseType CdmSession::GenerateRenewalRequest(CdmKeyMessage* key_request,
|
CdmResponseType CdmSession::GenerateRenewalRequest(CdmKeyMessage* key_request,
|
||||||
std::string* server_url) {
|
std::string* server_url) {
|
||||||
if (!license_parser_->PrepareKeyUpdateRequest(true, key_request,
|
CdmResponseType status =
|
||||||
server_url)) {
|
license_parser_->PrepareKeyUpdateRequest(true, key_request, server_url);
|
||||||
LOGE("CdmSession::GenerateRenewalRequest: ERROR on prepare");
|
|
||||||
return KEY_ERROR;
|
if (KEY_MESSAGE != status)
|
||||||
}
|
return status;
|
||||||
|
|
||||||
if (is_offline_) {
|
if (is_offline_) {
|
||||||
offline_key_renewal_request_ = *key_request;
|
offline_key_renewal_request_ = *key_request;
|
||||||
@@ -413,8 +413,11 @@ CdmResponseType CdmSession::RenewKey(const CdmKeyResponse& key_response) {
|
|||||||
CdmResponseType CdmSession::GenerateReleaseRequest(CdmKeyMessage* key_request,
|
CdmResponseType CdmSession::GenerateReleaseRequest(CdmKeyMessage* key_request,
|
||||||
std::string* server_url) {
|
std::string* server_url) {
|
||||||
is_release_ = true;
|
is_release_ = true;
|
||||||
if (!license_parser_->PrepareKeyUpdateRequest(false, key_request, server_url))
|
CdmResponseType status =
|
||||||
return UNKNOWN_ERROR;
|
license_parser_->PrepareKeyUpdateRequest(false, key_request, server_url);
|
||||||
|
|
||||||
|
if (KEY_MESSAGE != status)
|
||||||
|
return status;
|
||||||
|
|
||||||
if (is_offline_) { // Mark license as being released
|
if (is_offline_) { // Mark license as being released
|
||||||
if (!StoreLicense(DeviceFiles::kLicenseStateReleasing))
|
if (!StoreLicense(DeviceFiles::kLicenseStateReleasing))
|
||||||
|
|||||||
@@ -716,13 +716,19 @@ CdmResponseType CryptoSession::DeactivateUsageInformation(
|
|||||||
OEMCryptoResult status =
|
OEMCryptoResult status =
|
||||||
OEMCrypto_DeactivateUsageEntry(pst, provider_session_token.length());
|
OEMCrypto_DeactivateUsageEntry(pst, provider_session_token.length());
|
||||||
|
|
||||||
if (OEMCrypto_SUCCESS != status) {
|
switch(status) {
|
||||||
LOGE("CryptoSession::DeactivateUsageInformation: Deactivate Usage Entry "
|
case OEMCrypto_SUCCESS:
|
||||||
" error=%ld",
|
return NO_ERROR;
|
||||||
|
case OEMCrypto_ERROR_INVALID_CONTEXT:
|
||||||
|
LOGE("CryptoSession::DeactivateUsageInformation: Deactivate Usage Entry "
|
||||||
|
" invalid context error");
|
||||||
|
return KEY_CANCELED;
|
||||||
|
default:
|
||||||
|
LOGE("CryptoSession::DeactivateUsageInformation: Deactivate Usage Entry "
|
||||||
|
" error=%ld",
|
||||||
status);
|
status);
|
||||||
return UNKNOWN_ERROR;
|
return UNKNOWN_ERROR;
|
||||||
}
|
}
|
||||||
return NO_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CdmResponseType CryptoSession::GenerateUsageReport(
|
CdmResponseType CryptoSession::GenerateUsageReport(
|
||||||
|
|||||||
@@ -476,20 +476,21 @@ bool CdmLicense::PrepareKeyRequest(const InitializationData& init_data,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CdmLicense::PrepareKeyUpdateRequest(bool is_renewal,
|
CdmResponseType CdmLicense::PrepareKeyUpdateRequest(
|
||||||
CdmKeyMessage* signed_request,
|
bool is_renewal,
|
||||||
std::string* server_url) {
|
CdmKeyMessage* signed_request,
|
||||||
|
std::string* server_url) {
|
||||||
if (!initialized_) {
|
if (!initialized_) {
|
||||||
LOGE("CdmLicense::PrepareKeyUpdateRequest: not initialized");
|
LOGE("CdmLicense::PrepareKeyUpdateRequest: not initialized");
|
||||||
return false;
|
return UNKNOWN_ERROR;
|
||||||
}
|
}
|
||||||
if (!signed_request) {
|
if (!signed_request) {
|
||||||
LOGE("CdmLicense::PrepareKeyUpdateRequest: No signed request provided");
|
LOGE("CdmLicense::PrepareKeyUpdateRequest: No signed request provided");
|
||||||
return false;
|
return UNKNOWN_ERROR;
|
||||||
}
|
}
|
||||||
if (!server_url) {
|
if (!server_url) {
|
||||||
LOGE("CdmLicense::PrepareKeyUpdateRequest: No server url provided");
|
LOGE("CdmLicense::PrepareKeyUpdateRequest: No server url provided");
|
||||||
return false;
|
return UNKNOWN_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
LicenseRequest license_request;
|
LicenseRequest license_request;
|
||||||
@@ -513,7 +514,7 @@ bool CdmLicense::PrepareKeyUpdateRequest(bool is_renewal,
|
|||||||
CdmResponseType status =
|
CdmResponseType status =
|
||||||
session_->DeactivateUsageInformation(provider_session_token_);
|
session_->DeactivateUsageInformation(provider_session_token_);
|
||||||
if (NO_ERROR != status)
|
if (NO_ERROR != status)
|
||||||
return false;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string usage_report;
|
std::string usage_report;
|
||||||
@@ -526,7 +527,7 @@ bool CdmLicense::PrepareKeyUpdateRequest(bool is_renewal,
|
|||||||
if (NO_ERROR == status)
|
if (NO_ERROR == status)
|
||||||
current_license->set_session_usage_table_entry(usage_report);
|
current_license->set_session_usage_table_entry(usage_report);
|
||||||
else
|
else
|
||||||
return false;
|
return KEY_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -545,7 +546,7 @@ bool CdmLicense::PrepareKeyUpdateRequest(bool is_renewal,
|
|||||||
// of the license response.
|
// of the license response.
|
||||||
uint32_t nonce;
|
uint32_t nonce;
|
||||||
if (!session_->GenerateNonce(&nonce)) {
|
if (!session_->GenerateNonce(&nonce)) {
|
||||||
return false;
|
return KEY_ERROR;
|
||||||
}
|
}
|
||||||
license_request.set_key_control_nonce(nonce);
|
license_request.set_key_control_nonce(nonce);
|
||||||
LOGD("PrepareKeyUpdateRequest: nonce=%u", nonce);
|
LOGD("PrepareKeyUpdateRequest: nonce=%u", nonce);
|
||||||
@@ -559,13 +560,13 @@ bool CdmLicense::PrepareKeyUpdateRequest(bool is_renewal,
|
|||||||
std::string license_request_signature;
|
std::string license_request_signature;
|
||||||
if (!session_->PrepareRenewalRequest(serialized_license_req,
|
if (!session_->PrepareRenewalRequest(serialized_license_req,
|
||||||
&license_request_signature))
|
&license_request_signature))
|
||||||
return false;
|
return KEY_ERROR;
|
||||||
|
|
||||||
if (license_request_signature.empty()) {
|
if (license_request_signature.empty()) {
|
||||||
LOGE(
|
LOGE(
|
||||||
"CdmLicense::PrepareKeyUpdateRequest: empty license request"
|
"CdmLicense::PrepareKeyUpdateRequest: empty license request"
|
||||||
" signature");
|
" signature");
|
||||||
return false;
|
return KEY_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put serialize license request and signature together
|
// Put serialize license request and signature together
|
||||||
@@ -576,7 +577,7 @@ bool CdmLicense::PrepareKeyUpdateRequest(bool is_renewal,
|
|||||||
|
|
||||||
signed_message.SerializeToString(signed_request);
|
signed_message.SerializeToString(signed_request);
|
||||||
*server_url = server_url_;
|
*server_url = server_url_;
|
||||||
return true;
|
return KEY_MESSAGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
CdmResponseType CdmLicense::HandleKeyResponse(
|
CdmResponseType CdmLicense::HandleKeyResponse(
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ const uint32_t kMinute = 60;
|
|||||||
const uint32_t kClockTolerance = 5;
|
const uint32_t kClockTolerance = 5;
|
||||||
const uint32_t kTwoMinutes = 120;
|
const uint32_t kTwoMinutes = 120;
|
||||||
|
|
||||||
|
const uint32_t kMaxUsageTableSize = 50;
|
||||||
|
|
||||||
// Default license server, can be configured using --server command line option
|
// Default license server, can be configured using --server command line option
|
||||||
// Default key id (pssh), can be configured using --keyid command line option
|
// Default key id (pssh), can be configured using --keyid command line option
|
||||||
std::string g_client_auth;
|
std::string g_client_auth;
|
||||||
@@ -116,6 +118,29 @@ SubSampleInfo kEncryptedStreamingClip1SubSample = {
|
|||||||
"37326df26fa509343faa98dff667629f557873f1284903202e451227ef465a62"),
|
"37326df26fa509343faa98dff667629f557873f1284903202e451227ef465a62"),
|
||||||
wvcdm::a2b_hex("7362b5140c4ce0cd5f863858668d3f1a"), 0, 3};
|
wvcdm::a2b_hex("7362b5140c4ce0cd5f863858668d3f1a"), 0, 3};
|
||||||
|
|
||||||
|
SubSampleInfo kEncryptedStreamingClip5SubSample = {
|
||||||
|
true, 1, true, true, false,
|
||||||
|
wvcdm::a2bs_hex("3AE243D83B93B3311A1D777FF5FBE01A"),
|
||||||
|
wvcdm::a2b_hex(
|
||||||
|
"934997779aa1aeb45d6ba8845f13786575d0adf85a5e93674d9597f8d4286ed7"
|
||||||
|
"dcce02f306e502bbd9f1cadf502f354038ca921276d158d911bdf3171d335b18"
|
||||||
|
"0ae0f9abece16ff31ee263228354f724da2f3723b19caa38ea02bd6563b01208"
|
||||||
|
"fb5bf57854ac0fe38d5883197ef90324b2721ff20fdcf9a53819515e6daa096e"
|
||||||
|
"70f6f5c1d29a4a13dafd127e2e1f761ea0e28fd451607552ecbaef5da3c780bc"
|
||||||
|
"aaf2667b4cc4f858f01d480cac9e32c3fbb5705e5d2adcceebefc2535c117208"
|
||||||
|
"e65f604799fc3d7223e16908550f287a4bea687008cb0064cf14d3aeedb8c705"
|
||||||
|
"09ebc5c2b8b5315f43c04d78d2f55f4b32c7d33e157114362106395cc0bb6d93"),
|
||||||
|
wvcdm::a2b_hex(
|
||||||
|
"2dd54eee1307753508e1f250d637044d6e8f5abf057dab73e9e95f83910e4efc"
|
||||||
|
"191c9bac63950f13fd51833dd94a4d03f2b64fb5c721970c418fe53fa6f74ad5"
|
||||||
|
"a6e16477a35c7aa6e28909b069cd25770ef80da20918fc30fe95fd5c87fd3522"
|
||||||
|
"1649de17ca2c7b3dc31f936f0cbdf97c7b1c15de3a86b279dc4b4de64943914a"
|
||||||
|
"99734556c4b7a1a0b022c1933cb0786068fc18d49fed2f2b49f3ac6d01c32d07"
|
||||||
|
"92175ce2844eaf9064e6a3fcffade038d690cbed81659351163a22432f0d0545"
|
||||||
|
"037e1c805d8e92a1272b4196ad0ce22f26bb80063137a8e454d3b97e2414283d"
|
||||||
|
"ed0716cd8bceb80cf59166a217006bd147c51b04dfb183088ce3f51e9b9f759e"),
|
||||||
|
wvcdm::a2b_hex("b358ab21ac90455bbf60490daad457e3"), 0, 3};
|
||||||
|
|
||||||
SubSampleInfo kEncryptedOfflineClip2SubSample = {
|
SubSampleInfo kEncryptedOfflineClip2SubSample = {
|
||||||
true, 1, true, true, false,
|
true, 1, true, true, false,
|
||||||
wvcdm::a2bs_hex("3260F39E12CCF653529990168A3583FF"),
|
wvcdm::a2bs_hex("3260F39E12CCF653529990168A3583FF"),
|
||||||
@@ -150,6 +175,7 @@ std::string kOfflineClip2PstInitData = wvcdm::a2bs_hex(
|
|||||||
"EDEF8BA979D64ACEA3C827DCD51D21ED00000020" // Widevine system id
|
"EDEF8BA979D64ACEA3C827DCD51D21ED00000020" // Widevine system id
|
||||||
"08011a0d7769646576696e655f74657374220d6f" // pssh data
|
"08011a0d7769646576696e655f74657374220d6f" // pssh data
|
||||||
"66666c696e655f636c697032");
|
"66666c696e655f636c697032");
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace wvcdm {
|
namespace wvcdm {
|
||||||
@@ -167,6 +193,7 @@ class TestWvCdmClientPropertySet : public CdmClientPropertySet {
|
|||||||
session_sharing_id_(0) {}
|
session_sharing_id_(0) {}
|
||||||
virtual ~TestWvCdmClientPropertySet() {}
|
virtual ~TestWvCdmClientPropertySet() {}
|
||||||
|
|
||||||
|
virtual const std::string& app_id() const { return app_id_; }
|
||||||
virtual const std::string& security_level() const { return security_level_; }
|
virtual const std::string& security_level() const { return security_level_; }
|
||||||
virtual const std::string& service_certificate() const {
|
virtual const std::string& service_certificate() const {
|
||||||
return service_certificate_;
|
return service_certificate_;
|
||||||
@@ -177,6 +204,7 @@ class TestWvCdmClientPropertySet : public CdmClientPropertySet {
|
|||||||
}
|
}
|
||||||
virtual uint32_t session_sharing_id() const { return session_sharing_id_; }
|
virtual uint32_t session_sharing_id() const { return session_sharing_id_; }
|
||||||
|
|
||||||
|
void set_app_id(const std::string& app_id) { app_id_ = app_id; }
|
||||||
void set_security_level(const std::string& security_level) {
|
void set_security_level(const std::string& security_level) {
|
||||||
if (!security_level.compare(QUERY_VALUE_SECURITY_LEVEL_L1) ||
|
if (!security_level.compare(QUERY_VALUE_SECURITY_LEVEL_L1) ||
|
||||||
!security_level.compare(QUERY_VALUE_SECURITY_LEVEL_L3)) {
|
!security_level.compare(QUERY_VALUE_SECURITY_LEVEL_L3)) {
|
||||||
@@ -195,6 +223,7 @@ class TestWvCdmClientPropertySet : public CdmClientPropertySet {
|
|||||||
void set_session_sharing_id(uint32_t id) { session_sharing_id_ = id; }
|
void set_session_sharing_id(uint32_t id) { session_sharing_id_ = id; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::string app_id_;
|
||||||
std::string security_level_;
|
std::string security_level_;
|
||||||
std::string service_certificate_;
|
std::string service_certificate_;
|
||||||
bool use_privacy_mode_;
|
bool use_privacy_mode_;
|
||||||
@@ -794,6 +823,53 @@ TEST_F(WvCdmExtendedDurationTest, VerifyLicenseRenewalTest) {
|
|||||||
decryptor_.CloseSession(session_id_);
|
decryptor_.CloseSession(session_id_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(WvCdmExtendedDurationTest, UsageOverflowTest) {
|
||||||
|
Provision();
|
||||||
|
SubSampleInfo* data = &kEncryptedStreamingClip5SubSample;
|
||||||
|
TestWvCdmClientPropertySet client_property_set;
|
||||||
|
TestWvCdmClientPropertySet* property_set = NULL;
|
||||||
|
|
||||||
|
CdmSecurityLevel security_level = GetDefaultSecurityLevel();
|
||||||
|
DeviceFiles handle;
|
||||||
|
EXPECT_TRUE(handle.Init(security_level));
|
||||||
|
File file;
|
||||||
|
handle.SetTestFile(&file);
|
||||||
|
EXPECT_TRUE(handle.DeleteAllUsageInfoForApp(""));
|
||||||
|
|
||||||
|
for (size_t i = 0; i < kMaxUsageTableSize + 100; ++i) {
|
||||||
|
decryptor_.OpenSession(g_key_system, property_set, &session_id_);
|
||||||
|
std::string key_id = a2bs_hex(
|
||||||
|
"000000427073736800000000" // blob size and pssh
|
||||||
|
"EDEF8BA979D64ACEA3C827DCD51D21ED00000022" // Widevine system id
|
||||||
|
"08011a0d7769646576696e655f74657374220f73" // pssh data
|
||||||
|
"747265616d696e675f636c697035");
|
||||||
|
|
||||||
|
GenerateKeyRequest(key_id, kLicenseTypeStreaming);
|
||||||
|
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
|
||||||
|
decryptor_.CloseSession(session_id_);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t num_usage_info = 0;
|
||||||
|
CdmUsageInfo usage_info;
|
||||||
|
CdmUsageInfoReleaseMessage release_msg;
|
||||||
|
CdmResponseType status = decryptor_.GetUsageInfo("", &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("", &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 WvCdmStreamingNoPstTest : public WvCdmExtendedDurationTest,
|
class WvCdmStreamingNoPstTest : public WvCdmExtendedDurationTest,
|
||||||
public ::testing::WithParamInterface<size_t> {};
|
public ::testing::WithParamInterface<size_t> {};
|
||||||
|
|
||||||
|
|||||||
@@ -1200,6 +1200,68 @@ TEST_F(WvCdmRequestLicenseTest, RemoveKeys) {
|
|||||||
ASSERT_EQ(NO_ERROR, decryptor_.CloseSession(session_id_));
|
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
|
class WvCdmUsageInfoTest
|
||||||
: public WvCdmRequestLicenseTest,
|
: public WvCdmRequestLicenseTest,
|
||||||
public ::testing::WithParamInterface<UsageInfoSubSampleInfo*> {};
|
public ::testing::WithParamInterface<UsageInfoSubSampleInfo*> {};
|
||||||
|
|||||||
Reference in New Issue
Block a user