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:
@@ -20,7 +20,8 @@ using video_widevine::License;
|
||||
namespace {
|
||||
|
||||
const int kCdmPolicyTimerDurationSeconds = 1;
|
||||
const int kClockSkewDelta = 5; // seconds
|
||||
const int kClockSkewDelta = 5; // seconds
|
||||
const int64_t kLicenseStateUpdateDelay = 20; // seconds
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -30,6 +31,7 @@ PolicyEngine::PolicyEngine(CdmSessionId session_id,
|
||||
WvCdmEventListener* event_listener,
|
||||
CryptoSession* crypto_session)
|
||||
: license_state_(kLicenseStateInitial),
|
||||
license_state_update_deadline_(0),
|
||||
last_recorded_current_time_(0),
|
||||
session_id_(session_id),
|
||||
event_listener_(event_listener),
|
||||
@@ -90,6 +92,17 @@ void PolicyEngine::OnTimerEvent() {
|
||||
last_recorded_current_time_ += kCdmPolicyTimerDurationSeconds;
|
||||
const int64_t current_time = GetCurrentTime();
|
||||
|
||||
// This conditional should not succeed but being cautious in case license
|
||||
// state was not updated after the license was processed. Licenses and
|
||||
// renewals from the license service should update state on
|
||||
// |Set/UpdateLicense|. Offline licenses, when restored, should update license
|
||||
// state when |RestorePlaybackTimes| is called.
|
||||
if (license_state_update_deadline_ != 0 &&
|
||||
license_state_update_deadline_ < current_time) {
|
||||
LOGW("License state was not updated after a license was loaded/renewed");
|
||||
UpdateLicenseState(current_time);
|
||||
}
|
||||
|
||||
// If we have passed the grace period, the expiration will update.
|
||||
if (policy_timers_->HasPassedGracePeriod(current_time)) {
|
||||
NotifyExpirationUpdate(current_time);
|
||||
@@ -159,12 +172,13 @@ void PolicyEngine::OnTimerEvent() {
|
||||
}
|
||||
|
||||
void PolicyEngine::SetLicense(const License& license,
|
||||
bool supports_core_messages) {
|
||||
bool supports_core_messages,
|
||||
bool defer_license_state_update) {
|
||||
if (supports_core_messages) policy_timers_.reset(new PolicyTimersV16());
|
||||
license_id_.CopyFrom(license.id());
|
||||
license_keys_->SetFromLicense(license);
|
||||
policy_timers_->SetLicense(license);
|
||||
UpdateLicense(license);
|
||||
UpdateLicense(license, defer_license_state_update);
|
||||
}
|
||||
|
||||
void PolicyEngine::SetEntitledLicenseKeys(
|
||||
@@ -180,10 +194,11 @@ void PolicyEngine::SetLicenseForRelease(const License& license,
|
||||
// Expire any old keys.
|
||||
NotifyKeysChange(kKeyStatusExpired);
|
||||
policy_timers_->SetLicense(license);
|
||||
UpdateLicense(license);
|
||||
UpdateLicense(license, false);
|
||||
}
|
||||
|
||||
void PolicyEngine::UpdateLicense(const License& license) {
|
||||
void PolicyEngine::UpdateLicense(const License& license,
|
||||
bool defer_license_state_update) {
|
||||
if (!license.has_policy()) return;
|
||||
|
||||
if (kLicenseStateExpired == license_state_) {
|
||||
@@ -204,8 +219,15 @@ void PolicyEngine::UpdateLicense(const License& license) {
|
||||
|
||||
const int64_t current_time = GetCurrentTime();
|
||||
policy_timers_->UpdateLicense(current_time, license);
|
||||
if (defer_license_state_update)
|
||||
license_state_update_deadline_ = current_time + kLicenseStateUpdateDelay;
|
||||
else
|
||||
UpdateLicenseState(current_time);
|
||||
}
|
||||
|
||||
void PolicyEngine::UpdateLicenseState(int64_t current_time) {
|
||||
// Update time information
|
||||
license_state_update_deadline_ = 0;
|
||||
if (!policy_timers_->get_policy().can_play() ||
|
||||
policy_timers_->HasLicenseOrRentalOrPlaybackDurationExpired(
|
||||
current_time)) {
|
||||
@@ -349,7 +371,7 @@ void PolicyEngine::RestorePlaybackTimes(int64_t playback_start_time,
|
||||
last_playback_time,
|
||||
grace_period_end_time);
|
||||
|
||||
NotifyExpirationUpdate(current_time);
|
||||
UpdateLicenseState(current_time);
|
||||
}
|
||||
|
||||
void PolicyEngine::UpdateRenewalRequest(int64_t current_time) {
|
||||
|
||||
Reference in New Issue
Block a user