Merge changes Ib18af309,Iebd58823,Ic3a503ef

* changes:
  Support renew on load
  Move functionality to policy_timer.
  Remove references to policy_timers_v15
This commit is contained in:
Rahul Frias
2022-12-22 08:11:29 +00:00
committed by Android (Google) Code Review
9 changed files with 269 additions and 406 deletions

View File

@@ -24,6 +24,28 @@ void PolicyTimers::DecryptionEvent(int64_t current_time) {
last_playback_time_ = current_time;
}
void PolicyTimers::RestorePlaybackTimes(int64_t current_time,
int64_t playback_start_time,
int64_t last_playback_time,
int64_t /* grace_period_end_time */) {
playback_start_time_ = (playback_start_time > 0) ? playback_start_time : 0;
last_playback_time_ = (last_playback_time > 0) ? last_playback_time : 0;
const int64_t expiry_time = GetExpiryTime(
current_time, /* ignore_soft_enforce_playback_duration */ true);
was_expired_on_load_ =
expiry_time != NEVER_EXPIRES && expiry_time < current_time;
}
int64_t PolicyTimers::GetLicenseOrRentalOrPlaybackDurationRemaining(
int64_t current_time) {
const int64_t expiry_time = GetExpiryTime(
current_time, /* ignore_soft_enforce_playback_duration */ false);
if (expiry_time == NEVER_EXPIRES) return LLONG_MAX;
if (expiry_time < current_time) return 0;
return expiry_time - current_time;
}
int64_t PolicyTimers::GetPlaybackDurationRemaining(int64_t current_time) {
const int64_t playback_duration = policy_.playback_duration_seconds();
if (playback_duration == 0) return LLONG_MAX;
@@ -85,12 +107,6 @@ bool PolicyTimers::UpdateExpirationTime(int64_t current_time,
return has_expiry_time_been_updated;
}
bool PolicyTimers::HasRenewalDelayExpired(int64_t current_time) {
return policy_.can_renew() && (policy_.renewal_delay_seconds() > 0) &&
(license_start_time_ + policy_.renewal_delay_seconds() <=
current_time);
}
bool PolicyTimers::HasRenewalRetryIntervalExpired(int64_t current_time) {
return policy_.can_renew() &&
(policy_.renewal_retry_interval_seconds() > 0) &&
@@ -107,4 +123,61 @@ bool PolicyTimers::HasRenewalRecoveryDurationExpired(int64_t current_time) {
current_time);
}
int64_t PolicyTimers::GetExpiryTime(
int64_t current_time, bool ignore_soft_enforce_playback_duration) {
const int64_t rental_expiry_time = GetRentalExpiryTime(current_time);
const int64_t playback_expiry_time = GetPlaybackExpiryTime(
current_time, ignore_soft_enforce_playback_duration);
if (rental_expiry_time == NEVER_EXPIRES) return playback_expiry_time;
if (playback_expiry_time == NEVER_EXPIRES) return rental_expiry_time;
return std::min(rental_expiry_time, playback_expiry_time);
}
// For the policy time fields checked in the following methods, a value of 0
// (UNLIMITED_DURATION) indicates that there is no limit to the duration.
// If the fields are UNLIMITED_DURATION then these methods will return
// NEVER_EXPIRES.
int64_t PolicyTimers::GetRentalExpiryTime(int64_t current_time) {
if (policy_.rental_duration_seconds() == UNLIMITED_DURATION)
return NEVER_EXPIRES;
if (HasPlaybackStarted(current_time) &&
policy_.soft_enforce_rental_duration())
return NEVER_EXPIRES;
return license_start_time_ + policy_.rental_duration_seconds();
}
int64_t PolicyTimers::GetPlaybackExpiryTime(
int64_t current_time, bool ignore_soft_enforce_playback_duration) {
if (policy_.playback_duration_seconds() == UNLIMITED_DURATION)
return NEVER_EXPIRES;
if (!HasPlaybackStarted(current_time)) return NEVER_EXPIRES;
if (was_expired_on_load_) return current_time;
if (!ignore_soft_enforce_playback_duration &&
policy_.soft_enforce_playback_duration())
return NEVER_EXPIRES;
return playback_start_time_ + policy_.playback_duration_seconds();
}
int64_t PolicyTimers::GetRentalDurationRemaining(int64_t current_time) {
if (HasLicenseOrRentalOrPlaybackDurationExpired(current_time)) return 0;
const int64_t rental_expiry_time = GetRentalExpiryTime(current_time);
if (rental_expiry_time == NEVER_EXPIRES) return LLONG_MAX;
if (rental_expiry_time < current_time) return 0;
return rental_expiry_time - current_time;
}
bool PolicyTimers::HasRentalOrPlaybackDurationExpired(int64_t current_time) {
const int64_t expiry_time = GetExpiryTime(
current_time, /* ignore_soft_enforce_playback_duration */ false);
return expiry_time != NEVER_EXPIRES && expiry_time <= current_time;
}
} // namespace wvcdm

