Check for open session when initializing usage table.
[ Merge of http://go/wvgerrit/122984 ] There was an issue encountered by some vendors with how the usage table was initialized on some devices. Previously, the CDM would open an OEMCrypto session first, then initialize the usage table (loading existing or creating a new one). On these devices, OEMCrypto_CreateUsageTableHeader() and OEMCrypto_LoadUsageTableHeader() would fail if there were any open sessions. This CL changes the initialization process to create/load the usage table before opening an OEMCrypto session. This change also lays the ground work for another usage table fix to address GTS tests failure. In the process, several of the functions for the usage table have been split up into smaller chunks of code. This required additional changes to the usage table unittest to keep them up to date. Bug: 169195093 Bug: 180639135 Test: Linux unittests and MediaDrmTest Change-Id: Ifbf35f5d8cff5b89fea9b16edb998c84803f4fbe
This commit is contained in:
@@ -44,9 +44,7 @@ using ::testing::UnorderedElementsAre;
|
||||
using ::testing::UnorderedElementsAreArray;
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
namespace {
|
||||
|
||||
const std::string kEmptyString;
|
||||
|
||||
constexpr size_t kDefaultTableCapacity = 300;
|
||||
@@ -451,6 +449,8 @@ class MockCryptoSession : public TestCryptoSession {
|
||||
MOCK_METHOD2(UpdateUsageEntry,
|
||||
CdmResponseType(CdmUsageTableHeader*, CdmUsageEntry*));
|
||||
MOCK_METHOD1(MoveUsageEntry, CdmResponseType(uint32_t));
|
||||
MOCK_METHOD2(GetNumberOfOpenSessions,
|
||||
CdmResponseType(SecurityLevel, size_t*));
|
||||
|
||||
// Fake method for testing. Having an EXPECT_CALL causes complexities
|
||||
// for getting table capacity during initialization.
|
||||
@@ -566,6 +566,8 @@ class UsageTableHeaderTest : public WvCdmTestBase {
|
||||
void Init(CdmSecurityLevel security_level,
|
||||
const CdmUsageTableHeader& usage_table_header,
|
||||
const std::vector<CdmUsageEntryInfo>& usage_entry_info_vector) {
|
||||
EXPECT_CALL(*crypto_session_, GetNumberOfOpenSessions(_, NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<1>(0), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_,
|
||||
RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(usage_table_header),
|
||||
@@ -576,6 +578,12 @@ class UsageTableHeaderTest : public WvCdmTestBase {
|
||||
EXPECT_TRUE(usage_table_header_->Init(security_level, crypto_session_));
|
||||
}
|
||||
|
||||
void ExpectToDeleteUsageTableFiles() {
|
||||
EXPECT_CALL(*device_files_, DeleteAllLicenses()).WillOnce(Return(true));
|
||||
EXPECT_CALL(*device_files_, DeleteAllUsageInfo()).WillOnce(Return(true));
|
||||
EXPECT_CALL(*device_files_, DeleteUsageTableInfo()).WillOnce(Return(true));
|
||||
}
|
||||
|
||||
MockDeviceFiles* device_files_;
|
||||
metrics::CryptoMetrics crypto_metrics_;
|
||||
MockCryptoSession* crypto_session_;
|
||||
@@ -598,70 +606,17 @@ class UsageTableHeaderInitializationTest
|
||||
public ::testing::WithParamInterface<CdmSecurityLevel> {
|
||||
public:
|
||||
static void SetUpTestCase() { InitVectorConstants(); }
|
||||
|
||||
SecurityLevel GetSecurityLevel() const {
|
||||
return (GetParam() == kSecurityLevelL3) ? kLevel3 : kLevelDefault;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(UsageTableHeaderInitializationTest, CreateUsageTableHeader) {
|
||||
const SecurityLevel security_level =
|
||||
(GetParam() == kSecurityLevelL3) ? kLevel3 : kLevelDefault;
|
||||
EXPECT_CALL(*device_files_,
|
||||
RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(kEmptyUsageTableHeader),
|
||||
SetArgPointee<1>(kEmptyUsageEntryInfoVector),
|
||||
SetArgPointee<2>(false), Return(false)));
|
||||
TEST_P(UsageTableHeaderInitializationTest, RestoreUsageTable_Success) {
|
||||
const SecurityLevel security_level = GetSecurityLevel();
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
CreateUsageTableHeader(security_level, NotNull()))
|
||||
.WillOnce(
|
||||
DoAll(SetArgPointee<1>(kEmptyUsageTableHeader), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_, StoreUsageTableInfo(kEmptyUsageTableHeader,
|
||||
kEmptyUsageEntryInfoVector))
|
||||
.WillOnce(Return(true));
|
||||
|
||||
EXPECT_TRUE(usage_table_header_->Init(GetParam(), crypto_session_));
|
||||
}
|
||||
|
||||
TEST_P(UsageTableHeaderInitializationTest, Upgrade_UnableToRetrieveLicenses) {
|
||||
const SecurityLevel security_level =
|
||||
(GetParam() == kSecurityLevelL3) ? kLevel3 : kLevelDefault;
|
||||
EXPECT_CALL(*device_files_,
|
||||
RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(kEmptyUsageTableHeader),
|
||||
SetArgPointee<1>(kEmptyUsageEntryInfoVector),
|
||||
SetArgPointee<2>(false), Return(false)));
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
CreateUsageTableHeader(security_level, NotNull()))
|
||||
.WillOnce(
|
||||
DoAll(SetArgPointee<1>(kEmptyUsageTableHeader), Return(NO_ERROR)));
|
||||
// TODO: Why not being called?
|
||||
// EXPECT_CALL(*device_files_, DeleteAllLicenses()).WillOnce(Return(true));
|
||||
EXPECT_CALL(*device_files_, StoreUsageTableInfo(kEmptyUsageTableHeader,
|
||||
kEmptyUsageEntryInfoVector))
|
||||
.WillOnce(Return(true));
|
||||
|
||||
EXPECT_TRUE(usage_table_header_->Init(GetParam(), crypto_session_));
|
||||
}
|
||||
|
||||
TEST_P(UsageTableHeaderInitializationTest, Upgrade_UnableToRetrieveUsageInfo) {
|
||||
const SecurityLevel security_level =
|
||||
(GetParam() == kSecurityLevelL3) ? kLevel3 : kLevelDefault;
|
||||
EXPECT_CALL(*device_files_,
|
||||
RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(kEmptyUsageTableHeader),
|
||||
SetArgPointee<1>(kEmptyUsageEntryInfoVector),
|
||||
SetArgPointee<2>(false), Return(false)));
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
CreateUsageTableHeader(security_level, NotNull()))
|
||||
.WillOnce(
|
||||
DoAll(SetArgPointee<1>(kEmptyUsageTableHeader), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_, StoreUsageTableInfo(kEmptyUsageTableHeader,
|
||||
kEmptyUsageEntryInfoVector))
|
||||
.WillOnce(Return(true));
|
||||
|
||||
EXPECT_TRUE(usage_table_header_->Init(GetParam(), crypto_session_));
|
||||
}
|
||||
|
||||
TEST_P(UsageTableHeaderInitializationTest, UsageTableHeaderExists) {
|
||||
const SecurityLevel security_level =
|
||||
(GetParam() == kSecurityLevelL3) ? kLevel3 : kLevelDefault;
|
||||
GetNumberOfOpenSessions(security_level, NotNull()))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_,
|
||||
RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(kUsageTableHeader),
|
||||
@@ -670,15 +625,172 @@ TEST_P(UsageTableHeaderInitializationTest, UsageTableHeaderExists) {
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
LoadUsageTableHeader(security_level, kUsageTableHeader))
|
||||
.WillOnce(Return(NO_ERROR));
|
||||
EXPECT_TRUE(usage_table_header_->Init(GetParam(), crypto_session_));
|
||||
}
|
||||
|
||||
// First attempt at initializing the table succeeds, however, attempting
|
||||
// to reinitialize the usage table should result in a failure.
|
||||
TEST_P(UsageTableHeaderInitializationTest,
|
||||
RestoreUsageTable_FailureDueToReInit) {
|
||||
const SecurityLevel security_level = GetSecurityLevel();
|
||||
|
||||
// First run, success.
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
GetNumberOfOpenSessions(security_level, NotNull()))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_,
|
||||
RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(kUsageTableHeader),
|
||||
SetArgPointee<1>(kUsageEntryInfoVector),
|
||||
SetArgPointee<2>(false), Return(true)));
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
LoadUsageTableHeader(security_level, kUsageTableHeader))
|
||||
.WillOnce(Return(NO_ERROR));
|
||||
EXPECT_TRUE(usage_table_header_->Init(GetParam(), crypto_session_));
|
||||
|
||||
// Second run, failure.
|
||||
EXPECT_FALSE(usage_table_header_->Init(GetParam(), crypto_session_));
|
||||
}
|
||||
|
||||
// Table MUST not be initialized before another session has been opened.
|
||||
TEST_P(UsageTableHeaderInitializationTest,
|
||||
RestoreUsageTable_FailureDueToExistingSessions) {
|
||||
const SecurityLevel security_level = GetSecurityLevel();
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
GetNumberOfOpenSessions(security_level, NotNull()))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<1>(1), Return(NO_ERROR)));
|
||||
EXPECT_FALSE(usage_table_header_->Init(GetParam(), crypto_session_));
|
||||
}
|
||||
|
||||
// No existing usage table in storage, creating a new table succeeds.
|
||||
TEST_P(UsageTableHeaderInitializationTest,
|
||||
RestoreUsageTable_CreateNew_AfterRetrieveFails) {
|
||||
const SecurityLevel security_level = GetSecurityLevel();
|
||||
|
||||
// Expectations for restore:
|
||||
// 1) Fail to retrieve existing table file
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
GetNumberOfOpenSessions(security_level, NotNull()))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_,
|
||||
RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull()))
|
||||
.WillOnce(Return(false));
|
||||
|
||||
// Expectations for create:
|
||||
// 1) Existing table is destroyed (files etc.)
|
||||
// 2) Create new header within OEMCrypto succeeds
|
||||
// 3) Storing the table header succeeds
|
||||
ExpectToDeleteUsageTableFiles();
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
CreateUsageTableHeader(security_level, NotNull()))
|
||||
.WillOnce(
|
||||
DoAll(SetArgPointee<1>(kAnotherUsageTableHeader), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader,
|
||||
kEmptyUsageEntryInfoVector))
|
||||
.WillOnce(Return(true));
|
||||
|
||||
EXPECT_TRUE(usage_table_header_->Init(GetParam(), crypto_session_));
|
||||
}
|
||||
|
||||
TEST_P(UsageTableHeaderInitializationTest, UsageEntriesAtCapacity) {
|
||||
// A table exists in storage, but it cannot be loaded due to generation
|
||||
// skew. Creating a new table succeeds.
|
||||
TEST_P(UsageTableHeaderInitializationTest,
|
||||
RestoreUsageTable_CreateNew_AfterLoadFails) {
|
||||
const SecurityLevel security_level = GetSecurityLevel();
|
||||
|
||||
// Expectations for restore:
|
||||
// 1) Existing table file is retrieved
|
||||
// 2) Loading existing header within OEMCrypto fails
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
GetNumberOfOpenSessions(security_level, NotNull()))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_,
|
||||
RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(kUsageTableHeader),
|
||||
SetArgPointee<1>(kUsageEntryInfoVector),
|
||||
SetArgPointee<2>(false), Return(true)));
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
LoadUsageTableHeader(security_level, kUsageTableHeader))
|
||||
.WillOnce(Return(LOAD_USAGE_HEADER_GENERATION_SKEW));
|
||||
|
||||
// Expectations for create:
|
||||
// 1) Existing table is destroyed (files etc.)
|
||||
// 2) Create new header within OEMCrypto succeeds
|
||||
// 3) Storing the table header succeeds
|
||||
ExpectToDeleteUsageTableFiles();
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
CreateUsageTableHeader(security_level, NotNull()))
|
||||
.WillOnce(
|
||||
DoAll(SetArgPointee<1>(kAnotherUsageTableHeader), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader,
|
||||
kEmptyUsageEntryInfoVector))
|
||||
.WillOnce(Return(true));
|
||||
|
||||
EXPECT_TRUE(usage_table_header_->Init(GetParam(), crypto_session_));
|
||||
}
|
||||
|
||||
// No existing table in storage, and attempting to create a new usage
|
||||
// table fails for unknown reason. Initialization MUST fail.
|
||||
TEST_P(UsageTableHeaderInitializationTest,
|
||||
RestoreUsageTable_CreateNew_CreateFails) {
|
||||
const SecurityLevel security_level = GetSecurityLevel();
|
||||
// Expectations for restore:
|
||||
// 1) No table info file exists
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
GetNumberOfOpenSessions(security_level, NotNull()))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_,
|
||||
RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull()))
|
||||
.WillOnce(Return(false));
|
||||
// Expectations for create:
|
||||
// 1) Create new header within OEMCrypto fails
|
||||
ExpectToDeleteUsageTableFiles();
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
CreateUsageTableHeader(security_level, NotNull()))
|
||||
.WillOnce(Return(CREATE_USAGE_TABLE_ERROR));
|
||||
|
||||
EXPECT_FALSE(usage_table_header_->Init(GetParam(), crypto_session_));
|
||||
}
|
||||
|
||||
// No existing table in storage, attempting to create a new usage
|
||||
// table succeeds; however, storing the new table header fails.
|
||||
// Initialization MUST fail.
|
||||
TEST_P(UsageTableHeaderInitializationTest,
|
||||
RestoreUsageTable_CreateNew_StoreFails) {
|
||||
const SecurityLevel security_level = GetSecurityLevel();
|
||||
// Expectations for restore:
|
||||
// 1) No table info file exists
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
GetNumberOfOpenSessions(security_level, NotNull()))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_,
|
||||
RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull()))
|
||||
.WillOnce(Return(false));
|
||||
// Expectations for create:
|
||||
// 1) Create new header within OEMCrypto succeeds
|
||||
// 2) Storing the table header fails
|
||||
ExpectToDeleteUsageTableFiles();
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
CreateUsageTableHeader(security_level, NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<1>(kUsageTableHeader), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_, StoreUsageTableInfo(kUsageTableHeader,
|
||||
kEmptyUsageEntryInfoVector))
|
||||
.WillOnce(Return(false));
|
||||
EXPECT_FALSE(usage_table_header_->Init(GetParam(), crypto_session_));
|
||||
}
|
||||
|
||||
// Restoring table succeeds, and the current table is at capacity.
|
||||
// No special action needs to be taken.
|
||||
TEST_P(UsageTableHeaderInitializationTest, RestoreUsageTable_AtCapacity) {
|
||||
std::vector<CdmUsageEntryInfo> usage_entries = kOverFullUsageEntryInfoVector;
|
||||
usage_entries.resize(kDefaultTableCapacity);
|
||||
const SecurityLevel security_level =
|
||||
(GetParam() == kSecurityLevelL3) ? kLevel3 : kLevelDefault;
|
||||
const SecurityLevel security_level = GetSecurityLevel();
|
||||
// Expectations for restore:
|
||||
// 1) Existing table file is retrieved
|
||||
// 2) Loading existing header within OEMCrypto succeeds
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
GetNumberOfOpenSessions(security_level, NotNull()))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_,
|
||||
RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(kUsageTableHeader),
|
||||
@@ -687,18 +799,25 @@ TEST_P(UsageTableHeaderInitializationTest, UsageEntriesAtCapacity) {
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
LoadUsageTableHeader(security_level, kUsageTableHeader))
|
||||
.WillOnce(Return(NO_ERROR));
|
||||
|
||||
EXPECT_TRUE(usage_table_header_->Init(GetParam(), crypto_session_));
|
||||
}
|
||||
|
||||
// Restoring table succeeds, OEMCrypto does not specify an absolute
|
||||
// capacity, existing table is under the minimum required capacity.
|
||||
// No special action needs to be taken.
|
||||
TEST_P(UsageTableHeaderInitializationTest,
|
||||
UsageEntries_NoCapacity_UnderMinimum) {
|
||||
RestoreUsageTable_NoCapacity_UnderMinimum) {
|
||||
crypto_session_->SetMaximumUsageTableEntries(0); // Unlimited.
|
||||
std::vector<CdmUsageEntryInfo> usage_entries = kOverFullUsageEntryInfoVector;
|
||||
constexpr size_t kHalfMinCapacity = kDefaultTableCapacity / 2;
|
||||
usage_entries.resize(kHalfMinCapacity);
|
||||
const SecurityLevel security_level =
|
||||
(GetParam() == kSecurityLevelL3) ? kLevel3 : kLevelDefault;
|
||||
const SecurityLevel security_level = GetSecurityLevel();
|
||||
// Expectations for restore:
|
||||
// 1) Existing table file is retrieved
|
||||
// 2) Loading existing header within OEMCrypto succeeds
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
GetNumberOfOpenSessions(security_level, NotNull()))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_,
|
||||
RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(kUsageTableHeader),
|
||||
@@ -707,136 +826,134 @@ TEST_P(UsageTableHeaderInitializationTest,
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
LoadUsageTableHeader(security_level, kUsageTableHeader))
|
||||
.WillOnce(Return(NO_ERROR));
|
||||
// No expectations of creating or deleting entries if the number of entries
|
||||
// is less than minimally required capacity.
|
||||
|
||||
EXPECT_TRUE(usage_table_header_->Init(GetParam(), crypto_session_));
|
||||
}
|
||||
|
||||
TEST_P(UsageTableHeaderInitializationTest, UsageEntries_NoCapacity) {
|
||||
// Restoring table succeeds, OEMCrypto does not specify an absolute
|
||||
// capacity, existing table is above the minimum required capacity.
|
||||
// After restoring, the header class must check that new entries can
|
||||
// be added. This capacity check succeeds.
|
||||
TEST_P(UsageTableHeaderInitializationTest,
|
||||
RestoreUsageTable_NoCapacity_AboveMinimum) {
|
||||
crypto_session_->SetMaximumUsageTableEntries(0); // Unlimited.
|
||||
std::vector<CdmUsageEntryInfo> usage_entries = kOverFullUsageEntryInfoVector;
|
||||
usage_entries.resize(kDefaultTableCapacity);
|
||||
const SecurityLevel security_level =
|
||||
(GetParam() == kSecurityLevelL3) ? kLevel3 : kLevelDefault;
|
||||
ASSERT_LT(kDefaultTableCapacity, kOverFullUsageEntryInfoVector.size());
|
||||
const size_t kTableStartSize = kOverFullUsageEntryInfoVector.size();
|
||||
const SecurityLevel security_level = GetSecurityLevel();
|
||||
|
||||
// Expectations for restore:
|
||||
// 1) Existing table file is retrieved
|
||||
// 2) Loading existing header within OEMCrypto succeeds
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
GetNumberOfOpenSessions(security_level, NotNull()))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_,
|
||||
RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(kUsageTableHeader),
|
||||
SetArgPointee<1>(usage_entries), SetArgPointee<2>(false),
|
||||
Return(true)));
|
||||
SetArgPointee<1>(kOverFullUsageEntryInfoVector),
|
||||
SetArgPointee<2>(false), Return(true)));
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
LoadUsageTableHeader(security_level, kUsageTableHeader))
|
||||
.WillOnce(Return(NO_ERROR));
|
||||
|
||||
// Expect an attempt to create a new entry.
|
||||
// Expectations for capacity check:
|
||||
// 1) Open a new crypto session.
|
||||
// 2) Creating a new usage entry within OEMCrypto succeeds
|
||||
// 3) Header and usage entry is updated
|
||||
// 4) Table state is stored
|
||||
// 5) New session is closed
|
||||
// 6) Table is shrunk by 1
|
||||
// 7) Table state is stored
|
||||
EXPECT_CALL(*crypto_session_, Open(security_level))
|
||||
.WillOnce(Return(NO_ERROR));
|
||||
const uint32_t expect_usage_entry_number = kDefaultTableCapacity;
|
||||
const uint32_t expect_usage_entry_number = kTableStartSize;
|
||||
EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull()))
|
||||
.WillOnce(
|
||||
DoAll(SetArgPointee<0>(expect_usage_entry_number), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*crypto_session_, UpdateUsageEntry(NotNull(), NotNull()))
|
||||
.WillOnce(
|
||||
DoAll(SetArgPointee<0>(kAnotherUsageTableHeader), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_,
|
||||
StoreUsageTableInfo(kAnotherUsageTableHeader,
|
||||
SizeIs(kDefaultTableCapacity + 1)))
|
||||
EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader,
|
||||
SizeIs(kTableStartSize + 1)))
|
||||
.WillOnce(Return(true));
|
||||
|
||||
// Delete the entry after.
|
||||
EXPECT_CALL(
|
||||
*crypto_session_,
|
||||
ShrinkUsageTableHeader(security_level, kDefaultTableCapacity, NotNull()))
|
||||
EXPECT_CALL(*crypto_session_, ShrinkUsageTableHeader(
|
||||
security_level, kTableStartSize, NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<2>(kYetAnotherUsageTableHeader),
|
||||
Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_,
|
||||
StoreUsageTableInfo(kYetAnotherUsageTableHeader,
|
||||
SizeIs(kDefaultTableCapacity)))
|
||||
EXPECT_CALL(*device_files_, StoreUsageTableInfo(kYetAnotherUsageTableHeader,
|
||||
SizeIs(kTableStartSize)))
|
||||
.WillOnce(Return(true));
|
||||
|
||||
EXPECT_TRUE(usage_table_header_->Init(GetParam(), crypto_session_));
|
||||
}
|
||||
|
||||
// Restoring table succeeds, OEMCrypto does not specify an absolute
|
||||
// capacity, existing table is above the minimum required capacity.
|
||||
// After restoring, the header class must check that new entries can
|
||||
// be added. This capacity check fails due to adding an entry.
|
||||
// The result is a new usage table.
|
||||
TEST_P(UsageTableHeaderInitializationTest,
|
||||
UsageEntriesOverCapacity_AddEntryFails_UsageTableHeaderRecreated) {
|
||||
RestoreUsageTable_AboveCapacity_AddEntryFails) {
|
||||
ASSERT_LT(kDefaultTableCapacity, kOverFullUsageEntryInfoVector.size());
|
||||
const SecurityLevel security_level = GetSecurityLevel();
|
||||
|
||||
// Expectations for restore:
|
||||
// 1) Existing table file is retrieved
|
||||
// 2) Loading existing header within OEMCrypto succeeds
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
GetNumberOfOpenSessions(security_level, NotNull()))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_,
|
||||
RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(kUsageTableHeader),
|
||||
SetArgPointee<1>(kOverFullUsageEntryInfoVector),
|
||||
SetArgPointee<2>(false), Return(true)));
|
||||
|
||||
const SecurityLevel security_level =
|
||||
(GetParam() == kSecurityLevelL3) ? kLevel3 : kLevelDefault;
|
||||
EXPECT_CALL(*crypto_session_, Open(security_level))
|
||||
.WillOnce(Return(NO_ERROR));
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
LoadUsageTableHeader(security_level, kUsageTableHeader))
|
||||
.WillOnce(Return(NO_ERROR));
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
CreateUsageTableHeader(security_level, NotNull()))
|
||||
.WillOnce(
|
||||
DoAll(SetArgPointee<1>(kEmptyUsageTableHeader), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_, DeleteAllLicenses()).WillOnce(Return(true));
|
||||
EXPECT_CALL(*device_files_, DeleteAllUsageInfo()).WillOnce(Return(true));
|
||||
EXPECT_CALL(*device_files_, DeleteUsageTableInfo()).WillOnce(Return(true));
|
||||
EXPECT_CALL(*device_files_, StoreUsageTableInfo(kEmptyUsageTableHeader,
|
||||
kEmptyUsageEntryInfoVector))
|
||||
.WillOnce(Return(true));
|
||||
|
||||
// Expectations for AddEntry
|
||||
const uint32_t expect_usage_entry_number =
|
||||
kOverFullUsageEntryInfoVector.size();
|
||||
EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(expect_usage_entry_number),
|
||||
Return(CREATE_USAGE_ENTRY_UNKNOWN_ERROR)));
|
||||
|
||||
EXPECT_TRUE(usage_table_header_->Init(GetParam(), crypto_session_));
|
||||
}
|
||||
|
||||
TEST_P(UsageTableHeaderInitializationTest,
|
||||
UsageEntries_NoCapacity_AddEntryFails_UsageTableHeaderRecreated) {
|
||||
crypto_session_->SetMaximumUsageTableEntries(0); // Unlimited.
|
||||
std::vector<CdmUsageEntryInfo> usage_entries = kOverFullUsageEntryInfoVector;
|
||||
usage_entries.resize(kDefaultTableCapacity);
|
||||
const SecurityLevel security_level =
|
||||
(GetParam() == kSecurityLevelL3) ? kLevel3 : kLevelDefault;
|
||||
EXPECT_CALL(*device_files_,
|
||||
RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(kUsageTableHeader),
|
||||
SetArgPointee<1>(usage_entries), SetArgPointee<2>(false),
|
||||
Return(true)));
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
LoadUsageTableHeader(security_level, kUsageTableHeader))
|
||||
.WillOnce(Return(NO_ERROR));
|
||||
// Try to create a new entry, and fail.
|
||||
// Expectations for capacity check:
|
||||
// 1) Open a new crypto session.
|
||||
// 2) Creating a new usage entry within OEMCrypto fails
|
||||
EXPECT_CALL(*crypto_session_, Open(security_level))
|
||||
.WillOnce(Return(NO_ERROR));
|
||||
EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull()))
|
||||
.WillOnce(Return(CREATE_USAGE_ENTRY_UNKNOWN_ERROR));
|
||||
// Expect clean up.
|
||||
EXPECT_CALL(*device_files_, DeleteAllLicenses()).WillOnce(Return(true));
|
||||
EXPECT_CALL(*device_files_, DeleteAllUsageInfo()).WillOnce(Return(true));
|
||||
EXPECT_CALL(*device_files_, DeleteUsageTableInfo()).WillOnce(Return(true));
|
||||
// Expect recreation of usage table.
|
||||
|
||||
// Expectations for create:
|
||||
// 1) Existing table is destroyed (files etc.)
|
||||
// 2) Create new header within OEMCrypto succeeds
|
||||
// 3) Storing the table header fails
|
||||
ExpectToDeleteUsageTableFiles();
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
CreateUsageTableHeader(security_level, NotNull()))
|
||||
.WillOnce(
|
||||
DoAll(SetArgPointee<1>(kEmptyUsageTableHeader), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_, StoreUsageTableInfo(kEmptyUsageTableHeader,
|
||||
DoAll(SetArgPointee<1>(kAnotherUsageTableHeader), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader,
|
||||
kEmptyUsageEntryInfoVector))
|
||||
.WillOnce(Return(true));
|
||||
|
||||
EXPECT_TRUE(usage_table_header_->Init(GetParam(), crypto_session_));
|
||||
}
|
||||
|
||||
// Restoring table succeeds, OEMCrypto does not specify an absolute
|
||||
// capacity, existing table is above the minimum required capacity.
|
||||
// After restoring, the header class must check that new entries can
|
||||
// be added. This capacity check fails due to invalidating an entry.
|
||||
// The result is a new usage table.
|
||||
TEST_P(UsageTableHeaderInitializationTest,
|
||||
UsageEntriesOverCapacity_AddInvalidateEntrySucceeds) {
|
||||
// Capacity +2.
|
||||
std::vector<CdmUsageEntryInfo> usage_entries = kOverFullUsageEntryInfoVector;
|
||||
usage_entries.push_back(kDummyUsageEntryInfo);
|
||||
|
||||
const SecurityLevel security_level =
|
||||
(GetParam() == kSecurityLevelL3) ? kLevel3 : kLevelDefault;
|
||||
RestoreUsageTable_NoCapacity_AboveMinimum_InvalidateEntryFails) {
|
||||
crypto_session_->SetMaximumUsageTableEntries(0); // Unlimited.
|
||||
ASSERT_LT(kDefaultTableCapacity, kOverFullUsageEntryInfoVector.size());
|
||||
const size_t kTableStartSize = kOverFullUsageEntryInfoVector.size();
|
||||
const SecurityLevel security_level = GetSecurityLevel();
|
||||
|
||||
// Expectations for restore:
|
||||
// 1) Existing table file is retrieved
|
||||
// 2) Loading existing header within OEMCrypto succeeds
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
GetNumberOfOpenSessions(security_level, NotNull()))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_,
|
||||
RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(kUsageTableHeader),
|
||||
@@ -846,30 +963,42 @@ TEST_P(UsageTableHeaderInitializationTest,
|
||||
LoadUsageTableHeader(security_level, kUsageTableHeader))
|
||||
.WillOnce(Return(NO_ERROR));
|
||||
|
||||
// Expectations for AddEntry
|
||||
const uint32_t expect_usage_entry_number =
|
||||
kOverFullUsageEntryInfoVector.size();
|
||||
// Expectations for capacity check:
|
||||
// 1) Open a new crypto session.
|
||||
// 2) Creating a new usage entry within OEMCrypto succeeds.
|
||||
// 3) Header and usage entry is updated
|
||||
// 4) Table state is stored
|
||||
// 5) New session is closed
|
||||
// 6) Shrinking table fails
|
||||
EXPECT_CALL(*crypto_session_, Open(security_level))
|
||||
.WillOnce(Return(NO_ERROR));
|
||||
const uint32_t expect_usage_entry_number = kTableStartSize;
|
||||
EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull()))
|
||||
.WillOnce(
|
||||
DoAll(SetArgPointee<0>(expect_usage_entry_number), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*crypto_session_, UpdateUsageEntry(NotNull(), NotNull()))
|
||||
.WillOnce(
|
||||
DoAll(SetArgPointee<0>(kAnotherUsageTableHeader), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_,
|
||||
StoreUsageTableInfo(kAnotherUsageTableHeader, usage_entries))
|
||||
.WillOnce(Return(true));
|
||||
// Called twice due to defrag.
|
||||
EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader,
|
||||
SizeIs(kTableStartSize + 1)))
|
||||
.Times(2)
|
||||
.WillRepeatedly(Return(true));
|
||||
EXPECT_CALL(*crypto_session_, ShrinkUsageTableHeader(
|
||||
security_level, kTableStartSize, NotNull()))
|
||||
.WillOnce(Return(SHRINK_USAGE_TABLE_HEADER_UNKNOWN_ERROR));
|
||||
|
||||
// Expectations for InvalidateEntry, assumes no entry other entry is invalid.
|
||||
EXPECT_CALL(*crypto_session_, Open(security_level))
|
||||
.WillOnce(Return(NO_ERROR));
|
||||
// Expectations for create:
|
||||
// 1) Existing table is destroyed (files etc.)
|
||||
// 2) Create new header within OEMCrypto succeeds
|
||||
// 3) Storing the table header succeeds
|
||||
ExpectToDeleteUsageTableFiles();
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
ShrinkUsageTableHeader(security_level, usage_entries.size() - 1,
|
||||
NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<2>(kYetAnotherUsageTableHeader),
|
||||
CreateUsageTableHeader(security_level, NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<1>(kYetAnotherUsageTableHeader),
|
||||
Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_,
|
||||
StoreUsageTableInfo(kYetAnotherUsageTableHeader,
|
||||
SizeIs(kOverFullUsageEntryInfoVector.size())))
|
||||
EXPECT_CALL(*device_files_, StoreUsageTableInfo(kYetAnotherUsageTableHeader,
|
||||
kEmptyUsageEntryInfoVector))
|
||||
.WillOnce(Return(true));
|
||||
|
||||
EXPECT_TRUE(usage_table_header_->Init(GetParam(), crypto_session_));
|
||||
@@ -880,13 +1009,12 @@ INSTANTIATE_TEST_CASE_P(Cdm, UsageTableHeaderInitializationTest,
|
||||
|
||||
TEST_F(UsageTableHeaderTest, AddEntry_CreateUsageEntryFailed_UnknownError) {
|
||||
Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector);
|
||||
uint32_t usage_entry_number;
|
||||
uint32_t expect_usage_entry_number = kUsageEntryInfoVector.size();
|
||||
|
||||
const uint32_t expect_usage_entry_number = kUsageEntryInfoVector.size();
|
||||
EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(expect_usage_entry_number),
|
||||
Return(CREATE_USAGE_ENTRY_UNKNOWN_ERROR)));
|
||||
|
||||
uint32_t usage_entry_number = 0;
|
||||
EXPECT_NE(NO_ERROR,
|
||||
usage_table_header_->AddEntry(
|
||||
crypto_session_,
|
||||
@@ -898,13 +1026,12 @@ TEST_F(UsageTableHeaderTest, AddEntry_CreateUsageEntryFailed_UnknownError) {
|
||||
|
||||
TEST_F(UsageTableHeaderTest, AddEntry_UsageEntryTooSmall) {
|
||||
Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector);
|
||||
uint32_t usage_entry_number;
|
||||
uint32_t expect_usage_entry_number = kUsageEntryInfoVector.size() - 1;
|
||||
|
||||
const uint32_t expect_usage_entry_number = kUsageEntryInfoVector.size() - 1;
|
||||
EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull()))
|
||||
.WillOnce(
|
||||
DoAll(SetArgPointee<0>(expect_usage_entry_number), Return(NO_ERROR)));
|
||||
|
||||
uint32_t usage_entry_number = 0;
|
||||
EXPECT_NE(NO_ERROR,
|
||||
usage_table_header_->AddEntry(
|
||||
crypto_session_,
|
||||
@@ -916,11 +1043,9 @@ TEST_F(UsageTableHeaderTest, AddEntry_UsageEntryTooSmall) {
|
||||
|
||||
TEST_F(UsageTableHeaderTest, AddEntry_NextConsecutiveOfflineUsageEntry) {
|
||||
Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector);
|
||||
uint32_t usage_entry_number;
|
||||
uint32_t expect_usage_entry_number = kUsageEntryInfoVector.size();
|
||||
const uint32_t expect_usage_entry_number = kUsageEntryInfoVector.size();
|
||||
std::vector<CdmUsageEntryInfo> expect_usage_entry_info_vector =
|
||||
kUsageEntryInfoVector;
|
||||
|
||||
expect_usage_entry_info_vector.resize(expect_usage_entry_number + 1);
|
||||
expect_usage_entry_info_vector[expect_usage_entry_number] =
|
||||
kUsageEntryInfoOfflineLicense2;
|
||||
@@ -937,6 +1062,7 @@ TEST_F(UsageTableHeaderTest, AddEntry_NextConsecutiveOfflineUsageEntry) {
|
||||
UnorderedElementsAreArray(expect_usage_entry_info_vector)))
|
||||
.WillOnce(Return(true));
|
||||
|
||||
uint32_t usage_entry_number = 0;
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
usage_table_header_->AddEntry(
|
||||
crypto_session_,
|
||||
@@ -949,8 +1075,7 @@ TEST_F(UsageTableHeaderTest, AddEntry_NextConsecutiveOfflineUsageEntry) {
|
||||
|
||||
TEST_F(UsageTableHeaderTest, AddEntry_NextConsecutiveSecureStopUsageEntry) {
|
||||
Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector);
|
||||
uint32_t usage_entry_number;
|
||||
uint32_t expect_usage_entry_number = kUsageEntryInfoVector.size();
|
||||
const uint32_t expect_usage_entry_number = kUsageEntryInfoVector.size();
|
||||
std::vector<CdmUsageEntryInfo> expect_usage_entry_info_vector =
|
||||
kUsageEntryInfoVector;
|
||||
|
||||
@@ -970,6 +1095,7 @@ TEST_F(UsageTableHeaderTest, AddEntry_NextConsecutiveSecureStopUsageEntry) {
|
||||
UnorderedElementsAreArray(expect_usage_entry_info_vector)))
|
||||
.WillOnce(Return(true));
|
||||
|
||||
uint32_t usage_entry_number = 0;
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
usage_table_header_->AddEntry(
|
||||
crypto_session_,
|
||||
@@ -982,8 +1108,7 @@ TEST_F(UsageTableHeaderTest, AddEntry_NextConsecutiveSecureStopUsageEntry) {
|
||||
|
||||
TEST_F(UsageTableHeaderTest, AddEntry_SkipUsageEntries) {
|
||||
Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector);
|
||||
uint32_t usage_entry_number;
|
||||
uint32_t next_usage_entry_number = kUsageEntryInfoVector.size();
|
||||
const uint32_t next_usage_entry_number = kUsageEntryInfoVector.size();
|
||||
size_t skip_usage_entries = 3;
|
||||
uint32_t expect_usage_entry_number =
|
||||
next_usage_entry_number + skip_usage_entries;
|
||||
@@ -1006,6 +1131,7 @@ TEST_F(UsageTableHeaderTest, AddEntry_SkipUsageEntries) {
|
||||
kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoSecureStop2)))
|
||||
.WillOnce(Return(true));
|
||||
|
||||
uint32_t usage_entry_number = 0;
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
usage_table_header_->AddEntry(
|
||||
crypto_session_,
|
||||
@@ -1123,7 +1249,7 @@ TEST_F(UsageTableHeaderTest, AddEntry_CreateUsageEntryFailsEveryTime) {
|
||||
|
||||
TEST_F(UsageTableHeaderTest, LoadEntry_InvalidEntryNumber) {
|
||||
Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector);
|
||||
uint32_t usage_entry_number = kUsageEntryInfoVector.size() + 3;
|
||||
const uint32_t usage_entry_number = kUsageEntryInfoVector.size() + 3;
|
||||
|
||||
EXPECT_NE(NO_ERROR, usage_table_header_->LoadEntry(
|
||||
crypto_session_, kUsageEntry, usage_entry_number));
|
||||
@@ -1131,7 +1257,7 @@ TEST_F(UsageTableHeaderTest, LoadEntry_InvalidEntryNumber) {
|
||||
|
||||
TEST_F(UsageTableHeaderTest, LoadEntry_CryptoSessionError) {
|
||||
Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector);
|
||||
uint32_t usage_entry_number = 1;
|
||||
const uint32_t usage_entry_number = 1;
|
||||
|
||||
EXPECT_CALL(*crypto_session_, LoadUsageEntry(usage_entry_number, kUsageEntry))
|
||||
.WillOnce(Return(LOAD_USAGE_ENTRY_GENERATION_SKEW));
|
||||
@@ -1142,7 +1268,7 @@ TEST_F(UsageTableHeaderTest, LoadEntry_CryptoSessionError) {
|
||||
|
||||
TEST_F(UsageTableHeaderTest, LoadEntry) {
|
||||
Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector);
|
||||
uint32_t usage_entry_number = 1;
|
||||
const uint32_t usage_entry_number = 1;
|
||||
|
||||
EXPECT_CALL(*crypto_session_, LoadUsageEntry(usage_entry_number, kUsageEntry))
|
||||
.WillOnce(Return(NO_ERROR));
|
||||
@@ -1184,7 +1310,7 @@ TEST_F(UsageTableHeaderTest, UpdateEntry) {
|
||||
|
||||
TEST_F(UsageTableHeaderTest, InvalidateEntry_InvalidUsageEntryNumber) {
|
||||
Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector);
|
||||
uint32_t usage_entry_number = kUsageEntryInfoVector.size();
|
||||
const uint32_t usage_entry_number = kUsageEntryInfoVector.size();
|
||||
metrics::CryptoMetrics metrics;
|
||||
|
||||
EXPECT_NE(NO_ERROR, usage_table_header_->InvalidateEntry(
|
||||
@@ -3203,6 +3329,9 @@ TEST_F(UsageTableHeaderTest, StaleHeader) {
|
||||
ToVector(usage_entry_info_vector, usage_entry_info_array,
|
||||
sizeof(usage_entry_info_array));
|
||||
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
GetNumberOfOpenSessions(kLevelDefault, NotNull()))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_,
|
||||
RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(kUsageTableHeader),
|
||||
@@ -3211,14 +3340,12 @@ TEST_F(UsageTableHeaderTest, StaleHeader) {
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
LoadUsageTableHeader(kLevelDefault, kUsageTableHeader))
|
||||
.WillOnce(Return(LOAD_USAGE_HEADER_GENERATION_SKEW));
|
||||
ExpectToDeleteUsageTableFiles();
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
CreateUsageTableHeader(kLevelDefault, NotNull()))
|
||||
.WillOnce(
|
||||
DoAll(SetArgPointee<1>(kEmptyUsageTableHeader), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_, DeleteAllLicenses()).WillOnce(Return(true));
|
||||
EXPECT_CALL(*device_files_, DeleteAllUsageInfo()).WillOnce(Return(true));
|
||||
EXPECT_CALL(*device_files_, DeleteUsageTableInfo()).WillOnce(Return(true));
|
||||
EXPECT_CALL(*device_files_, StoreUsageTableInfo(kEmptyUsageTableHeader,
|
||||
DoAll(SetArgPointee<1>(kAnotherUsageTableHeader), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader,
|
||||
kEmptyUsageEntryInfoVector))
|
||||
.WillOnce(Return(true));
|
||||
|
||||
@@ -3302,6 +3429,9 @@ TEST_F(UsageTableHeaderTest, Shrink_MoreThanTable) {
|
||||
// the table header and entries are configured for LRU.
|
||||
// 2. No upgrading action is taken.
|
||||
TEST_F(UsageTableHeaderTest, LruUsageTableUpgrade_NoAction) {
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
GetNumberOfOpenSessions(kLevelDefault, NotNull()))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_,
|
||||
RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(kUpgradableUsageTableHeader),
|
||||
@@ -3329,6 +3459,9 @@ TEST_F(UsageTableHeaderTest, LruUsageTableUpgrade_NoAction) {
|
||||
// 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()))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_,
|
||||
RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(kUpgradableUsageTableHeader),
|
||||
@@ -3395,6 +3528,9 @@ TEST_F(UsageTableHeaderTest,
|
||||
upgraded_usage_entry_info_list[2].storage_type = kStorageTypeUnknown;
|
||||
|
||||
// Load table expectations.
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
GetNumberOfOpenSessions(kLevelDefault, NotNull()))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_,
|
||||
RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(kUpgradableUsageTableHeader),
|
||||
@@ -3455,6 +3591,9 @@ TEST_F(UsageTableHeaderTest,
|
||||
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()))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_,
|
||||
RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(kUpgradableUsageTableHeader),
|
||||
@@ -3510,6 +3649,9 @@ TEST_F(UsageTableHeaderTest,
|
||||
// that the table has not been configured for upgrade.
|
||||
// 2. None of the entries can have their license info loaded.
|
||||
TEST_F(UsageTableHeaderTest, LruUsageTableUpgrade_AllFailure) {
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
GetNumberOfOpenSessions(kLevelDefault, NotNull()))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_,
|
||||
RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(kUpgradableUsageTableHeader),
|
||||
@@ -3539,29 +3681,20 @@ TEST_F(UsageTableHeaderTest, LruUsageTableUpgrade_AllFailure) {
|
||||
|
||||
// After failure, these will be called to clear files and create a new
|
||||
// usage table header.
|
||||
EXPECT_CALL(*device_files_, DeleteAllLicenses());
|
||||
EXPECT_CALL(*device_files_, DeleteAllUsageInfo());
|
||||
EXPECT_CALL(*device_files_, DeleteUsageTableInfo());
|
||||
ExpectToDeleteUsageTableFiles();
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
CreateUsageTableHeader(kLevelDefault, NotNull()))
|
||||
.WillOnce(Return(NO_ERROR));
|
||||
EXPECT_CALL(*device_files_, StoreUsageTableInfo(_, _));
|
||||
.WillOnce(DoAll(SetArgPointee<1>(kUsageTableHeader), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_, StoreUsageTableInfo(kUsageTableHeader,
|
||||
kEmptyUsageEntryInfoVector))
|
||||
.WillOnce(Return(true));
|
||||
|
||||
EXPECT_TRUE(usage_table_header_->Init(kSecurityLevelL1, crypto_session_));
|
||||
}
|
||||
|
||||
TEST_F(UsageTableHeaderTest, LruLastUsedTime_CreateLicenseEntry) {
|
||||
// General setup.
|
||||
EXPECT_CALL(*device_files_,
|
||||
RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(kUpgradedUsageTableHeader),
|
||||
SetArgPointee<1>(kUpgradedUsageEntryInfoList),
|
||||
SetArgPointee<2>(/* lru_upgrade = */ false),
|
||||
Return(true)));
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
LoadUsageTableHeader(kLevelDefault, kUpgradedUsageTableHeader))
|
||||
.WillOnce(Return(NO_ERROR));
|
||||
EXPECT_TRUE(usage_table_header_->Init(kSecurityLevelL1, crypto_session_));
|
||||
Init(kSecurityLevelL1, kUpgradedUsageTableHeader,
|
||||
kUpgradedUsageEntryInfoList);
|
||||
|
||||
// Expected values.
|
||||
const uint32_t expected_usage_entry_number =
|
||||
@@ -3598,17 +3731,8 @@ TEST_F(UsageTableHeaderTest, LruLastUsedTime_CreateLicenseEntry) {
|
||||
}
|
||||
|
||||
TEST_F(UsageTableHeaderTest, LruLastUsedTime_CreateUsageInfoEntry) {
|
||||
// General setup.
|
||||
EXPECT_CALL(*device_files_,
|
||||
RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(kUpgradedUsageTableHeader),
|
||||
SetArgPointee<1>(kUpgradedUsageEntryInfoList),
|
||||
SetArgPointee<2>(/* lru_upgrade = */ false),
|
||||
Return(true)));
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
LoadUsageTableHeader(kLevelDefault, kUpgradedUsageTableHeader))
|
||||
.WillOnce(Return(NO_ERROR));
|
||||
EXPECT_TRUE(usage_table_header_->Init(kSecurityLevelL1, crypto_session_));
|
||||
Init(kSecurityLevelL1, kUpgradedUsageTableHeader,
|
||||
kUpgradedUsageEntryInfoList);
|
||||
|
||||
// Expected values.
|
||||
const uint32_t expected_usage_entry_number =
|
||||
@@ -3646,17 +3770,8 @@ TEST_F(UsageTableHeaderTest, LruLastUsedTime_CreateUsageInfoEntry) {
|
||||
}
|
||||
|
||||
TEST_F(UsageTableHeaderTest, LruLastUsedTime_UpdateEntry) {
|
||||
// General setup.
|
||||
EXPECT_CALL(*device_files_,
|
||||
RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(kUpgradedUsageTableHeader),
|
||||
SetArgPointee<1>(kUpgradedUsageEntryInfoList),
|
||||
SetArgPointee<2>(/* lru_upgrade = */ false),
|
||||
Return(true)));
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
LoadUsageTableHeader(kLevelDefault, kUpgradedUsageTableHeader))
|
||||
.WillOnce(Return(NO_ERROR));
|
||||
EXPECT_TRUE(usage_table_header_->Init(kSecurityLevelL1, crypto_session_));
|
||||
Init(kSecurityLevelL1, kUpgradedUsageTableHeader,
|
||||
kUpgradedUsageEntryInfoList);
|
||||
|
||||
std::vector<CdmUsageEntryInfo> expected_usage_info_list =
|
||||
kUpgradedUsageEntryInfoList;
|
||||
@@ -3689,17 +3804,8 @@ TEST_F(UsageTableHeaderTest, LruLastUsedTime_UpdateEntry) {
|
||||
}
|
||||
|
||||
TEST_F(UsageTableHeaderTest, LruLastUsedTime_LoadEntry) {
|
||||
// General setup.
|
||||
EXPECT_CALL(*device_files_,
|
||||
RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(kUpgradedUsageTableHeader),
|
||||
SetArgPointee<1>(kUpgradedUsageEntryInfoList),
|
||||
SetArgPointee<2>(/* lru_upgrade = */ false),
|
||||
Return(true)));
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
LoadUsageTableHeader(kLevelDefault, kUpgradedUsageTableHeader))
|
||||
.WillOnce(Return(NO_ERROR));
|
||||
EXPECT_TRUE(usage_table_header_->Init(kSecurityLevelL1, crypto_session_));
|
||||
Init(kSecurityLevelL1, kUpgradedUsageTableHeader,
|
||||
kUpgradedUsageEntryInfoList);
|
||||
|
||||
std::vector<CdmUsageEntryInfo> expected_usage_info_list =
|
||||
kUpgradedUsageEntryInfoList;
|
||||
@@ -4091,5 +4197,4 @@ TEST_F(UsageTableHeaderTest, PotentialTableCapacity_Available) {
|
||||
EXPECT_EQ(usage_table_header_->potential_table_capacity(), kTableCapacity);
|
||||
EXPECT_FALSE(usage_table_header_->HasUnlimitedTableCapacity());
|
||||
}
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
Reference in New Issue
Block a user