Corrections to license policy handling and reporting

If a key query occurred before a license was received an UNKNOWN_ERROR was
returned. This now succeeds but returns no information (an empty container).

Also licenses that were already expired when received were not marked as such.
This did not cause violations in playback rules but caused an exception when
they were queried.

[ Merge of https://widevine-internal-review.googlesource.com/#/c/12300
  from wv git repo ]

b/18843625

Change-Id: I6990765c15e519ddf203a2fd8f0a130306f090a6
This commit is contained in:
Rahul Frias
2015-01-09 00:28:56 -08:00
parent 61db592610
commit db1382e0a3
2 changed files with 87 additions and 10 deletions

View File

@@ -163,15 +163,14 @@ void PolicyEngine::UpdateLicense(
policy_max_duration_seconds_ = policy_.license_duration_seconds();
}
if (!policy_.can_play()) {
int64_t current_time = clock_->GetCurrentTime();
if (!policy_.can_play() ||
IsLicenseDurationExpired(current_time) ||
IsPlaybackDurationExpired(current_time)) {
license_state_ = kLicenseStateExpired;
return;
}
int64_t current_time = clock_->GetCurrentTime();
if (IsLicenseDurationExpired(current_time)) return;
if (IsPlaybackDurationExpired(current_time)) return;
// Update state
if (current_time >= license_start_time_) {
license_state_ = kLicenseStateCanPlay;
@@ -216,8 +215,10 @@ CdmResponseType PolicyEngine::Query(CdmQueryMap* key_info) {
std::stringstream ss;
int64_t current_time = clock_->GetCurrentTime();
if (license_state_ == kLicenseStateInitial)
return UNKNOWN_ERROR;
if (license_state_ == kLicenseStateInitial) {
key_info->clear();
return NO_ERROR;
}
(*key_info)[QUERY_KEY_LICENSE_TYPE] =
license_id_.type() == video_widevine_server::sdk::STREAMING ?

View File

@@ -135,7 +135,8 @@ TEST_F(PolicyEngineTest, PlaybackFailed_CanPlayFalse) {
policy->set_can_play(false);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1));
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kLicenseStartTime + 5));
policy_engine_->SetLicense(license_);
EXPECT_FALSE(policy_engine_->CanDecrypt(kKeyId));
@@ -825,12 +826,26 @@ TEST_F(PolicyEngineTest, PlaybackOk_RenewedWithUsage) {
EXPECT_TRUE(policy_engine_->CanDecrypt(kKeyId));
}
TEST_F(PolicyEngineTest, QueryFailed_LicenseNotReceived) {
TEST_F(PolicyEngineTest, QuerySuccess_LicenseNotReceived) {
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime));
CdmQueryMap query_info;
EXPECT_EQ(UNKNOWN_ERROR, policy_engine_->Query(&query_info));
EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info));
EXPECT_EQ(0, query_info.size());
}
TEST_F(PolicyEngineTest, QuerySuccess_LicenseStartTimeNotSet) {
license_.clear_license_start_time();
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1));
policy_engine_->SetLicense(license_);
CdmQueryMap query_info;
EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info));
EXPECT_EQ(0, query_info.size());
}
TEST_F(PolicyEngineTest, QuerySuccess) {
@@ -1001,6 +1016,66 @@ TEST_F(PolicyEngineTest, QuerySuccess_Offline) {
EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]);
}
TEST_F(PolicyEngineTest, QuerySuccess_InitialRentalDurationExpired) {
License_Policy* policy = license_.mutable_policy();
policy->set_rental_duration_seconds(kLowDuration);
policy->set_license_duration_seconds(kHighDuration);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + kLowDuration + 1))
.WillOnce(Return(kLicenseStartTime + kLowDuration + 5));
policy_engine_->SetLicense(license_);
EXPECT_FALSE(policy_engine_->CanDecrypt(kKeyId));
CdmQueryMap query_info;
EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info));
EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]);
EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]);
EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]);
EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]);
int64_t remaining_time;
std::istringstream ss;
ss.str(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING]);
ss >> remaining_time;
EXPECT_EQ(0, remaining_time);
ss.clear();
ss.str(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING]);
ss >> remaining_time;
EXPECT_EQ(kPlaybackDuration, remaining_time);
EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]);
}
TEST_F(PolicyEngineTest, QuerySuccess_InitialLicenseDurationExpired) {
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + kStreamingLicenseDuration + 1))
.WillOnce(Return(kLicenseStartTime + kStreamingLicenseDuration + 5));
policy_engine_->SetLicense(license_);
EXPECT_FALSE(policy_engine_->CanDecrypt(kKeyId));
CdmQueryMap query_info;
EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info));
EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]);
EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]);
EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]);
EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]);
int64_t remaining_time;
std::istringstream ss;
ss.str(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING]);
ss >> remaining_time;
EXPECT_EQ(0, remaining_time);
ss.clear();
ss.str(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING]);
ss >> remaining_time;
EXPECT_EQ(kPlaybackDuration, remaining_time);
EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]);
}
TEST_F(PolicyEngineTest, QuerySuccess_CanPlayFalse) {
LicenseIdentification* id = license_.mutable_id();
id->set_type(OFFLINE);
@@ -1014,6 +1089,7 @@ TEST_F(PolicyEngineTest, QuerySuccess_CanPlayFalse) {
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kLicenseStartTime + 5))
.WillOnce(Return(kLicenseStartTime + 100));
policy_engine_->SetLicense(license_);