View File

@@ -1,154 +0,0 @@
// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine License
// Agreement.
#include "policy_timers_v15.h"
#include <algorithm>
#include <string>
#include "log.h"
#include "wv_cdm_constants.h"
using video_widevine::License;
namespace {
const int64_t kTimeZero = 0;
} // namespace
namespace wvcdm {
bool PolicyTimersV15::UpdateLicense(int64_t current_time,
const License& license) {
if (!license.has_policy()) return false;
policy_.MergeFrom(license.policy());
// some basic license validation
// license start time needs to be specified in the initial response
if (!license.has_license_start_time()) return false;
// Update time information
license_start_time_ = license.license_start_time();
next_renewal_time_ = license_start_time_ + policy_.renewal_delay_seconds();
if (!policy_.can_play() ||
HasLicenseOrRentalOrPlaybackDurationExpired(current_time))
return false;
return true;
}
void PolicyTimersV15::BeginDecryption(int64_t current_time) {
if (playback_start_time_ == 0) {
playback_start_time_ = current_time;
last_playback_time_ = current_time;
if (policy_.play_start_grace_period_seconds() == 0)
grace_period_end_time_ = current_time;
}
}
void PolicyTimersV15::RestorePlaybackTimes(int64_t current_time,
int64_t playback_start_time,
int64_t last_playback_time,
int64_t grace_period_end_time) {
playback_start_time_ = std::max(playback_start_time, kTimeZero);
last_playback_time_ = std::max(last_playback_time, kTimeZero);
grace_period_end_time_ = grace_period_end_time;
if (policy_.play_start_grace_period_seconds() != 0) {
// If we are using grace period, we may need to override some of the values
// given to us by OEMCrypto. |grace_period_end_time| will be 0 if the grace
// period has not expired (effectively playback has not begun). Otherwise,
// |grace_period_end_time| contains the playback start time we should use.
playback_start_time_ = grace_period_end_time;
}
const int64_t expiry_time = GetExpiryTime(
current_time, /* ignore_soft_enforce_playback_duration */ true);
was_expired_on_load_ =
expiry_time != NEVER_EXPIRES && expiry_time < current_time;
}
bool PolicyTimersV15::HasPlaybackStarted(int64_t current_time) {
if (playback_start_time_ == 0) return false;
const int64_t playback_time = current_time - playback_start_time_;
return playback_time >= policy_.play_start_grace_period_seconds();
}
bool PolicyTimersV15::HasLicenseOrRentalOrPlaybackDurationExpired(
int64_t current_time) {
const int64_t expiry_time = GetExpiryTime(
current_time, /* ignore_soft_enforce_playback_duration */ false);
return expiry_time != NEVER_EXPIRES && expiry_time <= current_time;
}
bool PolicyTimersV15::HasPassedGracePeriod(int64_t current_time) {
if (grace_period_end_time_ == 0 && HasPlaybackStarted(current_time)) {
grace_period_end_time_ = playback_start_time_;
return true;
}
return false;
}
int64_t PolicyTimersV15::GetLicenseOrRentalOrPlaybackDurationRemaining(
int64_t current_time) {
const int64_t expiry_time = GetExpiryTime(
current_time, /* ignore_soft_enforce_playback_duration */ false);
if (expiry_time == NEVER_EXPIRES) return LLONG_MAX;
if (expiry_time < current_time) return 0;
return expiry_time - current_time;
}
int64_t PolicyTimersV15::GetLicenseOrRentalDurationRemaining(
int64_t current_time) {
if (HasLicenseOrRentalOrPlaybackDurationExpired(current_time)) return 0;
const int64_t license_expiry_time = GetRentalExpiryTime();
if (license_expiry_time == NEVER_EXPIRES) return LLONG_MAX;
if (license_expiry_time < current_time) return 0;
const int64_t policy_license_duration = policy_.license_duration_seconds();
if (policy_license_duration == UNLIMITED_DURATION)
return license_expiry_time - current_time;
return std::min(license_expiry_time - current_time, policy_license_duration);
}
// For the policy time fields checked in the following methods, a value of 0
// (UNLIMITED_DURATION) indicates that there is no limit to the duration.
// If the fields are UNLIMITED_DURATION (including the hard limit) then these
// methods will return NEVER_EXPIRES.
int64_t PolicyTimersV15::GetHardLicenseExpiryTime() {
return policy_.license_duration_seconds() > 0
? license_start_time_ + policy_.license_duration_seconds()
: NEVER_EXPIRES;
}
int64_t PolicyTimersV15::GetRentalExpiryTime() {
const int64_t hard_limit = GetHardLicenseExpiryTime();
if (policy_.rental_duration_seconds() == 0) return hard_limit;
const int64_t expiry_time =
license_start_time_ + policy_.rental_duration_seconds();
if (hard_limit == NEVER_EXPIRES) return expiry_time;
return std::min(hard_limit, expiry_time);
}
int64_t PolicyTimersV15::GetExpiryTime(
int64_t current_time, bool ignore_soft_enforce_playback_duration) {
if (!HasPlaybackStarted(current_time)) return GetRentalExpiryTime();
const int64_t hard_limit = GetHardLicenseExpiryTime();
if (policy_.playback_duration_seconds() == 0) return hard_limit;
if (!ignore_soft_enforce_playback_duration && !was_expired_on_load_ &&
policy_.soft_enforce_playback_duration()) {
return hard_limit;
}
const int64_t expiry_time =
playback_start_time_ + policy_.playback_duration_seconds();
if (hard_limit == NEVER_EXPIRES) return expiry_time;
return std::min(hard_limit, expiry_time);
}
} // namespace wvcdm

