Merge "Revert "Core CDM: Remove secure stop from LRU algorithm.""
This commit is contained in:
@@ -229,9 +229,9 @@ const CdmKeyResponse kKeyRenewalResponse = "key renewal response";
|
||||
const std::string kReleaseServerUrl = "some url";
|
||||
const std::string kProviderSessionToken = "provider session token";
|
||||
const CdmAppParameterMap kEmptyAppParameters;
|
||||
constexpr int64_t kPlaybackStartTime = 1030005;
|
||||
constexpr int64_t kPlaybackDuration = 300;
|
||||
constexpr int64_t kGracePeriodEndTime = 60;
|
||||
int64_t kPlaybackStartTime = 1030005;
|
||||
int64_t kPlaybackDuration = 300;
|
||||
int64_t kGracePeriodEndTime = 60;
|
||||
|
||||
// ==== LRU Upgrade Data ====
|
||||
const CdmUsageTableHeader kUpgradableUsageTableHeader =
|
||||
@@ -245,9 +245,9 @@ const CdmUsageEntryInfo kUpgradableUsageEntryInfo1 = {
|
||||
/* last_use_time = */ 0,
|
||||
/* offline_license_expiry_time = */ 0};
|
||||
const CdmUsageEntryInfo kUpgradableUsageEntryInfo2 = {
|
||||
/* storage_type = */ kStorageLicense,
|
||||
/* key_set_id = */ "offline_key_set_2",
|
||||
/* usage_info_file_name = */ "",
|
||||
/* storage_type = */ kStorageUsageInfo,
|
||||
/* key_set_id = */ "streaming_key_set_2",
|
||||
/* usage_info_file_name = */ "streaming_license_file_2",
|
||||
/* last_use_time = */ 0,
|
||||
/* offline_license_expiry_time = */ 0};
|
||||
const CdmUsageEntryInfo kUpgradableUsageEntryInfo3 = {
|
||||
@@ -256,11 +256,7 @@ const CdmUsageEntryInfo kUpgradableUsageEntryInfo3 = {
|
||||
/* usage_info_file_name = */ "",
|
||||
/* last_use_time = */ 0,
|
||||
/* offline_license_expiry_time = */ 0};
|
||||
const std::vector<CdmUsageEntryInfo> kUpgradableUsageEntryInfoList{
|
||||
kUpgradableUsageEntryInfo1, kUpgradableUsageEntryInfo2,
|
||||
kUpgradableUsageEntryInfo3};
|
||||
|
||||
const int64_t kLruBaseTime = 1563399000;
|
||||
std::vector<CdmUsageEntryInfo> kUpgradableUsageEntryInfoList;
|
||||
|
||||
// Offline license 1.
|
||||
// license_start_time = 1563399000
|
||||
@@ -270,14 +266,11 @@ const int64_t kLruBaseTime = 1563399000;
|
||||
const CdmKeyResponse kUpgradableLicenseInfo1 = wvutil::a2bs_hex(
|
||||
"08021214120C2080F5242880A3053080E90F20D8A6BEE9051A20D5F7ACE8D84A166C69BB"
|
||||
"27523C84C019464B90AA9BF06B8332004839119BFD14");
|
||||
// Offline license 2.
|
||||
// Streaming license 2.
|
||||
// license_start_time = 1563399000
|
||||
// license_duration_seconds = 259200 (3 days)
|
||||
// rental_duration_seconds = 0 (unlimited)
|
||||
// playback_duration_seconds = 0 (unlimited)
|
||||
const CdmKeyResponse kUpgradableLicenseInfo2 = wvutil::a2bs_hex(
|
||||
"080212101208200028003080E90F20D8A6BEE9051A20D0611C4AFEF3EC9C67143ED39B44"
|
||||
"8FAAA67DB6C4DBFDC28A733AF9A2EABDF0B3");
|
||||
"0802120620D8A6BEE9051A201956F2FD69E5E96DA8C65FDD04A3C294E484F219F2B1A8DD"
|
||||
"C2B0737F6EF5BD22");
|
||||
// Offline license 3.
|
||||
// license_start_time = 1563399000
|
||||
// license_duration_seconds = 0 (unlimited)
|
||||
@@ -286,56 +279,26 @@ const CdmKeyResponse kUpgradableLicenseInfo2 = wvutil::a2bs_hex(
|
||||
const CdmKeyResponse kUpgradableLicenseInfo3 = wvutil::a2bs_hex(
|
||||
"08021212120A2080F5242880A305300020D8A6BEE9051A207B09896F46C4EE443170E215"
|
||||
"B2D8D5F072951027B152F4758AC3A339D7C7B4CE");
|
||||
const std::vector<CdmKeyResponse> kUpgradableLicenseInfoList = {
|
||||
kUpgradableLicenseInfo1, kUpgradableLicenseInfo2, kUpgradableLicenseInfo3};
|
||||
|
||||
std::vector<CdmKeyResponse> kUpgradableLicenseInfoList;
|
||||
std::vector<DeviceFiles::CdmLicenseData> kUpgradableLicenseDataList;
|
||||
// Same as Offline license 1, but without signature.
|
||||
const CdmKeyResponse kUnsignedUpgradableLicenseInfo1 =
|
||||
wvutil::a2bs_hex("08021214120C2080F5242880A3053080E90F20D8A6BEE905");
|
||||
// Same as streaming license 2, but message type is certificate, not license.
|
||||
const CdmKeyResponse kWrongTypedUpgradableLicenseInfo2 = wvutil::a2bs_hex(
|
||||
"0805120620D8A6BEE9051A201956F2FD69E5E96DA8C65FDD04A3C294E484F219F2B1A8DD"
|
||||
"C2B0737F6EF5BD22");
|
||||
|
||||
const int64_t kLruBaseTime = 1563399000;
|
||||
const int64_t kUpgradedUsageEntryInfo1LastUsedTime = kLruBaseTime;
|
||||
const int64_t kUpgradedUsageEntryInfo1ExpireTime = kLruBaseTime + 259200;
|
||||
const int64_t kUpgradedUsageEntryInfo2LastUsedTime = kLruBaseTime;
|
||||
const int64_t kUpgradedUsageEntryInfo2ExpireTime = kLruBaseTime + 259200;
|
||||
const int64_t kUpgradedUsageEntryInfo2ExpireTime = 0; // Unset
|
||||
const int64_t kUpgradedUsageEntryInfo3LastUsedTime = kLruBaseTime;
|
||||
const int64_t kUpgradedUsageEntryInfo3ExpireTime =
|
||||
kLruBaseTime + 604800 + 86400;
|
||||
const CdmUsageTableHeader kUpgradedUsageTableHeader = "Upgraded Table Header";
|
||||
const CdmUsageEntryInfo kUpgradedUsageEntryInfo1 = {
|
||||
/* storage_type = */ kStorageLicense,
|
||||
/* key_set_id = */ "offline_key_set_1",
|
||||
/* usage_info_file_name = */ "",
|
||||
/* last_use_time = */ kUpgradedUsageEntryInfo1LastUsedTime,
|
||||
/* offline_license_expiry_time = */ kUpgradedUsageEntryInfo1ExpireTime};
|
||||
const CdmUsageEntryInfo kUpgradedUsageEntryInfo2 = {
|
||||
/* storage_type = */ kStorageLicense,
|
||||
/* key_set_id = */ "offline_key_set_2",
|
||||
/* usage_info_file_name = */ "",
|
||||
/* last_use_time = */ kUpgradedUsageEntryInfo2LastUsedTime,
|
||||
/* offline_license_expiry_time = */ kUpgradedUsageEntryInfo2ExpireTime};
|
||||
const CdmUsageEntryInfo kUpgradedUsageEntryInfo3 = {
|
||||
/* storage_type = */ kStorageLicense,
|
||||
/* key_set_id = */ "offline_key_set_3",
|
||||
/* usage_info_file_name = */ "",
|
||||
/* last_use_time = */ kUpgradedUsageEntryInfo3LastUsedTime,
|
||||
/* offline_license_expiry_time = */ kUpgradedUsageEntryInfo3ExpireTime};
|
||||
|
||||
const std::vector<CdmUsageEntryInfo> kUpgradedUsageEntryInfoList = {
|
||||
kUpgradedUsageEntryInfo1, kUpgradedUsageEntryInfo2,
|
||||
kUpgradedUsageEntryInfo3};
|
||||
|
||||
std::vector<DeviceFiles::CdmLicenseData> CreateUpgradableLicenseInfoList() {
|
||||
std::vector<DeviceFiles::CdmLicenseData> license_data_list;
|
||||
for (size_t i = 0; i < kUpgradableLicenseInfoList.size(); ++i) {
|
||||
DeviceFiles::CdmLicenseData license_data;
|
||||
license_data.key_set_id = kUpgradableUsageEntryInfoList[i].key_set_id;
|
||||
license_data.state = kActiveLicenseState;
|
||||
license_data.license = kUpgradableLicenseInfoList[i];
|
||||
license_data.usage_entry_number = static_cast<uint32_t>(i);
|
||||
license_data_list.push_back(license_data);
|
||||
}
|
||||
return license_data_list;
|
||||
}
|
||||
std::vector<CdmUsageEntryInfo> kUpgradedUsageEntryInfoList;
|
||||
|
||||
void InitVectorConstants() {
|
||||
kOverFullUsageEntryInfoVector.clear();
|
||||
@@ -369,6 +332,40 @@ void InitVectorConstants() {
|
||||
for (size_t i = 0; i < kLicenseArraySize; i++) {
|
||||
kLicenseList.push_back(kLicenseArray[i]);
|
||||
}
|
||||
|
||||
// LRU Data.
|
||||
kUpgradableUsageEntryInfoList.push_back(kUpgradableUsageEntryInfo1);
|
||||
kUpgradableUsageEntryInfoList.push_back(kUpgradableUsageEntryInfo2);
|
||||
kUpgradableUsageEntryInfoList.push_back(kUpgradableUsageEntryInfo3);
|
||||
|
||||
kUpgradableLicenseInfoList.push_back(kUpgradableLicenseInfo1);
|
||||
kUpgradableLicenseInfoList.push_back(kUpgradableLicenseInfo2);
|
||||
kUpgradableLicenseInfoList.push_back(kUpgradableLicenseInfo3);
|
||||
|
||||
kUpgradedUsageEntryInfoList.push_back(kUpgradableUsageEntryInfo1);
|
||||
kUpgradedUsageEntryInfoList.back().last_use_time =
|
||||
kUpgradedUsageEntryInfo1LastUsedTime;
|
||||
kUpgradedUsageEntryInfoList.back().offline_license_expiry_time =
|
||||
kUpgradedUsageEntryInfo1ExpireTime;
|
||||
kUpgradedUsageEntryInfoList.push_back(kUpgradableUsageEntryInfo2);
|
||||
kUpgradedUsageEntryInfoList.back().last_use_time =
|
||||
kUpgradedUsageEntryInfo2LastUsedTime;
|
||||
kUpgradedUsageEntryInfoList.back().offline_license_expiry_time =
|
||||
kUpgradedUsageEntryInfo2ExpireTime;
|
||||
kUpgradedUsageEntryInfoList.push_back(kUpgradableUsageEntryInfo3);
|
||||
kUpgradedUsageEntryInfoList.back().last_use_time =
|
||||
kUpgradedUsageEntryInfo3LastUsedTime;
|
||||
kUpgradedUsageEntryInfoList.back().offline_license_expiry_time =
|
||||
kUpgradedUsageEntryInfo3ExpireTime;
|
||||
|
||||
for (size_t i = 0; i < kUpgradableLicenseInfoList.size(); ++i) {
|
||||
DeviceFiles::CdmLicenseData license_data;
|
||||
license_data.key_set_id = kUpgradableUsageEntryInfoList[i].key_set_id;
|
||||
license_data.state = kActiveLicenseState;
|
||||
license_data.license = kUpgradableLicenseInfoList[i];
|
||||
license_data.usage_entry_number = static_cast<uint32_t>(i);
|
||||
kUpgradableLicenseDataList.push_back(license_data);
|
||||
}
|
||||
}
|
||||
|
||||
void ToVector(std::vector<CdmUsageEntryInfo>& vec, const CdmUsageEntryInfo* arr,
|
||||
@@ -405,6 +402,9 @@ class MockDeviceFiles : public DeviceFiles {
|
||||
(override));
|
||||
MOCK_METHOD(bool, DeleteUsageInfo, (const std::string&, const std::string&),
|
||||
(override));
|
||||
MOCK_METHOD(bool, DeleteMultipleUsageInfoByKeySetIds,
|
||||
(const std::string&, const std::vector<std::string>&),
|
||||
(override));
|
||||
MOCK_METHOD(bool, RetrieveUsageInfoByKeySetId,
|
||||
(const std::string&, const std::string&, std::string*,
|
||||
CdmKeyMessage*, CdmKeyResponse*, CdmUsageEntry*, uint32_t*,
|
||||
@@ -3728,6 +3728,9 @@ TEST_F(UsageTableHeaderTest, LruUsageTableUpgrade_NoAction) {
|
||||
|
||||
// These function are called specifically by the LRU upgrading system.
|
||||
EXPECT_CALL(*device_files_, RetrieveLicense(_, _, _)).Times(0);
|
||||
EXPECT_CALL(*device_files_,
|
||||
RetrieveUsageInfoByKeySetId(_, _, _, _, _, _, _, _, _))
|
||||
.Times(0);
|
||||
|
||||
EXPECT_TRUE(usage_table_header_->Init(kSecurityLevelL1, crypto_session_));
|
||||
EXPECT_EQ(usage_table_header_->usage_entry_info(),
|
||||
@@ -3737,8 +3740,8 @@ TEST_F(UsageTableHeaderTest, LruUsageTableUpgrade_NoAction) {
|
||||
// Initial Test state:
|
||||
// 1. Table info is load from device files; however, device files reports
|
||||
// that the table has not been configured for upgrade.
|
||||
// 2. The usage table header will load offline license to determine
|
||||
// appropriate expiry and last_used times.
|
||||
// 2. The usage table header will load license or usage information to
|
||||
// determine appropriate expiry and last_used times.
|
||||
TEST_F(UsageTableHeaderTest, LruUsageTableUpgrade_Succeed) {
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
GetNumberOfOpenSessions(kLevelDefault, NotNull()))
|
||||
@@ -3753,18 +3756,24 @@ TEST_F(UsageTableHeaderTest, LruUsageTableUpgrade_Succeed) {
|
||||
LoadUsageTableHeader(kLevelDefault, kUpgradableUsageTableHeader))
|
||||
.WillOnce(Return(NO_ERROR));
|
||||
|
||||
const std::vector<DeviceFiles::CdmLicenseData> license_info_list =
|
||||
CreateUpgradableLicenseInfoList();
|
||||
|
||||
for (size_t i = 0; i < kUpgradableUsageEntryInfoList.size(); ++i) {
|
||||
const CdmUsageEntryInfo& info = kUpgradableUsageEntryInfoList[i];
|
||||
|
||||
if (info.storage_type == kStorageLicense) {
|
||||
// Only offline licenses are supported.
|
||||
EXPECT_CALL(*device_files_,
|
||||
RetrieveLicense(info.key_set_id, NotNull(), NotNull()))
|
||||
.WillOnce(
|
||||
DoAll(SetArgPointee<1>(license_info_list[i]), Return(true)));
|
||||
.WillOnce(DoAll(SetArgPointee<1>(kUpgradableLicenseDataList[i]),
|
||||
Return(true)));
|
||||
} else {
|
||||
EXPECT_CALL(*device_files_,
|
||||
RetrieveUsageInfoByKeySetId(info.usage_info_file_name,
|
||||
info.key_set_id, NotNull(),
|
||||
NotNull(), NotNull(), NotNull(),
|
||||
NotNull(), NotNull(), NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<4>(kUpgradableLicenseInfoList[i]),
|
||||
SetArgPointee<6>(static_cast<uint32_t>(i)),
|
||||
SetArgPointee<7>(kDrmCertificate),
|
||||
SetArgPointee<8>(kCryptoWrappedKey), Return(true)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3774,22 +3783,33 @@ TEST_F(UsageTableHeaderTest, LruUsageTableUpgrade_Succeed) {
|
||||
}
|
||||
|
||||
// Initial Test state:
|
||||
// Table info is load from device files and must be upgraded.
|
||||
// A few entries have the unknown storage type value.
|
||||
// 1. Table info is load from device files and must be upgraded.
|
||||
// A few entries have the incorrect storage type value.
|
||||
// 2. During the LRU upgrade process, any license that cannot be
|
||||
// validated are cleared, and marked to be deleted.
|
||||
//
|
||||
// Entry# Storage type Result info
|
||||
// ====== ============ ===========
|
||||
// 0 Offline Upgraded
|
||||
// 1 Unknown Cleared
|
||||
// 2 Unknown Cleared
|
||||
// 2 Invalid (99) Cleared
|
||||
TEST_F(UsageTableHeaderTest,
|
||||
LruUsageTableUpgrade_PartialSucceedWithUnknownStorageTypes) {
|
||||
const std::vector<CdmUsageEntryInfo> upgradable_usage_entry_info_list = {
|
||||
kUpgradableUsageEntryInfo1, kUsageEntryInfoStorageTypeUnknown,
|
||||
kUsageEntryInfoStorageTypeUnknown};
|
||||
const std::vector<CdmUsageEntryInfo> upgraded_usage_entry_info_list = {
|
||||
kUpgradedUsageEntryInfo1, kUsageEntryInfoStorageTypeUnknown,
|
||||
kUsageEntryInfoStorageTypeUnknown};
|
||||
std::vector<CdmUsageEntryInfo> upgradable_usage_entry_info_list =
|
||||
kUpgradableUsageEntryInfoList;
|
||||
std::vector<CdmUsageEntryInfo> upgraded_usage_entry_info_list =
|
||||
kUpgradedUsageEntryInfoList;
|
||||
|
||||
// Set the wrong storage type.
|
||||
upgradable_usage_entry_info_list[1].storage_type = kStorageTypeUnknown;
|
||||
upgradable_usage_entry_info_list[2].storage_type =
|
||||
static_cast<CdmUsageEntryStorageType>(99);
|
||||
|
||||
// Set the expected output.
|
||||
upgraded_usage_entry_info_list[1] = CdmUsageEntryInfo{};
|
||||
upgraded_usage_entry_info_list[1].storage_type = kStorageTypeUnknown;
|
||||
upgraded_usage_entry_info_list[2] = CdmUsageEntryInfo{};
|
||||
upgraded_usage_entry_info_list[2].storage_type = kStorageTypeUnknown;
|
||||
|
||||
// Load table expectations.
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
@@ -3806,12 +3826,11 @@ TEST_F(UsageTableHeaderTest,
|
||||
.WillOnce(Return(NO_ERROR));
|
||||
|
||||
// Expectations of the one successful license.
|
||||
const std::vector<DeviceFiles::CdmLicenseData> license_info_list =
|
||||
CreateUpgradableLicenseInfoList();
|
||||
EXPECT_CALL(*device_files_,
|
||||
RetrieveLicense(upgradable_usage_entry_info_list[0].key_set_id,
|
||||
NotNull(), NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<1>(license_info_list[0]), Return(true)));
|
||||
.WillOnce(
|
||||
DoAll(SetArgPointee<1>(kUpgradableLicenseDataList[0]), Return(true)));
|
||||
|
||||
EXPECT_TRUE(usage_table_header_->Init(kSecurityLevelL1, crypto_session_));
|
||||
EXPECT_EQ(upgraded_usage_entry_info_list,
|
||||
@@ -3827,14 +3846,12 @@ TEST_F(UsageTableHeaderTest,
|
||||
// Entry# Storage type License Issue Result info
|
||||
// ====== ============ ============= ===========
|
||||
// 0 Offline No signature Cleared
|
||||
// 1 Unknown Clear entry Cleared
|
||||
// 1 Streaming Wrong type Cleared
|
||||
// 2 Offline Upgraded
|
||||
TEST_F(UsageTableHeaderTest,
|
||||
LruUsageTableUpgrade_PartialSucceedWithLicenseParseIssues) {
|
||||
std::vector<CdmUsageEntryInfo> upgradable_usage_entry_info_list =
|
||||
kUpgradableUsageEntryInfoList;
|
||||
std::vector<DeviceFiles::CdmLicenseData> license_data_list =
|
||||
CreateUpgradableLicenseInfoList();
|
||||
kUpgradableLicenseDataList;
|
||||
std::vector<CdmKeyResponse> upgradable_license_info_list =
|
||||
kUpgradableLicenseInfoList;
|
||||
std::vector<CdmUsageEntryInfo> upgraded_usage_entry_info_list =
|
||||
@@ -3842,12 +3859,21 @@ TEST_F(UsageTableHeaderTest,
|
||||
|
||||
// Modify entry 0 to be invalid.
|
||||
license_data_list[0].license = kUnsignedUpgradableLicenseInfo1;
|
||||
upgraded_usage_entry_info_list[0].Clear();
|
||||
CdmUsageEntryInfo& unsigned_usage_entry_info =
|
||||
upgraded_usage_entry_info_list[0];
|
||||
unsigned_usage_entry_info.storage_type = kStorageTypeUnknown;
|
||||
unsigned_usage_entry_info.key_set_id.clear();
|
||||
unsigned_usage_entry_info.last_use_time = 0;
|
||||
unsigned_usage_entry_info.offline_license_expiry_time = 0;
|
||||
|
||||
// Modify entry 1 to be clear.
|
||||
upgradable_usage_entry_info_list[1].Clear();
|
||||
upgradable_license_info_list[1].clear();
|
||||
upgraded_usage_entry_info_list[1].Clear();
|
||||
// Modify entry 1 to be invalid.
|
||||
upgradable_license_info_list[1] = kWrongTypedUpgradableLicenseInfo2;
|
||||
CdmUsageEntryInfo& wrond_typed_usage_entry_info =
|
||||
upgraded_usage_entry_info_list[1];
|
||||
wrond_typed_usage_entry_info.storage_type = kStorageTypeUnknown;
|
||||
wrond_typed_usage_entry_info.key_set_id.clear();
|
||||
wrond_typed_usage_entry_info.last_use_time = 0;
|
||||
wrond_typed_usage_entry_info.offline_license_expiry_time = 0;
|
||||
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
GetNumberOfOpenSessions(kLevelDefault, NotNull()))
|
||||
@@ -3855,27 +3881,46 @@ TEST_F(UsageTableHeaderTest,
|
||||
EXPECT_CALL(*device_files_, RetrieveUsageTableInfo(NotNull(), NotNull(),
|
||||
NotNull(), NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(kUpgradableUsageTableHeader),
|
||||
SetArgPointee<1>(upgradable_usage_entry_info_list),
|
||||
SetArgPointee<1>(kUpgradableUsageEntryInfoList),
|
||||
SetArgPointee<2>(/* lru_upgrade = */ true),
|
||||
SetArgPointee<3>(false), Return(true)));
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
LoadUsageTableHeader(kLevelDefault, kUpgradableUsageTableHeader))
|
||||
.WillOnce(Return(NO_ERROR));
|
||||
|
||||
for (size_t i = 0; i < upgradable_usage_entry_info_list.size(); ++i) {
|
||||
const CdmUsageEntryInfo& info = upgradable_usage_entry_info_list[i];
|
||||
for (size_t i = 0; i < kUpgradableUsageEntryInfoList.size(); ++i) {
|
||||
const CdmUsageEntryInfo& info = kUpgradableUsageEntryInfoList[i];
|
||||
if (info.storage_type == kStorageLicense) {
|
||||
EXPECT_CALL(*device_files_,
|
||||
RetrieveLicense(info.key_set_id, NotNull(), NotNull()))
|
||||
.WillOnce(
|
||||
DoAll(SetArgPointee<1>(license_data_list[i]), Return(true)));
|
||||
} else {
|
||||
EXPECT_CALL(*device_files_,
|
||||
RetrieveUsageInfoByKeySetId(info.usage_info_file_name,
|
||||
info.key_set_id, NotNull(),
|
||||
NotNull(), NotNull(), NotNull(),
|
||||
NotNull(), NotNull(), NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<4>(upgradable_license_info_list[i]),
|
||||
SetArgPointee<6>(static_cast<uint32_t>(i)),
|
||||
SetArgPointee<7>(kDrmCertificate),
|
||||
SetArgPointee<8>(kCryptoWrappedKey), Return(true)));
|
||||
}
|
||||
}
|
||||
|
||||
// For the entries which failed, there should be an attempt to delete the
|
||||
// files associated with them.
|
||||
// Offline license.
|
||||
EXPECT_CALL(*device_files_,
|
||||
DeleteLicense(upgradable_usage_entry_info_list[0].key_set_id))
|
||||
DeleteLicense(kUpgradableUsageEntryInfoList[0].key_set_id))
|
||||
.WillOnce(Return(true));
|
||||
// Streaming license.
|
||||
const std::vector<std::string> corrupted_usage_info_key_set_ids = {
|
||||
kUpgradableUsageEntryInfoList[1].key_set_id};
|
||||
EXPECT_CALL(*device_files_,
|
||||
DeleteMultipleUsageInfoByKeySetIds(
|
||||
kUpgradableUsageEntryInfoList[1].usage_info_file_name,
|
||||
ContainerEq(corrupted_usage_info_key_set_ids)))
|
||||
.WillOnce(Return(true));
|
||||
|
||||
EXPECT_TRUE(usage_table_header_->Init(kSecurityLevelL1, crypto_session_));
|
||||
@@ -3908,6 +3953,13 @@ TEST_F(UsageTableHeaderTest, LruUsageTableUpgrade_AllFailure) {
|
||||
EXPECT_CALL(*device_files_,
|
||||
RetrieveLicense(info.key_set_id, NotNull(), NotNull()))
|
||||
.WillOnce(Return(false));
|
||||
} else {
|
||||
EXPECT_CALL(*device_files_,
|
||||
RetrieveUsageInfoByKeySetId(info.usage_info_file_name,
|
||||
info.key_set_id, NotNull(),
|
||||
NotNull(), NotNull(), NotNull(),
|
||||
NotNull(), NotNull(), NotNull()))
|
||||
.WillOnce(Return(false));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3955,7 +4007,46 @@ TEST_F(UsageTableHeaderTest, LruLastUsedTime_CreateLicenseEntry) {
|
||||
EXPECT_EQ(NO_ERROR, usage_table_header_->AddEntry(
|
||||
crypto_session_, true /* persistent_license */,
|
||||
expected_new_entry.key_set_id,
|
||||
/* usage_info_file_name */ kEmptyString, kEmptyString,
|
||||
expected_new_entry.usage_info_file_name, kEmptyString,
|
||||
&usage_entry_number));
|
||||
|
||||
EXPECT_EQ(expected_usage_entry_number, usage_entry_number);
|
||||
EXPECT_EQ(expected_usage_info_list, usage_table_header_->usage_entry_info());
|
||||
}
|
||||
|
||||
TEST_F(UsageTableHeaderTest, LruLastUsedTime_CreateUsageInfoEntry) {
|
||||
Init(kSecurityLevelL1, kUpgradedUsageTableHeader,
|
||||
kUpgradedUsageEntryInfoList);
|
||||
|
||||
// Expected values.
|
||||
const uint32_t expected_usage_entry_number =
|
||||
static_cast<uint32_t>(kUpgradedUsageEntryInfoList.size());
|
||||
const CdmUsageEntryInfo expected_new_entry = {
|
||||
kStorageUsageInfo, "secure_stop_key_set_5", "streaming_license_file_4",
|
||||
kLruBaseTime, 0 /* No set for streaming license. */
|
||||
};
|
||||
std::vector<CdmUsageEntryInfo> expected_usage_info_list =
|
||||
kUpgradedUsageEntryInfoList;
|
||||
expected_usage_info_list.push_back(expected_new_entry);
|
||||
|
||||
// AddKey expectations
|
||||
EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(expected_usage_entry_number),
|
||||
Return(NO_ERROR)));
|
||||
MockClock mock_clock;
|
||||
usage_table_header_->SetClock(&mock_clock);
|
||||
EXPECT_CALL(mock_clock, GetCurrentTime()).WillOnce(Return(kLruBaseTime));
|
||||
EXPECT_CALL(*crypto_session_, UpdateUsageEntry(NotNull(), NotNull()))
|
||||
.WillOnce(
|
||||
DoAll(SetArgPointee<0>(kAnotherUsageTableHeader), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader, _));
|
||||
|
||||
// The Call.
|
||||
uint32_t usage_entry_number = 0;
|
||||
EXPECT_EQ(NO_ERROR, usage_table_header_->AddEntry(
|
||||
crypto_session_, false /* persistent_license */,
|
||||
expected_new_entry.key_set_id,
|
||||
expected_new_entry.usage_info_file_name, kEmptyString,
|
||||
&usage_entry_number));
|
||||
|
||||
EXPECT_EQ(expected_usage_entry_number, usage_entry_number);
|
||||
@@ -4060,7 +4151,6 @@ TEST_F(UsageTableHeaderTest, DetermineLicenseToRemove_BasicPriorities) {
|
||||
// Unexpired offline license.
|
||||
CdmUsageEntryInfo unexpired_entry_info;
|
||||
unexpired_entry_info.storage_type = kStorageLicense;
|
||||
unexpired_entry_info.key_set_id = "unexpired_key_set_id";
|
||||
unexpired_entry_info.last_use_time = kLruBaseTime;
|
||||
unexpired_entry_info.offline_license_expiry_time = kLruBaseTime + 2 * kOneDay;
|
||||
usage_entry_info_list.push_back(unexpired_entry_info);
|
||||
@@ -4069,43 +4159,59 @@ TEST_F(UsageTableHeaderTest, DetermineLicenseToRemove_BasicPriorities) {
|
||||
// Expired offline license.
|
||||
CdmUsageEntryInfo expired_entry_info;
|
||||
expired_entry_info.storage_type = kStorageLicense;
|
||||
expired_entry_info.key_set_id = "expired_key_set_id";
|
||||
expired_entry_info.last_use_time = kLruBaseTime;
|
||||
expired_entry_info.offline_license_expiry_time = kLruBaseTime;
|
||||
usage_entry_info_list.push_back(expired_entry_info);
|
||||
constexpr uint32_t expired_entry_number = 1;
|
||||
|
||||
// Streaming license.
|
||||
CdmUsageEntryInfo streaming_entry_info;
|
||||
streaming_entry_info.storage_type = kStorageUsageInfo;
|
||||
streaming_entry_info.last_use_time = kLruBaseTime;
|
||||
usage_entry_info_list.push_back(streaming_entry_info);
|
||||
constexpr uint32_t streaming_entry_number = 2;
|
||||
|
||||
// Unknown entry.
|
||||
CdmUsageEntryInfo unknown_entry_info;
|
||||
unknown_entry_info.storage_type = kStorageTypeUnknown;
|
||||
// Should be chosen regardless of |last_use_time|.
|
||||
unknown_entry_info.last_use_time = kCurrentTime;
|
||||
usage_entry_info_list.push_back(unknown_entry_info);
|
||||
constexpr uint32_t unknown_entry_number = 2;
|
||||
constexpr uint32_t unknown_entry_number = 3;
|
||||
|
||||
// Case 1: If there is a clear entry, it should be selected above
|
||||
// any other entry.
|
||||
// Case 1: If there is an entry with unknown storage type, it should
|
||||
// be selected above any other entry.
|
||||
uint32_t entry_to_remove = kInvalidEntry;
|
||||
|
||||
// Expect the clear.
|
||||
// Expect the unknown entry.
|
||||
EXPECT_TRUE(UsageTableHeader::DetermineLicenseToRemoveForTesting(
|
||||
usage_entry_info_list, kCurrentTime,
|
||||
/* unexpired_threshold = */ 3, &entry_to_remove));
|
||||
EXPECT_EQ(unknown_entry_number, entry_to_remove);
|
||||
|
||||
usage_entry_info_list.pop_back(); // Removing clear entry.
|
||||
// |usage_entry_info_list| only contains 1 expired and 1 unexpired offline
|
||||
// license.
|
||||
usage_entry_info_list.pop_back(); // Removing unknown.
|
||||
|
||||
// Case 2a: Threshold not met, all entries are equally stale.
|
||||
// The expired entry should be selected over the unexpired entry.
|
||||
// The expired entry should be selected over the streaming license.
|
||||
entry_to_remove = kInvalidEntry;
|
||||
EXPECT_TRUE(UsageTableHeader::DetermineLicenseToRemoveForTesting(
|
||||
usage_entry_info_list, kCurrentTime,
|
||||
/* unexpired_threshold = */ 3, &entry_to_remove));
|
||||
EXPECT_EQ(expired_entry_number, entry_to_remove);
|
||||
|
||||
// Case 2b: Threshold met, equally stale entries. Expect the expired
|
||||
// Case 2b: Threshold not met, streaming license is most stale.
|
||||
usage_entry_info_list[streaming_entry_number].last_use_time--;
|
||||
entry_to_remove = kInvalidEntry;
|
||||
EXPECT_TRUE(UsageTableHeader::DetermineLicenseToRemoveForTesting(
|
||||
usage_entry_info_list, kCurrentTime,
|
||||
/* unexpired_threshold = */ 3, &entry_to_remove));
|
||||
EXPECT_EQ(streaming_entry_number, entry_to_remove);
|
||||
|
||||
usage_entry_info_list.pop_back(); // Removing streaming.
|
||||
// |usage_entry_info_list| only contains 1 expired and 1 unexpired offline
|
||||
// license.
|
||||
|
||||
// Case 2c: Threshold met, equally stale entries. Expect the expired
|
||||
// entry over the unexpired.
|
||||
entry_to_remove = kInvalidEntry;
|
||||
EXPECT_TRUE(UsageTableHeader::DetermineLicenseToRemoveForTesting(
|
||||
@@ -4167,8 +4273,45 @@ TEST_F(UsageTableHeaderTest, DetermineLicenseToRemove_BasicPriorities) {
|
||||
EXPECT_EQ(unexpired_entry_number, entry_to_remove);
|
||||
}
|
||||
|
||||
// Testing algorithm with unexpired offline and streaming license. The
|
||||
// sum of offline licenses is below the threshold for consideration.
|
||||
// Only the streaming license should be considered for removal.
|
||||
TEST_F(UsageTableHeaderTest,
|
||||
DetermineLicenseToRemove_NoExpiredAndBelowThreshold) {
|
||||
constexpr int64_t kOneDay = 24 * 60 * 60;
|
||||
constexpr uint32_t kInvalidEntry = 9999;
|
||||
std::vector<CdmUsageEntryInfo> usage_entry_info_list =
|
||||
kUpgradedUsageEntryInfoList;
|
||||
const size_t offline_threshold = usage_entry_info_list.size() + 1;
|
||||
|
||||
size_t usage_info_count = 0;
|
||||
for (auto& usage_entry_info : usage_entry_info_list) {
|
||||
if (usage_entry_info.storage_type == kStorageUsageInfo) {
|
||||
// Make usage info entries less stale than offline.
|
||||
usage_entry_info.last_use_time += 100;
|
||||
++usage_info_count;
|
||||
} else {
|
||||
// Make offline licenses unexpired.
|
||||
usage_entry_info.offline_license_expiry_time =
|
||||
kLruBaseTime + kOneDay * 30;
|
||||
}
|
||||
}
|
||||
|
||||
// Must exist at least one streaming license for test to work.
|
||||
ASSERT_LT(0ull, usage_info_count);
|
||||
|
||||
uint32_t entry_to_remove = kInvalidEntry;
|
||||
EXPECT_TRUE(UsageTableHeader::DetermineLicenseToRemoveForTesting(
|
||||
usage_entry_info_list, kLruBaseTime, offline_threshold,
|
||||
&entry_to_remove));
|
||||
|
||||
EXPECT_EQ(kStorageUsageInfo,
|
||||
usage_entry_info_list[entry_to_remove].storage_type);
|
||||
}
|
||||
|
||||
// When the number of unexpired offline licenses are below the
|
||||
// threshold, only expired offline licenses should be considered.
|
||||
// threshold, only streaming licenses and expired offline licenses
|
||||
// should be considered.
|
||||
// Providing only offline licenses, only the expired license should be
|
||||
// considered for removal.
|
||||
TEST_F(UsageTableHeaderTest,
|
||||
@@ -4187,20 +4330,20 @@ TEST_F(UsageTableHeaderTest,
|
||||
for (uint32_t i = 0; i < kSetSize; ++i) {
|
||||
CdmUsageEntryInfo& usage_entry_info = usage_entry_info_list[i];
|
||||
usage_entry_info.storage_type = kStorageLicense;
|
||||
usage_entry_info.key_set_id = "unexpired_offline";
|
||||
usage_entry_info.key_set_id = "nothing_unusual";
|
||||
usage_entry_info.last_use_time = kLruBaseTime;
|
||||
usage_entry_info.offline_license_expiry_time =
|
||||
kCurrentTime + kDefaultExpireDuration;
|
||||
}
|
||||
|
||||
// Mark three licenses as expired.
|
||||
// Mark 3 as expired.
|
||||
std::vector<uint32_t> expired_license_numbers;
|
||||
while (expired_license_numbers.size() < 3) {
|
||||
const uint32_t i =
|
||||
static_cast<uint32_t>(wvutil::CdmRandom::RandomInRange(kSetSize - 1));
|
||||
CdmUsageEntryInfo& usage_entry_info = usage_entry_info_list[i];
|
||||
// Skip already expired ones
|
||||
if (usage_entry_info.key_set_id != "unexpired_offline") continue;
|
||||
if (usage_entry_info.key_set_id != "nothing_unusual") continue;
|
||||
// Make these less stale than the unexpired licenses.
|
||||
usage_entry_info.last_use_time = kLruBaseTime + kOneDay;
|
||||
usage_entry_info.offline_license_expiry_time = kCurrentTime - kOneDay;
|
||||
@@ -4216,31 +4359,16 @@ TEST_F(UsageTableHeaderTest,
|
||||
EXPECT_THAT(expired_license_numbers, Contains(entry_to_remove));
|
||||
}
|
||||
|
||||
// This primarily tests the robustness of the algorithm for a full
|
||||
// set of entries (200). Creates 1 offline license which are more
|
||||
// stale than the all other licenses.
|
||||
// This test primarily tests the robustness of the algorithm for a full
|
||||
// set of entries (200). Creates 1 stale streaming license and 1
|
||||
// offline licenses which are more stale than the streaming.
|
||||
//
|
||||
// All cases: 1 unexpired license is most stale.
|
||||
// First, with the stale offline licenses unexpired, checks that the
|
||||
// streaming are always selected, so long as |unexpired_threshold|
|
||||
// is not met.
|
||||
//
|
||||
// Case 1:
|
||||
// - Unexpired threshold met: No
|
||||
// - Exists expired license: No
|
||||
// - Expect most stale license to be selected
|
||||
//
|
||||
// Case 2:
|
||||
// - Unexpired threshold met: Yes
|
||||
// - Exists expired license: No
|
||||
// - Expect most stale license to be selected
|
||||
//
|
||||
// Case 3:
|
||||
// - Unexpired threshold met: No
|
||||
// - Exists expired license: Yes
|
||||
// - Expect expired license to be selected
|
||||
//
|
||||
// Case 4:
|
||||
// - Unexpired threshold met: Yes
|
||||
// - Exists expired license: Yes
|
||||
// - Expect most stale license to be selected
|
||||
// Second, with the stale offline license marked as expired, checks that
|
||||
// offline licenses are selected over the streaming.
|
||||
TEST_F(UsageTableHeaderTest, DetermineLicenseToRemove_LargeMixedSet) {
|
||||
constexpr int64_t kOneDay = 24 * 60 * 60;
|
||||
constexpr size_t kLargeSetSize = 200;
|
||||
@@ -4249,63 +4377,74 @@ TEST_F(UsageTableHeaderTest, DetermineLicenseToRemove_LargeMixedSet) {
|
||||
std::vector<CdmUsageEntryInfo> usage_entry_info_list;
|
||||
usage_entry_info_list.resize(kLargeSetSize);
|
||||
|
||||
// Create a set of unexpired license entries.
|
||||
// Create a set of usage entries.
|
||||
for (uint32_t i = 0; i < kLargeSetSize; ++i) {
|
||||
CdmUsageEntryInfo& usage_entry_info = usage_entry_info_list[i];
|
||||
usage_entry_info.storage_type = kStorageLicense;
|
||||
usage_entry_info.key_set_id = "unexpired_offline";
|
||||
usage_entry_info.key_set_id = "nothing_unusual";
|
||||
usage_entry_info.last_use_time = kLruBaseTime + kOneDay;
|
||||
usage_entry_info.offline_license_expiry_time =
|
||||
kCurrentTime + kDefaultExpireDuration;
|
||||
if ((i % 4) == 0) {
|
||||
// Roughly 25% are offline, the rest are streaming.
|
||||
usage_entry_info.storage_type = kStorageLicense;
|
||||
usage_entry_info.offline_license_expiry_time =
|
||||
kCurrentTime + kDefaultExpireDuration;
|
||||
} else {
|
||||
usage_entry_info.storage_type = kStorageUsageInfo;
|
||||
}
|
||||
}
|
||||
|
||||
// Select a streaming license to be more stale than the rest.
|
||||
uint32_t modified_usage_info_number = kInvalidEntry;
|
||||
while (modified_usage_info_number == kInvalidEntry) {
|
||||
const uint32_t i = static_cast<uint32_t>(
|
||||
wvutil::CdmRandom::RandomInRange(kLargeSetSize - 1));
|
||||
CdmUsageEntryInfo& usage_entry_info = usage_entry_info_list[i];
|
||||
// Skip offline licenses.
|
||||
if (usage_entry_info.storage_type != kStorageUsageInfo) continue;
|
||||
usage_entry_info.last_use_time = kLruBaseTime + 10;
|
||||
usage_entry_info.key_set_id = "stale_streaming";
|
||||
modified_usage_info_number = i;
|
||||
}
|
||||
|
||||
// Select a offline license to be even more stale, but unexpired.
|
||||
const uint32_t most_stale_offline_license_number = static_cast<uint32_t>(
|
||||
wvutil::CdmRandom::RandomInRange(kLargeSetSize - 1));
|
||||
CdmUsageEntryInfo& usage_entry_info =
|
||||
usage_entry_info_list[most_stale_offline_license_number];
|
||||
usage_entry_info.last_use_time = kLruBaseTime;
|
||||
usage_entry_info.key_set_id = "stale_offline";
|
||||
uint32_t modified_offline_license_number = kInvalidEntry;
|
||||
while (modified_offline_license_number == kInvalidEntry) {
|
||||
const uint32_t i = static_cast<uint32_t>(
|
||||
wvutil::CdmRandom::RandomInRange(kLargeSetSize - 1));
|
||||
CdmUsageEntryInfo& usage_entry_info = usage_entry_info_list[i];
|
||||
// Skip streaming licenses.
|
||||
if (usage_entry_info.storage_type != kStorageLicense) continue;
|
||||
usage_entry_info.last_use_time = kLruBaseTime;
|
||||
usage_entry_info.key_set_id = "stale_offline";
|
||||
modified_offline_license_number = i;
|
||||
}
|
||||
|
||||
// Case 1: Most stale license is selected.
|
||||
// Test using only streaming and expired offline licenses
|
||||
// (which there are none).
|
||||
uint32_t entry_to_remove = kInvalidEntry;
|
||||
EXPECT_TRUE(UsageTableHeader::DetermineLicenseToRemoveForTesting(
|
||||
usage_entry_info_list, kCurrentTime,
|
||||
/* unexpired_threshold = */ kLargeSetSize, &entry_to_remove));
|
||||
EXPECT_EQ(most_stale_offline_license_number, entry_to_remove);
|
||||
EXPECT_EQ(modified_usage_info_number, entry_to_remove);
|
||||
|
||||
// Case 2: Most stale license is selected.
|
||||
// Test where the equality threshold is met, now the stale unexpired
|
||||
// license should be selected.
|
||||
entry_to_remove = kInvalidEntry;
|
||||
EXPECT_TRUE(UsageTableHeader::DetermineLicenseToRemoveForTesting(
|
||||
usage_entry_info_list, kCurrentTime,
|
||||
/* unexpired_threshold = */ 0, &entry_to_remove));
|
||||
EXPECT_EQ(most_stale_offline_license_number, entry_to_remove);
|
||||
EXPECT_EQ(modified_offline_license_number, entry_to_remove);
|
||||
|
||||
// Select a offline license to be marked as expired but not the most
|
||||
// stale.
|
||||
uint32_t expired_offline_license_number = kInvalidEntry;
|
||||
while (expired_offline_license_number == kInvalidEntry) {
|
||||
const uint32_t i = static_cast<uint32_t>(
|
||||
wvutil::CdmRandom::RandomInRange(kLargeSetSize - 1));
|
||||
// Don't modify the stale offline license.
|
||||
if (usage_entry_info_list[i].key_set_id != "unexpired_offline") continue;
|
||||
usage_entry_info_list[i].offline_license_expiry_time = kLruBaseTime;
|
||||
expired_offline_license_number = i;
|
||||
}
|
||||
// Make the stale offline license expired.
|
||||
CdmUsageEntryInfo& offline_usage_entry_info =
|
||||
usage_entry_info_list[modified_offline_license_number];
|
||||
offline_usage_entry_info.offline_license_expiry_time = kLruBaseTime;
|
||||
|
||||
// Case 3: Expired license is selected.
|
||||
// Test again, expecting that the expired license should be considered.
|
||||
entry_to_remove = kInvalidEntry;
|
||||
EXPECT_TRUE(UsageTableHeader::DetermineLicenseToRemoveForTesting(
|
||||
usage_entry_info_list, kCurrentTime,
|
||||
/* unexpired_threshold = */ kLargeSetSize, &entry_to_remove));
|
||||
EXPECT_EQ(expired_offline_license_number, entry_to_remove);
|
||||
|
||||
// Case 4: Most stale license is selected.
|
||||
entry_to_remove = kInvalidEntry;
|
||||
EXPECT_TRUE(UsageTableHeader::DetermineLicenseToRemoveForTesting(
|
||||
usage_entry_info_list, kCurrentTime,
|
||||
/* unexpired_threshold = */ 0, &entry_to_remove));
|
||||
EXPECT_EQ(most_stale_offline_license_number, entry_to_remove);
|
||||
EXPECT_EQ(modified_offline_license_number, entry_to_remove);
|
||||
}
|
||||
|
||||
TEST_F(UsageTableHeaderTest, PotentialTableCapacity_Unavailable) {
|
||||
|
||||
Reference in New Issue
Block a user