Source release v3.0.0-0-g8d3792b-ce + third_party

Change-Id: I399e71ddfffcd436171d1c60283c63ab4658e0b1
This commit is contained in:
Joey Parrish
2015-06-19 15:13:34 -07:00
parent 58aba6b2ec
commit 0546ee6732
965 changed files with 426663 additions and 12897 deletions

View File

@@ -13,48 +13,60 @@
#include "properties.h"
#include "string_conversions.h"
#include "wv_cdm_constants.h"
#include "wv_cdm_event_listener.h"
using video_widevine_server::sdk::License;
namespace wvcdm {
PolicyEngine::PolicyEngine() { Init(new Clock()); }
PolicyEngine::PolicyEngine(CdmSessionId session_id,
WvCdmEventListener* event_listener,
CryptoSession* crypto_session)
: license_state_(kLicenseStateInitial),
license_start_time_(0),
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),
event_listener_(event_listener),
max_res_engine_(new MaxResEngine(crypto_session)),
clock_(new Clock) {}
PolicyEngine::PolicyEngine(Clock* clock) { Init(clock); }
PolicyEngine::~PolicyEngine() {}
PolicyEngine::~PolicyEngine() {
if (clock_) delete clock_;
bool PolicyEngine::CanDecrypt(const KeyId& key_id) {
if (keys_status_.find(key_id) == keys_status_.end()) {
LOGE("PolicyEngine::CanDecrypt Key '%s' not in license.",
b2a_hex(key_id).c_str());
return false;
}
return keys_status_[key_id] == kKeyStatusUsable;
}
void PolicyEngine::Init(Clock* clock) {
license_state_ = kLicenseStateInitial;
can_decrypt_ = false;
license_start_time_ = 0;
playback_start_time_ = 0;
next_renewal_time_ = 0;
policy_max_duration_seconds_ = 0;
clock_ = clock;
}
void PolicyEngine::OnTimerEvent(bool* event_occurred, CdmEventType* event) {
*event_occurred = false;
void PolicyEngine::OnTimerEvent() {
int64_t current_time = clock_->GetCurrentTime();
// License expiration trumps all.
if ((IsLicenseDurationExpired(current_time) ||
IsPlaybackDurationExpired(current_time)) &&
if (IsLicenseOrPlaybackDurationExpired(current_time) &&
license_state_ != kLicenseStateExpired) {
license_state_ = kLicenseStateExpired;
can_decrypt_ = false;
*event = LICENSE_EXPIRED_EVENT;
*event_occurred = true;
NotifyKeysChange(kKeyStatusExpired);
return;
}
max_res_engine_->OnTimerEvent();
bool renewal_needed = false;
// Test to determine if renewal should be attempted.
switch (license_state_) {
case kLicenseStateCanPlay: {
if (IsRenewalDelayExpired(current_time)) renewal_needed = true;
// HDCP may change, so force a check.
NotifyKeysChange(kKeyStatusUsable);
break;
}
@@ -71,7 +83,7 @@ void PolicyEngine::OnTimerEvent(bool* event_occurred, CdmEventType* event) {
case kLicenseStatePending: {
if (current_time >= license_start_time_) {
license_state_ = kLicenseStateCanPlay;
can_decrypt_ = true;
NotifyKeysChange(kKeyStatusUsable);
}
break;
}
@@ -83,28 +95,46 @@ void PolicyEngine::OnTimerEvent(bool* event_occurred, CdmEventType* event) {
default: {
license_state_ = kLicenseStateExpired;
can_decrypt_ = false;
NotifyKeysChange(kKeyStatusInternalError);
break;
}
}
if (renewal_needed) {
UpdateRenewalRequest(current_time);
*event = LICENSE_RENEWAL_NEEDED_EVENT;
*event_occurred = true;
if (event_listener_) event_listener_->OnSessionRenewalNeeded(session_id_);
}
}
void PolicyEngine::SetLicense(
const video_widevine_server::sdk::License& license) {
void PolicyEngine::SetLicense(const License& license) {
license_id_.Clear();
license_id_.CopyFrom(license.id());
policy_.Clear();
// Extract content key ids.
keys_status_.clear();
for (int key_index = 0; key_index < license.key_size(); ++key_index) {
const License::KeyContainer& key = license.key(key_index);
if (key.type() == License::KeyContainer::CONTENT && key.has_id())
keys_status_[key.id()] = kKeyStatusInternalError;
}
UpdateLicense(license);
max_res_engine_->SetLicense(license);
}
void PolicyEngine::SetLicenseForRelease(const License& license) {
license_id_.Clear();
license_id_.CopyFrom(license.id());
policy_.Clear();
// Expire any old keys.
NotifyKeysChange(kKeyStatusExpired);
UpdateLicense(license);
}
void PolicyEngine::UpdateLicense(
const video_widevine_server::sdk::License& license) {
void PolicyEngine::UpdateLicense(const License& license) {
if (!license.has_policy()) return;
if (kLicenseStateExpired == license_state_) {
@@ -144,23 +174,22 @@ void PolicyEngine::UpdateLicense(
policy_max_duration_seconds_ = policy_.license_duration_seconds();
}
if (!policy_.can_play()) {
int64_t current_time = clock_->GetCurrentTime();
if (!policy_.can_play() || IsLicenseOrPlaybackDurationExpired(current_time)) {
license_state_ = kLicenseStateExpired;
NotifyKeysChange(kKeyStatusExpired);
return;
}
int64_t current_time = clock_->GetCurrentTime();
if (IsLicenseDurationExpired(current_time)) return;
if (IsPlaybackDurationExpired(current_time)) return;
// Update state
if (current_time >= license_start_time_) {
license_state_ = kLicenseStateCanPlay;
can_decrypt_ = true;
NotifyKeysChange(kKeyStatusUsable);
} else {
license_state_ = kLicenseStatePending;
can_decrypt_ = false;
NotifyKeysChange(kKeyStatusPending);
}
NotifyExpirationUpdate();
}
void PolicyEngine::BeginDecryption() {
@@ -170,10 +199,12 @@ void PolicyEngine::BeginDecryption() {
case kLicenseStateNeedRenewal:
case kLicenseStateWaitingLicenseUpdate:
playback_start_time_ = clock_->GetCurrentTime();
last_playback_time_ = playback_start_time_;
if (policy_.renew_with_usage()) {
license_state_ = kLicenseStateNeedRenewal;
}
NotifyExpirationUpdate();
break;
case kLicenseStateInitial:
case kLicenseStatePending:
@@ -184,11 +215,27 @@ void PolicyEngine::BeginDecryption() {
}
}
void PolicyEngine::DecryptionEvent() {
last_playback_time_ = clock_->GetCurrentTime();
}
void PolicyEngine::NotifyResolution(uint32_t width, uint32_t height) {
max_res_engine_->SetResolution(width, height);
}
void PolicyEngine::NotifySessionExpiration() {
license_state_ = kLicenseStateExpired;
NotifyKeysChange(kKeyStatusExpired);
}
CdmResponseType PolicyEngine::Query(CdmQueryMap* key_info) {
std::stringstream ss;
int64_t current_time = clock_->GetCurrentTime();
if (license_state_ == kLicenseStateInitial) return UNKNOWN_ERROR;
if (license_state_ == kLicenseStateInitial) {
key_info->clear();
return NO_ERROR;
}
(*key_info)[QUERY_KEY_LICENSE_TYPE] =
license_id_.type() == video_widevine_server::sdk::STREAMING
@@ -210,47 +257,73 @@ CdmResponseType PolicyEngine::Query(CdmQueryMap* key_info) {
return NO_ERROR;
}
bool PolicyEngine::GetSecondsSinceStarted(int64_t* seconds_since_started) {
if (playback_start_time_ == 0) return false;
*seconds_since_started = clock_->GetCurrentTime() - playback_start_time_;
return (*seconds_since_started >= 0) ? true : false;
}
bool PolicyEngine::GetSecondsSinceLastPlayed(
int64_t* seconds_since_last_played) {
if (last_playback_time_ == 0) return false;
*seconds_since_last_played = clock_->GetCurrentTime() - last_playback_time_;
return (*seconds_since_last_played >= 0) ? true : false;
}
void PolicyEngine::RestorePlaybackTimes(int64_t playback_start_time,
int64_t last_playback_time) {
playback_start_time_ = (playback_start_time > 0) ? playback_start_time : 0;
last_playback_time_ = (last_playback_time > 0) ? last_playback_time : 0;
NotifyExpirationUpdate();
}
void PolicyEngine::UpdateRenewalRequest(int64_t current_time) {
license_state_ = kLicenseStateWaitingLicenseUpdate;
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.
bool PolicyEngine::IsLicenseDurationExpired(int64_t current_time) {
return policy_max_duration_seconds_ &&
license_start_time_ + policy_max_duration_seconds_ <= current_time;
int64_t PolicyEngine::GetLicenseExpiryTime() {
return policy_max_duration_seconds_ > 0
? license_start_time_ + policy_max_duration_seconds_
: NEVER_EXPIRES;
}
int64_t PolicyEngine::GetPlaybackExpiryTime() {
return (playback_start_time_ > 0 && policy_.playback_duration_seconds() > 0)
? (playback_start_time_ + policy_.playback_duration_seconds())
: NEVER_EXPIRES;
}
int64_t PolicyEngine::GetLicenseDurationRemaining(int64_t current_time) {
if (0 == policy_max_duration_seconds_) return LLONG_MAX;
int64_t remaining_time =
policy_max_duration_seconds_ + license_start_time_ - current_time;
if (remaining_time < 0)
remaining_time = 0;
else if (remaining_time > policy_max_duration_seconds_)
remaining_time = policy_max_duration_seconds_;
return remaining_time;
}
bool PolicyEngine::IsPlaybackDurationExpired(int64_t current_time) {
return (policy_.playback_duration_seconds() > 0) && playback_start_time_ &&
playback_start_time_ + policy_.playback_duration_seconds() <=
current_time;
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 (0 == policy_.playback_duration_seconds()) return LLONG_MAX;
if (0 == playback_start_time_) return policy_.playback_duration_seconds();
int64_t playback_expiry_time = GetPlaybackExpiryTime();
if (playback_expiry_time == NEVER_EXPIRES) {
return (policy_.playback_duration_seconds() != 0)
? policy_.playback_duration_seconds()
: LLONG_MAX;
}
int64_t remaining_time =
policy_.playback_duration_seconds() + playback_start_time_ - current_time;
if (remaining_time < 0) remaining_time = 0;
return remaining_time;
if (playback_expiry_time < current_time) return 0;
return std::min(playback_expiry_time - current_time,
policy_.playback_duration_seconds());
}
bool PolicyEngine::IsRenewalDelayExpired(int64_t current_time) {
@@ -271,4 +344,45 @@ bool PolicyEngine::IsRenewalRetryIntervalExpired(int64_t current_time) {
next_renewal_time_ <= current_time;
}
void PolicyEngine::NotifyKeysChange(CdmKeyStatus new_status) {
bool keys_changed = false;
bool has_new_usable_key = false;
for (std::map<KeyId, CdmKeyStatus>::iterator it = keys_status_.begin();
it != keys_status_.end(); ++it) {
const KeyId key_id = it->first;
CdmKeyStatus& key_status = it->second;
CdmKeyStatus updated_status = new_status;
if (updated_status == kKeyStatusUsable) {
if (!max_res_engine_->CanDecrypt(key_id))
updated_status = kKeyStatusOutputNotAllowed;
}
if (key_status != updated_status) {
key_status = updated_status;
if (updated_status == kKeyStatusUsable) has_new_usable_key = true;
keys_changed = true;
}
}
if (keys_changed && event_listener_) {
event_listener_->OnSessionKeysChange(session_id_, keys_status_,
has_new_usable_key);
}
}
void PolicyEngine::NotifyExpirationUpdate() {
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); }
void PolicyEngine::set_max_res_engine(MaxResEngine* max_res_engine) {
max_res_engine_.reset(max_res_engine);
}
} // wvcdm