View File

@@ -42,88 +42,10 @@ void PolicyTimersV16::BeginDecryption(int64_t current_time) {
}
}
void PolicyTimersV16::RestorePlaybackTimes(
int64_t current_time, int64_t playback_start_time,
int64_t last_playback_time, int64_t /* grace_period_end_time */) {
playback_start_time_ = (playback_start_time > 0) ? playback_start_time : 0;
last_playback_time_ = (last_playback_time > 0) ? last_playback_time : 0;
const int64_t expiry_time = GetExpiryTime(
current_time, /* ignore_soft_enforce_playback_duration */ true);
was_expired_on_load_ =
expiry_time != NEVER_EXPIRES && expiry_time < current_time;
}
bool PolicyTimersV16::HasRentalOrPlaybackDurationExpired(int64_t current_time) {
const int64_t expiry_time = GetExpiryTime(
current_time, /* ignore_soft_enforce_playback_duration */ false);
return expiry_time != NEVER_EXPIRES && expiry_time <= current_time;
}
int64_t PolicyTimersV16::GetLicenseOrRentalOrPlaybackDurationRemaining(
int64_t current_time) {
const int64_t expiry_time = GetExpiryTime(
current_time, /* ignore_soft_enforce_playback_duration */ false);
if (expiry_time == NEVER_EXPIRES) return LLONG_MAX;
if (expiry_time < current_time) return 0;
return expiry_time - current_time;
}
int64_t PolicyTimersV16::GetRentalDurationRemaining(int64_t current_time) {
if (HasLicenseOrRentalOrPlaybackDurationExpired(current_time)) return 0;
const int64_t rental_expiry_time = GetRentalExpiryTime(current_time);
if (rental_expiry_time == NEVER_EXPIRES) return LLONG_MAX;
if (rental_expiry_time < current_time) return 0;
return rental_expiry_time - current_time;
}
bool PolicyTimersV16::HasRenewalDelayExpired(int64_t current_time) {
return policy_.can_renew() && (policy_.renewal_delay_seconds() > 0) &&
(renewal_start_time_ + policy_.renewal_delay_seconds() <=
current_time);
}
// For the policy time fields checked in the following methods, a value of 0
// (UNLIMITED_DURATION) indicates that there is no limit to the duration.
// If the fields are UNLIMITED_DURATION then these methods will return
// NEVER_EXPIRES.
int64_t PolicyTimersV16::GetRentalExpiryTime(int64_t current_time) {
if (policy_.rental_duration_seconds() == UNLIMITED_DURATION)
return NEVER_EXPIRES;
if (HasPlaybackStarted(current_time) &&
policy_.soft_enforce_rental_duration())
return NEVER_EXPIRES;
return license_start_time_ + policy_.rental_duration_seconds();
}
int64_t PolicyTimersV16::GetPlaybackExpiryTime(
int64_t current_time, bool ignore_soft_enforce_playback_duration) {
if (policy_.playback_duration_seconds() == UNLIMITED_DURATION)
return NEVER_EXPIRES;
if (!HasPlaybackStarted(current_time)) return NEVER_EXPIRES;
if (was_expired_on_load_) return current_time;
if (!ignore_soft_enforce_playback_duration &&
policy_.soft_enforce_playback_duration())
return NEVER_EXPIRES;
return playback_start_time_ + policy_.playback_duration_seconds();
}
int64_t PolicyTimersV16::GetExpiryTime(
int64_t current_time, bool ignore_soft_enforce_playback_duration) {
const int64_t rental_expiry_time = GetRentalExpiryTime(current_time);
const int64_t playback_expiry_time = GetPlaybackExpiryTime(
current_time, ignore_soft_enforce_playback_duration);
if (rental_expiry_time == NEVER_EXPIRES) return playback_expiry_time;
if (playback_expiry_time == NEVER_EXPIRES) return rental_expiry_time;
return std::min(rental_expiry_time, playback_expiry_time);
}
} // namespace wvcdm

