LRU algorithm adapts to usage table capacity.

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

OEMCrypto v16 introduced the ability to report the maximum possible
size of the usage table to the CDM.  The LRU algorithm will take the
table capacity into account when deciding which entry is removed.

Bug: 148795097
Bug: 135298906
Test: CDM unit tests
Change-Id: Ibba88813618c13a9bf1121e560b8cc02b1c7e7a6
This commit is contained in:
Alex Dale
2020-02-18 12:22:23 -08:00
parent ea2e110213
commit 4a8aeb29ef
3 changed files with 92 additions and 16 deletions

View File

@@ -434,6 +434,27 @@ class MockCryptoSession : public TestCryptoSession {
MOCK_METHOD1(MoveUsageEntry, CdmResponseType(uint32_t));
MOCK_METHOD2(ShrinkUsageTableHeader,
CdmResponseType(uint32_t, CdmUsageTableHeader*));
// Fake method for testing. Having an EXPECT_CALL causes complexities
// for getting table capacity during initialization.
virtual bool GetMaximumUsageTableEntries(SecurityLevel security_level,
size_t* number_of_entries) {
if (number_of_entries == nullptr || !maximum_usage_table_entries_set_)
return false;
*number_of_entries = maximum_usage_table_entries_;
return true;
}
void SetMaximumUsageTableEntries(size_t number_of_entries) {
maximum_usage_table_entries_ = number_of_entries;
maximum_usage_table_entries_set_ = true;
}
void UnsetMaximumUsageTableEntries() {
maximum_usage_table_entries_set_ = false;
}
private:
size_t maximum_usage_table_entries_ = 0;
bool maximum_usage_table_entries_set_ = false;
};
// Partial mock of the UsageTableHeader. This is to test when dependency
@@ -618,6 +639,7 @@ TEST_P(UsageTableHeaderInitializationTest, Upgrade_UnableToRetrieveUsageInfo) {
EXPECT_CALL(*device_files_, StoreUsageTableInfo(kEmptyUsageTableHeader,
kEmptyUsageEntryInfoVector))
.WillOnce(Return(true));
EXPECT_TRUE(usage_table_header_->Init(GetParam(), crypto_session_));
}
@@ -655,7 +677,7 @@ TEST_P(UsageTableHeaderInitializationTest,
SetArgPointee<1>(k201UsageEntryInfoVector),
SetArgPointee<2>(false), Return(true)));
SecurityLevel security_level =
const SecurityLevel security_level =
(GetParam() == kSecurityLevelL3) ? kLevel3 : kLevelDefault;
EXPECT_CALL(*crypto_session_,
Open(security_level)).WillOnce(Return(NO_ERROR));
@@ -672,7 +694,7 @@ TEST_P(UsageTableHeaderInitializationTest,
.WillOnce(Return(true));
// Expectations for AddEntry
uint32_t expect_usage_entry_number = k201UsageEntryInfoVector.size();
const uint32_t expect_usage_entry_number = k201UsageEntryInfoVector.size();
EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull()))
.WillOnce(DoAll(SetArgPointee<0>(expect_usage_entry_number),
Return(CREATE_USAGE_ENTRY_UNKNOWN_ERROR)));
@@ -703,7 +725,7 @@ TEST_P(UsageTableHeaderInitializationTest,
.WillOnce(Return(true));
// Expectations for AddEntry
uint32_t expect_usage_entry_number = k201UsageEntryInfoVector.size();
const uint32_t expect_usage_entry_number = k201UsageEntryInfoVector.size();
EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull()))
.WillOnce(DoAll(SetArgPointee<0>(expect_usage_entry_number),
Return(NO_ERROR)));
@@ -712,7 +734,7 @@ TEST_P(UsageTableHeaderInitializationTest,
.WillOnce(Return(true));
// Expectations for DeleteEntry
SecurityLevel security_level =
const SecurityLevel security_level =
(GetParam() == kSecurityLevelL3) ? kLevel3 : kLevelDefault;
EXPECT_CALL(*crypto_session_,
Open(security_level))
@@ -740,7 +762,7 @@ TEST_P(UsageTableHeaderInitializationTest,
.WillOnce(Return(NO_ERROR));
// Expectations for AddEntry
uint32_t expect_usage_entry_number = k201UsageEntryInfoVector.size();
const uint32_t expect_usage_entry_number = k201UsageEntryInfoVector.size();
EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull()))
.WillOnce(DoAll(SetArgPointee<0>(expect_usage_entry_number),
Return(NO_ERROR)));
@@ -749,7 +771,7 @@ TEST_P(UsageTableHeaderInitializationTest,
.WillOnce(Return(true));
// Expectations for DeleteEntry
SecurityLevel security_level =
const SecurityLevel security_level =
(GetParam() == kSecurityLevelL3) ? kLevel3 : kLevelDefault;
EXPECT_CALL(*crypto_session_,
@@ -3467,4 +3489,37 @@ TEST_F(UsageTableHeaderTest, DetermineLicenseToRemove_LargeMixedSet) {
UnorderedElementsAreArray(modified_offline_license_numbers));
}
TEST_F(UsageTableHeaderTest, PotentialTableCapacity_Unavailable) {
crypto_session_->UnsetMaximumUsageTableEntries();
Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector);
EXPECT_EQ(usage_table_header_->potential_table_capacity(),
kMinimumUsageTableEntriesSupported);
}
TEST_F(UsageTableHeaderTest, PotentialTableCapacity_Zero) {
// This will issue a warning about the reported capacity is unexpected,
// and will default to the version's required minimum.
crypto_session_->SetMaximumUsageTableEntries(0u);
Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector);
EXPECT_EQ(usage_table_header_->potential_table_capacity(),
kMinimumUsageTableEntriesSupported);
}
TEST_F(UsageTableHeaderTest, PotentialTableCapacity_TooSmall) {
// This will issue a warning about the reported capacity is unexpected,
// and will default to the version's required minimum.
crypto_session_->SetMaximumUsageTableEntries(
kMinimumUsageTableEntriesSupported / 2);
Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector);
EXPECT_EQ(usage_table_header_->potential_table_capacity(),
kMinimumUsageTableEntriesSupported);
}
TEST_F(UsageTableHeaderTest, PotentialTableCapacity_Available) {
constexpr size_t kTableCapacity = 2000u;
crypto_session_->SetMaximumUsageTableEntries(kTableCapacity);
Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector);
EXPECT_EQ(usage_table_header_->potential_table_capacity(), kTableCapacity);
}
} // namespace wvcdm