Files
ce_cdm/core/test/policy_engine_unittest.cpp
2024-03-29 10:49:35 -07:00

5168 lines
202 KiB
C++

// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine License
// Agreement.
#include <limits.h>
#include <algorithm>
#include <memory>
#include <string>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "crypto_key.h"
#include "license.h"
#include "mock_clock.h"
#include "policy_engine.h"
#include "test_base.h"
#include "test_printers.h"
#include "wv_cdm_constants.h"
#include "wv_cdm_event_listener.h"
namespace wvcdm {
using namespace testing;
namespace {
const int64_t kLicenseStartTime = 1413517500; // ~ 01/01/2013
const int64_t kPlaybackStartTime = kLicenseStartTime + 5;
const int64_t kRentalDuration = 604800; // 7 days
const int64_t kPlaybackDuration = 172800; // 48 hours
const int64_t kLicenseDuration = kRentalDuration + kPlaybackDuration;
const int64_t kLicenseRenewalPeriod = 120; // 2 minutes
const int64_t kLicenseRenewalRetryInterval = 30; // 30 seconds
const int64_t kLicenseRenewalRecoveryDuration = 30; // 30 seconds
const int64_t kLowDuration = 300; // 5 minutes
const int64_t kHighDuration =
std::max(std::max(kRentalDuration, kPlaybackDuration), kLicenseDuration);
const int64_t kOneDay = 24 * 60 * 60;
const int64_t kTwoDays = 2 * 24 * 60 * 60;
const int64_t kSevenDays = 7 * 24 * 60 * 60;
const int64_t kFiveSeconds = 5;
const int64_t kTenSeconds = 10;
const int64_t kThirtySeconds = 30;
const int64_t kFortySeconds = 30;
const int64_t kFiveMinutes = 5 * 60;
const int64_t kFifteenMinutes = 15 * 60;
const int64_t kTwoHours = 2 * 60 * 60;
const int64_t kThreeHours = 3 * 60 * 60;
const int64_t kDurationUnlimited = 0;
const video_widevine::License::Policy::TimerDelayBase
kTimerDelayBaseUnspecified = video_widevine::
License_Policy_TimerDelayBase_TIMER_DELAY_BASE_UNSPECIFIED;
const video_widevine::License::Policy::TimerDelayBase
kTimerDelayBaseLicenseStart =
video_widevine::License_Policy_TimerDelayBase_LICENSE_START;
const video_widevine::License::Policy::TimerDelayBase
kTimerDelayBaseLicenseLoad =
video_widevine::License_Policy_TimerDelayBase_LICENSE_LOAD;
const video_widevine::License::Policy::TimerDelayBase
kTimerDelayBaseLicenseFirstDecrypt =
video_widevine::License_Policy_TimerDelayBase_FIRST_DECRYPT;
const char* kRenewalServerUrl =
"https://test.google.com/license/GetCencLicense";
const KeyId kKeyId = "357adc89f1673433c36c621f1b5c41ee";
const KeyId kEntitlementKeyId = "entitlementkeyid";
const KeyId kAnotherKeyId = "another_key_id";
const KeyId kSomeRandomKeyId = "some_random_key_id";
const KeyId kUnknownKeyId = "some_random_unknown_key_id";
const CdmSessionId kSessionId = "mock_session_id";
const uint32_t kOemCryptoV16 = 16;
const uint32_t kOemCryptoV18 = 18;
int64_t GetLicenseRenewalDelay(int64_t license_duration) {
return license_duration > kLicenseRenewalPeriod
? license_duration - kLicenseRenewalPeriod
: 0;
}
class MockCryptoSession : public CryptoSession {
public:
MockCryptoSession(metrics::CryptoMetrics* crypto_metrics)
: CryptoSession(crypto_metrics) {}
MOCK_METHOD(bool, IsOpen, (), (override));
MOCK_METHOD(const std::string&, request_id, (), (override));
MOCK_METHOD(bool, HasUsageTableSupport, (bool*), (override));
MOCK_METHOD(bool, GetSupportedCertificateTypes, (SupportedCertificateTypes*),
(override));
MOCK_METHOD(bool, GetApiVersion, (uint32_t*), (override));
MOCK_METHOD(CdmResponseType, GenerateNonce, (uint32_t*), (override));
MOCK_METHOD(CdmResponseType, PrepareAndSignLicenseRequest,
(const std::string&, std::string*, std::string*, bool&,
OEMCrypto_SignatureHashAlgorithm&),
(override));
MOCK_METHOD(CdmResponseType, LoadEntitledContentKeys,
(const std::vector<CryptoKey>& key_array), (override));
MOCK_METHOD(bool, GetResourceRatingTier, (uint32_t*), (override));
MOCK_METHOD(bool, GetWatermarkingSupport, (CdmWatermarkingSupport*),
(override));
MOCK_METHOD(bool, GetBuildInformation, (std::string*), (override));
MOCK_METHOD(CdmResponseType, GetHdcpCapabilities,
(HdcpCapability*, HdcpCapability*), (override));
CdmSecurityLevel GetSecurityLevel() override { return kSecurityLevelL1; }
};
class MockCdmEventListener : public WvCdmEventListener {
public:
MOCK_METHOD(void, OnSessionRenewalNeeded, (const CdmSessionId& session_id),
(override));
MOCK_METHOD(void, OnSessionKeysChange,
(const CdmSessionId& session_id,
const CdmKeyStatusMap& keys_status, bool has_new_usable_key),
(override));
MOCK_METHOD(void, OnExpirationUpdate,
(const CdmSessionId& session_id, int64_t new_expiry_time_seconds),
(override));
};
} // namespace
// protobuf generated classes.
using video_widevine::License;
using video_widevine::License_Policy;
using video_widevine::LicenseIdentification;
using video_widevine::OFFLINE;
using video_widevine::STREAMING;
// gmock methods
using ::testing::_;
using ::testing::InSequence;
using ::testing::MockFunction;
using ::testing::Pair;
using ::testing::Return;
using ::testing::StrictMock;
using ::testing::UnorderedElementsAre;
class PolicyEngineTest : public WvCdmTestBase {
public:
PolicyEngineTest()
: crypto_session_(new MockCryptoSession(&dummy_metrics_)) {}
protected:
void SetUp() override {
WvCdmTestBase::SetUp();
policy_engine_.reset(new PolicyEngine(kSessionId, &mock_event_listener_,
crypto_session_.get()));
InjectMockClock();
license_.set_license_start_time(kLicenseStartTime);
LicenseIdentification* id = license_.mutable_id();
id->set_version(1);
id->set_type(STREAMING);
License::KeyContainer* key = license_.add_key();
key->set_type(License::KeyContainer::CONTENT);
key->set_id(kKeyId);
License_Policy* policy = license_.mutable_policy();
policy->set_can_play(true);
policy->set_can_persist(false);
policy->set_can_renew(false);
// This is similar to an OFFLINE policy.
policy->set_rental_duration_seconds(kRentalDuration);
policy->set_playback_duration_seconds(kPlaybackDuration);
policy->set_license_duration_seconds(kLicenseDuration);
policy->set_renewal_recovery_duration_seconds(
kLicenseRenewalRecoveryDuration);
policy->set_renewal_server_url(kRenewalServerUrl);
policy->set_renewal_delay_seconds(0);
policy->set_renewal_retry_interval_seconds(kLicenseRenewalRetryInterval);
policy->set_renew_with_usage(false);
}
void InjectMockClock() {
mock_clock_ = new MockClock();
policy_engine_->set_clock(mock_clock_);
}
void ResetPolicyEngine(MockClock* mock_clock) {
policy_engine_.reset(new PolicyEngine(kSessionId, &mock_event_listener_,
crypto_session_.get()));
policy_engine_->set_clock(mock_clock);
}
void ExpectSessionKeysChange(CdmKeyStatus expected_key_status,
bool expected_has_new_usable_key) {
EXPECT_CALL(
mock_event_listener_,
OnSessionKeysChange(
kSessionId, UnorderedElementsAre(Pair(kKeyId, expected_key_status)),
expected_has_new_usable_key));
}
void ExpectSessionKeysChange(CdmKeyStatus expected_key_status,
bool expected_has_new_usable_key,
int repetitions) {
EXPECT_CALL(
mock_event_listener_,
OnSessionKeysChange(
kSessionId, UnorderedElementsAre(Pair(kKeyId, expected_key_status)),
expected_has_new_usable_key))
.Times(repetitions);
}
void ExpectSessionKeysChange(CdmKeyStatus expected_key_status,
bool expected_has_new_usable_key,
KeyId expected_keyid) {
EXPECT_CALL(
mock_event_listener_,
OnSessionKeysChange(kSessionId,
UnorderedElementsAre(Pair(std::move(expected_keyid),
expected_key_status)),
expected_has_new_usable_key));
}
void ExpectSessionKeysChange(CdmKeyStatus expected_key1_status,
CdmKeyStatus expected_key2_status,
bool expected_has_new_usable_key) {
EXPECT_CALL(
mock_event_listener_,
OnSessionKeysChange(
kSessionId,
UnorderedElementsAre(Pair(kKeyId, expected_key1_status),
Pair(kAnotherKeyId, expected_key2_status)),
expected_has_new_usable_key));
}
void SetCdmSecurityLevel(CdmSecurityLevel security_level) {
policy_engine_->SetSecurityLevelForTest(security_level);
}
metrics::CryptoMetrics dummy_metrics_;
std::unique_ptr<MockCryptoSession> crypto_session_;
StrictMock<MockCdmEventListener> mock_event_listener_;
MockClock* mock_clock_;
std::unique_ptr<PolicyEngine> policy_engine_;
License license_;
MockFunction<void(int i)> check_;
};
class PolicyEngineTestV16 : public PolicyEngineTest {
public:
PolicyEngineTestV16() {}
protected:
void SetUp() override {
EXPECT_CALL(*crypto_session_, GetApiVersion(_))
.WillRepeatedly(DoAll(SetArgPointee<0>(kOemCryptoV16), Return(true)));
PolicyEngineTest::SetUp();
}
};
class PolicyEngineTestV18 : public PolicyEngineTest {
public:
PolicyEngineTestV18() {}
protected:
void SetUp() override {
EXPECT_CALL(*crypto_session_, GetApiVersion(_))
.WillRepeatedly(DoAll(SetArgPointee<0>(kOemCryptoV18), Return(true)));
PolicyEngineTest::SetUp();
}
};
TEST_F(PolicyEngineTest, NoLicense) {
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
}
// TODO(b/256021697): Migrate to v16 or remove this test.
TEST_F(PolicyEngineTest,
DISABLED_PlaybackSuccess_EntitlementLicenseExpiration_V15) {
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kPlaybackStartTime))
.WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 10))
.WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 11));
ExpectSessionKeysChange(kKeyStatusUsable, true, kEntitlementKeyId);
ExpectSessionKeysChange(kKeyStatusExpired, false, kEntitlementKeyId);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration));
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kPlaybackStartTime + kPlaybackDuration));
License::KeyContainer* key = license_.mutable_key(0);
key->set_type(License::KeyContainer::ENTITLEMENT);
key->set_id(kEntitlementKeyId);
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
std::vector<WidevinePsshData_EntitledKey> entitled_keys(1);
entitled_keys[0].set_entitlement_key_id(kEntitlementKeyId);
entitled_keys[0].set_key_id(kKeyId);
policy_engine_->SetEntitledLicenseKeys(entitled_keys);
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
}
// TODO(b/256021697): Migrate to v16 or remove this test.
TEST_F(PolicyEngineTest, DISABLED_PlaybackSuccess_StreamingLicense_V15) {
License_Policy* policy = license_.mutable_policy();
policy->set_license_duration_seconds(kLowDuration);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kPlaybackStartTime))
.WillOnce(Return(kLicenseStartTime + 10));
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kLowDuration));
// TODO(b/256021697): Test is failing after migrating to v16.
// The value passed to OnExpirationUpdate() are not the same.
// Current expectation: kLicenseStartTime + kLowDuration (license duration)
// Actual: kLicenseStart + kRentalDuration
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
}
// TODO(b/256021697): Migrate to v16 or remove this test.
TEST_F(PolicyEngineTest, DISABLED_PlaybackFailed_RepeatedRenewFailures_V15) {
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(true);
const int64_t license_renewal_delay =
GetLicenseRenewalDelay(kLicenseDuration);
policy->set_renewal_delay_seconds(license_renewal_delay);
policy->clear_rental_duration_seconds();
policy->clear_playback_duration_seconds();
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kPlaybackStartTime))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay - 10))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay + 10))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay + 20))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay + 40))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay + 50))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay + 70))
.WillOnce(Return(kLicenseStartTime + kLicenseDuration - 15))
.WillOnce(Return(kLicenseStartTime + kLicenseDuration));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kLicenseDuration));
EXPECT_CALL(check_, Call(1));
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(2));
EXPECT_CALL(check_, Call(3));
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(4));
EXPECT_CALL(check_, Call(5));
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(6));
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(7));
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(check_, Call(8));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
for (int i = 1; i <= 8; ++i) {
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->OnTimerEvent();
check_.Call(i);
}
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
}
// TODO(b/256021697): Migrate to v16 or remove this test.
TEST_F(PolicyEngineTest, DISABLED_PlaybackOk_RenewSuccessAfterExpiry_V15) {
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(true);
policy->set_license_duration_seconds(kLowDuration);
int64_t license_renewal_delay = GetLicenseRenewalDelay(kLowDuration);
policy->set_renewal_delay_seconds(license_renewal_delay);
policy->clear_rental_duration_seconds();
int64_t new_license_start_time = kPlaybackStartTime + kPlaybackDuration + 10;
int64_t new_playback_duration = kPlaybackDuration + 100;
int64_t new_license_duration = kLicenseDuration + 100;
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kPlaybackStartTime))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay - 10))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay + 10))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay + 20))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay + 40))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay + 50))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay + 70))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay + 80))
.WillOnce(Return(kLicenseStartTime + kLowDuration - 10))
.WillOnce(Return(kLicenseStartTime + kLowDuration + 1))
.WillOnce(Return(new_license_start_time))
.WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 20));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kLowDuration));
EXPECT_CALL(check_, Call(1));
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(2));
EXPECT_CALL(check_, Call(3));
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(4));
EXPECT_CALL(check_, Call(5));
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(6));
EXPECT_CALL(check_, Call(7));
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(8));
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(check_, Call(9));
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(
mock_event_listener_,
OnExpirationUpdate(_, kPlaybackStartTime + new_playback_duration));
EXPECT_CALL(check_, Call(10));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
for (int i = 1; i <= 9; ++i) {
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->OnTimerEvent();
check_.Call(i);
}
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
license_.set_license_start_time(new_license_start_time);
LicenseIdentification* id = license_.mutable_id();
id->set_version(2);
policy->set_playback_duration_seconds(new_playback_duration);
policy->set_license_duration_seconds(new_license_duration);
policy_engine_->UpdateLicense(license_, false);
policy_engine_->OnTimerEvent();
check_.Call(10);
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
}
// TODO(b/256021697): Migrate to v16 or remove this test.
TEST_F(PolicyEngineTest, DISABLED_PlaybackOk_RenewSuccessAfterFailures_V15) {
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(true);
policy->clear_rental_duration_seconds();
policy->clear_playback_duration_seconds();
int64_t license_renewal_delay = GetLicenseRenewalDelay(kLicenseDuration);
policy->set_renewal_delay_seconds(license_renewal_delay);
int64_t new_license_start_time =
kLicenseStartTime + license_renewal_delay + 55;
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kLicenseStartTime + 5))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay - 10))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay + 10))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay + 20))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay + 40))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay + 50))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay + 55))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay + 67))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay + 200));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kLicenseDuration));
EXPECT_CALL(check_, Call(1));
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(2));
EXPECT_CALL(check_, Call(3));
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(4));
EXPECT_CALL(check_, Call(5));
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, new_license_start_time + kLicenseDuration));
EXPECT_CALL(check_, Call(6));
EXPECT_CALL(check_, Call(7));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
for (int i = 1; i <= 5; ++i) {
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->OnTimerEvent();
check_.Call(i);
}
license_.set_license_start_time(new_license_start_time);
LicenseIdentification* id = license_.mutable_id();
id->set_version(2);
policy_engine_->UpdateLicense(license_, false);
for (int i = 6; i <= 7; ++i) {
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->OnTimerEvent();
check_.Call(i);
}
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
}
// TODO(b/256021697): Migrate to v16 or remove this test.
// Note: Test passes in without v15 timers.
TEST_F(PolicyEngineTest, DISABLED_PlaybackOk_RenewedWithUsage_V15) {
int64_t new_license_start_time = kLicenseStartTime + 10;
int64_t new_playback_duration = kPlaybackDuration + 100;
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(true);
policy->set_renew_with_usage(true);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kLicenseStartTime + 3))
.WillOnce(Return(kPlaybackStartTime))
.WillOnce(Return(kLicenseStartTime + 10))
.WillOnce(Return(kLicenseStartTime + 20))
.WillOnce(Return(kLicenseStartTime + 40));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
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(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(2));
EXPECT_CALL(
mock_event_listener_,
OnExpirationUpdate(_, kPlaybackStartTime + new_playback_duration));
EXPECT_CALL(check_, Call(3));
policy_engine_->SetLicense(license_, false);
policy_engine_->OnTimerEvent();
check_.Call(1);
policy_engine_->BeginDecryption();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->OnTimerEvent();
check_.Call(2);
license_.set_license_start_time(new_license_start_time);
license_.mutable_policy()->set_playback_duration_seconds(
new_playback_duration);
policy->set_renew_with_usage(false);
LicenseIdentification* id = license_.mutable_id();
id->set_version(2);
policy_engine_->UpdateLicense(license_, false);
policy_engine_->OnTimerEvent();
check_.Call(3);
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
}
TEST_F(PolicyEngineTestV16, MultipleKeysInLicense) {
const char kSigningKeyId[] = "signing_key";
license_.clear_key();
License::KeyContainer* content_key = license_.add_key();
content_key->set_type(License::KeyContainer::CONTENT);
content_key->set_id(kKeyId);
License::KeyContainer* non_content_key = license_.add_key();
non_content_key->set_type(License::KeyContainer::SIGNING);
non_content_key->set_id(kSigningKeyId);
License::KeyContainer* content_key_without_id = license_.add_key();
content_key_without_id->set_type(License::KeyContainer::CONTENT);
License::KeyContainer* another_content_key = license_.add_key();
another_content_key->set_type(License::KeyContainer::CONTENT);
another_content_key->set_id(kAnotherKeyId);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
ExpectSessionKeysChange(kKeyStatusUsable, kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, _));
policy_engine_->SetLicense(license_, false);
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_TRUE(policy_engine_->CanDecryptContent(kAnotherKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSigningKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
}
// TODO(b/256021697): Migrate to v16 or remove this test.
TEST_F(PolicyEngineTest, DISABLED_PlaybackOk_SoftEnforcePlaybackDuration_V15) {
License_Policy* policy = license_.mutable_policy();
policy->set_soft_enforce_playback_duration(true);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kPlaybackStartTime))
.WillOnce(Return(kPlaybackStartTime + kPlaybackDuration - 5))
.WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 5))
.WillOnce(Return(kLicenseStartTime + kLicenseDuration - 5))
.WillOnce(Return(kLicenseStartTime + kLicenseDuration + 5));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence seq;
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration));
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kLicenseDuration));
EXPECT_CALL(check_, Call(1));
EXPECT_CALL(check_, Call(2));
EXPECT_CALL(check_, Call(3));
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(check_, Call(4));
policy_engine_->SetLicense(license_, false);
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));
}
// TODO(b/256021697): Migrate to v16 or remove this test.
TEST_F(PolicyEngineTest,
DISABLED_LicenseExpired_SoftEnforceLoadBeforeExpire_V15) {
License_Policy* policy = license_.mutable_policy();
policy->set_soft_enforce_playback_duration(true);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kPlaybackStartTime + kPlaybackDuration - 5))
.WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 10));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence seq;
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kLicenseDuration));
policy_engine_->SetLicense(license_, true);
policy_engine_->RestorePlaybackTimes(kPlaybackStartTime, kPlaybackStartTime,
kPlaybackStartTime);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
}
// TODO(b/256021697): Migrate to v16 or remove this test.
TEST_F(PolicyEngineTest,
DISABLED_LicenseExpired_SoftEnforceLoadAfterExpire_V15) {
License_Policy* policy = license_.mutable_policy();
policy->set_soft_enforce_playback_duration(true);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 5))
.WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 10));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence seq;
ExpectSessionKeysChange(kKeyStatusExpired, false);
policy_engine_->SetLicense(license_, true);
policy_engine_->RestorePlaybackTimes(kPlaybackStartTime, kPlaybackStartTime,
kPlaybackStartTime);
policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
}
// TODO(b/256021697): Migrate to v16 or remove this test.
// Note: Test passes in without v15 timers.
TEST_F(PolicyEngineTest, DISABLED_PlaybackOk_RestoreWithoutPlaybackTimes_V15) {
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kLicenseStartTime + 15))
.WillOnce(Return(kLicenseStartTime + 30));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence seq;
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration));
policy_engine_->SetLicense(license_, true);
policy_engine_->OnTimerEvent();
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
}
struct KeySecurityLevelParams {
bool is_security_level_set;
License::KeyContainer::SecurityLevel security_level;
bool expect_can_L1_use_key;
bool expect_can_L2_use_key;
bool expect_can_L3_use_key;
bool expect_can_level_unknown_use_key;
};
const KeySecurityLevelParams kKeySecurityTestVectors[] = {
{false, License::KeyContainer::HW_SECURE_ALL, true, true, true, true},
{true, License::KeyContainer::SW_SECURE_CRYPTO, true, true, true, false},
{true, License::KeyContainer::SW_SECURE_DECODE, true, true, true, false},
{true, License::KeyContainer::HW_SECURE_CRYPTO, true, true, false, false},
{true, License::KeyContainer::HW_SECURE_DECODE, true, false, false, false},
{true, License::KeyContainer::HW_SECURE_ALL, true, false, false, false},
};
class PolicyEngineKeySecurityLevelTest
: public PolicyEngineTestV16,
public ::testing::WithParamInterface<const KeySecurityLevelParams*> {};
TEST_P(PolicyEngineKeySecurityLevelTest, CanUseKeyForSecurityLeve) {
const KeySecurityLevelParams* param = GetParam();
license_.clear_key();
License::KeyContainer* content_key = license_.add_key();
content_key->set_type(License::KeyContainer::CONTENT);
content_key->set_id(kKeyId);
if (param->is_security_level_set)
content_key->set_level(param->security_level);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, _));
SetCdmSecurityLevel(kSecurityLevelL1);
policy_engine_->SetLicense(license_, false);
EXPECT_EQ(param->expect_can_L1_use_key,
policy_engine_->CanUseKeyForSecurityLevel(kKeyId));
SetCdmSecurityLevel(kSecurityLevelL2);
policy_engine_->SetLicense(license_, false);
EXPECT_EQ(param->expect_can_L2_use_key,
policy_engine_->CanUseKeyForSecurityLevel(kKeyId));
SetCdmSecurityLevel(kSecurityLevelL3);
policy_engine_->SetLicense(license_, false);
EXPECT_EQ(param->expect_can_L3_use_key,
policy_engine_->CanUseKeyForSecurityLevel(kKeyId));
SetCdmSecurityLevel(kSecurityLevelUnknown);
policy_engine_->SetLicense(license_, false);
EXPECT_EQ(param->expect_can_level_unknown_use_key,
policy_engine_->CanUseKeyForSecurityLevel(kKeyId));
}
INSTANTIATE_TEST_SUITE_P(PolicyEngine, PolicyEngineKeySecurityLevelTest,
::testing::Range(&kKeySecurityTestVectors[0],
&kKeySecurityTestVectors[5]));
class PolicyEngineKeyAllowedUsageTest : public PolicyEngineTestV16 {
protected:
enum KeyFlag { kKeyFlagNull, kKeyFlagFalse, kKeyFlagTrue };
static const KeyFlag kEncryptNull = kKeyFlagNull;
static const KeyFlag kEncryptFalse = kKeyFlagFalse;
static const KeyFlag kEncryptTrue = kKeyFlagTrue;
static const KeyFlag kDecryptNull = kKeyFlagNull;
static const KeyFlag kDecryptFalse = kKeyFlagFalse;
static const KeyFlag kDecryptTrue = kKeyFlagTrue;
static const KeyFlag kSignNull = kKeyFlagNull;
static const KeyFlag kSignFalse = kKeyFlagFalse;
static const KeyFlag kSignTrue = kKeyFlagTrue;
static const KeyFlag kVerifyNull = kKeyFlagNull;
static const KeyFlag kVerifyFalse = kKeyFlagFalse;
static const KeyFlag kVerifyTrue = kKeyFlagTrue;
static const KeyFlag kContentSecureFalse = kKeyFlagFalse;
static const KeyFlag kContentSecureTrue = kKeyFlagTrue;
static const KeyFlag kContentClearFalse = kKeyFlagFalse;
static const KeyFlag kContentClearTrue = kKeyFlagTrue;
void ExpectAllowedContentKeySettings(const CdmKeyAllowedUsage& key_usage,
KeyFlag secure, KeyFlag clear,
CdmKeySecurityLevel key_security_level) {
EXPECT_EQ(key_usage.decrypt_to_secure_buffer, secure == kKeyFlagTrue);
EXPECT_EQ(key_usage.decrypt_to_clear_buffer, clear == kKeyFlagTrue);
EXPECT_EQ(key_usage.key_security_level_, key_security_level);
EXPECT_FALSE(key_usage.generic_encrypt);
EXPECT_FALSE(key_usage.generic_decrypt);
EXPECT_FALSE(key_usage.generic_sign);
EXPECT_FALSE(key_usage.generic_verify);
}
void ExpectAllowedOperatorKeySettings(const CdmKeyAllowedUsage& key_usage,
KeyFlag encrypt, KeyFlag decrypt,
KeyFlag sign, KeyFlag verify) {
EXPECT_FALSE(key_usage.decrypt_to_secure_buffer);
EXPECT_FALSE(key_usage.decrypt_to_clear_buffer);
EXPECT_EQ(key_usage.generic_encrypt, encrypt == kKeyFlagTrue);
EXPECT_EQ(key_usage.generic_decrypt, decrypt == kKeyFlagTrue);
EXPECT_EQ(key_usage.generic_sign, sign == kKeyFlagTrue);
EXPECT_EQ(key_usage.generic_verify, verify == kKeyFlagTrue);
}
void ExpectSecureContentKey(const KeyId& key_id,
CdmKeySecurityLevel key_security_level) {
CdmKeyAllowedUsage key_usage;
EXPECT_EQ(NO_ERROR,
policy_engine_->QueryKeyAllowedUsage(key_id, &key_usage));
ExpectAllowedContentKeySettings(key_usage, kContentSecureTrue,
kContentSecureFalse, key_security_level);
}
void ExpectLessSecureContentKey(const KeyId& key_id,
CdmKeySecurityLevel key_security_level) {
CdmKeyAllowedUsage key_usage;
EXPECT_EQ(NO_ERROR,
policy_engine_->QueryKeyAllowedUsage(key_id, &key_usage));
ExpectAllowedContentKeySettings(key_usage, kContentSecureTrue,
kContentSecureTrue, key_security_level);
}
void ExpectOperatorSessionKey(const KeyId& key_id, KeyFlag encrypt,
KeyFlag decrypt, KeyFlag sign, KeyFlag verify) {
CdmKeyAllowedUsage key_usage;
EXPECT_EQ(NO_ERROR,
policy_engine_->QueryKeyAllowedUsage(key_id, &key_usage));
ExpectAllowedOperatorKeySettings(key_usage, encrypt, decrypt, sign, verify);
}
void AddOperatorSessionKey(const KeyId& key_id, KeyFlag encrypt,
KeyFlag decrypt, KeyFlag sign, KeyFlag verify) {
License::KeyContainer* non_content_key = license_.add_key();
non_content_key->set_type(License::KeyContainer::OPERATOR_SESSION);
non_content_key->set_id(key_id);
License::KeyContainer::OperatorSessionKeyPermissions* permissions =
non_content_key->mutable_operator_session_key_permissions();
if (encrypt != kKeyFlagNull) {
permissions->set_allow_encrypt(encrypt == kKeyFlagTrue);
}
if (decrypt != kKeyFlagNull) {
permissions->set_allow_decrypt(decrypt == kKeyFlagTrue);
}
if (sign != kKeyFlagNull) {
permissions->set_allow_sign(sign == kKeyFlagTrue);
}
if (verify != kKeyFlagNull) {
permissions->set_allow_signature_verify(verify == kKeyFlagTrue);
}
}
};
TEST_F(PolicyEngineKeyAllowedUsageTest, AllowedUsageBasic) {
const KeyId kGenericKeyId = "oper_session_key";
license_.clear_key();
// most secure
License::KeyContainer* content_key = license_.add_key();
content_key->set_type(License::KeyContainer::CONTENT);
content_key->set_id(kKeyId);
content_key->set_level(License::KeyContainer::HW_SECURE_ALL);
SetCdmSecurityLevel(kSecurityLevelL1);
// generic operator session key (sign)
AddOperatorSessionKey(kGenericKeyId, kEncryptNull, kDecryptNull, kSignTrue,
kVerifyNull);
License::KeyContainer* content_key_without_id = license_.add_key();
content_key_without_id->set_type(License::KeyContainer::CONTENT);
// default level - less secure
License::KeyContainer* another_content_key = license_.add_key();
another_content_key->set_type(License::KeyContainer::CONTENT);
another_content_key->set_id(kAnotherKeyId);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
ExpectSessionKeysChange(kKeyStatusUsable, kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, _));
policy_engine_->SetLicense(license_, false);
ExpectSecureContentKey(kKeyId, kHardwareSecureAll);
ExpectLessSecureContentKey(kAnotherKeyId, kKeySecurityLevelUnset);
ExpectOperatorSessionKey(kGenericKeyId, kEncryptNull, kDecryptNull, kSignTrue,
kVerifyNull);
CdmKeyAllowedUsage key_usage;
EXPECT_EQ(KEY_NOT_FOUND_1,
policy_engine_->QueryKeyAllowedUsage(kUnknownKeyId, &key_usage));
}
TEST_F(PolicyEngineKeyAllowedUsageTest, AllowedUsageGeneric) {
const KeyId kGenericEncryptKeyId = "oper_session_key_1";
const KeyId kGenericDecryptKeyId = "oper_session_key_2";
const KeyId kGenericSignKeyId = "oper_session_key_3";
const KeyId kGenericVerifyKeyId = "oper_session_key_4";
const KeyId kGenericFullKeyId = "oper_session_key_5";
const KeyId kGenericExplicitKeyId = "oper_session_key_6";
license_.clear_key();
// more secure
License::KeyContainer* content_key = license_.add_key();
content_key->set_type(License::KeyContainer::CONTENT);
content_key->set_id(kKeyId);
content_key->set_level(License::KeyContainer::HW_SECURE_DECODE);
// less secure
License::KeyContainer* another_content_key = license_.add_key();
another_content_key->set_type(License::KeyContainer::CONTENT);
another_content_key->set_id(kAnotherKeyId);
another_content_key->set_level(License::KeyContainer::HW_SECURE_CRYPTO);
SetCdmSecurityLevel(kSecurityLevelL1);
// generic operator session keys
AddOperatorSessionKey(kGenericSignKeyId, kEncryptNull, kDecryptNull,
kSignTrue, kVerifyNull);
AddOperatorSessionKey(kGenericEncryptKeyId, kEncryptTrue, kDecryptNull,
kSignNull, kVerifyNull);
AddOperatorSessionKey(kGenericDecryptKeyId, kEncryptNull, kDecryptTrue,
kSignNull, kVerifyNull);
AddOperatorSessionKey(kGenericVerifyKeyId, kEncryptNull, kDecryptNull,
kSignNull, kVerifyTrue);
AddOperatorSessionKey(kGenericFullKeyId, kEncryptTrue, kDecryptTrue,
kSignTrue, kVerifyTrue);
AddOperatorSessionKey(kGenericExplicitKeyId, kEncryptFalse, kDecryptTrue,
kSignFalse, kVerifyTrue);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
ExpectSessionKeysChange(kKeyStatusUsable, kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, _));
policy_engine_->SetLicense(license_, false);
ExpectSecureContentKey(kKeyId, kHardwareSecureDecode);
ExpectLessSecureContentKey(kAnotherKeyId, kHardwareSecureCrypto);
ExpectOperatorSessionKey(kGenericEncryptKeyId, kEncryptTrue, kDecryptFalse,
kSignFalse, kVerifyFalse);
ExpectOperatorSessionKey(kGenericDecryptKeyId, kEncryptFalse, kDecryptTrue,
kSignFalse, kVerifyFalse);
ExpectOperatorSessionKey(kGenericSignKeyId, kEncryptFalse, kDecryptFalse,
kSignTrue, kVerifyFalse);
ExpectOperatorSessionKey(kGenericVerifyKeyId, kEncryptFalse, kDecryptFalse,
kSignFalse, kVerifyTrue);
ExpectOperatorSessionKey(kGenericFullKeyId, kEncryptTrue, kDecryptTrue,
kSignTrue, kVerifyTrue);
ExpectOperatorSessionKey(kGenericExplicitKeyId, kEncryptFalse, kDecryptTrue,
kSignFalse, kVerifyTrue);
}
class PolicyEngineQueryTest : public PolicyEngineTestV16 {
protected:
void SetUp() override {
PolicyEngineTestV16::SetUp();
policy_engine_.reset(
new PolicyEngine(kSessionId, nullptr, crypto_session_.get()));
InjectMockClock();
// Use a STREAMING license policy.
License_Policy* policy = license_.mutable_policy();
policy->set_license_duration_seconds(kLowDuration);
policy->set_can_renew(true);
policy->set_renewal_delay_seconds(GetLicenseRenewalDelay(kLowDuration));
}
};
// TODO(b/256021697): Migrate to v16 or remove this test.
TEST_F(PolicyEngineQueryTest, DISABLED_QuerySuccess_Offline_V15) {
LicenseIdentification* id = license_.mutable_id();
id->set_type(OFFLINE);
License_Policy* policy = license_.mutable_policy();
policy->set_can_persist(true);
policy->set_can_renew(false);
policy->set_rental_duration_seconds(kRentalDuration);
policy->set_license_duration_seconds(kLicenseDuration);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kLicenseStartTime + 100))
.WillOnce(Return(kLicenseStartTime + 200))
.WillOnce(Return(kLicenseStartTime + 300));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
policy_engine_->SetLicense(license_, false);
policy_engine_->OnTimerEvent();
policy_engine_->BeginDecryption();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
CdmQueryMap query_info;
EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info));
EXPECT_EQ(QUERY_VALUE_OFFLINE, query_info[QUERY_KEY_LICENSE_TYPE]);
EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]);
EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PERSIST_ALLOWED]);
EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_RENEW_ALLOWED]);
EXPECT_EQ(kRentalDuration - 300,
std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING]));
EXPECT_EQ(kPlaybackDuration - 100,
std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING]));
EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]);
}
// TODO(b/256021697): Migrate to v16 or remove this test.
TEST_F(PolicyEngineQueryTest, DISABLED_QuerySuccess_Renew_V15) {
int64_t license_renewal_delay = license_.policy().renewal_delay_seconds();
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kLicenseStartTime + 5))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay - 25))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay + 10))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay + 20))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay +
kLicenseRenewalRetryInterval + 10))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay +
kLicenseRenewalRetryInterval + 15));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
for (int i = 1; i <= 2; ++i) {
policy_engine_->OnTimerEvent();
}
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
license_.set_license_start_time(kLicenseStartTime + license_renewal_delay +
15);
LicenseIdentification* id = license_.mutable_id();
id->set_version(2);
policy_engine_->UpdateLicense(license_, false);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(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]);
EXPECT_EQ(kLowDuration - kLicenseRenewalRetryInterval,
std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING]));
EXPECT_EQ(kPlaybackDuration + 5 - license_renewal_delay -
kLicenseRenewalRetryInterval - 15,
std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING]));
EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]);
}
// TODO(b/256021697): Migrate to v16 or remove this test.
TEST_F(PolicyEngineQueryTest,
DISABLED_QuerySuccess_RenewWithFutureStartTime_V15) {
int64_t license_renewal_delay = license_.policy().renewal_delay_seconds();
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kLicenseStartTime + 5))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay - 25))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay + 10))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay + 20))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay +
kLicenseRenewalRetryInterval + 10))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay +
kLicenseRenewalRetryInterval + 20))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay +
kLicenseRenewalRetryInterval + 30))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay +
kLicenseRenewalRetryInterval + 40));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
for (int i = 1; i <= 2; ++i) {
policy_engine_->OnTimerEvent();
}
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
license_.set_license_start_time(kLicenseStartTime + license_renewal_delay +
kLicenseRenewalRetryInterval + 20);
LicenseIdentification* id = license_.mutable_id();
id->set_version(2);
policy_engine_->UpdateLicense(license_, false);
policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(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]);
EXPECT_EQ(kLowDuration,
std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING]));
EXPECT_EQ(kPlaybackDuration + 5 - license_renewal_delay -
kLicenseRenewalRetryInterval - 20,
std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING]));
EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
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]);
EXPECT_EQ(kLowDuration - 20,
std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING]));
EXPECT_EQ(kPlaybackDuration + 5 - license_renewal_delay -
kLicenseRenewalRetryInterval - 40,
std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING]));
EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]);
}
// These test execise license policy when the license service and client
// both support OEMCrypto v16
TEST_F(PolicyEngineTestV16, PlaybackSuccess_OfflineLicense) {
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kPlaybackStartTime))
.WillOnce(Return(kLicenseStartTime + 10));
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration));
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kPlaybackStartTime + kPlaybackDuration));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(NO_ERROR))));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
}
TEST_F(PolicyEngineTestV16, PlaybackFailed_CanPlayFalse) {
License_Policy* policy = license_.mutable_policy();
policy->set_can_play(false);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kLicenseStartTime + 5))
.WillOnce(Return(kLicenseStartTime + 7));
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
policy_engine_->SetLicense(license_, false);
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->OnTimerEvent();
policy_engine_->BeginDecryption();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
}
TEST_F(PolicyEngineTestV16,
LicenseExpired_RentalDurationExpiredWithoutPlayback) {
License_Policy* policy = license_.mutable_policy();
policy->set_rental_duration_seconds(kLowDuration);
policy->set_license_duration_seconds(kHighDuration);
policy->set_soft_enforce_rental_duration(false);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kPlaybackStartTime))
.WillOnce(Return(kLicenseStartTime + kLowDuration - 1))
.WillOnce(Return(kLicenseStartTime + kLowDuration));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kLowDuration));
EXPECT_CALL(check_, Call(1));
EXPECT_CALL(check_, Call(2));
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(check_, Call(3));
policy_engine_->SetLicense(license_, false);
for (int i = 1; i <= 3; ++i) {
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->OnTimerEvent();
check_.Call(i);
}
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
}
TEST_F(
PolicyEngineTestV16,
LicenseExpired_RentalDurationExpiredWithoutPlayback_SoftEnforceRentalDuration) {
License_Policy* policy = license_.mutable_policy();
policy->set_rental_duration_seconds(kLowDuration);
policy->set_license_duration_seconds(kHighDuration);
policy->set_soft_enforce_rental_duration(true);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kPlaybackStartTime))
.WillOnce(Return(kLicenseStartTime + kLowDuration - 1))
.WillOnce(Return(kLicenseStartTime + kLowDuration));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kLowDuration));
EXPECT_CALL(check_, Call(1));
EXPECT_CALL(check_, Call(2));
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(check_, Call(3));
policy_engine_->SetLicense(license_, false);
for (int i = 1; i <= 3; ++i) {
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->OnTimerEvent();
check_.Call(i);
}
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
}
TEST_F(PolicyEngineTestV16, PlaybackFails_RentalDurationPassedWithPlayback) {
License_Policy* policy = license_.mutable_policy();
policy->set_rental_duration_seconds(kLowDuration);
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kPlaybackStartTime))
.WillOnce(Return(kLicenseStartTime + kLowDuration - 1))
.WillOnce(Return(kLicenseStartTime + kLowDuration + 1));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kLowDuration));
EXPECT_CALL(check_, Call(1));
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(check_, Call(2));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
for (int i = 1; i <= 2; ++i) {
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->OnTimerEvent();
check_.Call(i);
}
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
}
TEST_F(PolicyEngineTestV16,
PlaybackOk_RentalDurationPassedWithPlayback_SoftEnforceRentalDuration) {
License_Policy* policy = license_.mutable_policy();
policy->set_rental_duration_seconds(kLowDuration);
policy->set_soft_enforce_rental_duration(true);
policy->set_soft_enforce_playback_duration(false);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kPlaybackStartTime))
.WillOnce(Return(kLicenseStartTime + kLowDuration - 1))
.WillOnce(Return(kLicenseStartTime + kLowDuration + 1));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kLowDuration));
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kPlaybackStartTime + kPlaybackDuration));
EXPECT_CALL(check_, Call(1));
EXPECT_CALL(check_, Call(2));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
for (int i = 1; i <= 2; ++i) {
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->OnTimerEvent();
check_.Call(i);
}
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
}
TEST_F(PolicyEngineTestV16, PlaybackFails_PlaybackDurationExpired) {
const int64_t playback_start_time = kLicenseStartTime + 10000;
License_Policy* policy = license_.mutable_policy();
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(playback_start_time))
.WillOnce(Return(playback_start_time + kPlaybackDuration - 2))
.WillOnce(Return(playback_start_time + kPlaybackDuration + 2));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration));
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, playback_start_time + kPlaybackDuration));
EXPECT_CALL(check_, Call(1));
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(check_, Call(2));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
for (int i = 1; i <= 2; ++i) {
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->OnTimerEvent();
check_.Call(i);
}
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
}
TEST_F(PolicyEngineTestV16,
PlaybackOk_PlaybackDurationExpired_SoftEnforcePlaybackDuration) {
int64_t playback_start_time = kLicenseStartTime + 10000;
License_Policy* policy = license_.mutable_policy();
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(true);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(playback_start_time))
.WillOnce(Return(playback_start_time + kPlaybackDuration - 2))
.WillOnce(Return(playback_start_time + kPlaybackDuration + 2));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration));
EXPECT_CALL(check_, Call(1));
EXPECT_CALL(check_, Call(2));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
for (int i = 1; i <= 2; ++i) {
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->OnTimerEvent();
check_.Call(i);
}
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
}
// License duration is not enforced with the policy changes introduced in
// OEMCrypto v16. Rental and Playback durations are used for both streaming and
// offline. Verify that License duration expiry does not cause the license
// to expire.
TEST_F(PolicyEngineTestV16, LicenseOk_LicenseDurationExpiredWithoutPlayback) {
License_Policy* policy = license_.mutable_policy();
policy->set_license_duration_seconds(kLowDuration);
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kPlaybackStartTime))
.WillOnce(Return(kLicenseStartTime + kLowDuration - 1))
.WillOnce(Return(kLicenseStartTime + kLowDuration));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration));
EXPECT_CALL(check_, Call(1));
EXPECT_CALL(check_, Call(2));
EXPECT_CALL(check_, Call(3));
policy_engine_->SetLicense(license_, false);
for (int i = 1; i <= 3; ++i) {
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->OnTimerEvent();
check_.Call(i);
}
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
}
TEST_F(PolicyEngineTestV16, LicenseOk_LicenseDurationExpiredWithPlayback) {
License_Policy* policy = license_.mutable_policy();
policy->set_license_duration_seconds(kLowDuration);
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kPlaybackStartTime))
.WillOnce(Return(kPlaybackStartTime + 10))
.WillOnce(Return(kLicenseStartTime + kLowDuration - 1))
.WillOnce(Return(kLicenseStartTime + kLowDuration));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration));
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kPlaybackStartTime + kPlaybackDuration));
EXPECT_CALL(check_, Call(1));
EXPECT_CALL(check_, Call(2));
EXPECT_CALL(check_, Call(3));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
for (int i = 1; i <= 3; ++i) {
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->OnTimerEvent();
check_.Call(i);
}
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
}
TEST_F(PolicyEngineTestV16, PlaybackFails_ExpiryBeforeRenewalDelay) {
License_Policy* policy = license_.mutable_policy();
policy->set_renewal_delay_seconds(kLicenseDuration + 10);
policy->set_can_renew(true);
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kPlaybackStartTime))
.WillOnce(Return(kPlaybackStartTime + kPlaybackDuration - 1))
.WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 1));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration));
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kPlaybackStartTime + kPlaybackDuration));
EXPECT_CALL(check_, Call(1));
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(check_, Call(2));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
for (int i = 1; i <= 2; ++i) {
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->OnTimerEvent();
check_.Call(i);
}
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
}
TEST_F(PolicyEngineTestV16, LicenseOk_RentalDuration0) {
License_Policy* policy = license_.mutable_policy();
policy->set_rental_duration_seconds(UNLIMITED_DURATION);
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kLicenseStartTime + kRentalDuration - 1))
.WillOnce(Return(kLicenseStartTime + kRentalDuration + 10))
.WillOnce(Return(kLicenseStartTime + kLicenseDuration + 1));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, NEVER_EXPIRES));
EXPECT_CALL(check_, Call(1));
EXPECT_CALL(check_, Call(2));
EXPECT_CALL(check_, Call(3));
policy_engine_->SetLicense(license_, false);
for (int i = 1; i <= 3; ++i) {
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->OnTimerEvent();
check_.Call(i);
}
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
}
TEST_F(PolicyEngineTestV16, PlaybackOk_RentalDuration0) {
License_Policy* policy = license_.mutable_policy();
policy->set_rental_duration_seconds(UNLIMITED_DURATION);
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kLicenseStartTime + kRentalDuration - 1))
.WillOnce(Return(kLicenseStartTime + kRentalDuration + 10))
.WillOnce(Return(kLicenseStartTime + kLicenseDuration + 1))
.WillOnce(Return(kLicenseStartTime + kLicenseDuration + 10));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, NEVER_EXPIRES));
EXPECT_CALL(check_, Call(1));
EXPECT_CALL(check_, Call(2));
EXPECT_CALL(check_, Call(3));
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kLicenseDuration + 10 +
kPlaybackDuration));
policy_engine_->SetLicense(license_, false);
for (int i = 1; i <= 3; ++i) {
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->OnTimerEvent();
check_.Call(i);
}
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->BeginDecryption();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
}
TEST_F(PolicyEngineTestV16, PlaybackFails_PlaybackDuration0) {
License_Policy* policy = license_.mutable_policy();
policy->set_playback_duration_seconds(UNLIMITED_DURATION);
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime))
.WillOnce(Return(kPlaybackStartTime))
.WillOnce(Return(kPlaybackStartTime + kPlaybackDuration - 2))
.WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 2))
.WillOnce(Return(kLicenseStartTime + kRentalDuration - 2))
.WillOnce(Return(kLicenseStartTime + kRentalDuration + 2));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration));
EXPECT_CALL(check_, Call(1));
EXPECT_CALL(check_, Call(2));
EXPECT_CALL(check_, Call(3));
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(check_, Call(4));
policy_engine_->SetLicense(license_, false);
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(PolicyEngineTestV16,
PlaybackOk_PlaybackDuration0_SoftEnforceRentalDuration) {
License_Policy* policy = license_.mutable_policy();
policy->set_playback_duration_seconds(UNLIMITED_DURATION);
policy->set_soft_enforce_rental_duration(true);
policy->set_soft_enforce_playback_duration(false);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime))
.WillOnce(Return(kPlaybackStartTime))
.WillOnce(Return(kPlaybackStartTime + kPlaybackDuration - 2))
.WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 2))
.WillOnce(Return(kPlaybackStartTime + kRentalDuration - 2))
.WillOnce(Return(kPlaybackStartTime + kRentalDuration + 2));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration));
EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, NEVER_EXPIRES));
EXPECT_CALL(check_, Call(1));
EXPECT_CALL(check_, Call(2));
EXPECT_CALL(check_, Call(3));
EXPECT_CALL(check_, Call(4));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
for (int i = 1; i <= 4; ++i) {
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->OnTimerEvent();
check_.Call(i);
}
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
}
TEST_F(PolicyEngineTestV16, PlaybackOk_PlaybackAndRental0) {
License_Policy* policy = license_.mutable_policy();
policy->set_rental_duration_seconds(UNLIMITED_DURATION);
policy->set_playback_duration_seconds(UNLIMITED_DURATION);
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
// Only |license_duration_seconds| set.
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime))
.WillOnce(Return(kPlaybackStartTime))
.WillOnce(Return(kPlaybackStartTime + kPlaybackDuration - 2))
.WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 2))
.WillOnce(Return(kPlaybackStartTime + kRentalDuration - 2))
.WillOnce(Return(kPlaybackStartTime + kRentalDuration + 2));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, NEVER_EXPIRES));
EXPECT_CALL(check_, Call(1));
EXPECT_CALL(check_, Call(2));
EXPECT_CALL(check_, Call(3));
EXPECT_CALL(check_, Call(4));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
for (int i = 1; i <= 4; ++i) {
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->OnTimerEvent();
check_.Call(i);
}
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
}
TEST_F(PolicyEngineTestV16, PlaybackOk_LicenseWithFutureStartTime) {
License_Policy* policy = license_.mutable_policy();
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime - 100))
.WillOnce(Return(kLicenseStartTime - 50))
.WillOnce(Return(kLicenseStartTime))
.WillOnce(Return(kPlaybackStartTime));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
ExpectSessionKeysChange(kKeyStatusUsableInFuture, false);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration));
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kPlaybackStartTime + kPlaybackDuration));
policy_engine_->SetLicense(license_, false);
policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->BeginDecryption();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
}
TEST_F(PolicyEngineTestV16, PlaybackFailed_CanRenewFalse) {
License_Policy* policy = license_.mutable_policy();
const int64_t license_renewal_delay =
GetLicenseRenewalDelay(kPlaybackDuration);
policy->set_renewal_delay_seconds(license_renewal_delay);
policy->set_can_renew(false);
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kPlaybackStartTime))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay - 10))
.WillOnce(Return(kPlaybackStartTime + kPlaybackDuration - 10))
.WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 1));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration));
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kPlaybackStartTime + kPlaybackDuration));
EXPECT_CALL(check_, Call(1));
EXPECT_CALL(check_, Call(2));
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(check_, Call(3));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
for (int i = 1; i <= 3; ++i) {
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->OnTimerEvent();
check_.Call(i);
}
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
}
TEST_F(PolicyEngineTestV16, PlaybackOk_RenewSuccess) {
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(true);
int64_t license_renewal_delay = GetLicenseRenewalDelay(kPlaybackDuration);
policy->set_renewal_delay_seconds(license_renewal_delay);
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
int64_t new_license_start_time =
kLicenseStartTime + license_renewal_delay + 15;
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kPlaybackStartTime))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay - 15))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay + 10))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay + 20))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay +
kLicenseRenewalRetryInterval + 10));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration));
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kPlaybackStartTime + kPlaybackDuration));
EXPECT_CALL(check_, Call(1));
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(2));
EXPECT_CALL(check_, Call(3));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
for (int i = 1; i <= 2; ++i) {
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->OnTimerEvent();
check_.Call(i);
}
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
license_.set_license_start_time(new_license_start_time);
policy->set_renewal_delay_seconds(new_license_start_time);
LicenseIdentification* id = license_.mutable_id();
id->set_version(2);
policy_engine_->UpdateLicense(license_, false);
policy_engine_->OnTimerEvent();
check_.Call(3);
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
}
// TODO(b/161992421): Rewrite after clarifying expected behavior
TEST_F(PolicyEngineTestV16,
DISABLED_PlaybackOk_RenewSuccess_WithFutureStartTime) {
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(true);
const int64_t license_renewal_delay =
GetLicenseRenewalDelay(kPlaybackDuration);
policy->set_renewal_delay_seconds(license_renewal_delay);
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
const int64_t new_license_start_time =
kLicenseStartTime + license_renewal_delay + 50;
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kPlaybackStartTime))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay - 15))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay + 10))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay + 20))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay + 30))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay + 60));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration));
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kPlaybackStartTime + kPlaybackDuration));
EXPECT_CALL(check_, Call(1));
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(2));
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(3));
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(4));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
for (int i = 1; i <= 2; ++i) {
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->OnTimerEvent();
check_.Call(i);
}
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
license_.set_license_start_time(new_license_start_time);
LicenseIdentification* id = license_.mutable_id();
id->set_version(2);
policy_engine_->UpdateLicense(license_, false);
policy_engine_->OnTimerEvent();
check_.Call(3);
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->OnTimerEvent();
check_.Call(4);
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
}
TEST_F(PolicyEngineTestV16, LicenseExpired_RenewFailedVersionNotUpdated) {
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(true);
int64_t license_renewal_delay = GetLicenseRenewalDelay(kPlaybackDuration);
policy->set_renewal_delay_seconds(license_renewal_delay);
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay - 10))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay + 10))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay + 40))
.WillOnce(Return(kLicenseStartTime + kPlaybackDuration + 10));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration));
EXPECT_CALL(check_, Call(1));
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(2));
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(3));
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(4));
policy_engine_->SetLicense(license_, false);
for (int i = 1; i <= 2; ++i) {
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->OnTimerEvent();
check_.Call(i);
}
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
license_.set_license_start_time(kLicenseStartTime + license_renewal_delay +
30);
policy_engine_->UpdateLicense(license_, false);
policy_engine_->OnTimerEvent();
check_.Call(3);
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->OnTimerEvent();
check_.Call(4);
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
}
TEST_F(PolicyEngineTestV16, PlaybackSuccess_EntitlementLicense) {
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kPlaybackStartTime))
.WillOnce(Return(kLicenseStartTime + 10));
ExpectSessionKeysChange(kKeyStatusUsable, true, kEntitlementKeyId);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration));
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kPlaybackStartTime + kPlaybackDuration));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(NO_ERROR))));
License::KeyContainer* key = license_.mutable_key(0);
key->set_type(License::KeyContainer::ENTITLEMENT);
key->set_id(kEntitlementKeyId);
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
std::vector<WidevinePsshData_EntitledKey> entitled_keys(1);
entitled_keys[0].set_entitlement_key_id(kEntitlementKeyId);
entitled_keys[0].set_key_id(kKeyId);
policy_engine_->SetEntitledLicenseKeys(entitled_keys);
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
}
TEST_F(PolicyEngineQueryTest, QuerySuccess_LicenseNotReceived) {
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime));
CdmQueryMap query_info;
EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info));
EXPECT_EQ(0u, query_info.size());
}
TEST_F(PolicyEngineQueryTest, QuerySuccess_LicenseStartTimeNotSet) {
license_.clear_license_start_time();
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1));
policy_engine_->SetLicense(license_, false);
CdmQueryMap query_info;
EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info));
EXPECT_EQ(0u, query_info.size());
}
TEST_F(PolicyEngineQueryTest, QuerySuccess) {
License_Policy* policy = license_.mutable_policy();
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kLicenseStartTime + 100));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
policy_engine_->SetLicense(license_, false);
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]);
EXPECT_EQ(kRentalDuration - 100,
std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING]));
EXPECT_EQ(kPlaybackDuration,
std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING]));
EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]);
}
TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackNotBegun) {
License_Policy* policy = license_.mutable_policy();
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kLicenseStartTime + 100))
.WillOnce(Return(kLicenseStartTime + 200));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
policy_engine_->SetLicense(license_, false);
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]);
EXPECT_EQ(kRentalDuration - 100,
std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING]));
EXPECT_EQ(kPlaybackDuration,
std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING]));
EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]);
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]);
EXPECT_EQ(kRentalDuration - 200,
std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING]));
EXPECT_EQ(kPlaybackDuration,
std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING]));
EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]);
}
TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackBegun) {
License_Policy* policy = license_.mutable_policy();
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kLicenseStartTime + 50))
.WillOnce(Return(kLicenseStartTime + 100))
.WillOnce(Return(kLicenseStartTime + 150))
.WillOnce(Return(kLicenseStartTime + 200));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
policy_engine_->SetLicense(license_, false);
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]);
EXPECT_EQ(kRentalDuration - 50,
std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING]));
EXPECT_EQ(kPlaybackDuration,
std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING]));
EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]);
policy_engine_->BeginDecryption();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->OnTimerEvent();
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]);
EXPECT_EQ(kRentalDuration - 200,
std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING]));
EXPECT_EQ(kPlaybackDuration - 100,
std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING]));
EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]);
}
TEST_F(PolicyEngineQueryTest, QuerySuccess_InitialRentalDurationExpired) {
License_Policy* policy = license_.mutable_policy();
policy->set_rental_duration_seconds(kLowDuration);
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + kLowDuration + 1))
.WillOnce(Return(kLicenseStartTime + kLowDuration + 5));
policy_engine_->SetLicense(license_, false);
EXPECT_FALSE(policy_engine_->CanDecryptContent(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]);
EXPECT_EQ(0, std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING]));
EXPECT_EQ(kPlaybackDuration,
std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING]));
EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]);
}
TEST_F(PolicyEngineQueryTest, QuerySuccess_CanPlayFalse) {
LicenseIdentification* id = license_.mutable_id();
id->set_type(OFFLINE);
License_Policy* policy = license_.mutable_policy();
policy->set_can_play(false);
policy->set_can_persist(true);
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
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(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
policy_engine_->SetLicense(license_, false);
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->OnTimerEvent();
policy_engine_->BeginDecryption();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
CdmQueryMap query_info;
EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info));
EXPECT_EQ(QUERY_VALUE_OFFLINE, query_info[QUERY_KEY_LICENSE_TYPE]);
EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PLAY_ALLOWED]);
EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PERSIST_ALLOWED]);
EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]);
EXPECT_EQ(kRentalDuration - 100,
std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING]));
EXPECT_EQ(kPlaybackDuration,
std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING]));
EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]);
}
TEST_F(PolicyEngineQueryTest, QuerySuccess_RentalDurationExpired) {
License_Policy* policy = license_.mutable_policy();
policy->set_rental_duration_seconds(kLowDuration);
policy->set_license_duration_seconds(kHighDuration);
policy->set_renewal_delay_seconds(GetLicenseRenewalDelay(kHighDuration));
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kPlaybackStartTime))
.WillOnce(Return(kLicenseStartTime + kLowDuration - 1))
.WillOnce(Return(kLicenseStartTime + kLowDuration))
.WillOnce(Return(kLicenseStartTime + kLowDuration + 5));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
for (int i = 1; i <= 2; ++i) {
policy_engine_->OnTimerEvent();
}
EXPECT_FALSE(policy_engine_->CanDecryptContent(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]);
EXPECT_EQ(0, std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING]));
EXPECT_EQ(kPlaybackDuration - kLowDuration,
std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING]));
EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]);
}
TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackDurationExpired) {
License_Policy* policy = license_.mutable_policy();
policy->set_playback_duration_seconds(kLowDuration);
policy->set_license_duration_seconds(kHighDuration);
policy->set_renewal_delay_seconds(GetLicenseRenewalDelay(kHighDuration));
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
int64_t playback_start_time = kLicenseStartTime + 10000;
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(playback_start_time))
.WillOnce(Return(playback_start_time - 2 + kLowDuration))
.WillOnce(Return(playback_start_time + 2 + kLowDuration))
.WillOnce(Return(playback_start_time + 5 + kLowDuration));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
for (int i = 1; i <= 2; ++i) {
policy_engine_->OnTimerEvent();
}
EXPECT_FALSE(policy_engine_->CanDecryptContent(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]);
EXPECT_EQ(0, std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING]));
EXPECT_EQ(0, std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING]));
EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]);
}
TEST_F(PolicyEngineQueryTest,
QuerySuccess_RentalDurationExpired_SoftEnforceRentalDuration) {
License_Policy* policy = license_.mutable_policy();
policy->set_rental_duration_seconds(kLowDuration);
policy->set_license_duration_seconds(kHighDuration);
policy->set_renewal_delay_seconds(GetLicenseRenewalDelay(kHighDuration));
policy->set_soft_enforce_rental_duration(true);
policy->set_soft_enforce_playback_duration(false);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kPlaybackStartTime))
.WillOnce(Return(kLicenseStartTime - 2 + kLowDuration))
.WillOnce(Return(kLicenseStartTime + 2 + kLowDuration))
.WillOnce(Return(kLicenseStartTime + 5 + kLowDuration));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
for (int i = 1; i <= 2; ++i) {
policy_engine_->OnTimerEvent();
}
EXPECT_TRUE(policy_engine_->CanDecryptContent(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]);
EXPECT_EQ(LLONG_MAX,
std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING]));
EXPECT_EQ(kPlaybackDuration - kLicenseStartTime - 5 - kLowDuration +
kPlaybackStartTime,
std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING]));
EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]);
}
TEST_F(PolicyEngineQueryTest,
QuerySuccess_PlaybackDurationExpired_SoftEnforcePlaybackDuration) {
License_Policy* policy = license_.mutable_policy();
policy->set_playback_duration_seconds(kLowDuration);
policy->set_license_duration_seconds(kHighDuration);
policy->set_renewal_delay_seconds(GetLicenseRenewalDelay(kHighDuration));
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(true);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kPlaybackStartTime))
.WillOnce(Return(kPlaybackStartTime - 2 + kLowDuration))
.WillOnce(Return(kPlaybackStartTime + 2 + kLowDuration))
.WillOnce(Return(kPlaybackStartTime + 5 + kLowDuration));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
for (int i = 1; i <= 2; ++i) {
policy_engine_->OnTimerEvent();
}
EXPECT_TRUE(policy_engine_->CanDecryptContent(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]);
EXPECT_EQ(kRentalDuration - (kPlaybackStartTime + 5 + kLowDuration) +
kLicenseStartTime,
std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING]));
EXPECT_EQ(0, std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING]));
EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]);
}
TEST_F(PolicyEngineQueryTest, QuerySuccess_RentalDuration0) {
License_Policy* policy = license_.mutable_policy();
policy->set_rental_duration_seconds(UNLIMITED_DURATION);
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
int64_t license_renewal_delay = GetLicenseRenewalDelay(kLowDuration);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kPlaybackStartTime))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay - 1))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay))
.WillOnce(Return(kLicenseStartTime + kLowDuration - 1))
.WillOnce(Return(kLicenseStartTime + kLowDuration))
.WillOnce(Return(kLicenseStartTime + kLowDuration + 5));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
for (int i = 1; i <= 4; ++i) {
policy_engine_->OnTimerEvent();
}
EXPECT_TRUE(policy_engine_->CanDecryptContent(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]);
EXPECT_EQ(LLONG_MAX,
std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING]));
EXPECT_EQ(kPlaybackDuration - kLowDuration,
std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING]));
EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]);
}
TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackDuration0) {
License_Policy* policy = license_.mutable_policy();
policy->set_playback_duration_seconds(UNLIMITED_DURATION);
policy->set_license_duration_seconds(kHighDuration);
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
int64_t license_renewal_delay = GetLicenseRenewalDelay(kHighDuration);
policy->set_renewal_delay_seconds(license_renewal_delay);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime))
.WillOnce(Return(kLicenseStartTime + 5))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay - 2))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay + 2))
.WillOnce(Return(kLicenseStartTime + license_renewal_delay + 5))
.WillOnce(Return(kLicenseStartTime + kHighDuration - 2))
.WillOnce(Return(kLicenseStartTime + kHighDuration + 2))
.WillOnce(Return(kLicenseStartTime + kHighDuration + 5));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
for (int i = 1; i <= 2; ++i) {
policy_engine_->OnTimerEvent();
}
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]);
EXPECT_EQ(0, std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING]));
EXPECT_EQ(LLONG_MAX,
std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING]));
EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]);
for (int i = 3; i <= 4; ++i) {
policy_engine_->OnTimerEvent();
}
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
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]);
EXPECT_EQ(0, std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING]));
EXPECT_EQ(LLONG_MAX,
std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING]));
EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]);
}
TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackAndRental0) {
License_Policy* policy = license_.mutable_policy();
policy->set_rental_duration_seconds(UNLIMITED_DURATION);
policy->set_playback_duration_seconds(UNLIMITED_DURATION);
policy->set_license_duration_seconds(kLowDuration);
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
// Only |license_duration_seconds| set.
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kPlaybackStartTime))
.WillOnce(Return(kLicenseStartTime + 10))
.WillOnce(Return(kLicenseStartTime + kLowDuration - 10))
.WillOnce(Return(kLicenseStartTime + kLowDuration + 10))
.WillOnce(Return(kLicenseStartTime + kLowDuration + 10));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
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]);
EXPECT_EQ(LLONG_MAX,
std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING]));
EXPECT_EQ(LLONG_MAX,
std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING]));
EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]);
policy_engine_->OnTimerEvent();
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]);
EXPECT_EQ(LLONG_MAX,
std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING]));
EXPECT_EQ(LLONG_MAX,
std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING]));
EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]);
}
TEST_F(PolicyEngineQueryTest, QuerySuccess_LicenseWithFutureStartTime) {
License_Policy* policy = license_.mutable_policy();
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime - 100))
.WillOnce(Return(kLicenseStartTime - 50))
.WillOnce(Return(kLicenseStartTime - 10))
.WillOnce(Return(kLicenseStartTime))
.WillOnce(Return(kLicenseStartTime + 10))
.WillOnce(Return(kLicenseStartTime + 25));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
policy_engine_->SetLicense(license_, false);
policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(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]);
EXPECT_EQ(kRentalDuration + 10,
std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING]));
EXPECT_EQ(kPlaybackDuration,
std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING]));
EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]);
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->BeginDecryption();
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]);
EXPECT_EQ(kRentalDuration - 25,
std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING]));
EXPECT_EQ(kPlaybackDuration - 15,
std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING]));
EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]);
}
TEST_F(PolicyEngineTestV16, SetLicenseForRelease) {
License_Policy* policy = license_.mutable_policy();
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1));
// No key change event will fire.
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration));
policy_engine_->SetLicenseForRelease(license_);
// No keys were loaded.
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
}
TEST_F(PolicyEngineTestV16, SetLicenseForReleaseAfterSetLicense) {
License_Policy* policy = license_.mutable_policy();
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kPlaybackStartTime))
.WillOnce(Return(kLicenseStartTime + 10));
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration));
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kPlaybackStartTime + kPlaybackDuration));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
::testing::Mock::VerifyAndClear(&mock_event_listener_);
// Set the license again with use_keys set to false.
// This would happen when asking the session to generate a release message
// on an existing session.
ExpectSessionKeysChange(kKeyStatusExpired, false);
policy_engine_->SetLicenseForRelease(license_);
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
}
TEST_F(PolicyEngineTestV16, PlaybackOk_RestoreWithoutPlaybackTimes) {
License_Policy* policy = license_.mutable_policy();
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kLicenseStartTime + 15))
.WillOnce(Return(kLicenseStartTime + 30));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence seq;
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration));
policy_engine_->SetLicense(license_, true);
policy_engine_->OnTimerEvent();
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
}
// These tests exercise license policy when OEMCrypto supports v18.
// The following scenarios are from the duration-and-renewal doc.
// Verifies correct reporting of events, OnSessionRenewalNeeded,
// OnExpirationUpdate, OnSessionKeysChange. Actual license expiration
// is managed/tested by OEMCrypto.
// Scenario: Streaming
// Case: 1, 2, 3 and 4
//
// Verifies
// 1. When license is loaded
// a. Expiration is correctly set based on rental duration
// b. Usable keys are returned
// 2. Expiration is unaffected when playback begins
// 3. After rental window
// a. License is correctly expired based on rental duration
// b. Keys are reported as expired
TEST_F(PolicyEngineTestV18, Streaming_1) {
const int64_t license_load_time = kLicenseStartTime + 10;
const int64_t decrypt_start_time = kLicenseStartTime + 20;
const int64_t rental_duration = kThreeHours;
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(false);
policy->set_rental_duration_seconds(rental_duration);
policy->set_playback_duration_seconds(kDurationUnlimited);
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
policy->set_initial_renewal_delay_base(kTimerDelayBaseUnspecified);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(license_load_time))
.WillOnce(Return(decrypt_start_time))
.WillOnce(Return(kLicenseStartTime + rental_duration - 10))
.WillOnce(Return(kLicenseStartTime + rental_duration + 10));
ExpectSessionKeysChange(kKeyStatusUsable, true);
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + rental_duration));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
}
// Scenario: Streaming
// Case: 5
//
// Verifies
// 1. When license is loaded
// a. Expiration is correctly set based on rental duration
// b. Usable keys are returned
// 2. After rental window expires
// a. License is correctly expired based on rental duration
// b. Keys are reported as expired
TEST_F(PolicyEngineTestV18, Streaming_5) {
const int64_t rental_duration = kThreeHours;
const int64_t license_load_time = kLicenseStartTime + 10;
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(false);
policy->set_rental_duration_seconds(rental_duration);
policy->set_playback_duration_seconds(kDurationUnlimited);
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
policy->set_initial_renewal_delay_base(kTimerDelayBaseUnspecified);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(license_load_time))
.WillOnce(Return(kLicenseStartTime + rental_duration + 10));
ExpectSessionKeysChange(kKeyStatusUsable, true);
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + rental_duration));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
policy_engine_->SetLicense(license_, false);
policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
}
// Scenario: Streaming Quick Start
// Case: 1, 2
//
// Verifies
// 1. When license is loaded
// a. Expiration is correctly set based on rental duration
// b. Usable keys are returned
// 2. When playback begins
// a. Expiration is correctly set based on playback duration
// 3. After playback window
// a. License is correctly expired based on playback duration
// b. Keys are reported as expired
TEST_F(PolicyEngineTestV18, StreamingQuickStart_1) {
const int64_t license_load_time = kLicenseStartTime + 10;
const int64_t license_decrypt_start_time = kLicenseStartTime + 20;
const int64_t rental_duration = kThirtySeconds;
const int64_t playback_duration = kThreeHours;
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(false);
policy->set_rental_duration_seconds(rental_duration);
policy->set_playback_duration_seconds(playback_duration);
policy->set_soft_enforce_rental_duration(true);
policy->set_soft_enforce_playback_duration(false);
policy->set_initial_renewal_delay_base(kTimerDelayBaseUnspecified);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(license_load_time))
.WillOnce(Return(license_decrypt_start_time))
.WillOnce(Return(license_decrypt_start_time + playback_duration - 10))
.WillOnce(Return(license_decrypt_start_time + playback_duration + 10));
ExpectSessionKeysChange(kKeyStatusUsable, true);
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + rental_duration));
EXPECT_CALL(
mock_event_listener_,
OnExpirationUpdate(_, license_decrypt_start_time + playback_duration));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
}
// Scenario: Streaming Quick Start
// Case: 3
//
// Verifies
// 1. When license is loaded
// a. Expiration is correctly set based on rental duration
// b. Usable keys are returned
// 2. When playback begins
// a. Expiration is correctly set based on playback duration
// 3. After license is restored
// a. Expiration is correctly set based on playback duration
// b. Usable keys are returned
// 4. After license is restored
// a. Expiration is correctly set based on playback duration
// b. Usable keys are returned
// 5. After playback window is passed
// a. License is correctly expired based on playback duration
// b. Keys are reported as expired
TEST_F(PolicyEngineTestV18, StreamingQuickStart_3) {
const int64_t license_load_time = kLicenseStartTime + 10;
const int64_t license_decrypt_start_time = kLicenseStartTime + 20;
const int64_t rental_duration = kThirtySeconds;
const int64_t playback_duration = kThreeHours;
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(false);
policy->set_rental_duration_seconds(rental_duration);
policy->set_playback_duration_seconds(playback_duration);
policy->set_soft_enforce_rental_duration(true);
policy->set_soft_enforce_playback_duration(false);
policy->set_initial_renewal_delay_base(kTimerDelayBaseUnspecified);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(license_load_time))
.WillOnce(Return(license_decrypt_start_time))
.WillOnce(Return(license_decrypt_start_time + 10));
uint32_t license_last_decrypt_time = license_decrypt_start_time + 10;
ExpectSessionKeysChange(kKeyStatusUsable, true, 3);
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + rental_duration));
EXPECT_CALL(
mock_event_listener_,
OnExpirationUpdate(_, license_decrypt_start_time + playback_duration))
.Times(3);
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
MockClock* mock_clock1(new MockClock());
EXPECT_CALL(*mock_clock1, GetCurrentTime())
.WillOnce(Return(license_decrypt_start_time + 600))
.WillOnce(Return(license_decrypt_start_time + 610))
.WillOnce(Return(license_decrypt_start_time + 620));
ResetPolicyEngine(mock_clock1);
policy_engine_->SetLicense(license_, true);
policy_engine_->RestorePlaybackTimes(license_decrypt_start_time,
license_last_decrypt_time, 0);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
license_last_decrypt_time = license_decrypt_start_time + 620;
MockClock* mock_clock2(new MockClock());
EXPECT_CALL(*mock_clock2, GetCurrentTime())
.WillOnce(Return(license_decrypt_start_time + playback_duration - 30))
.WillOnce(Return(license_decrypt_start_time + playback_duration - 20))
.WillOnce(Return(license_decrypt_start_time + playback_duration - 10))
.WillOnce(Return(license_decrypt_start_time + playback_duration + 10));
ResetPolicyEngine(mock_clock2);
policy_engine_->SetLicense(license_, true);
policy_engine_->RestorePlaybackTimes(license_decrypt_start_time,
license_last_decrypt_time, 0);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
}
// Scenario: Streaming Quick Start
// Case: 4
//
// Verifies
// 1. When license is loaded
// a. Expiration is correctly set based on rental duration
// b. Usable keys are returned
// 2. After rental window expires
// a. License is correctly expired based on playback duration
// b. Keys are reported as expired
TEST_F(PolicyEngineTestV18, StreamingQuickStart_4) {
const int64_t rental_duration = kThirtySeconds;
const int64_t playback_duration = kThreeHours;
const int64_t license_load_time = kLicenseStartTime + 10;
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(false);
policy->set_rental_duration_seconds(rental_duration);
policy->set_playback_duration_seconds(playback_duration);
policy->set_soft_enforce_rental_duration(true);
policy->set_soft_enforce_playback_duration(false);
policy->set_initial_renewal_delay_base(kTimerDelayBaseUnspecified);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(license_load_time))
.WillOnce(Return(kLicenseStartTime + rental_duration + 10));
ExpectSessionKeysChange(kKeyStatusUsable, true);
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + rental_duration));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
policy_engine_->SetLicense(license_, false);
policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
}
// Scenario: Seven Day/Two Day Hard Rental Expiry (Seven Hard Two Hard)
// Case: 1, 2, 3, 4
//
// Verifies
// 1. When license is loaded
// a. Expiration is correctly set based on rental duration
// b. Usable keys are returned
// 2. When playback begins
// a. Expiration is correctly set based on playback duration
// 3. After playback window is past
// a. License is correctly expired based on playback duration
// b. Keys are reported as expired
TEST_F(PolicyEngineTestV18, SevenHardTwoHard_1) {
const int64_t license_load_time = kLicenseStartTime + 10;
const int64_t license_decrypt_start_time = kLicenseStartTime + 20;
const int64_t rental_duration = kSevenDays;
const int64_t playback_duration = kTwoDays;
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(false);
policy->set_rental_duration_seconds(rental_duration);
policy->set_playback_duration_seconds(playback_duration);
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
policy->set_initial_renewal_delay_base(kTimerDelayBaseUnspecified);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(license_load_time))
.WillOnce(Return(license_decrypt_start_time))
.WillOnce(Return(license_decrypt_start_time + playback_duration - 10))
.WillOnce(Return(license_decrypt_start_time + playback_duration + 10));
ExpectSessionKeysChange(kKeyStatusUsable, true);
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + rental_duration));
EXPECT_CALL(
mock_event_listener_,
OnExpirationUpdate(_, license_decrypt_start_time + playback_duration));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
}
// Scenario: Seven Day/Two Day Hard Rental Expiry (Seven Hard Two Hard)
// Case: 5, 6, 7, 8
//
// Verifies
// 1. When license is loaded
// a. Expiration is correctly set based on rental duration
// b. Usable keys are returned
// 2. When playback begins close to rental window expiration
// a. Expiration is unchanged
// 3. After rental window is past
// a. License is correctly expired based on rental duration
// b. Keys are reported as expired
// 4. Before playback window is past
// a. Keys remain expired
TEST_F(PolicyEngineTestV18, SevenHardTwoHard_5) {
const int64_t rental_duration = kSevenDays;
const int64_t playback_duration = kTwoDays;
const int64_t license_load_time = kLicenseStartTime + 10;
const int64_t license_decrypt_start_time =
kLicenseStartTime + rental_duration - playback_duration + kOneDay;
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(false);
policy->set_rental_duration_seconds(rental_duration);
policy->set_playback_duration_seconds(playback_duration);
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
policy->set_initial_renewal_delay_base(kTimerDelayBaseUnspecified);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(license_load_time))
.WillOnce(Return(license_decrypt_start_time))
.WillOnce(Return(kLicenseStartTime + rental_duration - 10))
.WillOnce(Return(kLicenseStartTime + rental_duration + 10))
.WillOnce(Return(license_decrypt_start_time + playback_duration - 10));
ExpectSessionKeysChange(kKeyStatusUsable, true);
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + rental_duration));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
}
// Scenario: Seven Day/Two Day Hard Rental Expiry (Seven Hard Two Hard)
// Case: 9
//
// Verifies
// 1. When license is loaded
// a. Expiration is correctly set based on rental duration
// b. Usable keys are returned
// 2. After rental window is past
// a. License is correctly expired based on rental duration
// b. Keys are reported as expired
TEST_F(PolicyEngineTestV18, SevenHardTwoHard_9) {
const int64_t rental_duration = kSevenDays;
const int64_t playback_duration = kTwoDays;
const int64_t license_load_time = kLicenseStartTime + 10;
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(false);
policy->set_rental_duration_seconds(rental_duration);
policy->set_playback_duration_seconds(playback_duration);
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
policy->set_initial_renewal_delay_base(kTimerDelayBaseUnspecified);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(license_load_time))
.WillOnce(Return(kLicenseStartTime + rental_duration + 10));
ExpectSessionKeysChange(kKeyStatusUsable, true);
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + rental_duration));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
policy_engine_->SetLicense(license_, false);
policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
}
// Scenario: Seven Day/Two Day Soft Playback Expiry (Seven Hard Two Soft)
// Case: 1, 2, 3
//
// Verifies
// 1. When license is loaded
// a. Expiration is correctly set based on rental duration
// b. Usable keys are returned
// 2. When playback begins
// a. Expiration is unchanged
// 3. After playback window is past
// a. Playback is allowed
// 4. After rental window is past
// a. Keys are expired correctly based on rental duration
// a. Playback is disallowed
TEST_F(PolicyEngineTestV18, SevenHardTwoSoft_1) {
const int64_t license_load_time = kLicenseStartTime + 10;
const int64_t license_decrypt_start_time = kLicenseStartTime + 20;
const int64_t rental_duration = kSevenDays;
const int64_t playback_duration = kTwoDays;
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(false);
policy->set_rental_duration_seconds(rental_duration);
policy->set_playback_duration_seconds(playback_duration);
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(true);
policy->set_initial_renewal_delay_base(kTimerDelayBaseUnspecified);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(license_load_time))
.WillOnce(Return(license_decrypt_start_time))
.WillOnce(Return(license_decrypt_start_time + playback_duration - 10))
.WillOnce(Return(license_decrypt_start_time + playback_duration + 10))
.WillOnce(Return(kLicenseStartTime + rental_duration - 10))
.WillOnce(Return(kLicenseStartTime + rental_duration + 10));
ExpectSessionKeysChange(kKeyStatusUsable, true);
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + rental_duration));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
}
// Scenario: Seven Day/Two Day Soft Playback Expiry (Seven Hard Two Soft)
// Case: 5, 6, 7, 8
//
// Verifies
// 1. When license is loaded
// a. Expiration is correctly set based on rental duration
// b. Usable keys are returned
// 2. When playback begins close to rental window expiration
// a. Expiration is unchanged
// 3. After rental window is past
// a. License is correctly expired based on rental duration
// b. Keys are reported as expired
// 4. Before and after playback window is past
// a. Keys remain expired
TEST_F(PolicyEngineTestV18, SevenHardTwoSoft_5) {
const int64_t rental_duration = kSevenDays;
const int64_t playback_duration = kTwoDays;
const int64_t license_load_time = kLicenseStartTime + 10;
const int64_t license_decrypt_start_time =
kLicenseStartTime + rental_duration - playback_duration + kOneDay;
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(false);
policy->set_rental_duration_seconds(rental_duration);
policy->set_playback_duration_seconds(playback_duration);
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(true);
policy->set_initial_renewal_delay_base(kTimerDelayBaseUnspecified);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(license_load_time))
.WillOnce(Return(license_decrypt_start_time))
.WillOnce(Return(kLicenseStartTime + rental_duration - 10))
.WillOnce(Return(kLicenseStartTime + rental_duration + 10))
.WillOnce(Return(license_decrypt_start_time + playback_duration - 10))
.WillOnce(Return(license_decrypt_start_time + playback_duration + 10));
ExpectSessionKeysChange(kKeyStatusUsable, true);
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + rental_duration));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
}
// Scenario: Seven Day/Two Day Soft Playback Expiry (Seven Hard Two Soft)
// Case: 9
//
// Verifies
// 1. When license is loaded
// a. Expiration is correctly set based on rental duration
// b. Usable keys are returned
// 2. After rental window is past
// a. License is correctly expired based on rental duration
// b. Keys are reported as expired
TEST_F(PolicyEngineTestV18, SevenHardTwoSoft_9) {
const int64_t rental_duration = kSevenDays;
const int64_t playback_duration = kTwoDays;
const int64_t license_load_time = kLicenseStartTime + 10;
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(false);
policy->set_rental_duration_seconds(rental_duration);
policy->set_playback_duration_seconds(playback_duration);
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(true);
policy->set_initial_renewal_delay_base(kTimerDelayBaseUnspecified);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(license_load_time))
.WillOnce(Return(kLicenseStartTime + rental_duration + 10));
ExpectSessionKeysChange(kKeyStatusUsable, true);
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + rental_duration));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
policy_engine_->SetLicense(license_, false);
policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
}
// Scenario: Seven Day/Two Day Soft Rental Expiry (Seven Soft Two Hard)
// Case: 1, 2, 3, 4
//
// Verifies
// 1. When license is loaded
// a. Expiration is correctly set based on rental duration
// b. Usable keys are returned
// 2. When playback begins
// a. Expiration is correctly set based on playback duration
// 3. After playback window is past
// a. License is correctly expired based on playback duration
// b. Keys are reported as expired
TEST_F(PolicyEngineTestV18, SevenSoftTwoHard_1) {
const int64_t license_load_time = kLicenseStartTime + 10;
const int64_t license_decrypt_start_time = kLicenseStartTime + 20;
const int64_t rental_duration = kSevenDays;
const int64_t playback_duration = kTwoDays;
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(false);
policy->set_rental_duration_seconds(rental_duration);
policy->set_playback_duration_seconds(playback_duration);
policy->set_soft_enforce_rental_duration(true);
policy->set_soft_enforce_playback_duration(false);
policy->set_initial_renewal_delay_base(kTimerDelayBaseUnspecified);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(license_load_time))
.WillOnce(Return(license_decrypt_start_time))
.WillOnce(Return(license_decrypt_start_time + playback_duration - 10))
.WillOnce(Return(license_decrypt_start_time + playback_duration + 10));
ExpectSessionKeysChange(kKeyStatusUsable, true);
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + rental_duration));
EXPECT_CALL(
mock_event_listener_,
OnExpirationUpdate(_, license_decrypt_start_time + playback_duration));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
}
// Scenario: Seven Day/Two Day Soft Rental Expiry (Seven Soft Two Hard)
// Case: 5, 6, 7, 8
//
// Verifies
// 1. When license is loaded
// a. Expiration is correctly set based on rental duration
// b. Usable keys are returned
// 2. When playback begins close to rental window expiration
// a. Expiration is correctly set based on playback duration
// 3. After rental window is past
// a. Expiration is unaffected
// b. Keys are not reported as expired
// 3. After playback window is past
// a. License is correctly expired based on playback duration
// b. Keys are reported as expired
// 4. Before playback window is past
// a. Keys remain expired
TEST_F(PolicyEngineTestV18, SevenSoftTwoHard_5) {
const int64_t rental_duration = kSevenDays;
const int64_t playback_duration = kTwoDays;
const int64_t license_load_time = kLicenseStartTime + 10;
const int64_t license_decrypt_start_time =
kLicenseStartTime + rental_duration - playback_duration + kOneDay;
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(false);
policy->set_rental_duration_seconds(rental_duration);
policy->set_playback_duration_seconds(playback_duration);
policy->set_soft_enforce_rental_duration(true);
policy->set_soft_enforce_playback_duration(false);
policy->set_initial_renewal_delay_base(kTimerDelayBaseUnspecified);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(license_load_time))
.WillOnce(Return(license_decrypt_start_time))
.WillOnce(Return(kLicenseStartTime + rental_duration - 10))
.WillOnce(Return(kLicenseStartTime + rental_duration + 10))
.WillOnce(Return(license_decrypt_start_time + playback_duration - 10))
.WillOnce(Return(license_decrypt_start_time + playback_duration + 10));
ExpectSessionKeysChange(kKeyStatusUsable, true);
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + rental_duration));
EXPECT_CALL(
mock_event_listener_,
OnExpirationUpdate(_, license_decrypt_start_time + playback_duration));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
}
// Scenario: Seven Day/Two Day Soft Rental Expiry (Seven Soft Two Hard)
// Case: 9
//
// Verifies
// 1. When license is loaded
// a. Expiration is correctly set based on rental duration
// b. Usable keys are returned
// 2. After rental window is past
// a. License is correctly expired based on rental duration
// b. Keys are reported as expired
TEST_F(PolicyEngineTestV18, SevenSoftTwoHard_9) {
const int64_t rental_duration = kSevenDays;
const int64_t playback_duration = kTwoDays;
const int64_t license_load_time = kLicenseStartTime + 10;
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(false);
policy->set_rental_duration_seconds(rental_duration);
policy->set_playback_duration_seconds(playback_duration);
policy->set_soft_enforce_rental_duration(true);
policy->set_soft_enforce_playback_duration(false);
policy->set_initial_renewal_delay_base(kTimerDelayBaseUnspecified);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(license_load_time))
.WillOnce(Return(kLicenseStartTime + rental_duration + 10));
ExpectSessionKeysChange(kKeyStatusUsable, true);
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + rental_duration));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
policy_engine_->SetLicense(license_, false);
policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
}
// Scenario: Seven Day/Two Day Soft Expiry (Seven Soft Two Soft)
// Case: 1, 2, 3
//
// Verifies
// 1. When license is loaded
// a. Expiration is correctly set based on rental duration
// b. Usable keys are returned
// 2. When playback begins
// a. Expiration is set to unlimited
// 3. After playback window is past
// a. Playback is allowed
// 4. After rental window is past
// a. Playback is allowed
TEST_F(PolicyEngineTestV18, SevenSoftTwoSoft_1) {
const int64_t license_load_time = kLicenseStartTime + 10;
const int64_t license_decrypt_start_time = kLicenseStartTime + 20;
const int64_t rental_duration = kSevenDays;
const int64_t playback_duration = kTwoDays;
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(false);
policy->set_rental_duration_seconds(rental_duration);
policy->set_playback_duration_seconds(playback_duration);
policy->set_soft_enforce_rental_duration(true);
policy->set_soft_enforce_playback_duration(true);
policy->set_initial_renewal_delay_base(kTimerDelayBaseUnspecified);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(license_load_time))
.WillOnce(Return(license_decrypt_start_time))
.WillOnce(Return(license_decrypt_start_time + playback_duration - 10))
.WillOnce(Return(license_decrypt_start_time + playback_duration + 10))
.WillOnce(Return(kLicenseStartTime + rental_duration - 10))
.WillOnce(Return(kLicenseStartTime + rental_duration + 10));
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + rental_duration));
EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, 0));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
}
// Scenario: Seven Day/Two Day Soft Expiry (Seven Soft Two Soft)
// Case: 5, 6, 7, 8
//
// Verifies
// 1. When license is loaded
// a. Expiration is correctly set based on rental duration
// b. Usable keys are returned
// 2. When playback begins close to rental window expiration
// a. Expiration is correctly set to unlimited
// 3. After rental window is past
// a. Expiration is unaffected
// b. Keys are not reported as expired
// 3. After playback window is past
// a. Expiration is unaffected
// b. Keys are not reported as expired
TEST_F(PolicyEngineTestV18, SevenSoftTwoSoft_5) {
const int64_t rental_duration = kSevenDays;
const int64_t playback_duration = kTwoDays;
const int64_t license_load_time = kLicenseStartTime + 10;
const int64_t license_decrypt_start_time =
kLicenseStartTime + rental_duration - playback_duration + kOneDay;
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(false);
policy->set_rental_duration_seconds(rental_duration);
policy->set_playback_duration_seconds(playback_duration);
policy->set_soft_enforce_rental_duration(true);
policy->set_soft_enforce_playback_duration(true);
policy->set_initial_renewal_delay_base(kTimerDelayBaseUnspecified);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(license_load_time))
.WillOnce(Return(license_decrypt_start_time))
.WillOnce(Return(kLicenseStartTime + rental_duration - 10))
.WillOnce(Return(kLicenseStartTime + rental_duration + 10))
.WillOnce(Return(license_decrypt_start_time + playback_duration - 10))
.WillOnce(Return(license_decrypt_start_time + playback_duration + 10));
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + rental_duration));
EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, 0));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
policy_engine_->SetLicense(license_, false);
policy_engine_->BeginDecryption();
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
}
// Scenario: Seven Day/Two Day Soft Expiry (Seven Soft Two Soft)
// Case: 9
//
// Verifies
// 1. When license is loaded
// a. Expiration is correctly set based on rental duration
// b. Usable keys are returned
// 2. After rental window is past
// a. License is correctly expired based on rental duration
// b. Keys are reported as expired
TEST_F(PolicyEngineTestV18, SevenSoftTwoSoft_9) {
const int64_t rental_duration = kSevenDays;
const int64_t playback_duration = kTwoDays;
const int64_t license_load_time = kLicenseStartTime + 10;
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(false);
policy->set_rental_duration_seconds(rental_duration);
policy->set_playback_duration_seconds(playback_duration);
policy->set_soft_enforce_rental_duration(true);
policy->set_soft_enforce_playback_duration(true);
policy->set_initial_renewal_delay_base(kTimerDelayBaseUnspecified);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(license_load_time))
.WillOnce(Return(kLicenseStartTime + rental_duration + 10));
ExpectSessionKeysChange(kKeyStatusUsable, true);
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + rental_duration));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
policy_engine_->SetLicense(license_, false);
policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
}
// Scenario: License with Renewal
// Case: 1, 2, 5, 6
//
// Verifies
// 1. When license is loaded
// a. Expiration is is set to unlimited as playback has not begun
// b. Usable keys are returned
// 2. When playback begins Expiration is correctly set based on
// playback duration
// 3. When renewal_delay is exceeded a session renewal event is returned
// 4. When license is renewed, durations have been adjusted but windows
// have not been changed so no event is sent
// 5. After playback window is past
// a. License is correctly expired based on playback duration
// b. Keys are reported as expired
TEST_F(PolicyEngineTestV18, LicenseWithRenewal_1) {
const int64_t playback_duration = kTwoDays;
const int64_t renewal_delay = kFiveMinutes;
const int64_t renewal_recovery_duration = kTenSeconds;
const int64_t license_decrypt_start_time = kLicenseStartTime + 10;
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(true);
policy->set_rental_duration_seconds(kDurationUnlimited);
policy->set_playback_duration_seconds(playback_duration);
policy->set_renewal_delay_seconds(renewal_delay);
policy->set_renewal_recovery_duration_seconds(renewal_recovery_duration);
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
policy->set_initial_renewal_delay_base(kTimerDelayBaseLicenseStart);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime))
.WillOnce(Return(license_decrypt_start_time))
.WillOnce(Return(kLicenseStartTime + renewal_delay - 10))
.WillOnce(Return(kLicenseStartTime + renewal_delay + 10))
.WillOnce(Return(kLicenseStartTime + renewal_delay + 20))
.WillOnce(Return(license_decrypt_start_time + playback_duration - 10))
.WillOnce(Return(license_decrypt_start_time + playback_duration + 10));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
EXPECT_CALL(check_, Call(1));
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, 0));
EXPECT_CALL(check_, Call(2));
EXPECT_CALL(
mock_event_listener_,
OnExpirationUpdate(_, license_decrypt_start_time + playback_duration));
EXPECT_CALL(check_, Call(3));
EXPECT_CALL(check_, Call(4));
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(5));
EXPECT_CALL(check_, Call(6));
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(7));
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(check_, Call(8));
check_.Call(1);
policy_engine_->SetLicense(license_, false);
check_.Call(2);
policy_engine_->BeginDecryption();
check_.Call(3);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(4);
policy_engine_->OnTimerEvent();
check_.Call(5);
LicenseIdentification* id = license_.mutable_id();
id->set_version(2);
policy_engine_->UpdateLicense(license_, false);
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(6);
policy_engine_->OnTimerEvent();
check_.Call(7);
policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(8);
}
// Scenario: License with Renewal
// Case: 3, 4
//
// Verifies
// 1. When license is loaded
// a. Expiration is is set to unlimited as playback has not begun
// b. Usable keys are returned
// 2. When playback begins Expiration is correctly set based on
// playback duration
// 3. When renewal_delay is exceeded a session renewal event is returned
// 4. When license is renewed, durations have been adjusted but windows
// have not been changed so no event is sent. Keys are still available
TEST_F(PolicyEngineTestV18, LicenseWithRenewal_3) {
const int64_t playback_duration = kTwoDays;
const int64_t renewal_delay = kFiveMinutes;
const int64_t renewal_recovery_duration = kTenSeconds;
const int64_t license_decrypt_start_time = kLicenseStartTime + 10;
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(true);
policy->set_rental_duration_seconds(kDurationUnlimited);
policy->set_playback_duration_seconds(playback_duration);
policy->set_renewal_delay_seconds(renewal_delay);
policy->set_renewal_recovery_duration_seconds(renewal_recovery_duration);
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
policy->set_initial_renewal_delay_base(kTimerDelayBaseLicenseStart);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime))
.WillOnce(Return(license_decrypt_start_time))
.WillOnce(Return(kLicenseStartTime + renewal_delay - 5))
.WillOnce(Return(kLicenseStartTime + renewal_delay + 5))
.WillOnce(Return(kLicenseStartTime + renewal_delay +
renewal_recovery_duration + 5))
.WillOnce(Return(kLicenseStartTime + renewal_delay +
renewal_recovery_duration + 10))
.WillOnce(Return(kLicenseStartTime + renewal_delay +
renewal_recovery_duration + 20));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
EXPECT_CALL(check_, Call(1));
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, 0));
EXPECT_CALL(check_, Call(2));
EXPECT_CALL(
mock_event_listener_,
OnExpirationUpdate(_, license_decrypt_start_time + playback_duration));
EXPECT_CALL(check_, Call(3));
EXPECT_CALL(check_, Call(4));
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(5));
EXPECT_CALL(check_, Call(6));
EXPECT_CALL(check_, Call(7));
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(8));
check_.Call(1);
policy_engine_->SetLicense(license_, false);
check_.Call(2);
policy_engine_->BeginDecryption();
check_.Call(3);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(4);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(5);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(6);
LicenseIdentification* id = license_.mutable_id();
id->set_version(2);
policy_engine_->UpdateLicense(license_, false);
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(7);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(8);
}
// Scenario: Limited duration license (playback starts in rental duration)
// Case: 1, 4, 5
//
// Verifies
// 1. When license is loaded
// a. Expiration is is set to rental duration as playback has not begun
// b. Usable keys are returned
// 2. When playback begins
// a. Expiration is correctly set based on playback duration
// b. A session renewal event is returned
// 3. When renewal_delay is exceeded a session renewal event is returned
// 4. When license is renewed, durations have been adjusted but windows
// have not been changed so no event is sent
// 5. After playback window is past
// a. License is correctly expired based on playback duration
// b. Keys are reported as expired
TEST_F(PolicyEngineTestV18, LimitedDurationLicense_1) {
const int64_t license_load_time = kLicenseStartTime + 10;
const int64_t license_decrypt_start_time = kLicenseStartTime + 20;
const int64_t rental_duration = kFifteenMinutes;
const int64_t playback_duration = kTwoHours;
const int64_t renewal_delay = kFiveSeconds;
const int64_t renewal_recovery_duration = kFortySeconds;
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(true);
policy->set_renew_with_usage(true);
policy->set_rental_duration_seconds(rental_duration);
policy->set_playback_duration_seconds(playback_duration);
policy->set_renewal_delay_seconds(renewal_delay);
policy->set_renewal_recovery_duration_seconds(renewal_recovery_duration);
policy->set_soft_enforce_rental_duration(true);
policy->set_soft_enforce_playback_duration(false);
policy->set_initial_renewal_delay_base(kTimerDelayBaseLicenseStart);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(license_load_time))
.WillOnce(Return(license_decrypt_start_time))
.WillOnce(Return(license_decrypt_start_time + 2))
.WillOnce(Return(license_decrypt_start_time + 10))
.WillOnce(Return(license_decrypt_start_time + 20))
.WillOnce(Return(license_decrypt_start_time + 30))
.WillOnce(Return(license_decrypt_start_time + playback_duration - 10))
.WillOnce(Return(license_decrypt_start_time + playback_duration + 10));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
EXPECT_CALL(check_, Call(1));
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + rental_duration));
EXPECT_CALL(check_, Call(2));
EXPECT_CALL(
mock_event_listener_,
OnExpirationUpdate(_, license_decrypt_start_time + playback_duration));
EXPECT_CALL(check_, Call(3));
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(4));
EXPECT_CALL(check_, Call(5));
EXPECT_CALL(check_, Call(6));
EXPECT_CALL(check_, Call(7));
EXPECT_CALL(check_, Call(8));
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(check_, Call(9));
check_.Call(1);
policy_engine_->SetLicense(license_, false);
check_.Call(2);
policy_engine_->BeginDecryption();
check_.Call(3);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(4);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(5);
LicenseIdentification* id = license_.mutable_id();
id->set_version(2);
policy->set_can_renew(false);
policy->set_renewal_delay_seconds(kTwoHours);
policy_engine_->UpdateLicense(license_, false);
check_.Call(6);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(7);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(8);
policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(9);
}
// Scenario: Limited duration license (playback starts after rental duration)
// Case: 2
//
// Verifies
// 1. When license is loaded
// a. Expiration is is set to rental duration as playback has not begun
// b. Usable keys are returned
// 2. When playback begins after rental duration expires
// a. License is correctly expired based on rental duration
// b. Keys are reported as expired
TEST_F(PolicyEngineTestV18, LimitedDurationLicense_2) {
const int64_t rental_duration = kFifteenMinutes;
const int64_t playback_duration = kTwoHours;
const int64_t renewal_delay = kFiveSeconds;
const int64_t renewal_recovery_duration = kFortySeconds;
const int64_t license_load_time = kLicenseStartTime + 10;
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(true);
policy->set_renew_with_usage(true);
policy->set_rental_duration_seconds(rental_duration);
policy->set_playback_duration_seconds(playback_duration);
policy->set_renewal_delay_seconds(renewal_delay);
policy->set_renewal_recovery_duration_seconds(renewal_recovery_duration);
policy->set_soft_enforce_rental_duration(true);
policy->set_soft_enforce_playback_duration(false);
policy->set_initial_renewal_delay_base(kTimerDelayBaseLicenseStart);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(license_load_time))
.WillOnce(Return(kLicenseStartTime + rental_duration + 10));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
EXPECT_CALL(check_, Call(1));
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + rental_duration));
EXPECT_CALL(check_, Call(2));
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(check_, Call(3));
check_.Call(1);
policy_engine_->SetLicense(license_, false);
check_.Call(2);
policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(3);
}
// Scenario: Limited duration license (playback starts after renewal)
// Case: 6
//
// Verifies
// 1. When license is loaded
// a. Expiration is is set to rental duration as playback has not begun
// b. Usable keys are returned
// 2. When renewal is received durations remain the same and no events are
// returned
// 3. When playback begins
// a. Expiration is correctly set based on playback duration
// b. A session renewal event is returned
TEST_F(PolicyEngineTestV18, LimitedDurationLicense_6) {
const int64_t license_load_time = kLicenseStartTime + 10;
const int64_t license_decrypt_start_time = kLicenseStartTime + 60;
const int64_t rental_duration = kFifteenMinutes;
const int64_t playback_duration = kTwoHours;
const int64_t renewal_delay = kFiveSeconds;
const int64_t renewal_recovery_duration = kFortySeconds;
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(true);
policy->set_renew_with_usage(true);
policy->set_rental_duration_seconds(rental_duration);
policy->set_playback_duration_seconds(playback_duration);
policy->set_renewal_delay_seconds(renewal_delay);
policy->set_renewal_recovery_duration_seconds(renewal_recovery_duration);
policy->set_soft_enforce_rental_duration(true);
policy->set_soft_enforce_playback_duration(false);
policy->set_initial_renewal_delay_base(kTimerDelayBaseLicenseStart);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(license_load_time))
.WillOnce(Return(license_load_time + 10))
.WillOnce(Return(license_decrypt_start_time))
.WillOnce(Return(license_decrypt_start_time + 10))
.WillOnce(Return(license_decrypt_start_time + playback_duration - 10))
.WillOnce(Return(license_decrypt_start_time + playback_duration + 10));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(_, _))
.WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(
CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))));
InSequence s;
EXPECT_CALL(check_, Call(1));
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + rental_duration));
EXPECT_CALL(check_, Call(2));
EXPECT_CALL(check_, Call(3));
EXPECT_CALL(
mock_event_listener_,
OnExpirationUpdate(_, license_decrypt_start_time + playback_duration));
EXPECT_CALL(check_, Call(4));
EXPECT_CALL(check_, Call(5));
EXPECT_CALL(check_, Call(6));
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(check_, Call(7));
check_.Call(1);
policy_engine_->SetLicense(license_, false);
check_.Call(2);
LicenseIdentification* id = license_.mutable_id();
id->set_version(2);
policy->set_can_renew(false);
policy->set_renewal_delay_seconds(kTwoHours);
policy_engine_->UpdateLicense(license_, false);
check_.Call(3);
policy_engine_->BeginDecryption();
check_.Call(4);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(5);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(6);
policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(7);
}
// Scenario: Limited duration license with clear lead
// Case: 1S
//
// Verifies
// 1. When license is loaded
// a. Expiration is is set to rental duration as playback has not begun
// b. Usable keys are returned
// 2. When renewal_delay is exceeded a session renewal event is returned
// 3. When encrypted playback begins
// a. Expiration is correctly set based on playback duration
// b. A session renewal event is returned
TEST_F(PolicyEngineTestV18, LimitedDurationLicenseWithClearLead_1S) {
const int64_t rental_duration = kFifteenMinutes;
const int64_t playback_duration = kTwoHours;
const int64_t renewal_delay = kFiveSeconds;
const int64_t renewal_recovery_duration = kFortySeconds;
const int64_t license_load_time = kLicenseStartTime + rental_duration - 30;
const int64_t license_decrypt_start_time = license_load_time + 20;
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(true);
policy->set_renew_with_usage(true);
policy->set_rental_duration_seconds(rental_duration);
policy->set_playback_duration_seconds(playback_duration);
policy->set_renewal_delay_seconds(renewal_delay);
policy->set_renewal_recovery_duration_seconds(renewal_recovery_duration);
policy->set_soft_enforce_rental_duration(true);
policy->set_soft_enforce_playback_duration(false);
policy->set_initial_renewal_delay_base(kTimerDelayBaseLicenseLoad);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(license_load_time))
.WillOnce(Return(license_load_time + 3))
.WillOnce(Return(license_load_time + renewal_delay + 10))
.WillOnce(Return(license_decrypt_start_time))
.WillOnce(Return(license_decrypt_start_time + 20))
.WillOnce(Return(license_load_time + playback_duration - 10));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
EXPECT_CALL(check_, Call(1));
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, license_load_time + playback_duration));
EXPECT_CALL(check_, Call(2));
EXPECT_CALL(check_, Call(3));
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(4));
EXPECT_CALL(check_, Call(5));
EXPECT_CALL(check_, Call(6));
EXPECT_CALL(check_, Call(7));
check_.Call(1);
policy_engine_->SetLicense(license_, false);
check_.Call(2);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(3);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(4);
policy_engine_->BeginDecryption();
check_.Call(5);
LicenseIdentification* id = license_.mutable_id();
id->set_version(2);
policy->set_can_renew(false);
policy->set_renewal_delay_seconds(kTwoHours);
policy_engine_->UpdateLicense(license_, false);
check_.Call(6);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(7);
}
// Scenario: Limited duration license with clear lead
// Case: 1M
//
// Verifies
// 1. When license is loaded
// a. Expiration is is set to rental duration as playback has not begun
// b. Usable keys are returned
// 2. When renewal_delay is exceeded a session renewal event is returned
// 3. When encrypted playback begins after rental duration
// a. Expiration is correctly set based on playback duration
// b. A session renewal event is returned
TEST_F(PolicyEngineTestV18, LimitedDurationLicenseWithClearLead_1M) {
const int64_t rental_duration = kFifteenMinutes;
const int64_t playback_duration = kTwoHours;
const int64_t renewal_delay = kFiveSeconds;
const int64_t renewal_recovery_duration = kFortySeconds;
const int64_t license_load_time = kLicenseStartTime + rental_duration - 30;
const int64_t license_decrypt_start_time = license_load_time + 35;
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(true);
policy->set_renew_with_usage(true);
policy->set_rental_duration_seconds(rental_duration);
policy->set_playback_duration_seconds(playback_duration);
policy->set_renewal_delay_seconds(renewal_delay);
policy->set_renewal_recovery_duration_seconds(renewal_recovery_duration);
policy->set_soft_enforce_rental_duration(true);
policy->set_soft_enforce_playback_duration(false);
policy->set_initial_renewal_delay_base(kTimerDelayBaseLicenseLoad);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(license_load_time))
.WillOnce(Return(license_load_time + 3))
.WillOnce(Return(license_load_time + renewal_delay + 10))
.WillOnce(Return(license_decrypt_start_time))
.WillOnce(Return(license_decrypt_start_time + 5))
.WillOnce(Return(license_load_time + playback_duration - 10));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
EXPECT_CALL(check_, Call(1));
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, license_load_time + playback_duration));
EXPECT_CALL(check_, Call(2));
EXPECT_CALL(check_, Call(3));
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(4));
EXPECT_CALL(check_, Call(5));
EXPECT_CALL(check_, Call(6));
EXPECT_CALL(check_, Call(7));
check_.Call(1);
policy_engine_->SetLicense(license_, false);
check_.Call(2);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(3);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(4);
policy_engine_->BeginDecryption();
check_.Call(5);
LicenseIdentification* id = license_.mutable_id();
id->set_version(2);
policy->set_can_renew(false);
policy->set_renewal_delay_seconds(kTwoHours);
policy_engine_->UpdateLicense(license_, false);
check_.Call(6);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(7);
}
// Scenario: Limited duration license with clear lead
// Case: 1L
//
// Verifies
// 1. When license is loaded
// a. Expiration is is set to rental duration as playback has not begun
// b. Usable keys are returned
// 2. When renewal_delay is exceeded a session renewal event is returned
// 3. When encrypted playback begins after rental duration
// a. Expiration is correctly set based on playback duration
// b. A session renewal event is returned
TEST_F(PolicyEngineTestV18, LimitedDurationLicenseWithClearLead_1L) {
const int64_t rental_duration = kFifteenMinutes;
const int64_t playback_duration = kTwoHours;
const int64_t renewal_delay = kFiveSeconds;
const int64_t renewal_recovery_duration = kFortySeconds;
const int64_t license_load_time = kLicenseStartTime + rental_duration - 30;
const int64_t license_decrypt_start_time =
license_load_time + renewal_delay + renewal_recovery_duration + 10;
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(true);
policy->set_renew_with_usage(true);
policy->set_rental_duration_seconds(rental_duration);
policy->set_playback_duration_seconds(playback_duration);
policy->set_renewal_delay_seconds(renewal_delay);
policy->set_renewal_recovery_duration_seconds(renewal_recovery_duration);
policy->set_soft_enforce_rental_duration(true);
policy->set_soft_enforce_playback_duration(false);
policy->set_initial_renewal_delay_base(kTimerDelayBaseLicenseLoad);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(license_load_time))
.WillOnce(Return(license_load_time + 3))
.WillOnce(Return(license_load_time + renewal_delay + 10))
.WillOnce(Return(license_load_time + renewal_delay +
renewal_recovery_duration - 5))
.WillOnce(Return(license_decrypt_start_time))
.WillOnce(Return(license_decrypt_start_time + 5))
.WillOnce(Return(license_load_time + playback_duration - 10));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
EXPECT_CALL(check_, Call(1));
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, license_load_time + playback_duration));
EXPECT_CALL(check_, Call(2));
EXPECT_CALL(check_, Call(3));
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(4));
EXPECT_CALL(check_, Call(5));
EXPECT_CALL(check_, Call(6));
EXPECT_CALL(check_, Call(7));
EXPECT_CALL(check_, Call(8));
check_.Call(1);
policy_engine_->SetLicense(license_, false);
check_.Call(2);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(3);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(4);
LicenseIdentification* id = license_.mutable_id();
id->set_version(2);
policy->set_can_renew(false);
policy->set_renewal_delay_seconds(kTwoHours);
policy_engine_->UpdateLicense(license_, false);
check_.Call(5);
policy_engine_->BeginDecryption();
check_.Call(6);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(7);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(8);
}
// Scenario: Limited duration license with clear lead
// Case: 2
//
// Verifies
// 1. When license is loaded
// a. Expiration is is set to rental duration as playback has not begun
// b. Usable keys are returned
// 2. When renewal_delay is exceeded a session renewal event is returned
// 3. When encrypted playback begins after rental duration
// a. Expiration is correctly set based on playback duration
// b. A session renewal event is returned
TEST_F(PolicyEngineTestV18, LimitedDurationLicenseWithClearLead_2) {
const int64_t rental_duration = kFifteenMinutes;
const int64_t playback_duration = kTwoHours;
const int64_t renewal_delay = kFiveSeconds;
const int64_t renewal_recovery_duration = kFortySeconds;
const int64_t license_load_time = kLicenseStartTime + rental_duration + 30;
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(true);
policy->set_renew_with_usage(true);
policy->set_rental_duration_seconds(rental_duration);
policy->set_playback_duration_seconds(playback_duration);
policy->set_renewal_delay_seconds(renewal_delay);
policy->set_renewal_recovery_duration_seconds(renewal_recovery_duration);
policy->set_soft_enforce_rental_duration(true);
policy->set_soft_enforce_playback_duration(false);
policy->set_initial_renewal_delay_base(kTimerDelayBaseLicenseLoad);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(license_load_time))
.WillOnce(Return(license_load_time + 10));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
EXPECT_CALL(check_, Call(1));
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(check_, Call(2));
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + rental_duration));
EXPECT_CALL(check_, Call(3));
check_.Call(1);
policy_engine_->SetLicense(license_, false);
check_.Call(2);
policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(3);
}
// Scenario: Limited duration license with clear lead
// Case: 3S
//
// Verifies
// 1. When license is loaded
// a. Expiration is is set to rental duration as playback has not begun
// b. Usable keys are returned
// 2. When renewal_delay is exceeded a session renewal event is returned
// 3. Encrypted playback begins just inside the rental window
// a. The expiration time is unaffected
// 4. No renewal license is loaded
TEST_F(PolicyEngineTestV18, LimitedDurationLicenseWithClearLead_3S) {
const int64_t rental_duration = kFifteenMinutes;
const int64_t playback_duration = kTwoHours;
const int64_t renewal_delay = kFiveSeconds;
const int64_t renewal_recovery_duration = kFortySeconds;
const int64_t license_load_time = kLicenseStartTime + rental_duration - 30;
const int64_t license_decrypt_start_time = license_load_time + 20;
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(true);
policy->set_renew_with_usage(true);
policy->set_rental_duration_seconds(rental_duration);
policy->set_playback_duration_seconds(playback_duration);
policy->set_renewal_delay_seconds(renewal_delay);
policy->set_renewal_recovery_duration_seconds(renewal_recovery_duration);
policy->set_soft_enforce_rental_duration(true);
policy->set_soft_enforce_playback_duration(false);
policy->set_initial_renewal_delay_base(kTimerDelayBaseLicenseLoad);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(license_load_time))
.WillOnce(Return(license_load_time + 3))
.WillOnce(Return(license_load_time + renewal_delay + 10))
.WillOnce(Return(license_decrypt_start_time))
.WillOnce(Return(license_decrypt_start_time + 20))
.WillOnce(Return(license_decrypt_start_time + 30));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
EXPECT_CALL(check_, Call(1));
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, license_load_time + playback_duration));
EXPECT_CALL(check_, Call(2));
EXPECT_CALL(check_, Call(3));
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(4));
EXPECT_CALL(check_, Call(5));
EXPECT_CALL(check_, Call(6));
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(7));
check_.Call(1);
policy_engine_->SetLicense(license_, false);
check_.Call(2);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(3);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(4);
policy_engine_->BeginDecryption();
check_.Call(5);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(6);
policy_engine_->OnTimerEvent();
check_.Call(7);
}
// Scenario: Limited duration license with clear lead
// Case: 3M
//
// Verifies
// 1. When license is loaded
// a. Expiration is is set to rental duration as playback has not begun
// b. Usable keys are returned
// 2. When renewal_delay is exceeded a session renewal event is returned
// 3. No renewal license is loaded
// 3. Encrypted playback begins just outside the rental window
// a. The expiration time is unaffected
// 4. No renewal license is loaded
TEST_F(PolicyEngineTestV18, LimitedDurationLicenseWithClearLead_3M) {
const int64_t rental_duration = kFifteenMinutes;
const int64_t playback_duration = kTwoHours;
const int64_t renewal_delay = kFiveSeconds;
const int64_t renewal_recovery_duration = kFortySeconds;
const int64_t license_load_time = kLicenseStartTime + rental_duration - 30;
const int64_t license_decrypt_start_time = license_load_time + 35;
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(true);
policy->set_renew_with_usage(true);
policy->set_rental_duration_seconds(rental_duration);
policy->set_playback_duration_seconds(playback_duration);
policy->set_renewal_delay_seconds(renewal_delay);
policy->set_renewal_recovery_duration_seconds(renewal_recovery_duration);
policy->set_soft_enforce_rental_duration(true);
policy->set_soft_enforce_playback_duration(false);
policy->set_initial_renewal_delay_base(kTimerDelayBaseLicenseLoad);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(license_load_time))
.WillOnce(Return(license_load_time + 3))
.WillOnce(Return(license_load_time + renewal_delay + 10))
.WillOnce(Return(license_decrypt_start_time))
.WillOnce(Return(license_decrypt_start_time + 5))
.WillOnce(Return(license_decrypt_start_time + 15));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
EXPECT_CALL(check_, Call(1));
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, license_load_time + playback_duration));
EXPECT_CALL(check_, Call(2));
EXPECT_CALL(check_, Call(3));
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(4));
EXPECT_CALL(check_, Call(5));
EXPECT_CALL(check_, Call(6));
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(7));
check_.Call(1);
policy_engine_->SetLicense(license_, false);
check_.Call(2);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(3);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(4);
policy_engine_->BeginDecryption();
check_.Call(5);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(6);
policy_engine_->OnTimerEvent();
check_.Call(7);
}
// Scenario: Limited duration license with clear lead
// Case: 3L
//
// Verifies
// 1. When license is loaded
// a. Expiration is is set to rental duration as playback has not begun
// b. Usable keys are returned
// 2. When renewal_delay is exceeded a session renewal event is returned
// 3. No renewal license is loaded
// 4. Encrypted playback begins outsdide the rental duration
TEST_F(PolicyEngineTestV18, LimitedDurationLicenseWithClearLead_3L) {
const int64_t rental_duration = kFifteenMinutes;
const int64_t playback_duration = kTwoHours;
const int64_t renewal_delay = kFiveSeconds;
const int64_t renewal_recovery_duration = kFortySeconds;
const int64_t license_load_time = kLicenseStartTime + rental_duration - 30;
const int64_t license_decrypt_start_time =
license_load_time + renewal_delay + renewal_recovery_duration + 10;
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(true);
policy->set_renew_with_usage(true);
policy->set_rental_duration_seconds(rental_duration);
policy->set_playback_duration_seconds(playback_duration);
policy->set_renewal_delay_seconds(renewal_delay);
policy->set_renewal_recovery_duration_seconds(renewal_recovery_duration);
policy->set_soft_enforce_rental_duration(true);
policy->set_soft_enforce_playback_duration(false);
policy->set_initial_renewal_delay_base(kTimerDelayBaseLicenseLoad);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(license_load_time))
.WillOnce(Return(license_load_time + 3))
.WillOnce(Return(license_load_time + renewal_delay + 10))
.WillOnce(Return(license_load_time + renewal_delay +
renewal_recovery_duration - 5))
.WillOnce(Return(license_decrypt_start_time))
.WillOnce(Return(license_decrypt_start_time + 5));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
EXPECT_CALL(check_, Call(1));
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, license_load_time + playback_duration));
EXPECT_CALL(check_, Call(2));
EXPECT_CALL(check_, Call(3));
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(4));
EXPECT_CALL(check_, Call(5));
EXPECT_CALL(check_, Call(6));
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(7));
check_.Call(1);
policy_engine_->SetLicense(license_, false);
check_.Call(2);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(3);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(4);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(5);
policy_engine_->BeginDecryption();
check_.Call(6);
policy_engine_->OnTimerEvent();
check_.Call(7);
}
// Scenario: Limited duration license with clear lead
// Case: 4, 5
//
// Verifies
// 1. When license is loaded
// a. Expiration is is set to rental duration as playback has not begun
// b. Usable keys are returned
// 2. When renewal_delay is exceeded a session renewal event is returned
// 3. When encrypted playback begins after rental duration
// a. Expiration is correctly set based on playback duration
// b. A session renewal event is returned
// 4. When playback duration is exceeded
// a. Keys are expired
TEST_F(PolicyEngineTestV18, LimitedDurationLicenseWithClearLead_4) {
const int64_t rental_duration = kFifteenMinutes;
const int64_t playback_duration = kTwoHours;
const int64_t renewal_delay = kFiveSeconds;
const int64_t renewal_recovery_duration = kFortySeconds;
const int64_t license_load_time = kLicenseStartTime + rental_duration - 30;
const int64_t license_decrypt_start_time = license_load_time + 30;
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(true);
policy->set_renew_with_usage(true);
policy->set_rental_duration_seconds(rental_duration);
policy->set_playback_duration_seconds(playback_duration);
policy->set_renewal_delay_seconds(renewal_delay);
policy->set_renewal_recovery_duration_seconds(renewal_recovery_duration);
policy->set_soft_enforce_rental_duration(true);
policy->set_soft_enforce_playback_duration(false);
policy->set_initial_renewal_delay_base(kTimerDelayBaseLicenseLoad);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(license_load_time))
.WillOnce(Return(license_load_time + 3))
.WillOnce(Return(license_load_time + 10))
.WillOnce(Return(license_decrypt_start_time))
.WillOnce(Return(license_decrypt_start_time + 10))
.WillOnce(Return(license_load_time + playback_duration - 10))
.WillOnce(Return(license_load_time + playback_duration + 10));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
EXPECT_CALL(check_, Call(1));
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, license_load_time + playback_duration));
EXPECT_CALL(check_, Call(2));
EXPECT_CALL(check_, Call(3));
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(4));
EXPECT_CALL(check_, Call(5));
EXPECT_CALL(check_, Call(6));
EXPECT_CALL(check_, Call(7));
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(check_, Call(8));
check_.Call(1);
policy_engine_->SetLicense(license_, false);
check_.Call(2);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(3);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(4);
policy_engine_->BeginDecryption();
check_.Call(5);
LicenseIdentification* id = license_.mutable_id();
id->set_version(2);
policy->set_can_renew(false);
policy->set_renewal_delay_seconds(kTwoHours);
policy_engine_->UpdateLicense(license_, false);
check_.Call(6);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(7);
policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(8);
}
// Scenario: License with Renewal
// Case: Timer Base unspecified.
//
// This should be the same bevhavior as license start
//
// Verifies
// 1. When license is loaded
// a. Expiration is is set to unlimited as playback has not begun
// b. Usable keys are returned
// 2. When playback begins Expiration is correctly set based on
// playback duration
// 3. When renewal_delay is exceeded a session renewal event is returned
// 4. When license is renewed, durations have been adjusted but windows
// have not been changed so no event is sent
// 5. After playback window is past
// a. License is correctly expired based on playback duration
// b. Keys are reported as expired
TEST_F(PolicyEngineTestV18, LicensWithRenewal_TimerBaseUnspecified) {
const int64_t playback_duration = kTwoDays;
const int64_t renewal_delay = kFiveMinutes;
const int64_t renewal_recovery_duration = kTenSeconds;
const int64_t license_decrypt_start_time = kLicenseStartTime + 10;
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(true);
policy->set_rental_duration_seconds(kDurationUnlimited);
policy->set_playback_duration_seconds(playback_duration);
policy->set_renewal_delay_seconds(renewal_delay);
policy->set_renewal_recovery_duration_seconds(renewal_recovery_duration);
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
policy->set_initial_renewal_delay_base(kTimerDelayBaseUnspecified);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime))
.WillOnce(Return(license_decrypt_start_time))
.WillOnce(Return(kLicenseStartTime + renewal_delay - 10))
.WillOnce(Return(kLicenseStartTime + renewal_delay + 10))
.WillOnce(Return(kLicenseStartTime + renewal_delay + 20))
.WillOnce(Return(license_decrypt_start_time + playback_duration - 10))
.WillOnce(Return(license_decrypt_start_time + playback_duration + 10));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
EXPECT_CALL(check_, Call(1));
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, 0));
EXPECT_CALL(check_, Call(2));
EXPECT_CALL(
mock_event_listener_,
OnExpirationUpdate(_, license_decrypt_start_time + playback_duration));
EXPECT_CALL(check_, Call(3));
EXPECT_CALL(check_, Call(4));
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(5));
EXPECT_CALL(check_, Call(6));
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(7));
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(check_, Call(8));
check_.Call(1);
policy_engine_->SetLicense(license_, false);
check_.Call(2);
policy_engine_->BeginDecryption();
check_.Call(3);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(4);
policy_engine_->OnTimerEvent();
check_.Call(5);
LicenseIdentification* id = license_.mutable_id();
id->set_version(2);
policy_engine_->UpdateLicense(license_, false);
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(6);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(7);
policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(8);
}
// Scenario: License with Renewal
// Case: Timer Base First Decrypt
//
// Verifies
// 1. When license is loaded
// a. Expiration is is set to unlimited as playback has not begun
// b. Usable keys are returned
// 2. When playback begins Expiration is correctly set based on
// playback duration
// 3. When renewal_delay is exceeded a session renewal event is returned
// 4. When license is renewed, durations have been adjusted but windows
// have not been changed so no event is sent
// 5. After playback window is past
// a. License is correctly expired based on playback duration
// b. Keys are reported as expired
TEST_F(PolicyEngineTestV18, LicensWithRenewal_TimerBaseFirstDecrypt) {
const int64_t playback_duration = kTwoDays;
const int64_t renewal_delay = kFiveMinutes;
const int64_t renewal_recovery_duration = kTenSeconds;
const int64_t license_decrypt_start_time = kLicenseStartTime + 10;
License_Policy* policy = license_.mutable_policy();
policy->set_can_renew(true);
policy->set_rental_duration_seconds(kDurationUnlimited);
policy->set_playback_duration_seconds(playback_duration);
policy->set_renewal_delay_seconds(renewal_delay);
policy->set_renewal_recovery_duration_seconds(renewal_recovery_duration);
policy->set_soft_enforce_rental_duration(false);
policy->set_soft_enforce_playback_duration(false);
policy->set_initial_renewal_delay_base(kTimerDelayBaseLicenseFirstDecrypt);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime))
.WillOnce(Return(license_decrypt_start_time))
.WillOnce(Return(kLicenseStartTime + renewal_delay - 10))
.WillOnce(Return(kLicenseStartTime + renewal_delay + 10))
.WillOnce(Return(kLicenseStartTime + renewal_delay + 20))
.WillOnce(Return(license_decrypt_start_time + playback_duration - 10))
.WillOnce(Return(license_decrypt_start_time + playback_duration + 10));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED))));
InSequence s;
EXPECT_CALL(check_, Call(1));
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, 0));
EXPECT_CALL(check_, Call(2));
EXPECT_CALL(
mock_event_listener_,
OnExpirationUpdate(_, license_decrypt_start_time + playback_duration));
EXPECT_CALL(check_, Call(3));
EXPECT_CALL(check_, Call(4));
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(5));
EXPECT_CALL(check_, Call(6));
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_));
EXPECT_CALL(check_, Call(7));
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(check_, Call(8));
check_.Call(1);
policy_engine_->SetLicense(license_, false);
check_.Call(2);
policy_engine_->BeginDecryption();
check_.Call(3);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(4);
policy_engine_->OnTimerEvent();
check_.Call(5);
LicenseIdentification* id = license_.mutable_id();
id->set_version(2);
policy_engine_->UpdateLicense(license_, false);
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(6);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(7);
policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId));
check_.Call(8);
}
} // namespace wvcdm