View File

@@ -0,0 +1,87 @@
// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine License
// Agreement.
#include "policy_timers_v18.h"
#include <algorithm>
#include "log.h"
#include "wv_cdm_constants.h"
using video_widevine::License;
namespace wvcdm {
bool PolicyTimersV18::UpdateLicense(int64_t current_time,
const License& license) {
if (!license.has_policy()) return false;
policy_.MergeFrom(license.policy());
// some basic license validation
// license start time needs to be specified in the initial response
if (!license.has_license_start_time()) return false;
// Update renewal information
if (license_renewal_) {
renewal_start_time_ = license.license_start_time();
next_renewal_time_ =
license.license_start_time() + policy_.renewal_delay_seconds();
} else {
// Initial license received, use |renewal_delay_base| in calcualtion
switch (license.policy().initial_renewal_delay_base()) {
case video_widevine::
License_Policy_TimerDelayBase_TIMER_DELAY_BASE_UNSPECIFIED:
case video_widevine::License_Policy_TimerDelayBase_LICENSE_START:
renewal_start_time_ = license.license_start_time();
break;
case video_widevine::License_Policy_TimerDelayBase_LICENSE_LOAD:
renewal_start_time_ = current_time;
break;
case video_widevine::License_Policy_TimerDelayBase_FIRST_DECRYPT:
break;
default:
LOGE("Unrecognized initial_renewal_delay_base value = %d",
license.policy().initial_renewal_delay_base());
renewal_start_time_ = license.license_start_time();
break;
}
if (!renew_on_first_decrypt_) {
next_renewal_time_ =
renewal_start_time_ + policy_.renewal_delay_seconds();
}
// Any subsequent calls to |UpdateLicense| will be license renewals
license_renewal_ = true;
}
if (!policy_.can_play() ||
HasLicenseOrRentalOrPlaybackDurationExpired(current_time))
return false;
return true;
}
void PolicyTimersV18::BeginDecryption(int64_t current_time) {
if (playback_start_time_ != 0) return;
playback_start_time_ = current_time;
last_playback_time_ = current_time;
if (renew_on_first_decrypt_) {
renewal_start_time_ = current_time;
next_renewal_time_ = renewal_start_time_ + policy_.renewal_delay_seconds();
renew_on_first_decrypt_ = false;
}
}
bool PolicyTimersV18::HasRenewalDelayExpired(int64_t current_time) {
if (renew_on_first_decrypt_ && playback_start_time_ == 0) return false;
return policy_.can_renew() &&
(renewal_start_time_ + policy_.renewal_delay_seconds() <=
current_time);
}
} // namespace wvcdm