Merge changes I420fb181,Id0c38b45

* changes:
  Policy Engine refactoring
  Update license proto
This commit is contained in:
Rahul Frias
2020-02-14 01:47:59 +00:00
committed by Android (Google) Code Review
13 changed files with 607 additions and 280 deletions

View File

@@ -44,6 +44,8 @@ cc_library_static {
CORE_SRC_DIR + "/license_key_status.cpp",
CORE_SRC_DIR + "/oemcrypto_adapter_dynamic.cpp",
CORE_SRC_DIR + "/policy_engine.cpp",
CORE_SRC_DIR + "/policy_timers.cpp",
CORE_SRC_DIR + "/policy_timers_v15.cpp",
CORE_SRC_DIR + "/privacy_crypto_boringssl.cpp",
CORE_SRC_DIR + "/service_certificate.cpp",
CORE_SRC_DIR + "/usage_table_header.cpp",

View File

@@ -9,6 +9,7 @@
#include <memory>
#include <string>
#include "clock.h"
#include "disallow_copy_and_assign.h"
#include "license_key_status.h"
#include "license_protocol.pb.h"
@@ -21,6 +22,7 @@ using video_widevine::WidevinePsshData_EntitledKey;
class Clock;
class CryptoSession;
class PolicyTimers;
class WvCdmEventListener;
// This acts as an oracle that basically says "Yes(true) you may still decrypt
@@ -68,6 +70,7 @@ class PolicyEngine {
// Call this on first decrypt to set the start of playback.
virtual bool BeginDecryption(void);
// Call this periodically to update the most recent playback time.
virtual void DecryptionEvent(void);
// UpdateLicense is used in handling a license response for a renewal request.
@@ -92,26 +95,20 @@ class PolicyEngine {
bool GetSecondsSinceStarted(int64_t* seconds_since_started);
bool GetSecondsSinceLastPlayed(int64_t* seconds_since_started);
// for offline save and restore
int64_t GetPlaybackStartTime() { return playback_start_time_; }
int64_t GetLastPlaybackTime() { return last_playback_time_; }
int64_t GetGracePeriodEndTime() { return grace_period_end_time_; }
// For offline save and restore
int64_t GetPlaybackStartTime();
int64_t GetLastPlaybackTime();
int64_t GetGracePeriodEndTime();
void RestorePlaybackTimes(int64_t playback_start_time,
int64_t last_playback_time,
int64_t grace_period_end_time);
bool IsLicenseForFuture() { return license_state_ == kLicenseStatePending; }
bool 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 HasLicenseOrPlaybackDurationExpired(int64_t current_time);
int64_t GetLicenseOrPlaybackDurationRemaining();
bool CanRenew() { return policy_.can_renew(); }
bool CanRenew() const;
bool IsSufficientOutputProtection(const KeyId& key_id) {
return license_keys_->MeetsConstraints(key_id);
@@ -135,26 +132,6 @@ class PolicyEngine {
kLicenseStateExpired
} LicenseState;
// 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();
// 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);
int64_t GetLicenseOrRentalDurationRemaining(int64_t current_time);
int64_t GetPlaybackDurationRemaining(int64_t current_time);
bool HasRenewalDelayExpired(int64_t current_time);
bool HasRenewalRecoveryDurationExpired(int64_t current_time);
bool HasRenewalRetryIntervalExpired(int64_t current_time);
void UpdateRenewalRequest(int64_t current_time);
// Notifies updates in keys information and fire OnKeysChange event if
// key changes.
void NotifyKeysChange(CdmKeyStatus new_status);
@@ -163,7 +140,8 @@ class PolicyEngine {
// expiry time changes.
void NotifyExpirationUpdate(int64_t current_time);
// Guard against clock rollbacks
void UpdateRenewalRequest(int64_t current_time);
int64_t GetCurrentTime();
// Test only methods
@@ -174,31 +152,11 @@ class PolicyEngine {
LicenseState license_state_;
// This is the current policy information for this license. This gets updated
// as license renewals occur.
video_widevine::License::Policy policy_;
// This is the license id field from server response. This data gets passed
// back to the server in each renewal request. When we get a renewal response
// from the license server we will get an updated id field.
video_widevine::LicenseIdentification license_id_;
// The server returns the license start time in the license/license renewal
// response based off the request time sent by the client in the
// license request/renewal
int64_t license_start_time_;
int64_t playback_start_time_;
int64_t last_playback_time_;
int64_t last_expiry_time_;
int64_t grace_period_end_time_;
bool last_expiry_time_set_;
bool was_expired_on_load_;
// This is used as a reference point for policy management. This value
// represents an offset from license_start_time_. This is used to
// calculate the time where renewal retries should occur.
int64_t next_renewal_time_;
// to assist in clock rollback checks
int64_t last_recorded_current_time_;
@@ -210,11 +168,16 @@ class PolicyEngine {
// and current status (CdmKeyStatus)
std::unique_ptr<LicenseKeys> license_keys_;
// This is the current policy information for this license. This gets updated
// as license renewals occur.
video_widevine::License::Policy policy_;
// Device checks
int64_t next_device_check_;
uint32_t current_resolution_;
CryptoSession* crypto_session_;
std::unique_ptr<PolicyTimers> policy_timers;
std::unique_ptr<Clock> clock_;
CORE_DISALLOW_COPY_AND_ASSIGN(PolicyEngine);

View File

@@ -0,0 +1,112 @@
// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#ifndef WVCDM_CORE_POLICY_TIMERS_H_
#define WVCDM_CORE_POLICY_TIMERS_H_
#include <memory>
#include <string>
#include "disallow_copy_and_assign.h"
#include "license_protocol.pb.h"
#include "wv_cdm_types.h"
namespace wvcdm {
// This is driven by the Policy Engine and maintains timer related
// information from the policy such as duration windows and renewals.
// Timer expiration behavior has changed with the introduction of core
// messages in OEMCrypto v16. Handling of behavior that differs between
// a OEMCrypto v16 license with core messages and one without is left to
// a class that derives from this interface.
class PolicyTimers {
public:
virtual ~PolicyTimers() {}
// SetLicense is used in handling the initial license response.
virtual void SetLicense(const video_widevine::License& license);
// UpdateLicense is used in handling a license response for a renewal request.
// The response may only contain policy fields that have changed. In this
// case an exact copy is not what we want to happen.
virtual bool UpdateLicense(int64_t current_time,
const video_widevine::License& license) = 0;
// Call this on first decrypt to set the start of playback.
virtual void BeginDecryption(int64_t current_time) = 0;
// Call this periodically to update the most recent playback time.
virtual void DecryptionEvent(int64_t current_time);
// 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;
virtual void RestorePlaybackTimes(int64_t current_time,
int64_t playback_start_time,
int64_t last_playback_time,
int64_t grace_period_end_time) = 0;
virtual bool HasPlaybackStarted(int64_t current_time) = 0;
virtual bool HasLicenseOrPlaybackDurationExpired(int64_t current_time) = 0;
virtual bool HasPassedGracePeriod(int64_t current_time) = 0;
virtual int64_t GetLicenseOrPlaybackDurationRemaining(
int64_t current_time) = 0;
virtual int64_t GetLicenseOrRentalDurationRemaining(int64_t current_time) = 0;
virtual int64_t GetPlaybackDurationRemaining(int64_t current_time) = 0;
virtual bool GetSecondsSinceStarted(int64_t current_time,
int64_t* seconds_since_started);
virtual bool GetSecondsSinceLastPlayed(int64_t current_time,
int64_t* seconds_since_started);
virtual bool IsLicenseForFuture(int64_t current_time);
virtual bool UpdateExpirationTime(int64_t current_time, int64_t* expiry_time);
// Renewal related methods
virtual bool HasRenewalDelayExpired(int64_t current_time);
virtual bool HasRenewalRetryIntervalExpired(int64_t current_time);
virtual void UpdateRenewalRequest(int64_t current_time);
virtual bool HasRenewalRecoveryDurationExpired(int64_t current_time);
const video_widevine::License::Policy& get_policy() { return policy_; }
protected:
PolicyTimers()
: 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),
was_expired_on_load_(false) {}
// Gets the clock time that the license expires based on whether we have
// started playing.
virtual int64_t GetExpiryTime(int64_t current_time,
bool ignore_soft_enforce_playback_duration) = 0;
// This is the current policy information for this license. This gets updated
// as license renewals occur.
video_widevine::License::Policy policy_;
int64_t license_start_time_;
int64_t playback_start_time_;
int64_t last_playback_time_;
int64_t last_expiry_time_;
int64_t last_expiry_time_set_;
int64_t next_renewal_time_;
// Indicates whether a persistent license was expired when loaded
bool was_expired_on_load_;
private:
CORE_DISALLOW_COPY_AND_ASSIGN(PolicyTimers);
};
} // namespace wvcdm
#endif // WVCDM_CORE_POLICY_TIMERS_H_

View File

@@ -0,0 +1,85 @@
// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#ifndef WVCDM_CORE_POLICY_TIMERS_V15_H_
#define WVCDM_CORE_POLICY_TIMERS_V15_H_
#include <memory>
#include <string>
#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) {}
virtual ~PolicyTimersV15(){};
// UpdateLicense is used in handling a license response for a renewal request.
// The response may only contain any policy fields that have changed. In this
// case an exact copy is not what we want to happen.
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 HasLicenseOrPlaybackDurationExpired(int64_t current_time) override;
bool HasPassedGracePeriod(int64_t current_time) override;
int64_t GetLicenseOrPlaybackDurationRemaining(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 offline licenses.
int64_t GetLicenseOrRentalDurationRemaining(int64_t current_time) override;
// This is only used in Query. This should return playback_duration_seconds,
// or the time remaining on it if playing.
int64_t GetPlaybackDurationRemaining(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;
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_

View File

@@ -37,9 +37,6 @@ const std::string kEmptyString;
namespace wvcdm {
// Protobuf generated classes.
using video_widevine::ClientIdentification_ClientCapabilities;
using video_widevine::ClientIdentification_NameValue;
using video_widevine::DrmDeviceCertificate;
using video_widevine::EncryptedClientIdentification;
using video_widevine::License;
using video_widevine::License_KeyContainer;
@@ -47,10 +44,9 @@ using video_widevine::LicenseError;
using video_widevine::LicenseIdentification;
using video_widevine::LicenseRequest;
using video_widevine::LicenseRequest_ContentIdentification;
using video_widevine::LicenseRequest_ContentIdentification_CencDeprecated;
using video_widevine::LicenseRequest_ContentIdentification_ExistingLicense;
using video_widevine::LicenseRequest_ContentIdentification_WebmDeprecated;
using video_widevine::SignedDrmDeviceCertificate;
using video_widevine::LicenseRequest_ContentIdentification_WebmKeyId;
using video_widevine::LicenseRequest_ContentIdentification_WidevinePsshData;
using video_widevine::SignedMessage;
namespace {
@@ -1052,31 +1048,31 @@ CdmResponseType CdmLicense::PrepareContentId(
license_request->mutable_content_id();
if (init_data.is_cenc() || init_data.is_hls()) {
LicenseRequest_ContentIdentification_CencDeprecated* cenc_content_id =
content_id->mutable_cenc_id_deprecated();
LicenseRequest_ContentIdentification_WidevinePsshData* widevine_pssh_data =
content_id->mutable_widevine_pssh_data();
if (!init_data.IsEmpty()) {
cenc_content_id->add_pssh(init_data.data());
widevine_pssh_data->add_pssh_data(init_data.data());
} else {
LOGE("ISO-CENC init data not available");
return CENC_INIT_DATA_UNAVAILABLE;
}
if (!SetTypeAndId(license_type, request_id, cenc_content_id)) {
if (!SetTypeAndId(license_type, request_id, widevine_pssh_data)) {
return PREPARE_CENC_CONTENT_ID_FAILED;
}
} else if (init_data.is_webm()) {
LicenseRequest_ContentIdentification_WebmDeprecated* webm_content_id =
content_id->mutable_webm_id_deprecated();
LicenseRequest_ContentIdentification_WebmKeyId* webm_key_id =
content_id->mutable_webm_key_id();
if (!init_data.IsEmpty()) {
webm_content_id->set_header(init_data.data());
webm_key_id->set_header(init_data.data());
} else {
LOGE("WebM init data not available");
return WEBM_INIT_DATA_UNAVAILABLE;
}
if (!SetTypeAndId(license_type, request_id, webm_content_id)) {
if (!SetTypeAndId(license_type, request_id, webm_key_id)) {
return PREPARE_WEBM_CONTENT_ID_FAILED;
}
} else {

View File

@@ -42,6 +42,8 @@ message RemoteAttestation {
enum LicenseType {
STREAMING = 1;
OFFLINE = 2;
// License type decision is left to provider.
AUTOMATIC = 3;
}
enum PlatformVerificationStatus {
@@ -131,15 +133,23 @@ message License {
// Enables "soft enforcement" of playback_duration_seconds, letting the user
// finish playback even if short window expires. Optional.
optional bool soft_enforce_playback_duration = 14 [default = false];
// Enables "soft enforcement" of rental_duration_seconds. Initial playback
// must always start before rental duration expires. In order to allow
// subsequent playbacks to start after the rental duration expires,
// soft_enforce_playback_duration must be true. Otherwise, subsequent
// playbacks will not be allowed once rental duration expires. Optional.
optional bool soft_enforce_rental_duration = 15 [default = true];
}
message KeyContainer {
enum KeyType {
SIGNING = 1; // Exactly one key of this type must appear.
CONTENT = 2; // Content key.
KEY_CONTROL = 3; // Key control block for license renewals. No key.
SIGNING = 1; // Exactly one key of this type must appear.
CONTENT = 2; // Content key.
KEY_CONTROL = 3; // Key control block for license renewals. No key.
OPERATOR_SESSION = 4; // wrapped keys for auxiliary crypto operations.
ENTITLEMENT = 5; // Entitlement keys.
ENTITLEMENT = 5; // Entitlement keys.
OEM_CONTENT = 6; // Partner-specific content key.
}
// The SecurityLevel enumeration allows the server to communicate the level
@@ -291,7 +301,6 @@ message License {
[default = PLATFORM_NO_VERIFICATION];
// IDs of the groups for which keys are delivered in this license, if any.
repeated bytes group_ids = 11;
}
enum ProtocolVersion {
@@ -302,13 +311,13 @@ enum ProtocolVersion {
message LicenseRequest {
message ContentIdentification {
message CencDeprecated {
repeated bytes pssh = 1;
message WidevinePsshData {
repeated bytes pssh_data = 1;
optional LicenseType license_type = 2;
optional bytes request_id = 3; // Opaque, client-specified.
}
message WebmDeprecated {
message WebmKeyId {
optional bytes header = 1;
optional LicenseType license_type = 2;
optional bytes request_id = 3; // Opaque, client-specified.
@@ -335,8 +344,8 @@ message LicenseRequest {
oneof content_id_variant {
// Exactly one of these must be present.
CencDeprecated cenc_id_deprecated = 1;
WebmDeprecated webm_id_deprecated = 2;
WidevinePsshData widevine_pssh_data = 1;
WebmKeyId webm_key_id = 2;
ExistingLicense existing_license = 3;
InitData init_data = 4;
}
@@ -431,7 +440,6 @@ message SignedMessage {
WRAPPED_AES_KEY = 1;
EPHERMERAL_ECC_PUBLIC_KEY = 2;
}
optional MessageType type = 1;
optional bytes msg = 2;
// Required field that contains the signature of the bytes of msg.

View File

@@ -4,12 +4,11 @@
#include "policy_engine.h"
#include <limits.h>
#include <string>
#include "clock.h"
#include "log.h"
#include "policy_timers_v15.h"
#include "properties.h"
#include "string_conversions.h"
#include "wv_cdm_constants.h"
@@ -30,18 +29,11 @@ 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),
grace_period_end_time_(0),
last_expiry_time_set_(false),
was_expired_on_load_(false),
next_renewal_time_(0),
last_recorded_current_time_(0),
session_id_(session_id),
event_listener_(event_listener),
license_keys_(new LicenseKeys(crypto_session->GetSecurityLevel())),
policy_timers(new PolicyTimersV15),
clock_(new Clock) {
InitDevice(crypto_session);
}
@@ -95,16 +87,15 @@ void PolicyEngine::CheckDeviceHdcpStatus() {
void PolicyEngine::OnTimerEvent() {
last_recorded_current_time_ += kCdmPolicyTimerDurationSeconds;
int64_t current_time = GetCurrentTime();
const int64_t current_time = GetCurrentTime();
// If we have passed the grace period, the expiration will update.
if (grace_period_end_time_ == 0 && HasPlaybackStarted(current_time)) {
grace_period_end_time_ = playback_start_time_;
if (policy_timers->HasPassedGracePeriod(current_time)) {
NotifyExpirationUpdate(current_time);
}
// License expiration trumps all.
if (HasLicenseOrPlaybackDurationExpired(current_time) &&
if (policy_timers->HasLicenseOrPlaybackDurationExpired(current_time) &&
license_state_ != kLicenseStateExpired) {
license_state_ = kLicenseStateExpired;
NotifyKeysChange(kKeyStatusExpired);
@@ -119,7 +110,7 @@ void PolicyEngine::OnTimerEvent() {
// Test to determine if renewal should be attempted.
switch (license_state_) {
case kLicenseStateCanPlay: {
if (HasRenewalDelayExpired(current_time)) {
if (policy_timers->HasRenewalDelayExpired(current_time)) {
renewal_needed = true;
}
// HDCP may change, so force a check.
@@ -133,14 +124,14 @@ void PolicyEngine::OnTimerEvent() {
}
case kLicenseStateWaitingLicenseUpdate: {
if (HasRenewalRetryIntervalExpired(current_time)) {
if (policy_timers->HasRenewalRetryIntervalExpired(current_time)) {
renewal_needed = true;
}
break;
}
case kLicenseStatePending: {
if (current_time >= license_start_time_) {
if (!policy_timers->IsLicenseForFuture(current_time)) {
license_state_ = kLicenseStateCanPlay;
NotifyKeysChange(kKeyStatusUsable);
}
@@ -168,8 +159,8 @@ void PolicyEngine::OnTimerEvent() {
void PolicyEngine::SetLicense(const License& license) {
license_id_.Clear();
license_id_.CopyFrom(license.id());
policy_.Clear();
license_keys_->SetFromLicense(license);
policy_timers->SetLicense(license);
UpdateLicense(license);
}
@@ -181,10 +172,10 @@ void PolicyEngine::SetEntitledLicenseKeys(
void PolicyEngine::SetLicenseForRelease(const License& license) {
license_id_.Clear();
license_id_.CopyFrom(license.id());
policy_.Clear();
// Expire any old keys.
NotifyKeysChange(kKeyStatusExpired);
policy_timers->SetLicense(license);
UpdateLicense(license);
}
@@ -195,8 +186,6 @@ void PolicyEngine::UpdateLicense(const License& license) {
LOGD("Updating an expired license");
}
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;
@@ -209,20 +198,19 @@ void PolicyEngine::UpdateLicense(const License& license) {
return;
}
// Update time information
license_start_time_ = license.license_start_time();
next_renewal_time_ = license_start_time_ + policy_.renewal_delay_seconds();
const int64_t current_time = GetCurrentTime();
policy_timers->UpdateLicense(current_time, license);
int64_t current_time = GetCurrentTime();
if (!policy_.can_play() ||
HasLicenseOrPlaybackDurationExpired(current_time)) {
// Update time information
if (!policy_timers->get_policy().can_play() ||
policy_timers->HasLicenseOrPlaybackDurationExpired(current_time)) {
license_state_ = kLicenseStateExpired;
NotifyKeysChange(kKeyStatusExpired);
return;
}
// Update state
if (current_time >= license_start_time_) {
if (!policy_timers->IsLicenseForFuture(current_time)) {
license_state_ = kLicenseStateCanPlay;
NotifyKeysChange(kKeyStatusUsable);
} else {
@@ -233,20 +221,18 @@ void PolicyEngine::UpdateLicense(const License& license) {
}
bool PolicyEngine::BeginDecryption() {
if (playback_start_time_ == 0) {
const int64_t current_time = GetCurrentTime();
if (!policy_timers->HasPlaybackStarted(current_time)) {
switch (license_state_) {
case kLicenseStateCanPlay:
case kLicenseStateNeedRenewal:
case kLicenseStateWaitingLicenseUpdate:
playback_start_time_ = GetCurrentTime();
last_playback_time_ = playback_start_time_;
if (policy_.play_start_grace_period_seconds() == 0)
grace_period_end_time_ = playback_start_time_;
policy_timers->BeginDecryption(current_time);
if (policy_.renew_with_usage()) {
if (policy_timers->get_policy().renew_with_usage()) {
license_state_ = kLicenseStateNeedRenewal;
}
NotifyExpirationUpdate(playback_start_time_);
NotifyExpirationUpdate(current_time);
return true;
case kLicenseStateInitial:
case kLicenseStatePending:
@@ -259,7 +245,9 @@ bool PolicyEngine::BeginDecryption() {
}
}
void PolicyEngine::DecryptionEvent() { last_playback_time_ = GetCurrentTime(); }
void PolicyEngine::DecryptionEvent() {
policy_timers->DecryptionEvent(GetCurrentTime());
}
void PolicyEngine::NotifyResolution(uint32_t width, uint32_t height) {
SetDeviceResolution(width, height);
@@ -271,7 +259,7 @@ void PolicyEngine::NotifySessionExpiration() {
}
CdmResponseType PolicyEngine::Query(CdmQueryMap* query_response) {
int64_t current_time = GetCurrentTime();
const int64_t current_time = GetCurrentTime();
if (license_state_ == kLicenseStateInitial) {
query_response->clear();
@@ -282,17 +270,20 @@ CdmResponseType PolicyEngine::Query(CdmQueryMap* query_response) {
license_id_.type() == video_widevine::STREAMING ? QUERY_VALUE_STREAMING
: QUERY_VALUE_OFFLINE;
(*query_response)[QUERY_KEY_PLAY_ALLOWED] =
policy_.can_play() ? QUERY_VALUE_TRUE : QUERY_VALUE_FALSE;
policy_timers->get_policy().can_play() ? QUERY_VALUE_TRUE
: QUERY_VALUE_FALSE;
(*query_response)[QUERY_KEY_PERSIST_ALLOWED] =
policy_.can_persist() ? QUERY_VALUE_TRUE : QUERY_VALUE_FALSE;
policy_timers->get_policy().can_persist() ? QUERY_VALUE_TRUE
: QUERY_VALUE_FALSE;
(*query_response)[QUERY_KEY_RENEW_ALLOWED] =
policy_.can_renew() ? QUERY_VALUE_TRUE : QUERY_VALUE_FALSE;
(*query_response)[QUERY_KEY_LICENSE_DURATION_REMAINING] =
std::to_string(GetLicenseOrRentalDurationRemaining(current_time));
policy_timers->get_policy().can_renew() ? QUERY_VALUE_TRUE
: QUERY_VALUE_FALSE;
(*query_response)[QUERY_KEY_LICENSE_DURATION_REMAINING] = std::to_string(
policy_timers->GetLicenseOrRentalDurationRemaining(current_time));
(*query_response)[QUERY_KEY_PLAYBACK_DURATION_REMAINING] =
std::to_string(GetPlaybackDurationRemaining(current_time));
std::to_string(policy_timers->GetPlaybackDurationRemaining(current_time));
(*query_response)[QUERY_KEY_RENEWAL_SERVER_URL] =
policy_.renewal_server_url();
policy_timers->get_policy().renewal_server_url();
return NO_ERROR;
}
@@ -314,148 +305,54 @@ bool PolicyEngine::CanUseKeyForSecurityLevel(const KeyId& key_id) {
}
bool PolicyEngine::GetSecondsSinceStarted(int64_t* seconds_since_started) {
if (playback_start_time_ == 0) return false;
*seconds_since_started = GetCurrentTime() - playback_start_time_;
return (*seconds_since_started >= 0) ? true : false;
return policy_timers->GetSecondsSinceStarted(GetCurrentTime(),
seconds_since_started);
}
bool PolicyEngine::GetSecondsSinceLastPlayed(
int64_t* seconds_since_last_played) {
if (last_playback_time_ == 0) return false;
*seconds_since_last_played = GetCurrentTime() - last_playback_time_;
return (*seconds_since_last_played >= 0) ? true : false;
return policy_timers->GetSecondsSinceLastPlayed(GetCurrentTime(),
seconds_since_last_played);
}
int64_t PolicyEngine::GetLicenseOrPlaybackDurationRemaining() {
const int64_t current_time = GetCurrentTime();
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;
return policy_timers->GetLicenseOrPlaybackDurationRemaining(GetCurrentTime());
}
bool PolicyEngine::CanRenew() const {
return policy_timers->get_policy().can_renew();
}
int64_t PolicyEngine::GetPlaybackStartTime() {
return policy_timers->GetPlaybackStartTime();
}
int64_t PolicyEngine::GetLastPlaybackTime() {
return policy_timers->GetLastPlaybackTime();
}
int64_t PolicyEngine::GetGracePeriodEndTime() {
return policy_timers->GetGracePeriodEndTime();
}
void PolicyEngine::RestorePlaybackTimes(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;
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 current_time = GetCurrentTime();
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;
policy_timers->RestorePlaybackTimes(current_time, playback_start_time,
last_playback_time,
grace_period_end_time);
NotifyExpirationUpdate(current_time);
}
void PolicyEngine::UpdateRenewalRequest(int64_t current_time) {
license_state_ = kLicenseStateWaitingLicenseUpdate;
next_renewal_time_ = current_time + policy_.renewal_retry_interval_seconds();
policy_timers->UpdateRenewalRequest(current_time);
}
bool PolicyEngine::HasLicenseOrPlaybackDurationExpired(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;
}
// For the policy time fields checked in the following methods, a value of 0
// indicates that there is no limit to the duration. If the fields are zero
// (including the hard limit) then these methods will return NEVER_EXPIRES.
int64_t PolicyEngine::GetHardLicenseExpiryTime() {
return policy_.license_duration_seconds() > 0
? license_start_time_ + policy_.license_duration_seconds()
: NEVER_EXPIRES;
}
int64_t PolicyEngine::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 PolicyEngine::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);
}
int64_t PolicyEngine::GetLicenseOrRentalDurationRemaining(
int64_t current_time) {
// This is only used in Query. This should return the time remaining on
// license_duration_seconds for streaming licenses and rental_duration_seconds
// for offline licenses.
if (HasLicenseOrPlaybackDurationExpired(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 == NEVER_EXPIRES)
return license_expiry_time - current_time;
return std::min(license_expiry_time - current_time, policy_license_duration);
}
int64_t PolicyEngine::GetPlaybackDurationRemaining(int64_t current_time) {
// This is only used in Query. This should return playback_duration_seconds,
// or the time remaining on it if playing.
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 PolicyEngine::HasRenewalDelayExpired(int64_t current_time) {
return policy_.can_renew() && (policy_.renewal_delay_seconds() > 0) &&
license_start_time_ + policy_.renewal_delay_seconds() <= current_time;
}
bool PolicyEngine::HasRenewalRecoveryDurationExpired(int64_t current_time) {
// NOTE: Renewal Recovery Duration is currently not used.
return (policy_.renewal_recovery_duration_seconds() > 0) &&
license_start_time_ + policy_.renewal_recovery_duration_seconds() <=
current_time;
}
bool PolicyEngine::HasRenewalRetryIntervalExpired(int64_t current_time) {
return policy_.can_renew() &&
(policy_.renewal_retry_interval_seconds() > 0) &&
next_renewal_time_ <= current_time;
return policy_timers->HasLicenseOrPlaybackDurationExpired(current_time);
}
// Apply a key status to the current keys.
@@ -479,15 +376,11 @@ void PolicyEngine::NotifyKeysChange(CdmKeyStatus new_status) {
}
void PolicyEngine::NotifyExpirationUpdate(int64_t current_time) {
const int64_t expiry_time =
GetExpiryTime(current_time,
/* ignore_soft_enforce_playback_duration */ false);
if (!last_expiry_time_set_ || expiry_time != last_expiry_time_) {
last_expiry_time_ = expiry_time;
int64_t expiry_time;
if (policy_timers->UpdateExpirationTime(current_time, &expiry_time)) {
if (event_listener_)
event_listener_->OnExpirationUpdate(session_id_, expiry_time);
}
last_expiry_time_set_ = true;
}
int64_t PolicyEngine::GetCurrentTime() {

View File

@@ -0,0 +1,97 @@
// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#include "policy_timers.h"
#include <limits.h>
#include <string>
#include "log.h"
using video_widevine::License;
namespace wvcdm {
void PolicyTimers::SetLicense(const video_widevine::License& license) {
policy_.Clear();
license_start_time_ = license.license_start_time();
}
void PolicyTimers::DecryptionEvent(int64_t current_time) {
last_playback_time_ = current_time;
}
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::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) &&
(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);
}
} // namespace wvcdm

View File

@@ -0,0 +1,164 @@
// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#include "policy_timers_v15.h"
#include <algorithm>
#include <string>
#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() || HasLicenseOrPlaybackDurationExpired(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::HasLicenseOrPlaybackDurationExpired(
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::GetLicenseOrPlaybackDurationRemaining(
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 (HasLicenseOrPlaybackDurationExpired(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 == NEVER_EXPIRES)
return license_expiry_time - current_time;
return std::min(license_expiry_time - current_time, policy_license_duration);
}
int64_t PolicyTimersV15::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);
}
// For the policy time fields checked in the following methods, a value of 0
// indicates that there is no limit to the duration. If the fields are zero
// (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

View File

@@ -402,17 +402,19 @@ TEST_F(CdmLicenseTest, PrepareKeyRequestValidation) {
// Verify Content Identification
const LicenseRequest_ContentIdentification& content_id =
license_request.content_id();
ASSERT_TRUE(content_id.has_cenc_id_deprecated());
EXPECT_FALSE(content_id.has_webm_id_deprecated());
ASSERT_TRUE(content_id.has_widevine_pssh_data());
EXPECT_FALSE(content_id.has_webm_key_id());
EXPECT_FALSE(content_id.has_existing_license());
const ::video_widevine::LicenseRequest_ContentIdentification_CencDeprecated&
cenc_id = content_id.cenc_id_deprecated();
EXPECT_TRUE(std::equal(cenc_id.pssh(0).begin(), cenc_id.pssh(0).end(),
const ::video_widevine::LicenseRequest_ContentIdentification_WidevinePsshData&
widevine_pssh_data = content_id.widevine_pssh_data();
EXPECT_TRUE(std::equal(widevine_pssh_data.pssh_data(0).begin(),
widevine_pssh_data.pssh_data(0).end(),
kCencPssh.begin()));
EXPECT_EQ(video_widevine::STREAMING, cenc_id.license_type());
EXPECT_TRUE(std::equal(cenc_id.request_id().begin(),
cenc_id.request_id().end(), kCryptoRequestId.begin()));
EXPECT_EQ(video_widevine::STREAMING, widevine_pssh_data.license_type());
EXPECT_TRUE(std::equal(widevine_pssh_data.request_id().begin(),
widevine_pssh_data.request_id().end(),
kCryptoRequestId.begin()));
// Verify other license request fields
EXPECT_EQ(::video_widevine::LicenseRequest_RequestType_NEW,
@@ -527,17 +529,19 @@ TEST_F(CdmLicenseTest, PrepareKeyRequestValidationV15) {
// Verify Content Identification
const LicenseRequest_ContentIdentification& content_id =
license_request.content_id();
ASSERT_TRUE(content_id.has_cenc_id_deprecated());
EXPECT_FALSE(content_id.has_webm_id_deprecated());
ASSERT_TRUE(content_id.has_widevine_pssh_data());
EXPECT_FALSE(content_id.has_webm_key_id());
EXPECT_FALSE(content_id.has_existing_license());
const ::video_widevine::LicenseRequest_ContentIdentification_CencDeprecated&
cenc_id = content_id.cenc_id_deprecated();
EXPECT_TRUE(std::equal(cenc_id.pssh(0).begin(), cenc_id.pssh(0).end(),
const ::video_widevine::LicenseRequest_ContentIdentification_WidevinePsshData&
widevine_pssh_data = content_id.widevine_pssh_data();
EXPECT_TRUE(std::equal(widevine_pssh_data.pssh_data(0).begin(),
widevine_pssh_data.pssh_data(0).end(),
kCencPssh.begin()));
EXPECT_EQ(video_widevine::STREAMING, cenc_id.license_type());
EXPECT_TRUE(std::equal(cenc_id.request_id().begin(),
cenc_id.request_id().end(), kCryptoRequestId.begin()));
EXPECT_EQ(video_widevine::STREAMING, widevine_pssh_data.license_type());
EXPECT_TRUE(std::equal(widevine_pssh_data.request_id().begin(),
widevine_pssh_data.request_id().end(),
kCryptoRequestId.begin()));
// Verify other license request fields
EXPECT_EQ(::video_widevine::LicenseRequest_RequestType_NEW,

View File

@@ -312,7 +312,8 @@ TEST_F(PolicyEngineTest, PlaybackFailed_CanPlayFalse) {
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kLicenseStartTime + 5));
.WillOnce(Return(kLicenseStartTime + 5))
.WillOnce(Return(kLicenseStartTime + 7));
ExpectSessionKeysChange(kKeyStatusExpired, false);
@@ -2170,6 +2171,7 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_CanPlayFalse) {
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kLicenseStartTime + 5))
.WillOnce(Return(kLicenseStartTime + 7))
.WillOnce(Return(kLicenseStartTime + 100));
EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _))

View File

@@ -190,7 +190,7 @@ namespace wvcdm {
using video_widevine::ClientIdentification;
using video_widevine::LicenseIdentification;
using video_widevine::LicenseRequest_ContentIdentification;
using video_widevine::LicenseRequest_ContentIdentification_CencDeprecated;
using video_widevine::LicenseRequest_ContentIdentification_WidevinePsshData;
using video_widevine::SignedMessage;
class TestWvCdmClientPropertySet : public CdmClientPropertySet {
@@ -505,8 +505,8 @@ class WvCdmExtendedDurationTest : public WvCdmTestBase {
// Verify Content Identification
const LicenseRequest_ContentIdentification& content_id =
license_renewal.content_id();
EXPECT_FALSE(content_id.has_cenc_id_deprecated());
EXPECT_FALSE(content_id.has_webm_id_deprecated());
EXPECT_FALSE(content_id.has_widevine_pssh_data());
EXPECT_FALSE(content_id.has_webm_key_id());
EXPECT_TRUE(content_id.has_existing_license());
const LicenseRequest_ContentIdentification::ExistingLicense&
@@ -551,8 +551,8 @@ class WvCdmExtendedDurationTest : public WvCdmTestBase {
// Verify Content Identification
const LicenseRequest_ContentIdentification& content_id =
license_renewal.content_id();
EXPECT_FALSE(content_id.has_cenc_id_deprecated());
EXPECT_FALSE(content_id.has_webm_id_deprecated());
EXPECT_FALSE(content_id.has_widevine_pssh_data());
EXPECT_FALSE(content_id.has_webm_key_id());
EXPECT_TRUE(content_id.has_existing_license());
const LicenseRequest_ContentIdentification::ExistingLicense&
@@ -790,16 +790,17 @@ TEST_F(WvCdmExtendedDurationTest, VerifyLicenseRequestTest) {
// Verify Content Identification
const LicenseRequest_ContentIdentification& content_id =
license_request.content_id();
EXPECT_TRUE(content_id.has_cenc_id_deprecated());
EXPECT_FALSE(content_id.has_webm_id_deprecated());
EXPECT_TRUE(content_id.has_widevine_pssh_data());
EXPECT_FALSE(content_id.has_webm_key_id());
EXPECT_FALSE(content_id.has_existing_license());
const LicenseRequest_ContentIdentification_CencDeprecated& cenc_id =
content_id.cenc_id_deprecated();
EXPECT_TRUE(std::equal(cenc_id.pssh(0).begin(), cenc_id.pssh(0).end(),
const LicenseRequest_ContentIdentification_WidevinePsshData& pssh_data =
content_id.widevine_pssh_data();
EXPECT_TRUE(std::equal(pssh_data.pssh_data(0).begin(),
pssh_data.pssh_data(0).end(),
binary_key_id().begin() + 32));
EXPECT_EQ(video_widevine::STREAMING, cenc_id.license_type());
EXPECT_TRUE(cenc_id.has_request_id());
EXPECT_EQ(video_widevine::STREAMING, pssh_data.license_type());
EXPECT_TRUE(pssh_data.has_request_id());
// Verify other license request fields
EXPECT_EQ(::video_widevine::LicenseRequest_RequestType_NEW,
@@ -859,8 +860,8 @@ TEST_F(WvCdmExtendedDurationTest, VerifyLicenseRenewalTest) {
// Verify Content Identification
const LicenseRequest_ContentIdentification& content_id =
license_renewal.content_id();
EXPECT_FALSE(content_id.has_cenc_id_deprecated());
EXPECT_FALSE(content_id.has_webm_id_deprecated());
EXPECT_FALSE(content_id.has_widevine_pssh_data());
EXPECT_FALSE(content_id.has_webm_key_id());
EXPECT_TRUE(content_id.has_existing_license());
const LicenseRequest_ContentIdentification::ExistingLicense&

View File

@@ -2766,8 +2766,8 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseOfflineKeySessionUsageDisabledTest) {
// Verify Content Identification
const LicenseRequest_ContentIdentification& content_id =
license_renewal.content_id();
EXPECT_FALSE(content_id.has_cenc_id_deprecated());
EXPECT_FALSE(content_id.has_webm_id_deprecated());
EXPECT_FALSE(content_id.has_widevine_pssh_data());
EXPECT_FALSE(content_id.has_webm_key_id());
EXPECT_TRUE(content_id.has_existing_license());
const LicenseRequest_ContentIdentification::ExistingLicense&