Merge "Unified State-Changing API for LicenseKeyStatus" into oc-mr1-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
cd6178cf82
@@ -86,14 +86,17 @@ bool LicenseKeys::GetAllowedUsage(const KeyId& key_id,
|
||||
}
|
||||
}
|
||||
|
||||
bool LicenseKeys::ApplyStatusChange(CdmKeyStatus new_status,
|
||||
bool* new_usable_keys) {
|
||||
bool LicenseKeys::ApplyStatusChange(
|
||||
const CdmKeyStatus* new_status, const uint32_t* new_resolution,
|
||||
const CryptoSession::HdcpCapability* new_hdcp_level,
|
||||
bool* new_usable_keys) {
|
||||
bool keys_changed = false;
|
||||
bool newly_usable = false;
|
||||
*new_usable_keys = false;
|
||||
for (LicenseKeyStatusIterator it = keys_.begin(); it != keys_.end(); ++it) {
|
||||
bool usable;
|
||||
if (it->second->ApplyStatusChange(new_status, &usable)) {
|
||||
if (it->second->ApplyStatusChange(new_status, new_resolution,
|
||||
new_hdcp_level, &usable)) {
|
||||
newly_usable |= usable;
|
||||
keys_changed = true;
|
||||
}
|
||||
@@ -122,13 +125,6 @@ bool LicenseKeys::MeetsConstraints(const KeyId& key_id) {
|
||||
}
|
||||
}
|
||||
|
||||
void LicenseKeys::ApplyConstraints(
|
||||
uint32_t new_resolution, CryptoSession::HdcpCapability new_hdcp_level) {
|
||||
for (LicenseKeyStatusIterator i = keys_.begin(); i != keys_.end(); ++i) {
|
||||
i->second->ApplyConstraints(new_resolution, new_hdcp_level);
|
||||
}
|
||||
}
|
||||
|
||||
void LicenseKeys::SetFromLicense(
|
||||
const video_widevine::License& license) {
|
||||
this->Clear();
|
||||
@@ -145,6 +141,9 @@ void LicenseKeys::SetFromLicense(
|
||||
LicenseKeyStatus::LicenseKeyStatus(const KeyContainer& key) :
|
||||
is_content_key_(false),
|
||||
key_status_(kKeyStatusInternalError),
|
||||
resolution_(kNoResolution),
|
||||
hdcp_level_(HDCP_NONE),
|
||||
can_check_constraints_(false),
|
||||
meets_constraints_(true),
|
||||
default_hdcp_level_(HDCP_NONE) {
|
||||
|
||||
@@ -221,26 +220,55 @@ bool LicenseKeyStatus::GetAllowedUsage(CdmKeyAllowedUsage* allowed_usage) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LicenseKeyStatus::ApplyStatusChange(CdmKeyStatus new_status,
|
||||
bool* new_usable_key) {
|
||||
*new_usable_key = false;
|
||||
bool LicenseKeyStatus::ApplyStatusChange(
|
||||
const CdmKeyStatus* maybe_new_status, const uint32_t* maybe_new_resolution,
|
||||
const CryptoSession::HdcpCapability* maybe_new_hdcp_level,
|
||||
bool* newly_usable) {
|
||||
*newly_usable = false;
|
||||
if (!is_content_key_) {
|
||||
return false;
|
||||
}
|
||||
CdmKeyStatus updated_status = new_status;
|
||||
if (updated_status == kKeyStatusUsable) {
|
||||
|
||||
// Most of this function is various work to calculate an updated value for
|
||||
// the status. We start at the same value as the current status.
|
||||
CdmKeyStatus updated_status = key_status_;
|
||||
|
||||
// Account for the new status, if provided.
|
||||
if (maybe_new_status != NULL) {
|
||||
const CdmKeyStatus& new_status = *maybe_new_status;
|
||||
can_check_constraints_ = (new_status == kKeyStatusUsable);
|
||||
updated_status = new_status;
|
||||
}
|
||||
|
||||
// Account for the new resolution, if provided.
|
||||
if (maybe_new_resolution != NULL) {
|
||||
resolution_ = *maybe_new_resolution;
|
||||
}
|
||||
|
||||
// Account for the new HDCP level, if provided.
|
||||
if (maybe_new_hdcp_level != NULL) {
|
||||
hdcp_level_ = *maybe_new_hdcp_level;
|
||||
}
|
||||
|
||||
// If we can, check the current state against the constraints and update the
|
||||
// status if needed.
|
||||
if (can_check_constraints_) {
|
||||
ApplyConstraints();
|
||||
if (!MeetsConstraints()) {
|
||||
updated_status = kKeyStatusOutputNotAllowed;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if any of that work changed the key status.
|
||||
if (key_status_ != updated_status) {
|
||||
key_status_ = updated_status;
|
||||
if (updated_status == kKeyStatusUsable) {
|
||||
*new_usable_key = true;
|
||||
*newly_usable = true;
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the key has constraints, find the constraint that applies.
|
||||
@@ -250,12 +278,16 @@ bool LicenseKeyStatus::ApplyStatusChange(CdmKeyStatus new_status,
|
||||
// If the key has no constraints, or if the constraint has no HDCP
|
||||
// requirement, use the key's default HDCP setting to check against the
|
||||
// device's current HDCP level.
|
||||
void LicenseKeyStatus::ApplyConstraints(
|
||||
uint32_t new_resolution, CryptoSession::HdcpCapability new_hdcp_level) {
|
||||
void LicenseKeyStatus::ApplyConstraints() {
|
||||
if (resolution_ == kNoResolution) {
|
||||
// Until a resolution has been detected, the constraints cannot be checked.
|
||||
meets_constraints_ = true;
|
||||
return;
|
||||
}
|
||||
|
||||
VideoResolutionConstraint* current_constraint = NULL;
|
||||
if (HasConstraints()) {
|
||||
current_constraint = GetConstraintForRes(new_resolution, constraints_);
|
||||
current_constraint = GetConstraintForRes(resolution_, constraints_);
|
||||
if (NULL == current_constraint) {
|
||||
meets_constraints_ = false;
|
||||
return;
|
||||
@@ -270,7 +302,7 @@ void LicenseKeyStatus::ApplyConstraints(
|
||||
desired_hdcp_level = default_hdcp_level_;
|
||||
}
|
||||
|
||||
meets_constraints_ = (new_hdcp_level >= desired_hdcp_level);
|
||||
meets_constraints_ = (hdcp_level_ >= desired_hdcp_level);
|
||||
}
|
||||
|
||||
void LicenseKeyStatus::SetConstraints(const ConstraintList& constraints) {
|
||||
|
||||
@@ -17,7 +17,6 @@ using video_widevine::License;
|
||||
namespace {
|
||||
|
||||
const int64_t kHdcpCheckInterval = 10;
|
||||
const uint32_t kNoResolution = 0;
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -71,7 +70,15 @@ void PolicyEngine::CheckDevice(int64_t current_time) {
|
||||
if (!crypto_session_->GetHdcpCapabilities(¤t_hdcp_level, &ignored)) {
|
||||
current_hdcp_level = HDCP_NONE;
|
||||
}
|
||||
license_keys_->ApplyConstraints(current_resolution_, current_hdcp_level);
|
||||
|
||||
bool new_usable_keys = false;
|
||||
bool keys_changed =
|
||||
license_keys_->ApplyStatusChange(NULL, // new_status
|
||||
¤t_resolution_,
|
||||
¤t_hdcp_level,
|
||||
&new_usable_keys);
|
||||
NotifyIfKeysChanged(keys_changed, new_usable_keys);
|
||||
|
||||
next_device_check_ = current_time + kHdcpCheckInterval;
|
||||
}
|
||||
}
|
||||
@@ -89,21 +96,19 @@ void PolicyEngine::OnTimerEvent() {
|
||||
if (HasLicenseOrPlaybackDurationExpired(current_time) &&
|
||||
license_state_ != kLicenseStateExpired) {
|
||||
license_state_ = kLicenseStateExpired;
|
||||
NotifyKeysChange(kKeyStatusExpired);
|
||||
UpdateKeyStatus(kKeyStatusExpired);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check device conditions that affect playability (HDCP, resolution)
|
||||
CheckDevice(current_time);
|
||||
|
||||
// Test to determine if renewal should be attempted.
|
||||
bool renewal_needed = false;
|
||||
|
||||
// Test to determine if renewal should be attempted.
|
||||
switch (license_state_) {
|
||||
case kLicenseStateCanPlay: {
|
||||
if (HasRenewalDelayExpired(current_time)) renewal_needed = true;
|
||||
// HDCP may change, so force a check.
|
||||
NotifyKeysChange(kKeyStatusUsable);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -120,7 +125,7 @@ void PolicyEngine::OnTimerEvent() {
|
||||
case kLicenseStatePending: {
|
||||
if (current_time >= license_start_time_) {
|
||||
license_state_ = kLicenseStateCanPlay;
|
||||
NotifyKeysChange(kKeyStatusUsable);
|
||||
UpdateKeyStatus(kKeyStatusUsable);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -132,7 +137,7 @@ void PolicyEngine::OnTimerEvent() {
|
||||
|
||||
default: {
|
||||
license_state_ = kLicenseStateExpired;
|
||||
NotifyKeysChange(kKeyStatusInternalError);
|
||||
UpdateKeyStatus(kKeyStatusInternalError);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -157,7 +162,7 @@ void PolicyEngine::SetLicenseForRelease(const License& license) {
|
||||
policy_.Clear();
|
||||
|
||||
// Expire any old keys.
|
||||
NotifyKeysChange(kKeyStatusExpired);
|
||||
UpdateKeyStatus(kKeyStatusExpired);
|
||||
UpdateLicense(license);
|
||||
}
|
||||
|
||||
@@ -190,17 +195,17 @@ void PolicyEngine::UpdateLicense(const License& license) {
|
||||
if (!policy_.can_play() ||
|
||||
HasLicenseOrPlaybackDurationExpired(current_time)) {
|
||||
license_state_ = kLicenseStateExpired;
|
||||
NotifyKeysChange(kKeyStatusExpired);
|
||||
UpdateKeyStatus(kKeyStatusExpired);
|
||||
return;
|
||||
}
|
||||
|
||||
// Update state
|
||||
if (current_time >= license_start_time_) {
|
||||
license_state_ = kLicenseStateCanPlay;
|
||||
NotifyKeysChange(kKeyStatusUsable);
|
||||
UpdateKeyStatus(kKeyStatusUsable);
|
||||
} else {
|
||||
license_state_ = kLicenseStatePending;
|
||||
NotifyKeysChange(kKeyStatusPending);
|
||||
UpdateKeyStatus(kKeyStatusPending);
|
||||
}
|
||||
NotifyExpirationUpdate(current_time);
|
||||
}
|
||||
@@ -240,7 +245,7 @@ void PolicyEngine::NotifyResolution(uint32_t width, uint32_t height) {
|
||||
|
||||
void PolicyEngine::NotifySessionExpiration() {
|
||||
license_state_ = kLicenseStateExpired;
|
||||
NotifyKeysChange(kKeyStatusExpired);
|
||||
UpdateKeyStatus(kKeyStatusExpired);
|
||||
}
|
||||
|
||||
CdmResponseType PolicyEngine::Query(CdmQueryMap* query_response) {
|
||||
@@ -429,16 +434,23 @@ bool PolicyEngine::HasRenewalRetryIntervalExpired(int64_t current_time) {
|
||||
next_renewal_time_ <= current_time;
|
||||
}
|
||||
|
||||
void PolicyEngine::NotifyKeysChange(CdmKeyStatus new_status) {
|
||||
bool keys_changed;
|
||||
bool has_new_usable_key = false;
|
||||
keys_changed = license_keys_->ApplyStatusChange(new_status,
|
||||
&has_new_usable_key);
|
||||
void PolicyEngine::UpdateKeyStatus(CdmKeyStatus new_status) {
|
||||
bool new_usable_keys = false;
|
||||
bool keys_changed =
|
||||
license_keys_->ApplyStatusChange(&new_status,
|
||||
NULL, // new_resolution
|
||||
NULL, // new_hdcp_level
|
||||
&new_usable_keys);
|
||||
NotifyIfKeysChanged(keys_changed, new_usable_keys);
|
||||
}
|
||||
|
||||
void PolicyEngine::NotifyIfKeysChanged(bool keys_changed,
|
||||
bool new_usable_keys) {
|
||||
if (event_listener_ && keys_changed) {
|
||||
CdmKeyStatusMap content_keys;
|
||||
license_keys_->ExtractKeyStatuses(&content_keys);
|
||||
event_listener_->OnSessionKeysChange(session_id_, content_keys,
|
||||
has_new_usable_key);
|
||||
new_usable_keys);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user