diff --git a/libwvdrmengine/cdm/Android.bp b/libwvdrmengine/cdm/Android.bp index 78f97935..1de41a91 100644 --- a/libwvdrmengine/cdm/Android.bp +++ b/libwvdrmengine/cdm/Android.bp @@ -61,8 +61,8 @@ cc_library_static { CORE_SRC_DIR + "/ota_keybox_provisioner.cpp", CORE_SRC_DIR + "/policy_engine.cpp", CORE_SRC_DIR + "/policy_timers.cpp", - CORE_SRC_DIR + "/policy_timers_v15.cpp", CORE_SRC_DIR + "/policy_timers_v16.cpp", + CORE_SRC_DIR + "/policy_timers_v18.cpp", CORE_SRC_DIR + "/privacy_crypto_boringssl.cpp", CORE_SRC_DIR + "/service_certificate.cpp", CORE_SRC_DIR + "/system_id_extractor.cpp", diff --git a/libwvdrmengine/cdm/core/include/policy_timers.h b/libwvdrmengine/cdm/core/include/policy_timers.h index 4287b0cf..564e3b38 100644 --- a/libwvdrmengine/cdm/core/include/policy_timers.h +++ b/libwvdrmengine/cdm/core/include/policy_timers.h @@ -10,6 +10,7 @@ #include "disallow_copy_and_assign.h" #include "license_protocol.pb.h" +#include "wv_cdm_constants.h" #include "wv_cdm_types.h" namespace wvcdm { @@ -43,20 +44,45 @@ class PolicyTimers { // For offline save and restore virtual int64_t GetPlaybackStartTime() { return playback_start_time_; } virtual int64_t GetLastPlaybackTime() { return last_playback_time_; } - virtual int64_t GetGracePeriodEndTime() = 0; + // This is a legacy field for offline licenses. Since no grace period is + // supported return a default value. + virtual int64_t GetGracePeriodEndTime() { return 0; } virtual void RestorePlaybackTimes(int64_t current_time, int64_t playback_start_time, int64_t last_playback_time, - int64_t grace_period_end_time) = 0; + int64_t grace_period_end_time); - virtual bool HasPlaybackStarted(int64_t current_time) = 0; + virtual bool HasPlaybackStarted(int64_t /* current_time */) { + return playback_start_time_ != 0; + } + + // For licenses that support core messages, evaluation of only rental and + // playback durations are needed. virtual bool HasLicenseOrRentalOrPlaybackDurationExpired( - int64_t current_time) = 0; - virtual bool HasPassedGracePeriod(int64_t current_time) = 0; + int64_t current_time) { + return HasRentalOrPlaybackDurationExpired(current_time); + } + virtual bool HasPassedGracePeriod(int64_t /* current_time */) { return true; } + // This returns + // * before playback begins: the time remaining on |rental_duration_seconds| + // * after playback begins: + // - |soft_enforce_playback_duration| is true: the time remaining on + // |playback_duration_seconds| + // - |soft_enforce_playback_duration| is false: the minimum + // of the time remaining on |rental_duration_seconds| or + // |playback_duration_seconds| + // + // |license_duration_seconds| is ignored with the introduction of core + // messages virtual int64_t GetLicenseOrRentalOrPlaybackDurationRemaining( - int64_t current_time) = 0; - virtual int64_t GetLicenseOrRentalDurationRemaining(int64_t current_time) = 0; + int64_t current_time); + // This is only used in Query. This should return the time remaining on + // |rental_duration_seconds|. + virtual int64_t GetLicenseOrRentalDurationRemaining(int64_t current_time) { + return GetRentalDurationRemaining(current_time); + }; + // This is only used in Query. This should return |playback_duration_seconds| // before playback begins or the time remaining on // |playback_duration_seconds| after playback begins. @@ -72,7 +98,7 @@ class PolicyTimers { virtual bool UpdateExpirationTime(int64_t current_time, int64_t* expiry_time); // Renewal related methods - virtual bool HasRenewalDelayExpired(int64_t current_time); + virtual bool HasRenewalDelayExpired(int64_t current_time) = 0; virtual bool HasRenewalRetryIntervalExpired(int64_t current_time); virtual void UpdateRenewalRequest(int64_t current_time); virtual bool HasRenewalRecoveryDurationExpired(int64_t current_time); @@ -90,11 +116,11 @@ class PolicyTimers { was_expired_on_load_(false) {} // Gets the clock time that the license expires based on whether we have - // started playing. + // started playing. This takes into account GetHardLicenseExpiryTime. virtual int64_t GetExpiryTime(int64_t current_time, - bool ignore_soft_enforce_playback_duration) = 0; + bool ignore_soft_enforce_playback_duration); - virtual int64_t GetRenewalStartTime() = 0; + virtual int64_t GetRenewalStartTime() { return renewal_start_time_; } // This is the current policy information for this license. This gets updated // as license renewals occur. @@ -105,12 +131,20 @@ class PolicyTimers { int64_t last_playback_time_; int64_t last_expiry_time_; int64_t last_expiry_time_set_; + int64_t renewal_start_time_ = 0; int64_t next_renewal_time_; // Indicates whether a persistent license was expired when loaded bool was_expired_on_load_; private: + // Gets the clock time that the rental duration or playback will expire. + virtual int64_t GetRentalExpiryTime(int64_t current_time); + virtual int64_t GetPlaybackExpiryTime( + int64_t current_time, bool ignore_soft_enforce_playback_duration); + bool HasRentalOrPlaybackDurationExpired(int64_t current_time); + virtual int64_t GetRentalDurationRemaining(int64_t current_time); + CORE_DISALLOW_COPY_AND_ASSIGN(PolicyTimers); }; diff --git a/libwvdrmengine/cdm/core/include/policy_timers_v15.h b/libwvdrmengine/cdm/core/include/policy_timers_v15.h deleted file mode 100644 index a9f42c2d..00000000 --- a/libwvdrmengine/cdm/core/include/policy_timers_v15.h +++ /dev/null @@ -1,97 +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. - -#ifndef WVCDM_CORE_POLICY_TIMERS_V15_H_ -#define WVCDM_CORE_POLICY_TIMERS_V15_H_ - -#include -#include - -#include "disallow_copy_and_assign.h" -#include "license_protocol.pb.h" -#include "policy_timers.h" -#include "wv_cdm_types.h" - -namespace wvcdm { - -// OEMCrypto v16 and core messages introduced changes to how duration values -// and clocks should be evaluated. This class provides backward compatibility -// for licenses that do not include a core message. Durations are handled -// in the same way as in earlier releases. -// -// Backward compatibility may be needed if -// * OEMCrypto has not been upgraded to v16 -// * Licenses were persisted before the device was upgraded to v16 -// * License service does not yet support core messages - -class PolicyTimersV15 : public PolicyTimers { - public: - PolicyTimersV15() : grace_period_end_time_(0) {} - - ~PolicyTimersV15() override {} - - // UpdateLicense is used in handling a license response, a renewal response, - // or when restoring or releasing a persistent license. - // In a renewal the response may only contain policy fields that have - // changed. In this case an exact copy is not what we want to happen. - // |license_start_time_| is updated to the time mentioned in the renewal - // response. - // UpdateLicense will return false if |license_start_time| is not - // present or playback is not allowed due to policy or timer duration - // expiration. - bool UpdateLicense(int64_t current_time, - const video_widevine::License& license) override; - - // Call this on first decrypt to set the start of playback. - void BeginDecryption(int64_t current_time) override; - - // for offline save and restore - int64_t GetGracePeriodEndTime() override { return grace_period_end_time_; } - - // for offline save and restore - void RestorePlaybackTimes(int64_t current_time, int64_t playback_start_time, - int64_t last_playback_time, - int64_t grace_period_end_time) override; - - bool HasPlaybackStarted(int64_t current_time) override; - bool HasLicenseOrRentalOrPlaybackDurationExpired( - int64_t current_time) override; - bool HasPassedGracePeriod(int64_t current_time) override; - - // This returns - // * for streaming licenses: the time remaining on |license_duration_seconds| - // * for persistent licenses: the time remaining on |rental_duration_seconds| - // before playback begins or the time remaining on - // |playback_duration_seconds| after. - int64_t GetLicenseOrRentalOrPlaybackDurationRemaining( - int64_t current_time) override; - // This is only used in Query. This should return the time remaining on - // |license_duration_seconds| for streaming licenses and - // |rental_duration_seconds| for persistent licenses. - int64_t GetLicenseOrRentalDurationRemaining(int64_t current_time) override; - - protected: - // Gets the clock time that the license expires based on whether we have - // started playing. This takes into account GetHardLicenseExpiryTime. - int64_t GetExpiryTime(int64_t current_time, - bool ignore_soft_enforce_playback_duration) override; - - int64_t GetRenewalStartTime() override { return license_start_time_; } - - private: - // Gets the clock time that the license expires. This is the hard limit that - // all license types must obey at all times. - int64_t GetHardLicenseExpiryTime(); - // Gets the clock time that the rental duration will expire, using the license - // duration if one is not present. - int64_t GetRentalExpiryTime(); - - int64_t grace_period_end_time_; - - CORE_DISALLOW_COPY_AND_ASSIGN(PolicyTimersV15); -}; - -} // namespace wvcdm - -#endif // WVCDM_CORE_POLICY_TIMERS_V15_H_ diff --git a/libwvdrmengine/cdm/core/include/policy_timers_v16.h b/libwvdrmengine/cdm/core/include/policy_timers_v16.h index 2e0c472d..15adc6c7 100644 --- a/libwvdrmengine/cdm/core/include/policy_timers_v16.h +++ b/libwvdrmengine/cdm/core/include/policy_timers_v16.h @@ -43,68 +43,10 @@ class PolicyTimersV16 : public PolicyTimers { // Call this on first decrypt to set the start of playback. void BeginDecryption(int64_t current_time) override; - // This is a legacy field for offline licenses. Since no grace period is - // supported return a default value. - int64_t GetGracePeriodEndTime() override { return 0; } - - // For offline save and restore. - void RestorePlaybackTimes(int64_t current_time, int64_t playback_start_time, - int64_t last_playback_time, - int64_t grace_period_end_time) override; - - bool HasPlaybackStarted(int64_t /* current_time */) override { - return playback_start_time_ != 0; - } - // For licenses that support core messages, evaluation of only rental and - // playback durations are needed. - bool HasLicenseOrRentalOrPlaybackDurationExpired( - int64_t current_time) override { - return HasRentalOrPlaybackDurationExpired(current_time); - } - bool HasPassedGracePeriod(int64_t /* current_time */) override { - return true; - } - - // This returns - // * before playback begins: the time remaining on |rental_duration_seconds| - // * after playback begins: - // - |soft_enforce_playback_duration| is true: the time remaining on - // |playback_duration_seconds| - // - |soft_enforce_playback_duration| is false: the minimum - // of the time remaining on |rental_duration_seconds| or - // |playback_duration_seconds| - // - // |license_duration_seconds| is ignored with the introduction of core - // messages - int64_t GetLicenseOrRentalOrPlaybackDurationRemaining( - int64_t current_time) override; - // This is only used in Query. This should return the time remaining on - // |rental_duration_seconds|. - int64_t GetLicenseOrRentalDurationRemaining(int64_t current_time) override { - return GetRentalDurationRemaining(current_time); - }; - + // Renewal related methods bool HasRenewalDelayExpired(int64_t current_time) override; - protected: - // Gets the clock time that the license expires based on whether we have - // started playing. This takes into account GetHardLicenseExpiryTime. - int64_t GetExpiryTime(int64_t current_time, - bool ignore_soft_enforce_playback_duration) override; - - int64_t GetRenewalStartTime() override { return renewal_start_time_; } - private: - // Gets the clock time that the rental duration or playback will expire. - int64_t GetRentalExpiryTime(int64_t current_time); - int64_t GetPlaybackExpiryTime(int64_t current_time, - bool ignore_soft_enforce_playback_duration); - - bool HasRentalOrPlaybackDurationExpired(int64_t current_time); - int64_t GetRentalDurationRemaining(int64_t current_time); - - int64_t renewal_start_time_ = 0; - CORE_DISALLOW_COPY_AND_ASSIGN(PolicyTimersV16); }; diff --git a/libwvdrmengine/cdm/core/include/policy_timers_v18.h b/libwvdrmengine/cdm/core/include/policy_timers_v18.h new file mode 100644 index 00000000..5eead2ac --- /dev/null +++ b/libwvdrmengine/cdm/core/include/policy_timers_v18.h @@ -0,0 +1,56 @@ +// Copyright 2022 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine License +// Agreement. + +#ifndef WVCDM_CORE_POLICY_TIMERS_V18_H_ +#define WVCDM_CORE_POLICY_TIMERS_V18_H_ + +#include "disallow_copy_and_assign.h" +#include "license_protocol.pb.h" +#include "policy_timers.h" +#include "wv_cdm_types.h" + +namespace wvcdm { + +// OEMCrypto v18 includes support for renewing licenses on load by using +// |initial_renewal_delay_base| and TimerDelayBase. +// +// Backward compatibility may be needed if +// * OEMCrypto has not been upgraded to v18 +// * Licenses were persisted before the device was upgraded to v18 + +class PolicyTimersV18 : public PolicyTimers { + public: + PolicyTimersV18() {} + + ~PolicyTimersV18() override {} + + // UpdateLicense is used in handling a license response, a renewal response, + // or when restoring or releasing a persistent license. + // In a renewal the response may only contain policy fields that have + // changed. In this case an exact copy is not what we want to happen. + // |renewal_start_time_| is set to the time mentioned in the renewal + // response. + // UpdateLicense will return false if |license_start_time| is not + // present or playback is not allowed due to policy or timer duration + // expiration. + bool UpdateLicense(int64_t current_time, + const video_widevine::License& license) override; + + // Call this on first decrypt to set the start of playback. + void BeginDecryption(int64_t current_time) override; + + // Renewal related methods + bool HasRenewalDelayExpired(int64_t current_time) override; + + private: + // Indicates whether this is an initial license or a renewal + bool license_renewal_ = false; + bool renew_on_first_decrypt_ = false; + + CORE_DISALLOW_COPY_AND_ASSIGN(PolicyTimersV18); +}; + +} // namespace wvcdm + +#endif // WVCDM_CORE_POLICY_TIMERS_V18_H_ diff --git a/libwvdrmengine/cdm/core/src/policy_timers.cpp b/libwvdrmengine/cdm/core/src/policy_timers.cpp index 55c54b4a..6a17f810 100644 --- a/libwvdrmengine/cdm/core/src/policy_timers.cpp +++ b/libwvdrmengine/cdm/core/src/policy_timers.cpp @@ -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 diff --git a/libwvdrmengine/cdm/core/src/policy_timers_v15.cpp b/libwvdrmengine/cdm/core/src/policy_timers_v15.cpp deleted file mode 100644 index f917c061..00000000 --- a/libwvdrmengine/cdm/core/src/policy_timers_v15.cpp +++ /dev/null @@ -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 -#include - -#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 diff --git a/libwvdrmengine/cdm/core/src/policy_timers_v16.cpp b/libwvdrmengine/cdm/core/src/policy_timers_v16.cpp index 4395a562..60f663f0 100644 --- a/libwvdrmengine/cdm/core/src/policy_timers_v16.cpp +++ b/libwvdrmengine/cdm/core/src/policy_timers_v16.cpp @@ -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 diff --git a/libwvdrmengine/cdm/core/src/policy_timers_v18.cpp b/libwvdrmengine/cdm/core/src/policy_timers_v18.cpp new file mode 100644 index 00000000..79b73c27 --- /dev/null +++ b/libwvdrmengine/cdm/core/src/policy_timers_v18.cpp @@ -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 + +#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