From 3cdc43caeb37173bc5bc60bd3f414da540640e03 Mon Sep 17 00:00:00 2001 From: Kongqun Yang Date: Fri, 22 May 2015 11:36:20 -0700 Subject: [PATCH] Use 0 to represent unexpired license in OnExpirationUpdate Also fix a missing change for "playback duration should override license duration". Merged from Widevine CDM repo: https://widevine-internal-review.googlesource.com/#/c/14435/ Bug: 21393975 Change-Id: Ibfcf3ae4c13db8944ea285bcc79b6312ea621e1b --- .../cdm/core/include/policy_engine.h | 10 ++----- .../cdm/core/include/wv_cdm_constants.h | 6 ++-- .../cdm/core/include/wv_cdm_event_listener.h | 2 ++ libwvdrmengine/cdm/core/src/cdm_session.cpp | 3 +- libwvdrmengine/cdm/core/src/policy_engine.cpp | 30 ++++++++++++------- 5 files changed, 29 insertions(+), 22 deletions(-) diff --git a/libwvdrmengine/cdm/core/include/policy_engine.h b/libwvdrmengine/cdm/core/include/policy_engine.h index e6e3c43f..c05f5418 100644 --- a/libwvdrmengine/cdm/core/include/policy_engine.h +++ b/libwvdrmengine/cdm/core/include/policy_engine.h @@ -66,13 +66,6 @@ class PolicyEngine { virtual const LicenseIdentification& license_id() { return license_id_; } - bool IsLicenseDurationExpired(int64_t current_time) { - return GetLicenseExpiryTime() <= current_time; - } - bool IsPlaybackDurationExpired(int64_t current_time) { - return GetPlaybackExpiryTime() <= current_time; - } - bool GetSecondsSinceStarted(int64_t* seconds_since_started); bool GetSecondsSinceLastPlayed(int64_t* seconds_since_started); @@ -85,6 +78,8 @@ class PolicyEngine { bool IsLicenseForFuture() { return license_state_ == kLicenseStatePending; } bool IsPlaybackStarted() { return playback_start_time_ > 0; } + bool IsLicenseOrPlaybackDurationExpired(int64_t current_time); + private: friend class PolicyEngineTest; @@ -139,6 +134,7 @@ class PolicyEngine { int64_t playback_start_time_; int64_t last_playback_time_; int64_t last_expiry_time_; + bool last_expiry_time_set_; // This is used as a reference point for policy management. This value // represents an offset from license_start_time_. This is used to diff --git a/libwvdrmengine/cdm/core/include/wv_cdm_constants.h b/libwvdrmengine/cdm/core/include/wv_cdm_constants.h index 1771ea3d..352da201 100644 --- a/libwvdrmengine/cdm/core/include/wv_cdm_constants.h +++ b/libwvdrmengine/cdm/core/include/wv_cdm_constants.h @@ -3,8 +3,6 @@ #ifndef WVCDM_CORE_WV_CDM_CONSTANTS_H_ #define WVCDM_CORE_WV_CDM_CONSTANTS_H_ -#include - #include namespace wvcdm { @@ -16,7 +14,9 @@ static const size_t KEY_SIZE = 16; static const size_t MAC_KEY_SIZE = 32; static const size_t KEYBOX_KEY_DATA_SIZE = 72; -static const int64_t NEVER_EXPIRES = LLONG_MAX; +// Use 0 to represent never expired license as specified in EME spec +// (NaN in JS translates to 0 in unix timestamp). +static const int64_t NEVER_EXPIRES = 0; static const char SESSION_ID_PREFIX[] = "sid"; static const char KEY_SET_ID_PREFIX[] = "ksid"; diff --git a/libwvdrmengine/cdm/core/include/wv_cdm_event_listener.h b/libwvdrmengine/cdm/core/include/wv_cdm_event_listener.h index 3074be96..87fae5d7 100644 --- a/libwvdrmengine/cdm/core/include/wv_cdm_event_listener.h +++ b/libwvdrmengine/cdm/core/include/wv_cdm_event_listener.h @@ -17,6 +17,8 @@ class WvCdmEventListener { virtual void OnSessionKeysChange(const CdmSessionId& session_id, const CdmKeyStatusMap& keys_status, bool has_new_usable_key) = 0; + // Note that a |new_expiry_time_seconds| of 0 represents never expired + // license. virtual void OnExpirationUpdate(const CdmSessionId& session_id, int64_t new_expiry_time_seconds) = 0; diff --git a/libwvdrmengine/cdm/core/src/cdm_session.cpp b/libwvdrmengine/cdm/core/src/cdm_session.cpp index 2c42b098..3674ca98 100644 --- a/libwvdrmengine/cdm/core/src/cdm_session.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_session.cpp @@ -348,8 +348,7 @@ CdmResponseType CdmSession::Decrypt(const CdmDecryptionParameters& params) { } else { Clock clock; int64_t current_time = clock.GetCurrentTime(); - if (policy_engine_->IsLicenseDurationExpired(current_time) || - policy_engine_->IsPlaybackDurationExpired(current_time)) { + if (policy_engine_->IsLicenseOrPlaybackDurationExpired(current_time)) { return NEED_KEY; } } diff --git a/libwvdrmengine/cdm/core/src/policy_engine.cpp b/libwvdrmengine/cdm/core/src/policy_engine.cpp index afbf45de..64f4423a 100644 --- a/libwvdrmengine/cdm/core/src/policy_engine.cpp +++ b/libwvdrmengine/cdm/core/src/policy_engine.cpp @@ -27,6 +27,7 @@ PolicyEngine::PolicyEngine(CdmSessionId session_id, playback_start_time_(0), last_playback_time_(0), last_expiry_time_(0), + last_expiry_time_set_(false), next_renewal_time_(0), policy_max_duration_seconds_(0), session_id_(session_id), @@ -49,8 +50,7 @@ void PolicyEngine::OnTimerEvent() { int64_t current_time = clock_->GetCurrentTime(); // License expiration trumps all. - if ((IsPlaybackDurationExpired(current_time) || - (IsLicenseDurationExpired(current_time) && !IsPlaybackStarted())) && + if (IsLicenseOrPlaybackDurationExpired(current_time) && license_state_ != kLicenseStateExpired) { license_state_ = kLicenseStateExpired; NotifyKeysChange(kKeyStatusExpired); @@ -164,8 +164,7 @@ void PolicyEngine::UpdateLicense(const License& license) { } int64_t current_time = clock_->GetCurrentTime(); - if (!policy_.can_play() || IsPlaybackDurationExpired(current_time) || - (IsLicenseDurationExpired(current_time) && !IsPlaybackStarted())) { + if (!policy_.can_play() || IsLicenseOrPlaybackDurationExpired(current_time)) { license_state_ = kLicenseStateExpired; NotifyKeysChange(kKeyStatusExpired); return; @@ -274,6 +273,12 @@ void PolicyEngine::UpdateRenewalRequest(int64_t current_time) { next_renewal_time_ = current_time + policy_.renewal_retry_interval_seconds(); } +bool PolicyEngine::IsLicenseOrPlaybackDurationExpired(int64_t current_time) { + int64_t expiry_time = + IsPlaybackStarted() ? GetPlaybackExpiryTime() : GetLicenseExpiryTime(); + return (expiry_time == NEVER_EXPIRES) ? false : (expiry_time <= current_time); +} + // For the policy time fields checked in the following methods, a value of 0 // indicates that there is no limit to the duration. These methods // will always return false if the value is 0. @@ -290,16 +295,21 @@ int64_t PolicyEngine::GetPlaybackExpiryTime() { } int64_t PolicyEngine::GetLicenseDurationRemaining(int64_t current_time) { - if (policy_max_duration_seconds_ == 0) return LLONG_MAX; int64_t license_expiry_time = GetLicenseExpiryTime(); + if (license_expiry_time == NEVER_EXPIRES) return LLONG_MAX; if (license_expiry_time < current_time) return 0; return std::min(license_expiry_time - current_time, policy_max_duration_seconds_); } int64_t PolicyEngine::GetPlaybackDurationRemaining(int64_t current_time) { - if (policy_.playback_duration_seconds() == 0) return LLONG_MAX; int64_t playback_expiry_time = GetPlaybackExpiryTime(); + if (playback_expiry_time == NEVER_EXPIRES) { + return (policy_.playback_duration_seconds() != 0) + ? policy_.playback_duration_seconds() + : LLONG_MAX; + } + if (playback_expiry_time < current_time) return 0; return std::min(playback_expiry_time - current_time, policy_.playback_duration_seconds()); @@ -348,14 +358,14 @@ void PolicyEngine::NotifyKeysChange(CdmKeyStatus new_status) { } void PolicyEngine::NotifyExpirationUpdate() { - int64_t expiry_time = IsPlaybackStarted() ? GetPlaybackExpiryTime() - : std::min(GetLicenseExpiryTime(), - GetPlaybackExpiryTime()); - if (expiry_time != last_expiry_time_) { + int64_t expiry_time = + IsPlaybackStarted() ? GetPlaybackExpiryTime() : GetLicenseExpiryTime(); + if (!last_expiry_time_set_ || expiry_time != last_expiry_time_) { last_expiry_time_ = expiry_time; if (event_listener_) event_listener_->OnExpirationUpdate(session_id_, expiry_time); } + last_expiry_time_set_ = true; } void PolicyEngine::set_clock(Clock* clock) { clock_.reset(clock); }