Add License::Policy::play_start_grace_period_seconds

[ Merge of http://go/wvgerrit/22565 ]

When using the grace period, the CDM will need to override the values
given to use by the TEE (through OEMCrypto).  Normally the first (and
last) decrypt times are stored securely by the TEE.  To avoid extra
complexity in OEMCrypto, we will simply ignore the values given to us
by the TEE when using this feature.

However, the TEE will still enforce the (hard) license duration.  So
only the rental/playback durations will be affected by malicious
editing of files.

b/34211676

Test: Reran unittests including newly added tests. All tests other than
some oemcrypto, request_license_test passed. Those tests failed with
or without this CL.

Change-Id: I6d7b5bfb669fd8603b474b68c2f7175b0c30901d
This commit is contained in:
Rahul Frias
2017-01-16 18:17:01 -08:00
parent b492f7b73b
commit 826c91ba26
10 changed files with 252 additions and 56 deletions

View File

@@ -53,6 +53,7 @@ class DeviceFiles {
const std::string& release_server_url, const std::string& release_server_url,
int64_t playback_start_time, int64_t playback_start_time,
int64_t last_playback_time, int64_t last_playback_time,
int64_t grace_period_end_time,
const CdmAppParameterMap& app_parameters); const CdmAppParameterMap& app_parameters);
virtual bool RetrieveLicense( virtual bool RetrieveLicense(
const std::string& key_set_id, LicenseState* state, const std::string& key_set_id, LicenseState* state,
@@ -60,7 +61,7 @@ class DeviceFiles {
CdmKeyResponse* key_response, CdmKeyMessage* key_renewal_request, CdmKeyResponse* key_response, CdmKeyMessage* key_renewal_request,
CdmKeyResponse* key_renewal_response, std::string* release_server_url, CdmKeyResponse* key_renewal_response, std::string* release_server_url,
int64_t* playback_start_time, int64_t* last_playback_time, int64_t* playback_start_time, int64_t* last_playback_time,
CdmAppParameterMap* app_parameters); int64_t* grace_period_end_time, CdmAppParameterMap* app_parameters);
virtual bool DeleteLicense(const std::string& key_set_id); virtual bool DeleteLicense(const std::string& key_set_id);
virtual bool DeleteAllFiles(); virtual bool DeleteAllFiles();
virtual bool DeleteAllLicenses(); virtual bool DeleteAllLicenses();

View File

@@ -44,7 +44,8 @@ class CdmLicense {
const CdmKeyMessage& license_request, const CdmKeyMessage& license_request,
const CdmKeyResponse& license_response, const CdmKeyResponse& license_response,
const CdmKeyResponse& license_renewal_response, const CdmKeyResponse& license_renewal_response,
int64_t playback_start_time, int64_t last_playback_time); int64_t playback_start_time, int64_t last_playback_time,
int64_t grace_period_end_time);
virtual bool RestoreLicenseForRelease(const CdmKeyMessage& license_request, virtual bool RestoreLicenseForRelease(const CdmKeyMessage& license_request,
const CdmKeyResponse& license_response); const CdmKeyResponse& license_response);
virtual bool HasInitData() { return stored_init_data_.get(); } virtual bool HasInitData() { return stored_init_data_.get(); }

View File

