// 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.h" #include #include #include "log.h" using video_widevine::License; namespace wvcdm { void PolicyTimers::SetLicense(const video_widevine::License& license) { policy_.Clear(); if (license.has_license_start_time()) license_start_time_ = license.license_start_time(); } 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; if (playback_start_time_ == 0) return playback_duration; const int64_t playback_expiry_time = playback_duration + playback_start_time_; if (playback_expiry_time < current_time) return 0; const int64_t policy_playback_duration = policy_.playback_duration_seconds(); return std::min(playback_expiry_time - current_time, policy_playback_duration); } bool PolicyTimers::GetSecondsSinceStarted(int64_t current_time, int64_t* seconds_since_started) { if (seconds_since_started == nullptr) { LOGE("|seconds_since_started| not provided"); return false; } if (playback_start_time_ == 0) return false; *seconds_since_started = current_time - playback_start_time_; return (*seconds_since_started >= 0) ? true : false; } bool PolicyTimers::GetSecondsSinceLastPlayed( int64_t current_time, int64_t* seconds_since_last_played) { if (seconds_since_last_played == nullptr) { LOGE("|seconds_since_last_played| not provided"); return false; } if (last_playback_time_ == 0) return false; *seconds_since_last_played = current_time - last_playback_time_; return (*seconds_since_last_played >= 0) ? true : false; } bool PolicyTimers::IsLicenseForFuture(int64_t current_time) { return current_time < license_start_time_; } bool PolicyTimers::UpdateExpirationTime(int64_t current_time, int64_t* expiry_time) { if (expiry_time == nullptr) { LOGE("|expiry_time| mot provided"); return false; } *expiry_time = GetExpiryTime(current_time, /* ignore_soft_enforce_playback_duration */ false); const bool has_expiry_time_been_updated = !last_expiry_time_set_ || *expiry_time != last_expiry_time_; if (has_expiry_time_been_updated) last_expiry_time_ = *expiry_time; last_expiry_time_set_ = true; return has_expiry_time_been_updated; } bool PolicyTimers::HasRenewalRetryIntervalExpired(int64_t current_time) { return policy_.can_renew() && (policy_.renewal_retry_interval_seconds() > 0) && (next_renewal_time_ <= current_time); } void PolicyTimers::UpdateRenewalRequest(int64_t current_time) { next_renewal_time_ = current_time + policy_.renewal_retry_interval_seconds(); } bool PolicyTimers::HasRenewalRecoveryDurationExpired(int64_t current_time) { return (policy_.renewal_recovery_duration_seconds() > 0) && (license_start_time_ + policy_.renewal_recovery_duration_seconds() <= 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