Delay license state evaluation for offline licenses

[ Merge of http://go/wvgerrit/106325 and http://go/ag/12644840 ]

When offline licenses are restored, licenses and any renewals are processed.
License state evaluation occurs and notifications are sent to listeners.
If the license is expired, which is likely if a renewal is present,
the license state will transition to expired. Transitions out of
expired state are not allowed and the renewal has no effect.

If we work around this by allowing transitions out of expired state,
listeners will get notifications that keys have expired and then that are
usable soon after. To avoid delivering erroneous notifications we delay
evaluation of license state while the license and renewal are being processed.
Evaluation occurs at the last stage of license restoration when playback
information from the usage table is being restored.

This only need to occur for when licenses are being restored. In other
cases when a license or renewal is received, license state evaluation
and event listener notification needs to occur immediately.

Bug: 166131956

Test: WV unit/integration tests, GtsMediaTestCases tests
Change-Id: Ic8ade25316c5e20cc88de9225c43c24b28f21ac4
This commit is contained in:
Rahul Frias
2020-09-19 02:37:08 -07:00
parent 80667cbac3
commit 8543b4c903
7 changed files with 248 additions and 171 deletions

View File

@@ -530,7 +530,7 @@ CdmResponseType CdmLicense::PrepareKeyUpdateRequest(
}
CdmResponseType CdmLicense::HandleKeyResponse(
const CdmKeyResponse& license_response) {
bool is_restore, const CdmKeyResponse& license_response) {
if (!initialized_) {
LOGE("CdmLicense not initialized");
return LICENSE_PARSER_NOT_INITIALIZED_2;
@@ -683,18 +683,19 @@ CdmResponseType CdmLicense::HandleKeyResponse(
CdmResponseType resp = NO_CONTENT_KEY;
if (kLicenseKeyTypeEntitlement == key_type) {
resp =
HandleEntitlementKeyResponse(signed_message, core_message, signature,
mac_key_iv, mac_keys, key_array, license);
resp = HandleEntitlementKeyResponse(is_restore, signed_message,
core_message, signature, mac_key_iv,
mac_keys, key_array, license);
} else if (kLicenseKeyTypeContent == key_type) {
resp = HandleContentKeyResponse(signed_message, core_message, signature,
mac_key_iv, mac_keys, key_array, license);
resp = HandleContentKeyResponse(is_restore, signed_message, core_message,
signature, mac_key_iv, mac_keys, key_array,
license);
}
return resp;
}
CdmResponseType CdmLicense::HandleKeyUpdateResponse(
bool is_renewal, const CdmKeyResponse& license_response) {
bool is_renewal, bool is_restore, const CdmKeyResponse& license_response) {
if (!initialized_) {
LOGE("CdmLicense not initialized");
return LICENSE_PARSER_NOT_INITIALIZED_3;
@@ -781,7 +782,7 @@ CdmResponseType CdmLicense::HandleKeyUpdateResponse(
}
if (status == KEY_ADDED) {
policy_engine_->UpdateLicense(license);
policy_engine_->UpdateLicense(license, is_restore);
}
return status;
@@ -836,14 +837,14 @@ CdmResponseType CdmLicense::RestoreOfflineLicense(
license_nonce_ = original_license_request.key_control_nonce();
}
CdmResponseType sts = HandleKeyResponse(license_response);
CdmResponseType sts = HandleKeyResponse(true, license_response);
if (sts != KEY_ADDED) return sts;
if (!license_renewal_response.empty()) {
sts = PrepareKeyUpdateReload(cdm_session);
if (sts != KEY_MESSAGE) return sts;
sts = HandleKeyUpdateResponse(true, license_renewal_response);
if (sts != KEY_MESSAGE && sts != NO_ERROR) return sts;
sts = HandleKeyUpdateResponse(true, true, license_renewal_response);
if (sts != KEY_ADDED) return sts;
}
@@ -968,7 +969,7 @@ CdmResponseType CdmLicense::RestoreLicenseForRelease(
}
if (!license.id().has_provider_session_token()) {
CdmResponseType result = HandleKeyResponse(license_response);
CdmResponseType result = HandleKeyResponse(false, license_response);
return result == KEY_ADDED ? NO_ERROR : result;
}
@@ -1116,7 +1117,7 @@ CdmResponseType CdmLicense::PrepareContentId(
}
CdmResponseType CdmLicense::HandleContentKeyResponse(
const std::string& msg, const std::string& core_message,
bool is_restore, const std::string& msg, const std::string& core_message,
const std::string& signature, const std::string& mac_key_iv,
const std::string& mac_key, const std::vector<CryptoKey>& key_array,
const video_widevine::License& license) {
@@ -1140,13 +1141,13 @@ CdmResponseType CdmLicense::HandleContentKeyResponse(
it != key_array.end(); ++it) {
loaded_keys_.insert(it->key_id());
}
policy_engine_->SetLicense(license, supports_core_messages());
policy_engine_->SetLicense(license, supports_core_messages(), is_restore);
}
return resp;
}
CdmResponseType CdmLicense::HandleEntitlementKeyResponse(
const std::string& msg, const std::string& core_message,
bool is_restore, const std::string& msg, const std::string& core_message,
const std::string& signature, const std::string& mac_key_iv,
const std::string& mac_key, const std::vector<CryptoKey>& key_array,
const video_widevine::License& license) {
@@ -1170,7 +1171,7 @@ CdmResponseType CdmLicense::HandleEntitlementKeyResponse(
// Save the entitlement keys for future use to handle key changes.
entitlement_keys_.CopyFrom(license.key());
policy_engine_->SetLicense(license, supports_core_messages());
policy_engine_->SetLicense(license, supports_core_messages(), is_restore);
return HandleNewEntitledKeys(wrapped_keys_);
}