@@ -80,11 +80,19 @@ class PolicyEngine {
// for offline save and restore // for offline save and restore
int64_t GetPlaybackStartTime() { return playback_start_time_; } int64_t GetPlaybackStartTime() { return playback_start_time_; }
int64_t GetLastPlaybackTime() { return last_playback_time_; } int64_t GetLastPlaybackTime() { return last_playback_time_; }
int64_t GetGracePeriodEndTime() { return grace_period_end_time_; }
void RestorePlaybackTimes(int64_t playback_start_time, void RestorePlaybackTimes(int64_t playback_start_time,
int64_t last_playback_time); int64_t last_playback_time,
int64_t grace_period_end_time);
bool IsLicenseForFuture() { return license_state_ == kLicenseStatePending; } bool IsLicenseForFuture() { return license_state_ == kLicenseStatePending; }
bool HasPlaybackStarted() { return playback_start_time_ > 0; } 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); bool HasLicenseOrPlaybackDurationExpired(int64_t current_time);
int64_t GetLicenseOrPlaybackDurationRemaining(); int64_t GetLicenseOrPlaybackDurationRemaining();
@@ -119,7 +127,8 @@ class PolicyEngine {
int64_t GetRentalExpiryTime(); int64_t GetRentalExpiryTime();
// Gets the clock time that the license expires based on whether we have // Gets the clock time that the license expires based on whether we have
// started playing. This takes into account GetHardLicenseExpiryTime. // started playing. This takes into account GetHardLicenseExpiryTime.
int64_t GetExpiryTime(bool ignore_soft_enforce_playback_duration); int64_t GetExpiryTime(int64_t current_time,
bool ignore_soft_enforce_playback_duration);
int64_t GetLicenseOrRentalDurationRemaining(int64_t current_time); int64_t GetLicenseOrRentalDurationRemaining(int64_t current_time);
int64_t GetPlaybackDurationRemaining(int64_t current_time); int64_t GetPlaybackDurationRemaining(int64_t current_time);
@@ -136,7 +145,7 @@ class PolicyEngine {
// Notifies updates in expiry time and fire OnExpirationUpdate event if // Notifies updates in expiry time and fire OnExpirationUpdate event if
// expiry time changes. // expiry time changes.
void NotifyExpirationUpdate(); void NotifyExpirationUpdate(int64_t current_time);
// set_clock() is for testing only. It alters ownership of the // set_clock() is for testing only. It alters ownership of the
// passed-in pointer. // passed-in pointer.
@@ -160,6 +169,7 @@ class PolicyEngine {
int64_t playback_start_time_; int64_t playback_start_time_;
int64_t last_playback_time_; int64_t last_playback_time_;
int64_t last_expiry_time_; int64_t last_expiry_time_;
int64_t grace_period_end_time_;
bool last_expiry_time_set_; bool last_expiry_time_set_;
bool was_expired_on_load_; bool was_expired_on_load_;

View File

@@ -129,12 +129,14 @@ CdmResponseType CdmSession::RestoreOfflineSession(
DeviceFiles::LicenseState license_state; DeviceFiles::LicenseState license_state;
int64_t playback_start_time; int64_t playback_start_time;
int64_t last_playback_time; int64_t last_playback_time;
int64_t grace_period_end_time;
if (!file_handle_->RetrieveLicense( if (!file_handle_->RetrieveLicense(
key_set_id, &license_state, &offline_init_data_, &key_request_, key_set_id, &license_state, &offline_init_data_, &key_request_,
&key_response_, &offline_key_renewal_request_, &key_response_, &offline_key_renewal_request_,
&offline_key_renewal_response_, &offline_release_server_url_, &offline_key_renewal_response_, &offline_release_server_url_,
&playback_start_time, &last_playback_time, &app_parameters_)) { &playback_start_time, &last_playback_time, &grace_period_end_time,
&app_parameters_)) {
LOGE("CdmSession::Init failed to retrieve license. key set id = %s", LOGE("CdmSession::Init failed to retrieve license. key set id = %s",
key_set_id.c_str()); key_set_id.c_str());
return GET_LICENSE_ERROR; return GET_LICENSE_ERROR;
@@ -156,7 +158,7 @@ CdmResponseType CdmSession::RestoreOfflineSession(
} else { } else {
if (!license_parser_->RestoreOfflineLicense( if (!license_parser_->RestoreOfflineLicense(
key_request_, key_response_, offline_key_renewal_response_, key_request_, key_response_, offline_key_renewal_response_,
playback_start_time, last_playback_time)) { playback_start_time, last_playback_time, grace_period_end_time)) {
return RESTORE_OFFLINE_LICENSE_ERROR_2; return RESTORE_OFFLINE_LICENSE_ERROR_2;
} }
} }
@@ -568,7 +570,8 @@ bool CdmSession::StoreLicense(DeviceFiles::LicenseState state) {
key_set_id_, state, offline_init_data_, key_request_, key_response_, key_set_id_, state, offline_init_data_, key_request_, key_response_,
offline_key_renewal_request_, offline_key_renewal_response_, offline_key_renewal_request_, offline_key_renewal_response_,
offline_release_server_url_, policy_engine_->GetPlaybackStartTime(), offline_release_server_url_, policy_engine_->GetPlaybackStartTime(),
policy_engine_->GetLastPlaybackTime(), app_parameters_); policy_engine_->GetLastPlaybackTime(),
policy_engine_->GetGracePeriodEndTime(), app_parameters_);
} }
CdmResponseType CdmSession::ReleaseCrypto() { CdmResponseType CdmSession::ReleaseCrypto() {

View File

@@ -168,7 +168,8 @@ bool DeviceFiles::StoreLicense(
const CdmKeyMessage& license_renewal_request, const CdmKeyMessage& license_renewal_request,
const CdmKeyResponse& license_renewal, const CdmKeyResponse& license_renewal,
const std::string& release_server_url, int64_t playback_start_time, const std::string& release_server_url, int64_t playback_start_time,
int64_t last_playback_time, const CdmAppParameterMap& app_parameters) { int64_t last_playback_time, int64_t grace_period_end_time,
const CdmAppParameterMap& app_parameters) {
if (!initialized_) { if (!initialized_) {
LOGW("DeviceFiles::StoreLicense: not initialized"); LOGW("DeviceFiles::StoreLicense: not initialized");
return false; return false;
@@ -201,6 +202,7 @@ bool DeviceFiles::StoreLicense(
license->set_release_server_url(release_server_url); license->set_release_server_url(release_server_url);
license->set_playback_start_time(playback_start_time); license->set_playback_start_time(playback_start_time);
license->set_last_playback_time(last_playback_time); license->set_last_playback_time(last_playback_time);
license->set_grace_period_end_time(grace_period_end_time);
NameValue* app_params; NameValue* app_params;
for (CdmAppParameterMap::const_iterator iter = app_parameters.begin(); for (CdmAppParameterMap::const_iterator iter = app_parameters.begin();
iter != app_parameters.end(); ++iter) { iter != app_parameters.end(); ++iter) {
@@ -221,7 +223,8 @@ bool DeviceFiles::RetrieveLicense(
CdmKeyMessage* license_request, CdmKeyResponse* license_message, CdmKeyMessage* license_request, CdmKeyResponse* license_message,
CdmKeyMessage* license_renewal_request, CdmKeyResponse* license_renewal, CdmKeyMessage* license_renewal_request, CdmKeyResponse* license_renewal,
std::string* release_server_url, int64_t* playback_start_time, std::string* release_server_url, int64_t* playback_start_time,
int64_t* last_playback_time, CdmAppParameterMap* app_parameters) { int64_t* last_playback_time, int64_t* grace_period_end_time,
CdmAppParameterMap* app_parameters) {
if (!initialized_) { if (!initialized_) {
LOGW("DeviceFiles::RetrieveLicense: not initialized"); LOGW("DeviceFiles::RetrieveLicense: not initialized");
return false; return false;
@@ -270,6 +273,7 @@ bool DeviceFiles::RetrieveLicense(
*release_server_url = license.release_server_url(); *release_server_url = license.release_server_url();
*playback_start_time = license.playback_start_time(); *playback_start_time = license.playback_start_time();
*last_playback_time = license.last_playback_time(); *last_playback_time = license.last_playback_time();
*grace_period_end_time = license.grace_period_end_time();
for (int i = 0; i < license.app_parameters_size(); ++i) { for (int i = 0; i < license.app_parameters_size(); ++i) {
(*app_parameters)[license.app_parameters(i).name()] = (*app_parameters)[license.app_parameters(i).name()] =
license.app_parameters(i).value(); license.app_parameters(i).value();

View File

@@ -39,6 +39,10 @@ message License {
optional int64 playback_start_time = 8 [default = 0]; optional int64 playback_start_time = 8 [default = 0];
optional int64 last_playback_time = 9 [default = 0]; optional int64 last_playback_time = 9 [default = 0];
repeated NameValue app_parameters = 10; repeated NameValue app_parameters = 10;
// This will be 0/missing if the grace period has not expired; otherwise it
// contains the playback_start_time we should use as an override. This is
// ignored if there is no grace period.
optional int64 grace_period_end_time = 11 [default = 0];
} }
message UsageInfo { message UsageInfo {

View File

@@ -674,7 +674,7 @@ bool CdmLicense::RestoreOfflineLicense(
const CdmKeyMessage& license_request, const CdmKeyMessage& license_request,
const CdmKeyResponse& license_response, const CdmKeyResponse& license_response,
const CdmKeyResponse& license_renewal_response, int64_t playback_start_time, const CdmKeyResponse& license_renewal_response, int64_t playback_start_time,
int64_t last_playback_time) { int64_t last_playback_time, int64_t grace_period_end_time) {
if (license_request.empty() || license_response.empty()) { if (license_request.empty() || license_response.empty()) {
LOGE( LOGE(
"CdmLicense::RestoreOfflineLicense: key_request or response empty: " "CdmLicense::RestoreOfflineLicense: key_request or response empty: "
@@ -742,7 +742,8 @@ bool CdmLicense::RestoreOfflineLicense(
} }
} }
policy_engine_->RestorePlaybackTimes(playback_start_time, last_playback_time); policy_engine_->RestorePlaybackTimes(playback_start_time, last_playback_time,
grace_period_end_time);
return true; return true;
} }

View File

@@ -31,6 +31,7 @@ PolicyEngine::PolicyEngine(CdmSessionId session_id,
playback_start_time_(0), playback_start_time_(0),
last_playback_time_(0), last_playback_time_(0),
last_expiry_time_(0), last_expiry_time_(0),
grace_period_end_time_(0),
last_expiry_time_set_(false), last_expiry_time_set_(false),
was_expired_on_load_(false), was_expired_on_load_(false),
next_renewal_time_(0), next_renewal_time_(0),
@@ -78,6 +79,12 @@ void PolicyEngine::CheckDevice(int64_t current_time) {
void PolicyEngine::OnTimerEvent() { void PolicyEngine::OnTimerEvent() {
int64_t current_time = clock_->GetCurrentTime(); int64_t current_time = clock_->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_;
NotifyExpirationUpdate(current_time);
}
// License expiration trumps all. // License expiration trumps all.
if (HasLicenseOrPlaybackDurationExpired(current_time) && if (HasLicenseOrPlaybackDurationExpired(current_time) &&
license_state_ != kLicenseStateExpired) { license_state_ != kLicenseStateExpired) {
@@ -195,7 +202,7 @@ void PolicyEngine::UpdateLicense(const License& license) {
license_state_ = kLicenseStatePending; license_state_ = kLicenseStatePending;
NotifyKeysChange(kKeyStatusPending); NotifyKeysChange(kKeyStatusPending);
} }
NotifyExpirationUpdate(); NotifyExpirationUpdate(current_time);
} }
void PolicyEngine::BeginDecryption() { void PolicyEngine::BeginDecryption() {
@@ -206,11 +213,13 @@ void PolicyEngine::BeginDecryption() {
case kLicenseStateWaitingLicenseUpdate: case kLicenseStateWaitingLicenseUpdate:
playback_start_time_ = clock_->GetCurrentTime(); playback_start_time_ = clock_->GetCurrentTime();
last_playback_time_ = playback_start_time_; last_playback_time_ = playback_start_time_;
if (policy_.play_start_grace_period_seconds() == 0)
grace_period_end_time_ = playback_start_time_;
if (policy_.renew_with_usage()) { if (policy_.renew_with_usage()) {
license_state_ = kLicenseStateNeedRenewal; license_state_ = kLicenseStateNeedRenewal;
} }
NotifyExpirationUpdate(); NotifyExpirationUpdate(playback_start_time_);
break; break;
case kLicenseStateInitial: case kLicenseStateInitial:
case kLicenseStatePending: case kLicenseStatePending:
@@ -290,26 +299,38 @@ bool PolicyEngine::GetSecondsSinceLastPlayed(
} }
int64_t PolicyEngine::GetLicenseOrPlaybackDurationRemaining() { int64_t PolicyEngine::GetLicenseOrPlaybackDurationRemaining() {
int64_t current_time = clock_->GetCurrentTime(); const int64_t current_time = clock_->GetCurrentTime();
const int64_t expiry_time = const int64_t expiry_time =
GetExpiryTime(/* ignore_soft_enforce_playback_duration */ false); GetExpiryTime(current_time,
/* ignore_soft_enforce_playback_duration */ false);
if (expiry_time == NEVER_EXPIRES) return LLONG_MAX; if (expiry_time == NEVER_EXPIRES) return LLONG_MAX;
if (expiry_time < current_time) return 0; if (expiry_time < current_time) return 0;
return expiry_time - current_time; return expiry_time - current_time;
} }
void PolicyEngine::RestorePlaybackTimes(int64_t playback_start_time, void PolicyEngine::RestorePlaybackTimes(int64_t playback_start_time,
int64_t last_playback_time) { int64_t last_playback_time,
int64_t grace_period_end_time) {
playback_start_time_ = (playback_start_time > 0) ? playback_start_time : 0; playback_start_time_ = (playback_start_time > 0) ? playback_start_time : 0;
last_playback_time_ = (last_playback_time > 0) ? last_playback_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 = clock_->GetCurrentTime(); const int64_t current_time = clock_->GetCurrentTime();
const int64_t expiry_time = const int64_t expiry_time =
GetExpiryTime(/* ignore_soft_enforce_playback_duration */ true); GetExpiryTime(current_time,
/* ignore_soft_enforce_playback_duration */ true);
was_expired_on_load_ = was_expired_on_load_ =
expiry_time != NEVER_EXPIRES && expiry_time < current_time; expiry_time != NEVER_EXPIRES && expiry_time < current_time;
NotifyExpirationUpdate(); NotifyExpirationUpdate(current_time);
} }
void PolicyEngine::UpdateRenewalRequest(int64_t current_time) { void PolicyEngine::UpdateRenewalRequest(int64_t current_time) {
@@ -319,8 +340,9 @@ void PolicyEngine::UpdateRenewalRequest(int64_t current_time) {
bool PolicyEngine::HasLicenseOrPlaybackDurationExpired(int64_t current_time) { bool PolicyEngine::HasLicenseOrPlaybackDurationExpired(int64_t current_time) {
const int64_t expiry_time = const int64_t expiry_time =
GetExpiryTime(/* ignore_soft_enforce_playback_duration */ false); GetExpiryTime(current_time,
return (expiry_time != NEVER_EXPIRES) && expiry_time <= 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 // For the policy time fields checked in the following methods, a value of 0
@@ -343,8 +365,9 @@ int64_t PolicyEngine::GetRentalExpiryTime() {
} }
int64_t PolicyEngine::GetExpiryTime( int64_t PolicyEngine::GetExpiryTime(
int64_t current_time,
bool ignore_soft_enforce_playback_duration) { bool ignore_soft_enforce_playback_duration) {
if (!HasPlaybackStarted()) if (!HasPlaybackStarted(current_time))
return GetRentalExpiryTime(); return GetRentalExpiryTime();
const int64_t hard_limit = GetHardLicenseExpiryTime(); const int64_t hard_limit = GetHardLicenseExpiryTime();
@@ -418,9 +441,10 @@ void PolicyEngine::NotifyKeysChange(CdmKeyStatus new_status) {
} }
} }
void PolicyEngine::NotifyExpirationUpdate() { void PolicyEngine::NotifyExpirationUpdate(int64_t current_time) {
const int64_t expiry_time = const int64_t expiry_time =
GetExpiryTime(/* ignore_soft_enforce_playback_duration */ false); GetExpiryTime(current_time,
/* ignore_soft_enforce_playback_duration */ false);
if (!last_expiry_time_set_ || expiry_time != last_expiry_time_) { if (!last_expiry_time_set_ || expiry_time != last_expiry_time_) {
last_expiry_time_ = expiry_time; last_expiry_time_ = expiry_time;
if (event_listener_) if (event_listener_)

View File

@@ -118,6 +118,7 @@ struct LicenseInfo {
std::string key_release_url; std::string key_release_url;
int64_t playback_start_time; int64_t playback_start_time;
int64_t last_playback_time; int64_t last_playback_time;
int64_t grace_period_end_time;
std::string app_parameters; std::string app_parameters;
std::string file_data; std::string file_data;
}; };
@@ -225,9 +226,9 @@ LicenseInfo license_test_data[] = {
"0112001A16200342120A106B63746C0000000000ECDCBE0000000020DBDF" "0112001A16200342120A106B63746C0000000000ECDCBE0000000020DBDF"
"A68F051A20182F029E35047A3841FA176C74E5B387350E8D58DEA6878FF0" "A68F051A20182F029E35047A3841FA176C74E5B387350E8D58DEA6878FF0"
"BEA6CABACA1C2C"), "BEA6CABACA1C2C"),
"https://test.google.com/license/GetCencLicense", 0x0, 0x0, "", "https://test.google.com/license/GetCencLicense", 0x0, 0x0, 0x0, "",
a2bs_hex( a2bs_hex(
"0AA8150802100122A1150801121408011210303132333435363738394142434445461" "0AAA150802100122A3150801121408011210303132333435363738394142434445461"
"A9D0E080112950C0AD70B080112EF090AB002080212103E560EC5335E346F591BC4D0" "A9D0E080112950C0AD70B080112EF090AB002080212103E560EC5335E346F591BC4D0"
"7A7D507618A5D3A68F05228E023082010A0282010100A947904B8DBD55FB685FDB302" "7A7D507618A5D3A68F05228E023082010A0282010100A947904B8DBD55FB685FDB302"
"5574517CCCC74EE4FEAF6629D5179A52FF85CE7409528EFFA0E5DFC3DE9A34BA5F08B" "5574517CCCC74EE4FEAF6629D5179A52FF85CE7409528EFFA0E5DFC3DE9A34BA5F08B"
@@ -306,8 +307,8 @@ LicenseInfo license_test_data[] = {
"106B63746C0000000000ECDCBE0000000020DBDFA68F051A20182F029E35047A3841F" "106B63746C0000000000ECDCBE0000000020DBDFA68F051A20182F029E35047A3841F"
"A176C74E5B387350E8D58DEA6878FF0BEA6CABACA1C2C3A2E68747470733A2F2F7465" "A176C74E5B387350E8D58DEA6878FF0BEA6CABACA1C2C3A2E68747470733A2F2F7465"
"73742E676F6F676C652E636F6D2F6C6963656E73652F47657443656E634C6963656E7" "73742E676F6F676C652E636F6D2F6C6963656E73652F47657443656E634C6963656E7"
"365400048001220CD0599C2B85D9F2D573AC7893CE77CB5A10B326828BA8C89047505" "365400048005800122066F4FFF1CB2C0F978149A9402F3E4FF8D49B19635E646A0678"
"A8C9B606AC")}, "71AA08E7A8FDC3")},
// license 1 // license 1
{"ksidC8EAA2579A282EB0", DeviceFiles::kLicenseStateReleasing, {"ksidC8EAA2579A282EB0", DeviceFiles::kLicenseStateReleasing,
@@ -406,9 +407,9 @@ LicenseInfo license_test_data[] = {
"A68F051A20BDA6A56F7CBFD0942198F87C23A34AA5CBD64AFEB134277774" "A68F051A20BDA6A56F7CBFD0942198F87C23A34AA5CBD64AFEB134277774"
"CCF8E789D815DD"), "CCF8E789D815DD"),
"https://test.google.com/license/GetCencLicense", 0x12345678, 0x12348765, "https://test.google.com/license/GetCencLicense", 0x12345678, 0x12348765,
"Name1 Value1", 0x0, "Name1 Value1",
a2bs_hex( a2bs_hex(
"0AC1150802100122BA150802121408011210303132333435363738394142434445461" "0AC3150802100122BC150802121408011210303132333435363738394142434445461"
"A9D0E080112950C0AD70B080112EF090AB002080212103E560EC5335E346F591BC4D0" "A9D0E080112950C0AD70B080112EF090AB002080212103E560EC5335E346F591BC4D0"
"7A7D507618A5D3A68F05228E023082010A0282010100A947904B8DBD55FB685FDB302" "7A7D507618A5D3A68F05228E023082010A0282010100A947904B8DBD55FB685FDB302"
"5574517CCCC74EE4FEAF6629D5179A52FF85CE7409528EFFA0E5DFC3DE9A34BA5F08B" "5574517CCCC74EE4FEAF6629D5179A52FF85CE7409528EFFA0E5DFC3DE9A34BA5F08B"
@@ -487,8 +488,8 @@ LicenseInfo license_test_data[] = {
"106B63746C00000000CA3A6A75000000002083E5A68F051A20BDA6A56F7CBFD094219" "106B63746C00000000CA3A6A75000000002083E5A68F051A20BDA6A56F7CBFD094219"
"8F87C23A34AA5CBD64AFEB134277774CCF8E789D815DD3A2E68747470733A2F2F7465" "8F87C23A34AA5CBD64AFEB134277774CCF8E789D815DD3A2E68747470733A2F2F7465"
"73742E676F6F676C652E636F6D2F6C6963656E73652F47657443656E634C6963656E7" "73742E676F6F676C652E636F6D2F6C6963656E73652F47657443656E634C6963656E7"
"36540F8ACD1910148E58ED29101520F0A054E616D6531120656616C7565311220BE69" "36540F8ACD1910148E58ED29101520F0A054E616D6531120656616C75653158001220"
"AAB25B481BCAF57B741518D9F9DB8E3A7A6911D10C53D4F4649D78393C65")}, "9C0315FC1812C6A0E5936E36D04ECE2FA56AF4AB544ECDF3C9135D54B4A26167")},
// license 2 // license 2
{"ksidE8C37662C88DC673", DeviceFiles::kLicenseStateReleasing, {"ksidE8C37662C88DC673", DeviceFiles::kLicenseStateReleasing,
@@ -587,9 +588,9 @@ LicenseInfo license_test_data[] = {
"A68F051A2041EF0A9267D613D17AA90E1D1DA5BE091860E5E296D41D6D0F" "A68F051A2041EF0A9267D613D17AA90E1D1DA5BE091860E5E296D41D6D0F"
"75E73660C279B3"), "75E73660C279B3"),
"https://test.google.com/license/GetCencLicense", 0x0123456789abcdef, "https://test.google.com/license/GetCencLicense", 0x0123456789abcdef,
0x123456789abfedc, "Name1 Value1 Name2 Param2", 0x123456789abfedc, 0x0, "Name1 Value1 Name2 Param2",
a2bs_hex( a2bs_hex(
"0AE7150802100122E0150802121408011210303132333435363738394142434445461" "0AE9150802100122E2150802121408011210303132333435363738394142434445461"
"A9D0E080112950C0AD70B080112EF090AB002080212103E560EC5335E346F591BC4D0" "A9D0E080112950C0AD70B080112EF090AB002080212103E560EC5335E346F591BC4D0"
"7A7D507618A5D3A68F05228E023082010A0282010100A947904B8DBD55FB685FDB302" "7A7D507618A5D3A68F05228E023082010A0282010100A947904B8DBD55FB685FDB302"
"5574517CCCC74EE4FEAF6629D5179A52FF85CE7409528EFFA0E5DFC3DE9A34BA5F08B" "5574517CCCC74EE4FEAF6629D5179A52FF85CE7409528EFFA0E5DFC3DE9A34BA5F08B"
@@ -669,9 +670,9 @@ LicenseInfo license_test_data[] = {
"90E1D1DA5BE091860E5E296D41D6D0F75E73660C279B33A2E68747470733A2F2F7465" "90E1D1DA5BE091860E5E296D41D6D0F75E73660C279B33A2E68747470733A2F2F7465"
"73742E676F6F676C652E636F6D2F6C6963656E73652F47657443656E634C6963656E7" "73742E676F6F676C652E636F6D2F6C6963656E73652F47657443656E634C6963656E7"
"36540EF9BAFCDF8ACD1910148DCFDAFCDF8ACD1910152150A054E616D6531120C5661" "36540EF9BAFCDF8ACD1910148DCFDAFCDF8ACD1910152150A054E616D6531120C5661"
"6C756531204E616D653252160A0C4E616D653220506172616D321206506172616D321" "6C756531204E616D653252160A0C4E616D653220506172616D321206506172616D325"
"2203653BA57F16FE28D66D9F7A76128B7AD7F33680815FF70A3684617DE1FBB0F9" "8001220616E6AC4AF6EB4F7147E98CF7302425E2390B293BBC01F9F8E89B49F653EA3"
"F")}}; "45")}};
// Sample license data and related data for storage and use for offline // Sample license data and related data for storage and use for offline
// playback. The license data and URLs in this test are not real. // playback. The license data and URLs in this test are not real.
@@ -774,9 +775,9 @@ LicenseInfo license_update_test_data[] = {
"B68F051A2000351030900858FCFD6977B67803ADFD1280AA661E6B0BD30B" "B68F051A2000351030900858FCFD6977B67803ADFD1280AA661E6B0BD30B"
"08B2C467355129"), "08B2C467355129"),
"https://test.google.com/license/GetCencLicense", 0x0123456789abcdef, "https://test.google.com/license/GetCencLicense", 0x0123456789abcdef,
0x123456789abfedc, "Name1 Value1 Name2 Value2 Name3 Value3", 0x123456789abfedc, 0x0, "Name1 Value1 Name2 Value2 Name3 Value3",
a2bs_hex( a2bs_hex(
"0AB8150802100122B1150801121408011210303132333435363738394142434445461" "0ABA150802100122B3150801121408011210303132333435363738394142434445461"
"A9D0E080112950C0AD70B080112EF090AB002080212103E560EC5335E346F591BC4D0" "A9D0E080112950C0AD70B080112EF090AB002080212103E560EC5335E346F591BC4D0"
"7A7D5076189EDFB68F05228E023082010A0282010100CC1715C81AD3F6F279C686F82" "7A7D5076189EDFB68F05228E023082010A0282010100CC1715C81AD3F6F279C686F82"
"6E6D7C8961EB13318367D06B4061BBC57E3C616A226A10F042CAD54D44C6484C725CD" "6E6D7C8961EB13318367D06B4061BBC57E3C616A226A10F042CAD54D44C6484C725CD"
@@ -855,13 +856,14 @@ LicenseInfo license_update_test_data[] = {
"106B63746C0000000071FEF30B0000000020F4DFB68F051A2000351030900858FCFD6" "106B63746C0000000071FEF30B0000000020F4DFB68F051A2000351030900858FCFD6"
"977B67803ADFD1280AA661E6B0BD30B08B2C4673551293A2E68747470733A2F2F7465" "977B67803ADFD1280AA661E6B0BD30B08B2C4673551293A2E68747470733A2F2F7465"
"73742E676F6F676C652E636F6D2F6C6963656E73652F47657443656E634C6963656E7" "73742E676F6F676C652E636F6D2F6C6963656E73652F47657443656E634C6963656E7"
"36540EF9BAFCDF8ACD1910148DCFDAFCDF8ACD191011220C7ACA00F6877DAAE2E8F50" "36540EF9BAFCDF8ACD1910148DCFDAFCDF8ACD191015800122051F15CDA5B9414919D"
"126C3222C2E584A50D08EFA75BC4FC091E7034E1DD")}, "B67769A781CC4F43138D314DAFFCBFBD620E53167E4AF2")},
// license being released. all fields are identical except for license // license being released. all fields are identical except for license
// state and hashed file data // state and hashed file data
{"", DeviceFiles::kLicenseStateReleasing, "", "", "", "", "", "", 0, 0, "", {"", DeviceFiles::kLicenseStateReleasing, "", "", "", "", "", "", 0, 0, 0,
"",
a2bs_hex( a2bs_hex(
"0AB8150802100122B1150802121408011210303132333435363738394142434445461" "0ABA150802100122B3150802121408011210303132333435363738394142434445461"
"A9D0E080112950C0AD70B080112EF090AB002080212103E560EC5335E346F591BC4D0" "A9D0E080112950C0AD70B080112EF090AB002080212103E560EC5335E346F591BC4D0"
"7A7D5076189EDFB68F05228E023082010A0282010100CC1715C81AD3F6F279C686F82" "7A7D5076189EDFB68F05228E023082010A0282010100CC1715C81AD3F6F279C686F82"
"6E6D7C8961EB13318367D06B4061BBC57E3C616A226A10F042CAD54D44C6484C725CD" "6E6D7C8961EB13318367D06B4061BBC57E3C616A226A10F042CAD54D44C6484C725CD"
@@ -940,8 +942,8 @@ LicenseInfo license_update_test_data[] = {
"106B63746C0000000071FEF30B0000000020F4DFB68F051A2000351030900858FCFD6" "106B63746C0000000071FEF30B0000000020F4DFB68F051A2000351030900858FCFD6"
"977B67803ADFD1280AA661E6B0BD30B08B2C4673551293A2E68747470733A2F2F7465" "977B67803ADFD1280AA661E6B0BD30B08B2C4673551293A2E68747470733A2F2F7465"
"73742E676F6F676C652E636F6D2F6C6963656E73652F47657443656E634C6963656E7" "73742E676F6F676C652E636F6D2F6C6963656E73652F47657443656E634C6963656E7"
"36540EF9BAFCDF8ACD1910148DCFDAFCDF8ACD1910112203D8933A735A22FE27AA956" "36540EF9BAFCDF8ACD1910148DCFDAFCDF8ACD191015800122093FDE0D42BC60D3932"
"802B597529E8FFCB91A5F3CBBB3CE0C38E4AF3DC88")}}; "02E0D5A49775E08093BF01560EF72C298321E921716E24")}};
// Application parameters were added to the License message. This data // Application parameters were added to the License message. This data
// is used to verify that a License saved without application parameters can // is used to verify that a License saved without application parameters can
@@ -1043,7 +1045,7 @@ LicenseInfo license_app_parameters_backwards_compatibility_test_data = {
"0112001A16200342120A106B63746C0000000000ECDCBE0000000020DBDF" "0112001A16200342120A106B63746C0000000000ECDCBE0000000020DBDF"
"A68F051A20182F029E35047A3841FA176C74E5B387350E8D58DEA6878FF0" "A68F051A20182F029E35047A3841FA176C74E5B387350E8D58DEA6878FF0"
"BEA6CABACA1C2C"), "BEA6CABACA1C2C"),
"https://test.google.com/license/GetCencLicense", 0x0, 0x0, "", "https://test.google.com/license/GetCencLicense", 0x0, 0x0, 0x0, "",
a2bs_hex( a2bs_hex(
"0AA8150802100122A1150801121408011210303132333435363738394142434445461" "0AA8150802100122A1150801121408011210303132333435363738394142434445461"
"A9D0E080112950C0AD70B080112EF090AB002080212103E560EC5335E346F591BC4D0" "A9D0E080112950C0AD70B080112EF090AB002080212103E560EC5335E346F591BC4D0"
@@ -1489,7 +1491,7 @@ class DeviceFilesTest : public ::testing::Test {
return sizeof(DeviceFiles::LicenseState) + data.pssh_data.size() + return sizeof(DeviceFiles::LicenseState) + data.pssh_data.size() +
data.key_request.size() + data.key_response.size() + data.key_request.size() + data.key_response.size() +
data.key_renewal_request.size() + data.key_renewal_response.size() + data.key_renewal_request.size() + data.key_renewal_response.size() +
data.key_release_url.size() + 2 * sizeof(int64_t); data.key_release_url.size() + 3 * sizeof(int64_t);
} }
CdmAppParameterMap GetAppParameters(std::string str) { CdmAppParameterMap GetAppParameters(std::string str) {
@@ -1747,7 +1749,8 @@ TEST_P(DeviceFilesStoreTest, StoreLicense) {
license_test_data[license_num].key_renewal_response, license_test_data[license_num].key_renewal_response,
license_test_data[license_num].key_release_url, license_test_data[license_num].key_release_url,
license_test_data[license_num].playback_start_time, license_test_data[license_num].playback_start_time,
license_test_data[license_num].last_playback_time, app_parameters)); license_test_data[license_num].last_playback_time,
license_test_data[license_num].grace_period_end_time, app_parameters));
} }
INSTANTIATE_TEST_CASE_P(StoreLicense, DeviceFilesStoreTest, ::testing::Bool()); INSTANTIATE_TEST_CASE_P(StoreLicense, DeviceFilesStoreTest, ::testing::Bool());
@@ -1794,7 +1797,8 @@ TEST_F(DeviceFilesTest, StoreLicenses) {
license_test_data[i].key_renewal_response, license_test_data[i].key_renewal_response,
license_test_data[i].key_release_url, license_test_data[i].key_release_url,
license_test_data[i].playback_start_time, license_test_data[i].playback_start_time,
license_test_data[i].last_playback_time, app_parameters)); license_test_data[i].last_playback_time,
license_test_data[i].grace_period_end_time, app_parameters));
} }
} }
@@ -1832,6 +1836,7 @@ TEST_F(DeviceFilesTest, RetrieveLicenses) {
CdmKeyMessage key_renewal_request; CdmKeyMessage key_renewal_request;
CdmKeyResponse key_renewal_response; CdmKeyResponse key_renewal_response;
int64_t playback_start_time, last_playback_time; int64_t playback_start_time, last_playback_time;
int64_t grace_period_end_time;
std::string release_server_url; std::string release_server_url;
CdmAppParameterMap app_parameters; CdmAppParameterMap app_parameters;
@@ -1841,7 +1846,7 @@ TEST_F(DeviceFilesTest, RetrieveLicenses) {
license_test_data[i].key_set_id, &license_state, &pssh_data, license_test_data[i].key_set_id, &license_state, &pssh_data,
&key_request, &key_response, &key_renewal_request, &key_request, &key_response, &key_renewal_request,
&key_renewal_response, &release_server_url, &playback_start_time, &key_renewal_response, &release_server_url, &playback_start_time,
&last_playback_time, &app_parameters)); &last_playback_time, &grace_period_end_time, &app_parameters));
EXPECT_EQ(license_test_data[i].license_state, license_state); EXPECT_EQ(license_test_data[i].license_state, license_state);
EXPECT_EQ(license_test_data[i].pssh_data, pssh_data); EXPECT_EQ(license_test_data[i].pssh_data, pssh_data);
EXPECT_EQ(license_test_data[i].key_request, key_request); EXPECT_EQ(license_test_data[i].key_request, key_request);
@@ -1850,6 +1855,8 @@ TEST_F(DeviceFilesTest, RetrieveLicenses) {
EXPECT_EQ(license_test_data[i].key_response, key_response); EXPECT_EQ(license_test_data[i].key_response, key_response);
EXPECT_EQ(license_test_data[i].playback_start_time, playback_start_time); EXPECT_EQ(license_test_data[i].playback_start_time, playback_start_time);
EXPECT_EQ(license_test_data[i].last_playback_time, last_playback_time); EXPECT_EQ(license_test_data[i].last_playback_time, last_playback_time);
EXPECT_EQ(license_test_data[i].grace_period_end_time,
grace_period_end_time);
std::map<std::string, std::string>::iterator itr; std::map<std::string, std::string>::iterator itr;
for (itr = app_parameters.begin(); itr != app_parameters.end(); ++itr) { for (itr = app_parameters.begin(); itr != app_parameters.end(); ++itr) {
@@ -1894,6 +1901,7 @@ TEST_F(DeviceFilesTest, AppParametersBackwardCompatibility) {
CdmKeyMessage key_renewal_request; CdmKeyMessage key_renewal_request;
CdmKeyResponse key_renewal_response; CdmKeyResponse key_renewal_response;
int64_t playback_start_time, last_playback_time; int64_t playback_start_time, last_playback_time;
int64_t grace_period_end_time;
std::string release_server_url; std::string release_server_url;
CdmAppParameterMap app_parameters; CdmAppParameterMap app_parameters;
@@ -1901,7 +1909,7 @@ TEST_F(DeviceFilesTest, AppParametersBackwardCompatibility) {
test_data->key_set_id, &license_state, &pssh_data, &key_request, test_data->key_set_id, &license_state, &pssh_data, &key_request,
&key_response, &key_renewal_request, &key_renewal_response, &key_response, &key_renewal_request, &key_renewal_response,
&release_server_url, &playback_start_time, &last_playback_time, &release_server_url, &playback_start_time, &last_playback_time,
&app_parameters)); &grace_period_end_time, &app_parameters));
EXPECT_EQ(test_data->license_state, license_state); EXPECT_EQ(test_data->license_state, license_state);
EXPECT_EQ(test_data->pssh_data, pssh_data); EXPECT_EQ(test_data->pssh_data, pssh_data);
EXPECT_EQ(test_data->key_request, key_request); EXPECT_EQ(test_data->key_request, key_request);
@@ -1910,6 +1918,7 @@ TEST_F(DeviceFilesTest, AppParametersBackwardCompatibility) {
EXPECT_EQ(test_data->key_response, key_response); EXPECT_EQ(test_data->key_response, key_response);
EXPECT_EQ(test_data->playback_start_time, playback_start_time); EXPECT_EQ(test_data->playback_start_time, playback_start_time);
EXPECT_EQ(test_data->last_playback_time, last_playback_time); EXPECT_EQ(test_data->last_playback_time, last_playback_time);
EXPECT_EQ(test_data->grace_period_end_time, grace_period_end_time);
EXPECT_EQ(0u, app_parameters.size()); EXPECT_EQ(0u, app_parameters.size());
} }
@@ -1945,6 +1954,7 @@ TEST_F(DeviceFilesTest, UpdateLicenseState) {
license_update_test_data[0].key_release_url, license_update_test_data[0].key_release_url,
license_update_test_data[0].playback_start_time, license_update_test_data[0].playback_start_time,
license_update_test_data[0].last_playback_time, license_update_test_data[0].last_playback_time,
license_update_test_data[0].grace_period_end_time,
GetAppParameters(license_test_data[0].app_parameters))); GetAppParameters(license_test_data[0].app_parameters)));
EXPECT_TRUE(device_files.StoreLicense( EXPECT_TRUE(device_files.StoreLicense(
@@ -1958,6 +1968,7 @@ TEST_F(DeviceFilesTest, UpdateLicenseState) {
license_update_test_data[0].key_release_url, license_update_test_data[0].key_release_url,
license_update_test_data[0].playback_start_time, license_update_test_data[0].playback_start_time,
license_update_test_data[0].last_playback_time, license_update_test_data[0].last_playback_time,
license_update_test_data[0].grace_period_end_time,
GetAppParameters(license_test_data[0].app_parameters))); GetAppParameters(license_test_data[0].app_parameters)));
} }
@@ -1996,14 +2007,14 @@ TEST_F(DeviceFilesTest, DeleteLicense) {
CdmKeyMessage key_renewal_request; CdmKeyMessage key_renewal_request;
CdmKeyResponse key_renewal_response; CdmKeyResponse key_renewal_response;
std::string release_server_url; std::string release_server_url;
int64_t playback_start_time, last_playback_time; int64_t playback_start_time, last_playback_time, grace_period_end_time;
CdmAppParameterMap app_parameters; CdmAppParameterMap app_parameters;
EXPECT_TRUE(device_files.RetrieveLicense( EXPECT_TRUE(device_files.RetrieveLicense(
license_test_data[0].key_set_id, &license_state, &pssh_data, &key_request, license_test_data[0].key_set_id, &license_state, &pssh_data, &key_request,
&key_response, &key_renewal_request, &key_renewal_response, &key_response, &key_renewal_request, &key_renewal_response,
&release_server_url, &playback_start_time, &last_playback_time, &release_server_url, &playback_start_time, &last_playback_time,
&app_parameters)); &grace_period_end_time, &app_parameters));
EXPECT_EQ(license_test_data[0].license_state, license_state); EXPECT_EQ(license_test_data[0].license_state, license_state);
EXPECT_EQ(license_test_data[0].pssh_data, pssh_data); EXPECT_EQ(license_test_data[0].pssh_data, pssh_data);
EXPECT_EQ(license_test_data[0].key_request, key_request); EXPECT_EQ(license_test_data[0].key_request, key_request);
@@ -2012,6 +2023,7 @@ TEST_F(DeviceFilesTest, DeleteLicense) {
EXPECT_EQ(license_test_data[0].key_response, key_response); EXPECT_EQ(license_test_data[0].key_response, key_response);
EXPECT_EQ(license_test_data[0].playback_start_time, playback_start_time); EXPECT_EQ(license_test_data[0].playback_start_time, playback_start_time);
EXPECT_EQ(license_test_data[0].last_playback_time, last_playback_time); EXPECT_EQ(license_test_data[0].last_playback_time, last_playback_time);
EXPECT_EQ(license_test_data[0].grace_period_end_time, grace_period_end_time);
std::map<std::string, std::string>::iterator itr; std::map<std::string, std::string>::iterator itr;
for (itr = app_parameters.begin(); itr != app_parameters.end(); ++itr) { for (itr = app_parameters.begin(); itr != app_parameters.end(); ++itr) {
EXPECT_NE(license_test_data[0].app_parameters.find(itr->first), EXPECT_NE(license_test_data[0].app_parameters.find(itr->first),

View File

@@ -1093,7 +1093,8 @@ TEST_F(PolicyEngineTest, LicenseExpired_SoftEnforceLoadBeforeExpire) {
OnExpirationUpdate(_, kLicenseStartTime + kLicenseDuration)); OnExpirationUpdate(_, kLicenseStartTime + kLicenseDuration));
policy_engine_->SetLicense(license_); policy_engine_->SetLicense(license_);
policy_engine_->RestorePlaybackTimes(kPlaybackStartTime, kPlaybackStartTime); policy_engine_->RestorePlaybackTimes(kPlaybackStartTime, kPlaybackStartTime,
kPlaybackStartTime);
policy_engine_->OnTimerEvent(); policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
@@ -1117,12 +1118,147 @@ TEST_F(PolicyEngineTest, LicenseExpired_SoftEnforceLoadAfterExpire) {
ExpectSessionKeysChange(kKeyStatusExpired, false); ExpectSessionKeysChange(kKeyStatusExpired, false);
policy_engine_->SetLicense(license_); policy_engine_->SetLicense(license_);
policy_engine_->RestorePlaybackTimes(kPlaybackStartTime, kPlaybackStartTime); policy_engine_->RestorePlaybackTimes(kPlaybackStartTime, kPlaybackStartTime,
kPlaybackStartTime);
policy_engine_->OnTimerEvent(); policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
} }
TEST_F(PolicyEngineTest, PlaybackOk_GracePeriod) {
const int64_t kGracePeriod = 300; // 5 minutes
License_Policy* policy = license_.mutable_policy();
policy->set_play_start_grace_period_seconds(kGracePeriod);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kPlaybackStartTime))
.WillOnce(Return(kPlaybackStartTime + kGracePeriod - 5))
.WillOnce(Return(kPlaybackStartTime + kGracePeriod + 5))
.WillOnce(Return(kPlaybackStartTime + kPlaybackDuration - 5))
.WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 5));
InSequence seq;
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration));
EXPECT_CALL(check_, Call(1));
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kPlaybackStartTime + kPlaybackDuration));
EXPECT_CALL(check_, Call(2));
EXPECT_CALL(check_, Call(3));
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(check_, Call(4));
policy_engine_->SetLicense(license_);
policy_engine_->BeginDecryption();
for (int i = 1; i <= 4; ++i) {
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->OnTimerEvent();
check_.Call(i);
}
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
}
TEST_F(PolicyEngineTest, PlaybackOk_GracePeriodWithLoad) {
const int64_t kGracePeriod = 300; // 5 minutes
const int64_t kNewPlaybackStartTime = kPlaybackStartTime + kPlaybackDuration;
License_Policy* policy = license_.mutable_policy();
policy->set_play_start_grace_period_seconds(kGracePeriod);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kNewPlaybackStartTime))
.WillOnce(Return(kNewPlaybackStartTime))
.WillOnce(Return(kNewPlaybackStartTime + kGracePeriod - 5))
.WillOnce(Return(kNewPlaybackStartTime + kGracePeriod + 5))
.WillOnce(Return(kNewPlaybackStartTime + kPlaybackDuration - 5))
.WillOnce(Return(kNewPlaybackStartTime + kPlaybackDuration + 5));
InSequence seq;
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration));
EXPECT_CALL(check_, Call(1));
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kNewPlaybackStartTime + kPlaybackDuration));
EXPECT_CALL(check_, Call(2));
EXPECT_CALL(check_, Call(3));
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(check_, Call(4));
policy_engine_->SetLicense(license_);
policy_engine_->RestorePlaybackTimes(kPlaybackStartTime, kPlaybackStartTime,
0);
policy_engine_->BeginDecryption();
for (int i = 1; i <= 4; ++i) {
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->OnTimerEvent();
check_.Call(i);
}
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
}
TEST_F(PolicyEngineTest, PlaybackOk_GracePeriodWithExpiredLoad) {
const int64_t kGracePeriod = 300; // 5 minutes
const int64_t kNewPlaybackStartTime =
kPlaybackStartTime + kPlaybackDuration + 5;
License_Policy* policy = license_.mutable_policy();
policy->set_play_start_grace_period_seconds(kGracePeriod);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kNewPlaybackStartTime))
.WillOnce(Return(kNewPlaybackStartTime));
InSequence seq;
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration));
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kPlaybackStartTime + kPlaybackDuration));
ExpectSessionKeysChange(kKeyStatusExpired, false);
policy_engine_->SetLicense(license_);
policy_engine_->RestorePlaybackTimes(kPlaybackStartTime, kPlaybackStartTime,
kPlaybackStartTime);
policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
}
TEST_F(PolicyEngineTest, PlaybackOk_CanStoreGracePeriod) {
const int64_t kGracePeriod = 300; // 5 minutes
License_Policy* policy = license_.mutable_policy();
policy->set_play_start_grace_period_seconds(kGracePeriod);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kPlaybackStartTime))
.WillOnce(Return(kPlaybackStartTime + 50))
.WillOnce(Return(kPlaybackStartTime + kGracePeriod + 2));
InSequence seq;
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration));
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kPlaybackStartTime + kPlaybackDuration));
policy_engine_->SetLicense(license_);
policy_engine_->BeginDecryption();
policy_engine_->OnTimerEvent();
EXPECT_EQ(0, policy_engine_->GetGracePeriodEndTime());
policy_engine_->OnTimerEvent();
EXPECT_EQ(kPlaybackStartTime, policy_engine_->GetGracePeriodEndTime());
}
class PolicyEngineKeyAllowedUsageTest : public PolicyEngineTest { class PolicyEngineKeyAllowedUsageTest : public PolicyEngineTest {
protected: protected:
enum KeyFlag { enum KeyFlag {