From 5dd2b07286bf86240e0261b37aeff99baef81521 Mon Sep 17 00:00:00 2001 From: Alex Dale Date: Mon, 17 Oct 2022 17:34:34 -0700 Subject: [PATCH] Core CDM: Remove usage info as a run-time type. [ Merge of http://go/wvgerrit/159221 ] This CL modifies how usage entry info is tracked internally by the CDM at run time. It removes the different "storage types" that entries represent (license or usage info), and instead it contains only the information associated with license types. The presences of a key-set-id allows the UsageTableHeader to determine if the entry slot is currently being used, or if it can be treated as unoccupied. By removing this different type, it completely prevents the CDM and its tests from using "usage-info" type entries. This required significant updates to the UsageTableHeader tests. Additionally, several of the variable names within the usage table have been simplified and shortened to reflect their new meanings. Bug: 242289743 Test: run_x86_64_tests and usage_table_header_unittest Change-Id: I939e479779425550a17a3c9e6c6d1bc6885e493e --- .../cdm/core/include/device_files.h | 23 +- .../cdm/core/include/usage_table_header.h | 82 +- .../cdm/core/include/wv_cdm_types.h | 86 +- libwvdrmengine/cdm/core/src/cdm_session.cpp | 6 +- libwvdrmengine/cdm/core/src/device_files.cpp | 30 +- .../cdm/core/src/usage_table_header.cpp | 551 +++++---- libwvdrmengine/cdm/core/src/wv_cdm_types.cpp | 13 - .../cdm/core/test/device_files_unittest.cpp | 52 +- .../core/test/usage_table_header_unittest.cpp | 1085 +++++++---------- .../test/metrics_collections_unittest.cpp | 6 +- 10 files changed, 868 insertions(+), 1066 deletions(-) diff --git a/libwvdrmengine/cdm/core/include/device_files.h b/libwvdrmengine/cdm/core/include/device_files.h index a1566b93..8d5bc7ac 100644 --- a/libwvdrmengine/cdm/core/include/device_files.h +++ b/libwvdrmengine/cdm/core/include/device_files.h @@ -103,17 +103,6 @@ class DeviceFiles { CryptoWrappedKey wrapped_private_key; }; - struct CdmUsageData { - std::string provider_session_token; - CdmKeyMessage license_request; - CdmKeyResponse license; - std::string key_set_id; - CdmUsageEntry usage_entry; - uint32_t usage_entry_number; - std::string drm_certificate; - CryptoWrappedKey wrapped_private_key; - }; - DeviceFiles(wvutil::FileSystem*); virtual ~DeviceFiles(); @@ -179,7 +168,7 @@ class DeviceFiles { virtual bool StoreUsageTableInfo( const CdmUsageTableHeader& usage_table_header, - const std::vector& usage_entry_info); + const std::vector& usage_entry_info_list); // When retrieving usage table information from the file system; any // table that has yet to be updated for the LRU attributes will be @@ -190,7 +179,7 @@ class DeviceFiles { // is set to true if any are detected. virtual bool RetrieveUsageTableInfo( CdmUsageTableHeader* usage_table_header, - std::vector* usage_entry_info, bool* lru_upgrade, + std::vector* usage_entry_info_list, bool* lru_upgrade, bool* has_usage_info_entries); virtual bool DeleteUsageTableInfo(); @@ -262,10 +251,6 @@ class DeviceFiles { FRIEND_TEST(DeviceFilesTest, OkpInfo_FileDoesNotExist); FRIEND_TEST(DeviceFilesTest, OkpInfo_DeleteFile); FRIEND_TEST(DeviceFilesTest, OkpInfo_StoreAndRetrieve); - FRIEND_TEST(DeviceFilesUsageInfoTest, Delete); - FRIEND_TEST(DeviceFilesUsageInfoTest, DeleteAll); - FRIEND_TEST(DeviceFilesUsageInfoTest, Read); - FRIEND_TEST(DeviceFilesUsageInfoTest, Store); FRIEND_TEST(DeviceFilesUsageTableTest, Read); FRIEND_TEST(DeviceFilesUsageTableTest, Store); FRIEND_TEST(DeviceFilesUsageTableTest, ReadWithoutLruData); @@ -275,11 +260,7 @@ class DeviceFiles { FRIEND_TEST(StoreCertificateTest, DefaultAndLegacy); FRIEND_TEST(WvCdmRequestLicenseTest, UnprovisionTest); FRIEND_TEST(WvCdmRequestLicenseTest, ForceL3Test); - FRIEND_TEST(WvCdmRequestLicenseTest, UsageInfoRetryTest); FRIEND_TEST(WvCdmRequestLicenseTest, UsageReleaseAllTest); - FRIEND_TEST(WvCdmUsageInfoTest, UsageInfo); - FRIEND_TEST(WvCdmUsageTest, WithClientId); - FRIEND_TEST(WvCdmExtendedDurationTest, UsageOverflowTest); #endif static std::set reserved_license_ids_; diff --git a/libwvdrmengine/cdm/core/include/usage_table_header.h b/libwvdrmengine/cdm/core/include/usage_table_header.h index 4fd992f5..a479dffa 100644 --- a/libwvdrmengine/cdm/core/include/usage_table_header.h +++ b/libwvdrmengine/cdm/core/include/usage_table_header.h @@ -46,7 +46,7 @@ namespace wvcdm { // // Upgrades from a fixed size usage table (supported by previous // versions of the OEMCrypto API v9-12) are handled by this class. -// |usage_entry| and |usage_entry_number|s need to be saved in the license +// |usage_entry| and |entry_number|s need to be saved in the license // and usage info records by the caller. class UsageTableHeader { public: @@ -65,30 +65,30 @@ class UsageTableHeader { // Adds a new entry to the OEMCrypto usage table header, and associates // the entry with the provided |crypto_session|. The index of the new - // usage entry will be returned by |usage_entry_number|. + // usage entry will be returned by |entry_number|. // - // Threading: Method takes exclusive use of |usage_table_header_lock_|. + // Threading: Method takes exclusive use of |table_lock_|. virtual CdmResponseType AddEntry(CryptoSession* crypto_session, const CdmKeySetId& key_set_id, const CdmKeyResponse& license_message, - uint32_t* usage_entry_number); - // Threading: Method takes exclusive use of |usage_table_header_lock_|. + uint32_t* entry_number); + // Threading: Method takes exclusive use of |table_lock_|. virtual CdmResponseType LoadEntry(CryptoSession* crypto_session, const CdmUsageEntry& usage_entry, - uint32_t usage_entry_number); - // Threading: Method takes exclusive use of |usage_table_header_lock_|. - virtual CdmResponseType UpdateEntry(uint32_t usage_entry_number, + uint32_t entry_number); + // Threading: Method takes exclusive use of |table_lock_|. + virtual CdmResponseType UpdateEntry(uint32_t entry_number, CryptoSession* crypto_session, CdmUsageEntry* usage_entry); - // The licenses or usage info records specified by |usage_entry_number| + // The licenses or usage info records specified by |entry_number| // should not be in use by any open CryptoSession objects when calls // to InvalidateEntry and MoveEntry are made. // If |defrag_table| is true, the table will be defragmented after // the entry has been invalidated. // - // Threading: Method takes exclusive use of |usage_table_header_lock_|. - virtual CdmResponseType InvalidateEntry(uint32_t usage_entry_number, + // Threading: Method takes exclusive use of |table_lock_|. + virtual CdmResponseType InvalidateEntry(uint32_t entry_number, bool defrag_table, DeviceFiles* device_files, metrics::CryptoMetrics* metrics); @@ -101,13 +101,13 @@ class UsageTableHeader { // for the objects that InvalidateEntry depends on. // // Threading: Method requires care of caller for exclusive access. - void InvalidateEntryForTest(uint32_t usage_entry_number); + void InvalidateEntryForTest(uint32_t entry_number); // == Table information methods == // Threading: None of the following are thread safe. Intended for // testing or internal use. - size_t size() { return usage_entry_info_.size(); } + size_t size() { return entry_info_list_.size(); } size_t potential_table_capacity() const { return potential_table_capacity_; } @@ -116,11 +116,11 @@ class UsageTableHeader { } // Returns the number of entries currently tracked by the CDM that - // are related to offline licenses. - size_t OfflineEntryCount() const; + // are populated (non-empty). + size_t OccupiedEntryCount() const; - const std::vector& usage_entry_info() const { - return usage_entry_info_; + const std::vector& entry_info_list() const { + return entry_info_list_; } // Set the reference clock used for the method GetCurrentTime(). @@ -132,10 +132,10 @@ class UsageTableHeader { } static bool DetermineLicenseToRemoveForTesting( - const std::vector& usage_entry_info_list, + const std::vector& entry_info_list, int64_t current_time, size_t unexpired_threshold, uint32_t* entry_to_remove) { - return DetermineLicenseToRemove(usage_entry_info_list, current_time, + return DetermineLicenseToRemove(entry_info_list, current_time, unexpired_threshold, entry_to_remove); } @@ -146,13 +146,13 @@ class UsageTableHeader { // Creates a new, empty usage table. Any existing usage table files // will be deleted. - // Threading: Method takes exclusive use of |usage_table_header_lock_| + // Threading: Method takes exclusive use of |table_lock_| // when required. bool CreateNewTable(CryptoSession* const crypto_session); // Attempts to restore the usage table from persistent storage, and // loads the usage table header into OEMCrypto. // Note: No other OEMCrypto session should be opened before calling. - // Threading: Method takes exclusive use of |usage_table_header_lock_| + // Threading: Method takes exclusive use of |table_lock_| // when required. bool RestoreTable(CryptoSession* const crypto_session); @@ -164,52 +164,52 @@ class UsageTableHeader { // one more entry if the table is at or near the reported capacity. // If this check fails, a new usage table SHOULD be created. // Threading: Method requires caller to take exclusive use of - // |usage_table_header_lock_|. + // |table_lock_|. bool CapacityCheck(CryptoSession* const crypto_session); // Attempts to determine the capacity of the OEMCrypto usage table. // Sets the result to |potential_table_capacity_|. // Threading: Method requires caller to take exclusive use of - // |usage_table_header_lock_|. + // |table_lock_|. bool DetermineTableCapacity(CryptoSession* crypto_session); // == Table operation methods == // Threading: All of the following methods require caller to take - // exclusive use of |usage_table_header_lock_|. + // exclusive use of |table_lock_|. // Creates a new entry for the provided crypto session. If the // entry is created successfully in OEMCrypto, then a new entry // info is added to the table's vector of entry info. CdmResponseType CreateEntry(CryptoSession* const crypto_session, - uint32_t* usage_entry_number); + uint32_t* entry_number); // Attempts to relocate a newly created usage entry associated with // the provided |crypto_session| to the lowest unoccupied position in // the table. - // |usage_entry_number| is treated as both an input and output. + // |entry_number| is treated as both an input and output. // Returns NO_ERROR so long as no internal operation fails, // regardless of whether the entry was moved or not. CdmResponseType RelocateNewEntry(CryptoSession* const crypto_session, - uint32_t* usage_entry_number); + uint32_t* entry_number); - // Checks if the specified |usage_entry_number| is known to be + // Checks if the specified |entry_number| is known to be // unoccupied (released). - bool IsEntryUnoccupied(const uint32_t usage_entry_number) const; + bool IsEntryUnoccupied(const uint32_t entry_number) const; // Populates the entry's meta-data with the required information based // entry meta-data with the required information based on the type // on the license content. - void SetOfflineEntryInfo(const uint32_t usage_entry_number, + void SetOfflineEntryInfo(const uint32_t entry_number, const std::string& key_set_id, const CdmKeyResponse& license_message); // Shrinks the table, removing all trailing unoccupied entries. - // |usage_entry_info_| will be resized appropriately. + // |entry_info_| will be resized appropriately. // Caller must store the table after a successful call. CdmResponseType RefitTable(CryptoSession* const crypto_session); virtual CdmResponseType InvalidateEntryInternal( - uint32_t usage_entry_number, bool defrag_table, DeviceFiles* device_files, + uint32_t entry_number, bool defrag_table, DeviceFiles* device_files, metrics::CryptoMetrics* metrics); CdmResponseType MoveEntry(uint32_t from /* usage entry number */, @@ -218,11 +218,9 @@ class UsageTableHeader { DeviceFiles* device_files, metrics::CryptoMetrics* metrics); - CdmResponseType GetEntry(uint32_t usage_entry_number, - DeviceFiles* device_files, + CdmResponseType GetEntry(uint32_t entry_number, DeviceFiles* device_files, CdmUsageEntry* usage_entry); - CdmResponseType StoreEntry(uint32_t usage_entry_number, - DeviceFiles* device_files, + CdmResponseType StoreEntry(uint32_t entry_number, DeviceFiles* device_files, const CdmUsageEntry& usage_entry); // Stores the usage table and it's info. This will increment @@ -273,7 +271,7 @@ class UsageTableHeader { // types. // // Parameters: - // [in] usage_entry_info_list: The complete list of known usage + // [in] entry_info_list: The complete list of known usage // entries. // [in] current_time: The current time to compare expiration times // against. @@ -288,20 +286,20 @@ class UsageTableHeader { // |true| if an entry has been determined to be removed. // Otherwise returns |false|. static bool DetermineLicenseToRemove( - const std::vector& usage_entry_info_list, + const std::vector& entry_info_list, int64_t current_time, size_t unexpired_threshold, uint32_t* entry_to_remove); // This handle and file system is only to be used when accessing - // usage_table_header. Usage entries should use the file system provided + // |table_header|. Usage entries should use the file system provided // by CdmSession. std::unique_ptr device_files_; std::unique_ptr file_system_; CdmSecurityLevel security_level_ = kSecurityLevelUninitialized; RequestedSecurityLevel requested_security_level_ = kLevelDefault; - CdmUsageTableHeader usage_table_header_; - std::vector usage_entry_info_; + CdmUsageTableHeader table_header_; + std::vector entry_info_list_; // Table is sync with persistent storage and can be used by the CDM // to interact with OEMCrypto. @@ -309,7 +307,7 @@ class UsageTableHeader { // Synchonizes access to the Usage Table Header and bookkeeping // data-structures - mutable std::mutex usage_table_header_lock_; + mutable std::mutex table_lock_; metrics::CryptoMetrics alternate_crypto_metrics_; diff --git a/libwvdrmengine/cdm/core/include/wv_cdm_types.h b/libwvdrmengine/cdm/core/include/wv_cdm_types.h index d1111d79..69a5ae21 100644 --- a/libwvdrmengine/cdm/core/include/wv_cdm_types.h +++ b/libwvdrmengine/cdm/core/include/wv_cdm_types.h @@ -537,44 +537,71 @@ enum CdmUsageSupportType : int32_t { kUnknownUsageSupport, }; -enum CdmUsageEntryStorageType : int32_t { - kStorageLicense, - kStorageUsageInfo, - kStorageTypeUnknown, -}; +class CdmUsageEntryInfo { + public: + CdmUsageEntryInfo() {} + CdmUsageEntryInfo(const std::string& key_set_id, int64_t last_use_time, + int64_t license_expiry_time) + : key_set_id_(key_set_id), + last_use_time_(last_use_time), + license_expiry_time_(license_expiry_time) { + if (key_set_id.empty()) Clear(); + } + + CdmUsageEntryInfo(const CdmUsageEntryInfo&) = default; + CdmUsageEntryInfo& operator=(const CdmUsageEntryInfo&) = default; + + CdmUsageEntryInfo(CdmUsageEntryInfo&&) = default; + CdmUsageEntryInfo& operator=(CdmUsageEntryInfo&&) = default; + + bool HasKeySetId() const { return !key_set_id_.empty(); } + bool IsEmpty() const { return key_set_id_.empty(); } + + const std::string& key_set_id() const { return key_set_id_; } + void SetKeySetId(const std::string& key_set_id) { + if (key_set_id.empty()) { + Clear(); + } else { + key_set_id_ = key_set_id; + } + } + + int64_t last_use_time() const { return last_use_time_; } + void SetLastUseTime(int64_t last_use_time) { last_use_time_ = last_use_time; } + // Used for testing. + void IncLastUseTime() { last_use_time_++; } + void DecLastUseTime() { last_use_time_--; } + + int64_t license_expiry_time() const { return license_expiry_time_; } + void SetLicenseExpiryTime(int64_t license_expiry_time) { + license_expiry_time_ = license_expiry_time; + } + + void Clear() { + key_set_id_.clear(); + last_use_time_ = license_expiry_time_ = 0; + } -struct CdmUsageEntryInfo { - CdmUsageEntryStorageType storage_type; - CdmKeySetId key_set_id; - std::string usage_info_file_name; - int64_t last_use_time; - int64_t offline_license_expiry_time; // Only for offline licenses. bool operator==(const CdmUsageEntryInfo& other) const { if (this == &other) { return true; } - if (storage_type != other.storage_type || key_set_id != other.key_set_id || - last_use_time != other.last_use_time) { + if (IsEmpty() && other.IsEmpty()) { + // All other fields are ignored if there is no key set ID set. + return true; + } + if (key_set_id_ != other.key_set_id_) { return false; } - // Certain fields only have meaning based on the storage type. - if (storage_type == kStorageUsageInfo) { - return usage_info_file_name == other.usage_info_file_name; - } - if (storage_type == kStorageLicense) { - return offline_license_expiry_time == other.offline_license_expiry_time; - } - // else storage_type == kStorageTypeUnknown - return true; + return last_use_time_ == other.last_use_time_ && + license_expiry_time_ == other.license_expiry_time_; } - void Clear() { - storage_type = kStorageTypeUnknown; - key_set_id.clear(); - usage_info_file_name.clear(); - last_use_time = 0; - offline_license_expiry_time = 0; - } + private: + // If |key_set_id_| is empty, the other fields are ignored. + CdmKeySetId key_set_id_ = ""; + int64_t last_use_time_ = 0; + int64_t license_expiry_time_ = 0; }; enum CdmKeySecurityLevel : int32_t { @@ -846,7 +873,6 @@ const char* CdmOfflineLicenseStateToString( CdmOfflineLicenseState license_state); const std::string CdmResponseTypeToString(int cdm_response_type); const char* CdmSecurityLevelToString(CdmSecurityLevel security_level); -const char* CdmUsageEntryStorageTypeToString(CdmUsageEntryStorageType type); const char* RequestedSecurityLevelToString( RequestedSecurityLevel security_level); const char* CdmWatermarkingSupportToString(CdmWatermarkingSupport support); diff --git a/libwvdrmengine/cdm/core/src/cdm_session.cpp b/libwvdrmengine/cdm/core/src/cdm_session.cpp index 9c1295a7..823f687f 100644 --- a/libwvdrmengine/cdm/core/src/cdm_session.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_session.cpp @@ -1049,9 +1049,9 @@ bool CdmSession::VerifyOfflineUsageEntry() { return false; } const CdmUsageEntryInfo& usage_entry_info = - usage_table_header_->usage_entry_info().at(usage_entry_number_); - if (usage_entry_info.storage_type != kStorageLicense || - usage_entry_info.key_set_id != key_set_id_) { + usage_table_header_->entry_info_list().at(usage_entry_number_); + if (usage_entry_info.IsEmpty() || + usage_entry_info.key_set_id() != key_set_id_) { LOGD("License usage entry does not match"); return false; } diff --git a/libwvdrmengine/cdm/core/src/device_files.cpp b/libwvdrmengine/cdm/core/src/device_files.cpp index 22c14086..02dacd02 100644 --- a/libwvdrmengine/cdm/core/src/device_files.cpp +++ b/libwvdrmengine/cdm/core/src/device_files.cpp @@ -1014,7 +1014,7 @@ bool DeviceFiles::DeleteHlsAttributes(const std::string& key_set_id) { bool DeviceFiles::StoreUsageTableInfo( const CdmUsageTableHeader& usage_table_header, - const std::vector& usage_entry_info) { + const std::vector& usage_entry_info_list) { RETURN_FALSE_IF_UNINITIALIZED(); using video_widevine_client::sdk::UsageTableInfo; using UsageEntryInfo = UsageTableInfo::UsageEntryInfo; @@ -1028,14 +1028,14 @@ bool DeviceFiles::StoreUsageTableInfo( UsageTableInfo* stored_table_info = file.mutable_usage_table_info(); stored_table_info->set_usage_table_header(usage_table_header); - for (const auto& entry_info : usage_entry_info) { + for (const auto& entry_info : usage_entry_info_list) { UsageEntryInfo* stored_info = stored_table_info->add_usage_entry_info(); - if (entry_info.storage_type == kStorageLicense) { + if (entry_info.HasKeySetId()) { stored_info->set_storage(UsageEntryInfo::LICENSE); - stored_info->set_key_set_id(entry_info.key_set_id); - stored_info->set_last_use_time(entry_info.last_use_time); + stored_info->set_key_set_id(entry_info.key_set_id()); + stored_info->set_last_use_time(entry_info.last_use_time()); stored_info->set_offline_license_expiry_time( - entry_info.offline_license_expiry_time); + entry_info.license_expiry_time()); } else { stored_info->set_storage(UsageEntryInfo::UNKNOWN); } @@ -1051,11 +1051,11 @@ bool DeviceFiles::StoreUsageTableInfo( bool DeviceFiles::RetrieveUsageTableInfo( CdmUsageTableHeader* usage_table_header, - std::vector* usage_entry_info, bool* lru_upgrade, + std::vector* usage_entry_info_list, bool* lru_upgrade, bool* has_usage_info_entries) { RETURN_FALSE_IF_UNINITIALIZED(); RETURN_FALSE_IF_NULL(usage_table_header); - RETURN_FALSE_IF_NULL(usage_entry_info); + RETURN_FALSE_IF_NULL(usage_entry_info_list); RETURN_FALSE_IF_NULL(lru_upgrade); RETURN_FALSE_IF_NULL(has_usage_info_entries); using video_widevine_client::sdk::UsageTableInfo; @@ -1091,22 +1091,22 @@ bool DeviceFiles::RetrieveUsageTableInfo( *lru_upgrade = !stored_table_info.use_lru(); *has_usage_info_entries = false; *usage_table_header = stored_table_info.usage_table_header(); - usage_entry_info->reserve(stored_table_info.usage_entry_info_size()); + usage_entry_info_list->clear(); + usage_entry_info_list->reserve(stored_table_info.usage_entry_info_size()); for (const auto& stored_entry_info : stored_table_info.usage_entry_info()) { CdmUsageEntryInfo entry_info; entry_info.Clear(); if (stored_entry_info.storage() == UsageEntryInfo::LICENSE) { - entry_info.storage_type = kStorageLicense; - entry_info.key_set_id = stored_entry_info.key_set_id(); - entry_info.last_use_time = stored_entry_info.last_use_time(); - entry_info.offline_license_expiry_time = - stored_entry_info.offline_license_expiry_time(); + entry_info.SetKeySetId(stored_entry_info.key_set_id()); + entry_info.SetLastUseTime(stored_entry_info.last_use_time()); + entry_info.SetLicenseExpiryTime( + stored_entry_info.offline_license_expiry_time()); } else if (stored_entry_info.storage() == UsageEntryInfo::USAGE_INFO) { // USAGE_INFO are deprecated, do not retrieve this entries. *has_usage_info_entries = true; } - usage_entry_info->emplace_back(std::move(entry_info)); + usage_entry_info_list->emplace_back(std::move(entry_info)); } return true; } diff --git a/libwvdrmengine/cdm/core/src/usage_table_header.cpp b/libwvdrmengine/cdm/core/src/usage_table_header.cpp index ba85f65e..4052210e 100644 --- a/libwvdrmengine/cdm/core/src/usage_table_header.cpp +++ b/libwvdrmengine/cdm/core/src/usage_table_header.cpp @@ -71,7 +71,7 @@ bool ParseLicenseFromLicenseMessage(const CdmKeyResponse& license_message, bool RetrieveOfflineLicense(DeviceFiles* device_files, const std::string& key_set_id, CdmKeyResponse* license_message, - uint32_t* usage_entry_number) { + uint32_t* entry_number) { if (device_files == nullptr) { LOGE("DeviceFiles handle is null"); return false; @@ -80,8 +80,8 @@ bool RetrieveOfflineLicense(DeviceFiles* device_files, LOGE("Output parameter |license_message| is null"); return false; } - if (usage_entry_number == nullptr) { - LOGE("Output parameter |usage_entry_number| is null"); + if (entry_number == nullptr) { + LOGE("Output parameter |entry_number| is null"); return false; } DeviceFiles::CdmLicenseData license_data; @@ -92,13 +92,30 @@ bool RetrieveOfflineLicense(DeviceFiles* device_files, return false; } *license_message = std::move(license_data.license); - *usage_entry_number = license_data.usage_entry_number; + *entry_number = license_data.usage_entry_number; return true; } -bool EntryIsOfflineLicense(const CdmUsageEntryInfo& info) { +int64_t CalculateOfflineLicenseExpiryTime(const CdmKeyResponse& license_message, + int64_t last_use_time) { + // Need to determine the expire time for offline licenses. + video_widevine::License license; + if (license_message.empty() || + !ParseLicenseFromLicenseMessage(license_message, &license)) { + // If the license duration cannot be determined for any reason, it + // is assumed to last at most 33 days. + return last_use_time + kDefaultExpireDuration; + } + // TODO(b/256037954): Fix how entry expiry time for unlimited licenses + // are calculated. They should last at least 33 days. + const video_widevine::License::Policy& policy = license.policy(); + return license.license_start_time() + policy.rental_duration_seconds() + + policy.playback_duration_seconds(); +} + +bool EntryIsOccupied(const CdmUsageEntryInfo& info) { // Used for stl filters. - return info.storage_type == kStorageLicense; + return info.HasKeySetId(); } bool IsValidCdmSecurityLevelForUsageTable(CdmSecurityLevel security_level) { @@ -110,6 +127,18 @@ RequestedSecurityLevel CdmSecurityLevelToRequestedLevel( CdmSecurityLevel security_level) { return security_level == kSecurityLevelL3 ? kLevel3 : kLevelDefault; } + +const char* GetEntryStateString( + uint32_t entry_number, + const std::vector& entry_info_list) { + if (static_cast(entry_number) >= entry_info_list.size()) { + return ""; + } + if (entry_info_list[entry_number].HasKeySetId()) { + return ""; + } + return ""; +} } // namespace UsageTableHeader::UsageTableHeader() : clock_ref_(&clock_) { @@ -155,17 +184,17 @@ bool UsageTableHeader::Init(CdmSecurityLevel security_level, bool UsageTableHeader::RestoreTable(CryptoSession* const crypto_session) { bool run_lru_upgrade = false; bool has_usage_info_entries = false; - if (!device_files_->RetrieveUsageTableInfo( - &usage_table_header_, &usage_entry_info_, &run_lru_upgrade, - &has_usage_info_entries)) { + if (!device_files_->RetrieveUsageTableInfo(&table_header_, &entry_info_list_, + &run_lru_upgrade, + &has_usage_info_entries)) { LOGW("Could not retrieve usage table"); return false; } LOGI("Found usage table to restore: entry_count = %zu", - usage_entry_info_.size()); + entry_info_list_.size()); const CdmResponseType status = crypto_session->LoadUsageTableHeader( - requested_security_level_, usage_table_header_); + requested_security_level_, table_header_); if (status != NO_ERROR) { LOGE("Failed to load usage table header: sts = %d", static_cast(status)); @@ -203,11 +232,11 @@ bool UsageTableHeader::CreateNewTable(CryptoSession* const crypto_session) { device_files_->DeleteAllLicenses(); device_files_->DeleteAllUsageInfo(); device_files_->DeleteUsageTableInfo(); - usage_entry_info_.clear(); - usage_table_header_.clear(); + entry_info_list_.clear(); + table_header_.clear(); const CdmResponseType status = crypto_session->CreateUsageTableHeader( - requested_security_level_, &usage_table_header_); + requested_security_level_, &table_header_); if (status != NO_ERROR) { LOGE("Failed to create new usage table header"); return false; @@ -222,34 +251,34 @@ bool UsageTableHeader::CreateNewTable(CryptoSession* const crypto_session) { CdmResponseType UsageTableHeader::AddEntry( CryptoSession* crypto_session, const CdmKeySetId& key_set_id, - const CdmKeyResponse& license_message, uint32_t* usage_entry_number) { + const CdmKeyResponse& license_message, uint32_t* entry_number) { LOGD("key_set_id = %s, current_size = %zu", IdToString(key_set_id), - usage_entry_info_.size()); + entry_info_list_.size()); metrics::CryptoMetrics* metrics = crypto_session->GetCryptoMetrics(); if (metrics == nullptr) metrics = &alternate_crypto_metrics_; - TableLock auto_lock(usage_table_header_lock_); + TableLock auto_lock(table_lock_); - CdmResponseType status = CreateEntry(crypto_session, usage_entry_number); + CdmResponseType status = CreateEntry(crypto_session, entry_number); if (status == INSUFFICIENT_CRYPTO_RESOURCES) { LOGW("Usage table may be full, releasing oldest entry: size = %zu", - usage_entry_info_.size()); + entry_info_list_.size()); status = ReleaseOldestEntry(metrics); if (status == NO_ERROR) { - status = CreateEntry(crypto_session, usage_entry_number); + status = CreateEntry(crypto_session, entry_number); } } if (status != NO_ERROR) return status; - status = RelocateNewEntry(crypto_session, usage_entry_number); + status = RelocateNewEntry(crypto_session, entry_number); if (status != NO_ERROR) return status; - SetOfflineEntryInfo(*usage_entry_number, key_set_id, license_message); + SetOfflineEntryInfo(*entry_number, key_set_id, license_message); status = RefitTable(crypto_session); if (status != NO_ERROR) { // Clear new entry on failure. - usage_entry_info_[*usage_entry_number].Clear(); + entry_info_list_[*entry_number].Clear(); return status; } @@ -257,11 +286,10 @@ CdmResponseType UsageTableHeader::AddEntry( // entry. If the entry is used by the CDM, the CDM session will make // subsequent calls to update the usage entry and store that entry. std::string usage_entry; - status = crypto_session->UpdateUsageEntry(&usage_table_header_, &usage_entry); + status = crypto_session->UpdateUsageEntry(&table_header_, &usage_entry); if (status != NO_ERROR) { - LOGE("Failed to update new usage entry: usage_entry_number = %u", - *usage_entry_number); - usage_entry_info_[*usage_entry_number].Clear(); + LOGE("Failed to update new usage entry: entry_number = %u", *entry_number); + entry_info_list_[*entry_number].Clear(); return status; } StoreTable(); @@ -270,16 +298,16 @@ CdmResponseType UsageTableHeader::AddEntry( CdmResponseType UsageTableHeader::LoadEntry(CryptoSession* crypto_session, const CdmUsageEntry& usage_entry, - uint32_t usage_entry_number) { + uint32_t entry_number) { { - LOGD("usage_entry_number = %u", usage_entry_number); - std::unique_lock auto_lock(usage_table_header_lock_); + LOGD("entry_number = %u", entry_number); + std::unique_lock auto_lock(table_lock_); - if (usage_entry_number >= usage_entry_info_.size()) { + if (entry_number >= entry_info_list_.size()) { LOGE( "Requested usage entry number is larger than table size: " - "usage_entry_number = %u, table_size = %zu", - usage_entry_number, usage_entry_info_.size()); + "entry_number = %u, table_size = %zu", + entry_number, entry_info_list_.size()); return USAGE_INVALID_LOAD_ENTRY; } } @@ -287,66 +315,66 @@ CdmResponseType UsageTableHeader::LoadEntry(CryptoSession* crypto_session, if (metrics == nullptr) metrics = &alternate_crypto_metrics_; const CdmResponseType status = - crypto_session->LoadUsageEntry(usage_entry_number, usage_entry); + crypto_session->LoadUsageEntry(entry_number, usage_entry); if (status == NO_ERROR) { - usage_entry_info_[usage_entry_number].last_use_time = GetCurrentTime(); + entry_info_list_[entry_number].SetLastUseTime(GetCurrentTime()); } return status; } -CdmResponseType UsageTableHeader::UpdateEntry(uint32_t usage_entry_number, +CdmResponseType UsageTableHeader::UpdateEntry(uint32_t entry_number, CryptoSession* crypto_session, CdmUsageEntry* usage_entry) { - LOGD("usage_entry_number = %u", usage_entry_number); - std::unique_lock auto_lock(usage_table_header_lock_); - if (usage_entry_number >= usage_entry_info_.size()) { + LOGD("entry_number = %u", entry_number); + std::unique_lock auto_lock(table_lock_); + if (entry_number >= entry_info_list_.size()) { LOGE("Usage entry number %u is larger than usage entry size %zu", - usage_entry_number, usage_entry_info_.size()); + entry_number, entry_info_list_.size()); return USAGE_INVALID_PARAMETERS_2; } CdmResponseType status = - crypto_session->UpdateUsageEntry(&usage_table_header_, usage_entry); + crypto_session->UpdateUsageEntry(&table_header_, usage_entry); if (status != NO_ERROR) return status; - usage_entry_info_[usage_entry_number].last_use_time = GetCurrentTime(); + entry_info_list_[entry_number].SetLastUseTime(GetCurrentTime()); StoreTable(); return NO_ERROR; } CdmResponseType UsageTableHeader::InvalidateEntry( - uint32_t usage_entry_number, bool defrag_table, DeviceFiles* device_files, + uint32_t entry_number, bool defrag_table, DeviceFiles* device_files, metrics::CryptoMetrics* metrics) { - LOGD("usage_entry_number = %u", usage_entry_number); - TableLock auto_lock(usage_table_header_lock_); - return InvalidateEntryInternal(usage_entry_number, defrag_table, device_files, + LOGD("entry_number = %u", entry_number); + TableLock auto_lock(table_lock_); + return InvalidateEntryInternal(entry_number, defrag_table, device_files, metrics); } CdmResponseType UsageTableHeader::InvalidateEntryInternal( - uint32_t usage_entry_number, bool defrag_table, DeviceFiles* device_files, + uint32_t entry_number, bool defrag_table, DeviceFiles* device_files, metrics::CryptoMetrics* metrics) { // OEMCrypto does not have any concept of "deleting" an entry. - // Instead, the CDM marks the entry's meta data as invalid (storage - // type unknown) and then performs a "defrag" of the OEMCrypto table. - if (usage_entry_number >= usage_entry_info_.size()) { + // Instead, the CDM clears the entry's meta data and then performs a + // "defrag" of the OEMCrypto table. + if (entry_number >= entry_info_list_.size()) { LOGE( "Usage entry number is larger than table size: " - "usage_entry_number = %u, table_size = %zu", - usage_entry_number, usage_entry_info_.size()); + "entry_number = %u, table_size = %zu", + entry_number, entry_info_list_.size()); return USAGE_INVALID_PARAMETERS_1; } - usage_entry_info_[usage_entry_number].Clear(); + entry_info_list_[entry_number].Clear(); if (defrag_table) { // The defrag operation calls many OEMCrypto functions that are - // unrelated to the caller, the only error that will be returned is - // a SYSTEM_INVALIDATED_ERROR. As long as the storage type is - // properly set to unknown, the operation is considered successful. + // unrelated to the caller, the only error that will be returned + // is a SYSTEM_INVALIDATED_ERROR. As long as the entry is cleared + // the operation is considered successful. // SYSTEM_INVALIDATED_ERROR is a special type of error that must be // sent back to the caller for the CDM as a whole to handle. const uint32_t pre_defrag_store_counter = store_table_counter_; @@ -369,10 +397,10 @@ CdmResponseType UsageTableHeader::InvalidateEntryInternal( return NO_ERROR; } -size_t UsageTableHeader::OfflineEntryCount() const { - LOGV("Locking to count offline license entries"); - return std::count_if(usage_entry_info_.cbegin(), usage_entry_info_.cend(), - EntryIsOfflineLicense); +size_t UsageTableHeader::OccupiedEntryCount() const { + LOGV("Locking to count occupied entries"); + return std::count_if(entry_info_list_.cbegin(), entry_info_list_.cend(), + EntryIsOccupied); } bool UsageTableHeader::OpenSessionCheck(CryptoSession* const crypto_session) { @@ -399,7 +427,7 @@ bool UsageTableHeader::CapacityCheck(CryptoSession* const crypto_session) { const size_t capacity_threshold = HasUnlimitedTableCapacity() ? kMinimumUsageTableEntriesSupported : potential_table_capacity(); - if (usage_entry_info_.size() <= capacity_threshold) { + if (entry_info_list_.size() <= capacity_threshold) { // No need to perform test if below capacity. return true; } @@ -423,9 +451,9 @@ bool UsageTableHeader::CapacityCheck(CryptoSession* const crypto_session) { return false; } - uint32_t temporary_usage_entry_number; + uint32_t temporary_entry_number; status = AddEntry(local_crypto_session, kDummyKeySetId, kEmptyString, - &temporary_usage_entry_number); + &temporary_entry_number); if (status != NO_ERROR) { LOGE("Failed to add entry for capacity test: sts = %d", static_cast(status)); @@ -433,14 +461,14 @@ bool UsageTableHeader::CapacityCheck(CryptoSession* const crypto_session) { } status = - InvalidateEntry(temporary_usage_entry_number, + InvalidateEntry(temporary_entry_number, /* defrag_table = */ true, device_files_.get(), metrics); if (status != NO_ERROR) { LOGE("Failed to invalidate entry for capacity test: sts = %d", static_cast(status)); return false; } - if (usage_entry_info_.size() > temporary_usage_entry_number) { + if (entry_info_list_.size() > temporary_entry_number) { // The entry should have been deleted from the usage table, // not just marked as type unknown. Failure to call // Shrink() may be an indicator of other issues. @@ -475,40 +503,39 @@ bool UsageTableHeader::DetermineTableCapacity(CryptoSession* crypto_session) { } CdmResponseType UsageTableHeader::CreateEntry( - CryptoSession* const crypto_session, uint32_t* usage_entry_number) { - const CdmResponseType status = - crypto_session->CreateUsageEntry(usage_entry_number); + CryptoSession* const crypto_session, uint32_t* entry_number) { + const CdmResponseType status = crypto_session->CreateUsageEntry(entry_number); if (status != NO_ERROR) return status; // If the new entry number is smaller than expected, then the usage // table may be out of sync or OEMCrypto has been rolled back. // Not safe to continue. - if (*usage_entry_number < usage_entry_info_.size()) { + if (*entry_number < entry_info_list_.size()) { LOGE( "New entry number is smaller than table size: " "entry_info_number = %u, table_size = %zu", - *usage_entry_number, usage_entry_info_.size()); + *entry_number, entry_info_list_.size()); return USAGE_INVALID_NEW_ENTRY; } - LOGI("usage_entry_number = %u", *usage_entry_number); - const size_t previous_size = usage_entry_info_.size(); - usage_entry_info_.resize(*usage_entry_number + 1); - if (*usage_entry_number > previous_size) { + LOGI("entry_number = %u", *entry_number); + const size_t previous_size = entry_info_list_.size(); + entry_info_list_.resize(*entry_number + 1); + if (*entry_number > previous_size) { LOGW( "New entry number is larger than table size, resizing: " "entry_info_number = %u, table_size = %zu", - *usage_entry_number, previous_size); - for (size_t i = previous_size; i < usage_entry_info_.size() - 1; ++i) { - usage_entry_info_[i].Clear(); + *entry_number, previous_size); + for (size_t i = previous_size; i < entry_info_list_.size() - 1; ++i) { + entry_info_list_[i].Clear(); } } - usage_entry_info_[*usage_entry_number].Clear(); + entry_info_list_[*entry_number].Clear(); return NO_ERROR; } CdmResponseType UsageTableHeader::RelocateNewEntry( - CryptoSession* const crypto_session, uint32_t* usage_entry_number) { + CryptoSession* const crypto_session, uint32_t* entry_number) { static constexpr uint32_t kMinimumEntryNumber = 0; - const uint32_t initial_entry_number = *usage_entry_number; + const uint32_t initial_entry_number = *entry_number; if (initial_entry_number == kMinimumEntryNumber) { // First entry in the table. return NO_ERROR; @@ -535,86 +562,72 @@ CdmResponseType UsageTableHeader::RelocateNewEntry( if (status != NO_ERROR) return status; LOGI("Entry moved: from_index = %u, to_index = %u", initial_entry_number, unoccupied_entry_number); - *usage_entry_number = unoccupied_entry_number; - usage_entry_info_[unoccupied_entry_number] = - std::move(usage_entry_info_[initial_entry_number]); - usage_entry_info_[initial_entry_number].Clear(); + *entry_number = unoccupied_entry_number; + entry_info_list_[unoccupied_entry_number] = + std::move(entry_info_list_[initial_entry_number]); + entry_info_list_[initial_entry_number].Clear(); return NO_ERROR; } -bool UsageTableHeader::IsEntryUnoccupied( - const uint32_t usage_entry_number) const { - if (usage_entry_info_[usage_entry_number].storage_type != - kStorageTypeUnknown) { +bool UsageTableHeader::IsEntryUnoccupied(const uint32_t entry_number) const { + if (entry_info_list_[entry_number].HasKeySetId()) { return false; } // TODO(sigquit): Check that entry is not in use by another session. - // NOTE: The |storage_type| check will protect the integrity of the - // entry. Attempting to use an entry index that is used by another + // NOTE: The check will protect the integrity of the entry. + // Attempting to use an entry index that is used by another // session is recoverable and will not affect any opened sessions. return true; } void UsageTableHeader::SetOfflineEntryInfo( - const uint32_t usage_entry_number, const std::string& key_set_id, + const uint32_t entry_number, const std::string& key_set_id, const CdmKeyResponse& license_message) { - CdmUsageEntryInfo& entry_info = usage_entry_info_[usage_entry_number]; + CdmUsageEntryInfo& entry_info = entry_info_list_[entry_number]; + const int64_t current_time = GetCurrentTime(); entry_info.Clear(); - entry_info.storage_type = kStorageLicense; - entry_info.key_set_id = key_set_id; - entry_info.last_use_time = GetCurrentTime(); - // Need to determine the expire time for offline licenses. - video_widevine::License license; - if (!license_message.empty() && - ParseLicenseFromLicenseMessage(license_message, &license)) { - const video_widevine::License::Policy& policy = license.policy(); - entry_info.offline_license_expiry_time = license.license_start_time() + - policy.rental_duration_seconds() + - policy.playback_duration_seconds(); - } else { - // If the license duration cannot be determined for any reason, it - // is assumed to last at most 33 days. - entry_info.offline_license_expiry_time = - entry_info.last_use_time + kDefaultExpireDuration; - } + entry_info.SetKeySetId(key_set_id); + entry_info.SetLastUseTime(current_time); + entry_info.SetLicenseExpiryTime( + CalculateOfflineLicenseExpiryTime(license_message, current_time)); } CdmResponseType UsageTableHeader::RefitTable( CryptoSession* const crypto_session) { // Remove all unoccupied entries at end of the table. uint32_t entries_to_remove = 0; - const uint32_t old_size = static_cast(usage_entry_info_.size()); + const uint32_t old_size = static_cast(entry_info_list_.size()); for (uint32_t i = 0; i < old_size; i++) { - const uint32_t usage_entry_number = old_size - i - 1; - if (!IsEntryUnoccupied(usage_entry_number)) break; + const uint32_t entry_number = old_size - i - 1; + if (!IsEntryUnoccupied(entry_number)) break; ++entries_to_remove; } if (entries_to_remove == 0) return NO_ERROR; const uint32_t new_size = old_size - entries_to_remove; const CdmResponseType status = crypto_session->ShrinkUsageTableHeader( - requested_security_level_, new_size, &usage_table_header_); + requested_security_level_, new_size, &table_header_); if (status == SHRINK_USAGE_TABLE_HEADER_ENTRY_IN_USE) { // This error likely indicates that another session has released // its entry via a call to InvalidateEntry(), but has yet to close // its OEMCrypto session. // Safe to assume table state is not invalidated. LOGW("Unexpected entry in use: range = [%u, %zu]", new_size, - usage_entry_info_.size() - 1); + entry_info_list_.size() - 1); return NO_ERROR; } if (status != NO_ERROR) return status; - LOGD("Table shrunk: old_size = %zu, new_size = %u", usage_entry_info_.size(), + LOGD("Table shrunk: old_size = %zu, new_size = %u", entry_info_list_.size(), new_size); - usage_entry_info_.resize(new_size); + entry_info_list_.resize(new_size); return NO_ERROR; } CdmResponseType UsageTableHeader::MoveEntry( - uint32_t from_usage_entry_number, const CdmUsageEntry& from_usage_entry, - uint32_t to_usage_entry_number, DeviceFiles* device_files, + uint32_t from_entry_number, const CdmUsageEntry& from_usage_entry, + uint32_t to_entry_number, DeviceFiles* device_files, metrics::CryptoMetrics* metrics) { - LOGD("from_usage_entry_number = %u, to_usage_entry_number = %u", - from_usage_entry_number, to_usage_entry_number); + LOGD("from_entry_number = %u, to_entry_number = %u", from_entry_number, + to_entry_number); // crypto_session points to an object whose scope is this method or a test // object whose scope is the lifetime of this class @@ -627,87 +640,78 @@ CdmResponseType UsageTableHeader::MoveEntry( CdmResponseType status = crypto_session->Open(requested_security_level_); if (status != NO_ERROR) { - LOGE("Cannot open session for move: usage_entry_number = %u", - from_usage_entry_number); + LOGE("Cannot open session for move: entry_number = %u", from_entry_number); return status; } - status = - crypto_session->LoadUsageEntry(from_usage_entry_number, from_usage_entry); + status = crypto_session->LoadUsageEntry(from_entry_number, from_usage_entry); if (status != NO_ERROR) { - LOGE("Failed to load usage entry: usage_entry_number = %u", - from_usage_entry_number); + LOGE("Failed to load usage entry: entry_number = %u", from_entry_number); return status; } - status = crypto_session->MoveUsageEntry(to_usage_entry_number); + status = crypto_session->MoveUsageEntry(to_entry_number); if (status != NO_ERROR) { LOGE( "Failed to move usage entry: " - "from_usage_entry_number = %u, to_usage_entry_number = %u", - from_usage_entry_number, to_usage_entry_number); + "from_entry_number = %u, to_entry_number = %u", + from_entry_number, to_entry_number); return status; } - usage_entry_info_[to_usage_entry_number] = - usage_entry_info_[from_usage_entry_number]; - usage_entry_info_[from_usage_entry_number].Clear(); + entry_info_list_[to_entry_number] = entry_info_list_[from_entry_number]; + entry_info_list_[from_entry_number].Clear(); CdmUsageEntry usage_entry; - status = crypto_session->UpdateUsageEntry(&usage_table_header_, &usage_entry); + status = crypto_session->UpdateUsageEntry(&table_header_, &usage_entry); if (status != NO_ERROR) { - LOGE("Failed to update usage entry: usage_entry_number = %u", - to_usage_entry_number); + LOGE("Failed to update usage entry: entry_number = %u", to_entry_number); return status; } // Store the usage table and usage entry after successful move. StoreTable(); - StoreEntry(to_usage_entry_number, device_files, usage_entry); + StoreEntry(to_entry_number, device_files, usage_entry); return NO_ERROR; } -CdmResponseType UsageTableHeader::GetEntry(uint32_t usage_entry_number, +CdmResponseType UsageTableHeader::GetEntry(uint32_t entry_number, DeviceFiles* device_files, CdmUsageEntry* usage_entry) { - LOGD("Getting usage_entry_number = %u, storage_type = %s", usage_entry_number, - CdmUsageEntryStorageTypeToString( - usage_entry_number < usage_entry_info_.size() - ? usage_entry_info_[usage_entry_number].storage_type - : kStorageTypeUnknown)); - if (usage_entry_number >= usage_entry_info_.size()) { - LOGE("Entry out of bounds: usage_entry_number = %u, table_size = %zu", - usage_entry_number, usage_entry_info_.size()); + LOGD("entry_number = %u, entry_state = %s", entry_number, + GetEntryStateString(entry_number, entry_info_list_)); + if (entry_number >= entry_info_list_.size()) { + LOGE("Entry out of bounds: entry_number = %u, table_size = %zu", + entry_number, entry_info_list_.size()); return USAGE_GET_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE; } - CdmUsageEntryInfo& entry_info = usage_entry_info_[usage_entry_number]; - if (entry_info.storage_type != kStorageLicense) { + const CdmUsageEntryInfo& entry_info = entry_info_list_[entry_number]; + if (!entry_info.HasKeySetId()) { LOGE( - "Cannot retrieve information not associated without a license: " - "usage_entry_number = %u", - usage_entry_number); + "Cannot retrieve information not associated without a key set ID: " + "entry_number = %u", + entry_number); return USAGE_GET_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE; } // Retrieve license. DeviceFiles::CdmLicenseData license_data; DeviceFiles::ResponseType sub_error_code = DeviceFiles::kNoError; - if (!device_files->RetrieveLicense( - usage_entry_info_[usage_entry_number].key_set_id, &license_data, - &sub_error_code)) { + if (!device_files->RetrieveLicense(entry_info.key_set_id(), &license_data, + &sub_error_code)) { LOGE("Failed to retrieve license: status = %d", static_cast(sub_error_code)); return USAGE_GET_ENTRY_RETRIEVE_LICENSE_FAILED; } // Validate entry number. - if (usage_entry_number != license_data.usage_entry_number) { + if (entry_number != license_data.usage_entry_number) { LOGE( - "Usage entry number mismatch: expected_usage_entry_number = %u, " - "retrieved_usage_entry_number = %u", - usage_entry_number, license_data.usage_entry_number); + "Usage entry number mismatch: expected_entry_number = %u, " + "retrieved_entry_number = %u", + entry_number, license_data.usage_entry_number); return USAGE_ENTRY_NUMBER_MISMATCH; } @@ -715,40 +719,36 @@ CdmResponseType UsageTableHeader::GetEntry(uint32_t usage_entry_number, return NO_ERROR; } -CdmResponseType UsageTableHeader::StoreEntry(uint32_t usage_entry_number, +CdmResponseType UsageTableHeader::StoreEntry(uint32_t entry_number, DeviceFiles* device_files, const CdmUsageEntry& usage_entry) { - LOGD("usage_entry_number = %u, storage_type = %s", usage_entry_number, - CdmUsageEntryStorageTypeToString( - usage_entry_number < usage_entry_info_.size() - ? usage_entry_info_[usage_entry_number].storage_type - : kStorageTypeUnknown)); - if (usage_entry_number >= usage_entry_info_.size()) { - LOGE("Entry out of bounds: usage_entry_number = %u, table_size = %zu", - usage_entry_number, usage_entry_info_.size()); + LOGD("entry_number = %u, entry_state = %s", entry_number, + GetEntryStateString(entry_number, entry_info_list_)); + if (entry_number >= entry_info_list_.size()) { + LOGE("Entry out of bounds: entry_number = %u, table_size = %zu", + entry_number, entry_info_list_.size()); return USAGE_STORE_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE; } - CdmUsageEntryInfo& entry_info = usage_entry_info_[usage_entry_number]; - if (entry_info.storage_type != kStorageLicense) { + CdmUsageEntryInfo& entry_info = entry_info_list_[entry_number]; + if (!entry_info.HasKeySetId()) { LOGE( - "Cannot store information not associated without a license: " - "usage_entry_number = %u", - usage_entry_number); + "Cannot store information not associated without a key set ID: " + "entry_number = %u", + entry_number); return USAGE_STORE_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE; } // Retrieve existing. DeviceFiles::CdmLicenseData license_data; DeviceFiles::ResponseType sub_error_code = DeviceFiles::kNoError; - if (!device_files->RetrieveLicense( - usage_entry_info_[usage_entry_number].key_set_id, &license_data, - &sub_error_code)) { + if (!device_files->RetrieveLicense(entry_info.key_set_id(), &license_data, + &sub_error_code)) { LOGE("Failed to retrieve license: status = %s", DeviceFiles::ResponseTypeToString(sub_error_code)); return USAGE_STORE_ENTRY_RETRIEVE_LICENSE_FAILED; } // Update. license_data.usage_entry = usage_entry; - license_data.usage_entry_number = usage_entry_number; + license_data.usage_entry_number = entry_number; if (!device_files->StoreLicense(license_data, &sub_error_code)) { LOGE("Failed to store license: status = %s", @@ -760,8 +760,8 @@ CdmResponseType UsageTableHeader::StoreEntry(uint32_t usage_entry_number, bool UsageTableHeader::StoreTable() { LOGV("Storing usage table information"); - const bool result = device_files_->StoreUsageTableInfo(usage_table_header_, - usage_entry_info_); + const bool result = + device_files_->StoreUsageTableInfo(table_header_, entry_info_list_); if (result) { ++store_table_counter_; } else { @@ -770,26 +770,25 @@ bool UsageTableHeader::StoreTable() { return result; } -CdmResponseType UsageTableHeader::Shrink( - metrics::CryptoMetrics* metrics, - uint32_t number_of_usage_entries_to_delete) { - LOGD("table_size = %zu, number_to_delete = %u", usage_entry_info_.size(), - number_of_usage_entries_to_delete); - if (usage_entry_info_.empty()) { +CdmResponseType UsageTableHeader::Shrink(metrics::CryptoMetrics* metrics, + uint32_t number_of_entries_to_delete) { + LOGD("table_size = %zu, number_to_delete = %u", entry_info_list_.size(), + number_of_entries_to_delete); + if (entry_info_list_.empty()) { LOGE("Usage entry info table unexpectedly empty"); return NO_USAGE_ENTRIES; } - if (usage_entry_info_.size() < number_of_usage_entries_to_delete) { + if (entry_info_list_.size() < number_of_entries_to_delete) { LOGW( "Cannot delete more entries than the table size, reducing to current " "table size: table_size = %zu, number_to_delete = %u", - usage_entry_info_.size(), number_of_usage_entries_to_delete); - number_of_usage_entries_to_delete = - static_cast(usage_entry_info_.size()); + entry_info_list_.size(), number_of_entries_to_delete); + number_of_entries_to_delete = + static_cast(entry_info_list_.size()); } - if (number_of_usage_entries_to_delete == 0) return NO_ERROR; + if (number_of_entries_to_delete == 0) return NO_ERROR; // crypto_session points to an object whose scope is this method or a test // object whose scope is the lifetime of this class @@ -800,13 +799,13 @@ CdmResponseType UsageTableHeader::Shrink( crypto_session = scoped_crypto_session.get(); } - const uint32_t new_size = static_cast(usage_entry_info_.size()) - - number_of_usage_entries_to_delete; + const uint32_t new_size = static_cast(entry_info_list_.size()) - + number_of_entries_to_delete; const CdmResponseType status = crypto_session->ShrinkUsageTableHeader( - requested_security_level_, new_size, &usage_table_header_); + requested_security_level_, new_size, &table_header_); if (status == NO_ERROR) { - usage_entry_info_.resize(new_size); + entry_info_list_.resize(new_size); StoreTable(); } return status; @@ -814,7 +813,7 @@ CdmResponseType UsageTableHeader::Shrink( CdmResponseType UsageTableHeader::DefragTable(DeviceFiles* device_files, metrics::CryptoMetrics* metrics) { - LOGV("current_size = %zu", usage_entry_info_.size()); + LOGV("current_size = %zu", entry_info_list_.size()); // Defragging the usage table involves moving valid entries near the // end of the usage table to the position of invalid entries near the // front of the table. After the entries are moved, the CDM shrinks @@ -822,7 +821,7 @@ CdmResponseType UsageTableHeader::DefragTable(DeviceFiles* device_files, // the table. // Special case 0: Empty table, do nothing. - if (usage_entry_info_.empty()) { + if (entry_info_list_.empty()) { LOGD("Table empty, nothing to defrag"); return NO_ERROR; } @@ -832,10 +831,10 @@ CdmResponseType UsageTableHeader::DefragTable(DeviceFiles* device_files, // To avoid large delays from the swapping process, we limit the // quantity of entries to remove to |kMaxDefragEntryMoves| or fewer. std::vector entries_to_remove; - for (uint32_t i = 0; i < usage_entry_info_.size() && + for (uint32_t i = 0; i < entry_info_list_.size() && entries_to_remove.size() < kMaxDefragEntryMoves; ++i) { - if (usage_entry_info_[i].storage_type == kStorageTypeUnknown) { + if (entry_info_list_[i].IsEmpty()) { entries_to_remove.push_back(i); } } @@ -850,13 +849,13 @@ CdmResponseType UsageTableHeader::DefragTable(DeviceFiles* device_files, // Step 2: Create a list of entries to be moved from the end of the // table to the positions identified for removal. std::vector entries_to_move; - for (uint32_t i = 0; i < usage_entry_info_.size() && + for (uint32_t i = 0; i < entry_info_list_.size() && entries_to_move.size() < entries_to_remove.size(); ++i) { // Search from the end of the table. const uint32_t entry_index = - static_cast(usage_entry_info_.size()) - i - 1; - if (usage_entry_info_[entry_index].storage_type != kStorageTypeUnknown) { + static_cast(entry_info_list_.size()) - i - 1; + if (entry_info_list_[entry_index].HasKeySetId()) { entries_to_move.push_back(entry_index); } } @@ -865,8 +864,8 @@ CdmResponseType UsageTableHeader::DefragTable(DeviceFiles* device_files, // the whole table can be removed. if (entries_to_move.empty()) { LOGD("No valid entries found, shrinking entire table: size = %zu", - usage_entry_info_.size()); - return Shrink(metrics, static_cast(usage_entry_info_.size())); + entry_info_list_.size()); + return Shrink(metrics, static_cast(entry_info_list_.size())); } // Step 3: Ignore invalid entries that are after the last valid @@ -886,7 +885,7 @@ CdmResponseType UsageTableHeader::DefragTable(DeviceFiles* device_files, // be shrunk to the last valid entry. if (entries_to_remove.empty()) { const uint32_t to_remove = - static_cast(usage_entry_info_.size()) - last_valid_entry - 1; + static_cast(entry_info_list_.size()) - last_valid_entry - 1; LOGD("Removing all entries after the last valid entry: count = %u", to_remove); return Shrink(metrics, to_remove); @@ -921,7 +920,7 @@ CdmResponseType UsageTableHeader::DefragTable(DeviceFiles* device_files, LOGW("Could not get entry: entry_number = %u", from_entry_number); // It is unlikely that an unretrievable entry will suddenly // become retrievable later on when it is needed. - usage_entry_info_[from_entry_number].Clear(); + entry_info_list_[from_entry_number].Clear(); entries_to_move.pop_back(); continue; } @@ -951,7 +950,7 @@ CdmResponseType UsageTableHeader::DefragTable(DeviceFiles* device_files, // can no longer be used. Safe to continue loop. // TODO(b/152256186): Remove local files associated with this // entry. - usage_entry_info_[from_entry_number].Clear(); + entry_info_list_[from_entry_number].Clear(); LOGW("From entry was corrupted: from_entry_number = %u", from_entry_number); entries_to_move.pop_back(); @@ -961,8 +960,8 @@ CdmResponseType UsageTableHeader::DefragTable(DeviceFiles* device_files, case MOVE_USAGE_ENTRY_DESTINATION_IN_USE: { // The usage entry specified by |to_entry_number| is currently // being used by another session. This is unlikely, but still - // possible. Given that this entry is already marked as unknown - // storage type, it will likely be removed at a later time. + // possible. Given that this entry is already cleared, it will + // likely be removed at a later time. LOGD("To entry already in use: to_entry_number = %u", to_entry_number); entries_to_remove.pop_back(); break; @@ -1000,11 +999,11 @@ CdmResponseType UsageTableHeader::DefragTable(DeviceFiles* device_files, // Step 5: Find the new last valid entry. uint32_t new_last_valid_entry = - static_cast(usage_entry_info_.size()); - for (uint32_t i = 0; i < usage_entry_info_.size(); ++i) { + static_cast(entry_info_list_.size()); + for (uint32_t i = 0; i < entry_info_list_.size(); ++i) { const uint32_t entry_index = - static_cast(usage_entry_info_.size()) - i - 1; - if (usage_entry_info_[entry_index].storage_type != kStorageTypeUnknown) { + static_cast(entry_info_list_.size()) - i - 1; + if (entry_info_list_[entry_index].HasKeySetId()) { new_last_valid_entry = entry_index; break; } @@ -1013,15 +1012,15 @@ CdmResponseType UsageTableHeader::DefragTable(DeviceFiles* device_files, // Special case 5: No entries in the table are valid. This could // have occurred if entries during the move process were found to be // invalid. In this case, remove the whole table. - if (new_last_valid_entry == usage_entry_info_.size()) { + if (new_last_valid_entry == entry_info_list_.size()) { LOGD( "All entries have been invalidated, shrinking entire table: size = %zu", - usage_entry_info_.size()); - return Shrink(metrics, static_cast(usage_entry_info_.size())); + entry_info_list_.size()); + return Shrink(metrics, static_cast(entry_info_list_.size())); } - const uint32_t to_remove = static_cast(usage_entry_info_.size()) - - new_last_valid_entry - 1; + const uint32_t to_remove = + static_cast(entry_info_list_.size()) - new_last_valid_entry - 1; // Special case 6: It is possible that the last entry in the table // is valid and currently loaded in the table by another session. @@ -1046,13 +1045,13 @@ CdmResponseType UsageTableHeader::ReleaseOldestEntry( LOGE("Could not determine which license to remove"); return UNKNOWN_ERROR; } - const CdmUsageEntryInfo& usage_entry_info = - usage_entry_info_[entry_number_to_delete]; + const CdmUsageEntryInfo& entry_info = + entry_info_list_[entry_number_to_delete]; const int64_t current_time = GetCurrentTime(); - // Capture metric values now, as the |usage_entry_info| reference will + // Capture metric values now, as the |entry_info| reference will // change after the call to invalidate. - const int64_t staleness = current_time - usage_entry_info.last_use_time; + const int64_t staleness = current_time - entry_info.last_use_time(); const CdmResponseType status = InvalidateEntryInternal(entry_number_to_delete, /* defrag_table = */ true, @@ -1070,99 +1069,96 @@ CdmResponseType UsageTableHeader::ReleaseOldestEntry( } // Test only method. -void UsageTableHeader::InvalidateEntryForTest(uint32_t usage_entry_number) { - LOGD("usage_entry_number = %u", usage_entry_number); - if (usage_entry_number >= usage_entry_info_.size()) { +void UsageTableHeader::InvalidateEntryForTest(uint32_t entry_number) { + LOGD("entry_number = %u", entry_number); + if (entry_number >= entry_info_list_.size()) { LOGE( "Requested usage entry number is larger than table size: " - "usage_entry_number = %u, table_size = %zu", - usage_entry_number, usage_entry_info_.size()); + "entry_number = %u, table_size = %zu", + entry_number, entry_info_list_.size()); return; } // Move last entry into invalidated entry location and shrink usage // entries. - usage_entry_info_[usage_entry_number] = - usage_entry_info_[usage_entry_info_.size() - 1]; - usage_entry_info_.resize(usage_entry_info_.size() - 1); + entry_info_list_[entry_number] = + entry_info_list_[entry_info_list_.size() - 1]; + entry_info_list_.resize(entry_info_list_.size() - 1); } bool UsageTableHeader::LruUpgradeAllUsageEntries() { LOGV("Upgrading all usage entries with LRU information"); - if (usage_entry_info_.size() == 0) return true; // Nothing to upgrade. + if (entry_info_list_.size() == 0) return true; // Nothing to upgrade. // For each entry, the status upgrading that entry is stored. At the // end, all problematic licenses will be marked as invalid. std::vector bad_license_file_entries; - for (uint32_t usage_entry_number = 0; - usage_entry_number < usage_entry_info_.size(); ++usage_entry_number) { - CdmUsageEntryInfo& usage_entry_info = usage_entry_info_[usage_entry_number]; + for (uint32_t entry_number = 0; entry_number < entry_info_list_.size(); + ++entry_number) { + CdmUsageEntryInfo& entry_info = entry_info_list_[entry_number]; - if (usage_entry_info.storage_type != kStorageLicense) { - bad_license_file_entries.push_back(usage_entry_number); + if (entry_info.IsEmpty()) { + bad_license_file_entries.push_back(entry_number); continue; } uint32_t retrieved_entry_number; CdmKeyResponse license_message; const bool retrieve_response = - RetrieveOfflineLicense(device_files_.get(), usage_entry_info.key_set_id, + RetrieveOfflineLicense(device_files_.get(), entry_info.key_set_id(), &license_message, &retrieved_entry_number); if (!retrieve_response) { - LOGW("Could not retrieve license message: usage_entry_number = %u", - usage_entry_number); - bad_license_file_entries.push_back(usage_entry_number); + LOGW("Could not retrieve license message: entry_number = %u", + entry_number); + bad_license_file_entries.push_back(entry_number); continue; } - if (retrieved_entry_number != usage_entry_number) { + if (retrieved_entry_number != entry_number) { LOGW( - "Usage entry number mismatched: usage_entry_number = %u, " + "Usage entry number mismatched: entry_number = %u, " "retrieved_entry_number = %u", - usage_entry_number, retrieved_entry_number); - bad_license_file_entries.push_back(usage_entry_number); + entry_number, retrieved_entry_number); + bad_license_file_entries.push_back(entry_number); continue; } video_widevine::License license; if (!ParseLicenseFromLicenseMessage(license_message, &license)) { - LOGW("Could not parse license: usage_entry_number = %u", - usage_entry_number); - bad_license_file_entries.push_back(usage_entry_number); + LOGW("Could not parse license: entry_number = %u", entry_number); + bad_license_file_entries.push_back(entry_number); continue; } // If |license_start_time| is 0, then this entry will be considered // for replacement above all others. - usage_entry_info.last_use_time = license.license_start_time(); - - // Only offline licenses need |offline_license_expiry_time| set. + entry_info.SetLastUseTime(license.license_start_time()); const video_widevine::License::Policy& policy = license.policy(); // TODO(b/139372190): Change how these fields are set once feature is // implemented. if (policy.license_duration_seconds() == 0) { // Zero implies unlimited license duration. - usage_entry_info.offline_license_expiry_time = - license.license_start_time() + policy.rental_duration_seconds() + - policy.playback_duration_seconds(); + entry_info.SetLicenseExpiryTime(license.license_start_time() + + policy.rental_duration_seconds() + + policy.playback_duration_seconds()); } else { - usage_entry_info.offline_license_expiry_time = - license.license_start_time() + policy.license_duration_seconds(); + entry_info.SetLicenseExpiryTime(license.license_start_time() + + policy.license_duration_seconds()); } } // End for loop. - if (bad_license_file_entries.size() == usage_entry_info_.size()) { + if (bad_license_file_entries.size() == entry_info_list_.size()) { LOGE("Failed to perform LRU upgrade for every entry: count = %zu", - usage_entry_info_.size()); + entry_info_list_.size()); return false; } - for (size_t usage_entry_number : bad_license_file_entries) { - CdmUsageEntryInfo& usage_entry_info = usage_entry_info_[usage_entry_number]; - if (usage_entry_info.storage_type == kStorageLicense) { - device_files_->DeleteLicense(usage_entry_info.key_set_id); + for (size_t entry_number : bad_license_file_entries) { + CdmUsageEntryInfo& entry_info = entry_info_list_[entry_number]; + if (entry_info.HasKeySetId()) { + device_files_->DeleteLicense(entry_info.key_set_id()); } - usage_entry_info.Clear(); + entry_info.Clear(); } return true; @@ -1173,7 +1169,7 @@ bool UsageTableHeader::GetRemovalCandidate(uint32_t* entry_to_remove) { HasUnlimitedTableCapacity() ? kLruUnexpiredThresholdFraction * size() : kLruUnexpiredThresholdFraction * potential_table_capacity(); - return DetermineLicenseToRemove(usage_entry_info_, GetCurrentTime(), + return DetermineLicenseToRemove(entry_info_list_, GetCurrentTime(), lru_unexpired_threshold, entry_to_remove); } @@ -1182,8 +1178,9 @@ void UsageTableHeader::RecordLruEventMetrics(metrics::CryptoMetrics* metrics, if (metrics == nullptr) return; // Usage info are deprecated, always record 0. metrics->usage_table_header_lru_usage_info_count_.Record(0); + // All occupied entries are assumed to be offline licenses. metrics->usage_table_header_lru_offline_license_count_.Record( - OfflineEntryCount()); + OccupiedEntryCount()); metrics->usage_table_header_lru_evicted_entry_staleness_.Record(staleness); // Can be assumed that only offline licenses are removed. constexpr int kDefaultEntryType = 0; @@ -1193,44 +1190,41 @@ void UsageTableHeader::RecordLruEventMetrics(metrics::CryptoMetrics* metrics, // Static. bool UsageTableHeader::DetermineLicenseToRemove( - const std::vector& usage_entry_info_list, - int64_t current_time, size_t unexpired_threshold, - uint32_t* entry_to_remove) { + const std::vector& entry_info_list, int64_t current_time, + size_t unexpired_threshold, uint32_t* entry_to_remove) { if (entry_to_remove == nullptr) { LOGE("Output parameter |entry_to_remove| is null"); return false; } - if (usage_entry_info_list.empty()) { + if (entry_info_list.empty()) { return false; } // Returns true if entry of first index is more stale than the // entry of the second index. const auto is_more_stale = [&](uint32_t i, uint32_t j) -> bool { - return usage_entry_info_list[i].last_use_time < - usage_entry_info_list[j].last_use_time; + return entry_info_list[i].last_use_time() < + entry_info_list[j].last_use_time(); }; // Find the most stale expired offline license and the // most stale unexpired offline entry. Count the number of unexpired - // entries. If any entry is not of storage type license, then it should - // be removed. + // entries. If any entry is empty, then it should be removed. constexpr uint32_t kNoEntry = std::numeric_limits::max(); uint32_t stalest_expired_offline_license = kNoEntry; uint32_t stalest_unexpired_offline_license = kNoEntry; size_t unexpired_license_count = 0; - for (uint32_t entry_number = 0; entry_number < usage_entry_info_list.size(); + for (uint32_t entry_number = 0; entry_number < entry_info_list.size(); ++entry_number) { - const CdmUsageEntryInfo& usage_entry_info = - usage_entry_info_list[entry_number]; + const CdmUsageEntryInfo& entry_info = entry_info_list[entry_number]; - if (usage_entry_info.storage_type != kStorageLicense) { - // Non-license storage type entries. Remove this entry. + if (entry_info.IsEmpty()) { + // Remove empty entry. *entry_to_remove = entry_number; return true; } - if (usage_entry_info.offline_license_expiry_time > current_time) { + if (entry_info.license_expiry_time() > current_time) { // Unexpired offline. ++unexpired_license_count; if (stalest_unexpired_offline_license == kNoEntry || @@ -1252,8 +1246,7 @@ bool UsageTableHeader::DetermineLicenseToRemove( LOGW( "Table only contains unexpired offline licenses, " "but threshold not met: size = %zu, count = %zu, threshold = %zu", - usage_entry_info_list.size(), unexpired_license_count, - unexpired_threshold); + entry_info_list.size(), unexpired_license_count, unexpired_threshold); *entry_to_remove = stalest_unexpired_offline_license; return true; } @@ -1274,9 +1267,9 @@ bool UsageTableHeader::DetermineLicenseToRemove( if (*entry_to_remove == kNoEntry) { // Illegal state check. The loop above should have found at least - // one entry given that |usage_entry_info_list| is not empty. + // one entry given that |entry_info_list| is not empty. LOGE("No entry could be used for removal: size = %zu", - usage_entry_info_list.size()); + entry_info_list.size()); return false; } return true; diff --git a/libwvdrmengine/cdm/core/src/wv_cdm_types.cpp b/libwvdrmengine/cdm/core/src/wv_cdm_types.cpp index ccf57b36..bea2d17a 100644 --- a/libwvdrmengine/cdm/core/src/wv_cdm_types.cpp +++ b/libwvdrmengine/cdm/core/src/wv_cdm_types.cpp @@ -95,19 +95,6 @@ const char* CdmOfflineLicenseStateToString( return UnknownValueRep(license_state); } -const char* CdmUsageEntryStorageTypeToString(CdmUsageEntryStorageType type) { - switch (type) { - case kStorageLicense: - return "License"; - case kStorageUsageInfo: - return "UsageInfo"; - case kStorageTypeUnknown: - // Special value used to indicate an empty entry. - return "None"; - } - return UnknownValueRep(type); -} - const char* RequestedSecurityLevelToString( RequestedSecurityLevel security_level) { switch (security_level) { diff --git a/libwvdrmengine/cdm/core/test/device_files_unittest.cpp b/libwvdrmengine/cdm/core/test/device_files_unittest.cpp index 4458766c..ca9ec8a8 100644 --- a/libwvdrmengine/cdm/core/test/device_files_unittest.cpp +++ b/libwvdrmengine/cdm/core/test/device_files_unittest.cpp @@ -2920,17 +2920,17 @@ constexpr size_t kNumberOfHlsAttributes = ArraySize(kHlsAttributesTestData); // kUsageTableInfoTestData are equal. const std::vector kUsageEntriesTestData = { // usage entry 0 - {kStorageLicense, "ksid0", "", 1318402800, 1321254000}, + {"ksid0", 1318402800, 1321254000}, // usage entry 1 - {kStorageLicense, "ksid1", "", 1050649200, 1053500400}, + {"ksid1", 1050649200, 1053500400}, // usage entry 2 - {kStorageTypeUnknown, "", "", 0, 0}, + {"", 0, 0}, // usage entry 3 - {kStorageTypeUnknown, "", "", 0, 0}, + {"", 0, 0}, // usage entry 4 - {kStorageLicense, "ksid4", "", 316166400, 319017600}, + {"ksid4", 316166400, 319017600}, // usage entry 5 - {kStorageLicense, "ksid5", "", 316166400, 319017600}, + {"ksid5", 316166400, 319017600}, }; struct UsageTableTestInfo { @@ -3008,8 +3008,8 @@ const UsageTableTestInfo kUsageTableInfoTestData[] = { "ce072f3d2ef52febcaddff3040246a638deee994a0862142")}, }; -const CdmUsageEntryInfo kUsageEntriesWithoutLruData[] = { - {kStorageLicense, "ksid0", "", 0, 0}, {kStorageTypeUnknown, "", "", 0, 0}}; +const CdmUsageEntryInfo kUsageEntriesWithoutLruData[] = {{"ksid0", 0, 0}, + {"", 0, 0}}; const std::string kUsageTableWithoutLruData = a2bs_hex( "0A1F080510013A191209080112056B73696430120C08021A086170705F69645F" @@ -3030,9 +3030,7 @@ const UsageTableTestInfo kUsageTableInfoWithUsageInfoType = { // Expected entries after removal of USAGE_INFO. const std::vector kUsageEntriesWithoutUsageInfoType = { - {kStorageLicense, "ksid0", "", 1318402800, 1321254000}, - {kStorageTypeUnknown, "", "", 0, 0}, - {kStorageTypeUnknown, "", "", 0, 0}}; + {"ksid0", 1318402800, 1321254000}, {"", 0, 0}, {"", 0, 0}}; // Contains kOemCertificate and kCryptoWrappedKey const std::string kFakeOemCertificateFile = a2bs_hex( @@ -4389,11 +4387,11 @@ TEST_P(DeviceFilesUsageTableTest, Store) { const int entry_count = GetParam(); std::vector entry_data; - const std::vector usage_entry_info( + const std::vector usage_entry_info_list( kUsageEntriesTestData.begin(), kUsageEntriesTestData.begin() + entry_count); for (int i = 0; i < entry_count; ++i) { - entry_data.push_back(kUsageEntriesTestData[i].key_set_id); + entry_data.push_back(kUsageEntriesTestData[i].key_set_id()); } entry_data.push_back(kUsageTableInfoTestData[entry_count].usage_table_header); @@ -4411,7 +4409,7 @@ TEST_P(DeviceFilesUsageTableTest, Store) { EXPECT_TRUE(device_files.Init(kSecurityLevelL1)); ASSERT_TRUE(device_files.StoreUsageTableInfo( kUsageTableInfoTestData[entry_count].usage_table_header, - usage_entry_info)); + usage_entry_info_list)); } TEST_P(DeviceFilesUsageTableTest, Read) { @@ -4437,20 +4435,20 @@ TEST_P(DeviceFilesUsageTableTest, Read) { DeviceFiles device_files(&file_system); EXPECT_TRUE(device_files.Init(kSecurityLevelL1)); - std::vector usage_entry_info; + std::vector usage_entry_info_list; CdmUsageTableHeader usage_table_header; bool lru_upgrade; bool has_usage_info_entries; ASSERT_TRUE(device_files.RetrieveUsageTableInfo( - &usage_table_header, &usage_entry_info, &lru_upgrade, + &usage_table_header, &usage_entry_info_list, &lru_upgrade, &has_usage_info_entries)); EXPECT_EQ(kUsageTableInfoTestData[entry_count].usage_table_header, usage_table_header); - EXPECT_EQ(entry_count, usage_entry_info.size()); + EXPECT_EQ(entry_count, usage_entry_info_list.size()); for (size_t i = 0; i < entry_count; ++i) { // TODO(b/242289743): Update test data to exclude usage info files. - EXPECT_EQ(usage_entry_info[i], kUsageEntriesTestData[i]); + EXPECT_EQ(usage_entry_info_list[i], kUsageEntriesTestData[i]); } EXPECT_FALSE(lru_upgrade); } @@ -4478,19 +4476,20 @@ TEST_F(DeviceFilesUsageTableTest, ReadWithoutLruData) { DeviceFiles device_files(&file_system); EXPECT_TRUE(device_files.Init(kSecurityLevelL1)); - std::vector usage_entry_info; + std::vector usage_entry_info_list; CdmUsageTableHeader usage_table_header; bool lru_upgrade; bool has_usage_info_entries; ASSERT_TRUE(device_files.RetrieveUsageTableInfo( - &usage_table_header, &usage_entry_info, &lru_upgrade, + &usage_table_header, &usage_entry_info_list, &lru_upgrade, &has_usage_info_entries)); - EXPECT_EQ(ArraySize(kUsageEntriesWithoutLruData), usage_entry_info.size()); + EXPECT_EQ(ArraySize(kUsageEntriesWithoutLruData), + usage_entry_info_list.size()); for (size_t i = 0; i < ArraySize(kUsageEntriesWithoutLruData); ++i) { const CdmUsageEntryInfo& expected_entry = kUsageEntriesWithoutLruData[i]; - const CdmUsageEntryInfo& retrieved_entry = usage_entry_info[i]; + const CdmUsageEntryInfo& retrieved_entry = usage_entry_info_list[i]; EXPECT_EQ(expected_entry, retrieved_entry); } @@ -4520,20 +4519,21 @@ TEST_F(DeviceFilesUsageTableTest, ReadWithUsageInfoType) { DeviceFiles device_files(&file_system); EXPECT_TRUE(device_files.Init(kSecurityLevelL1)); - std::vector usage_entry_info; + std::vector usage_entry_info_list; CdmUsageTableHeader usage_table_header; bool lru_upgrade; bool has_usage_info_entries; ASSERT_TRUE(device_files.RetrieveUsageTableInfo( - &usage_table_header, &usage_entry_info, &lru_upgrade, + &usage_table_header, &usage_entry_info_list, &lru_upgrade, &has_usage_info_entries)); - EXPECT_EQ(kUsageEntriesWithoutUsageInfoType.size(), usage_entry_info.size()); + EXPECT_EQ(kUsageEntriesWithoutUsageInfoType.size(), + usage_entry_info_list.size()); for (size_t i = 0; i < kUsageEntriesWithoutUsageInfoType.size(); ++i) { const CdmUsageEntryInfo& expected_entry = kUsageEntriesWithoutUsageInfoType[i]; - const CdmUsageEntryInfo& retrieved_entry = usage_entry_info[i]; + const CdmUsageEntryInfo& retrieved_entry = usage_entry_info_list[i]; EXPECT_EQ(expected_entry, retrieved_entry); } diff --git a/libwvdrmengine/cdm/core/test/usage_table_header_unittest.cpp b/libwvdrmengine/cdm/core/test/usage_table_header_unittest.cpp index da402682..66f94031 100644 --- a/libwvdrmengine/cdm/core/test/usage_table_header_unittest.cpp +++ b/libwvdrmengine/cdm/core/test/usage_table_header_unittest.cpp @@ -71,155 +71,48 @@ const std::string kWrappedPrivateKey = "a wrapped private key"; const CryptoWrappedKey kCryptoWrappedKey(CryptoWrappedKey::kRsa, kWrappedPrivateKey); const CdmUsageEntryInfo kUsageEntryInfoOfflineLicense1 = { - /* storage_type = */ kStorageLicense, /* key_set_id = */ "offline_key_set_1", - /* usage_info_file_name = */ "", /* last_use_time = */ 0, /* offline_license_expiry_time = */ kDefaultExpireDuration}; const CdmUsageEntryInfo kUsageEntryInfoOfflineLicense2 = { - /* storage_type = */ kStorageLicense, /* key_set_id = */ "offline_key_set_2", - /* usage_info_file_name = */ "", /* last_use_time = */ 0, /* offline_license_expiry_time = */ kDefaultExpireDuration}; const CdmUsageEntryInfo kUsageEntryInfoOfflineLicense3 = { - /* storage_type = */ kStorageLicense, /* key_set_id = */ "offline_key_set_3", - /* usage_info_file_name = */ "", /* last_use_time = */ 0, /* offline_license_expiry_time = */ kDefaultExpireDuration}; const CdmUsageEntryInfo kUsageEntryInfoOfflineLicense4 = { - /* storage_type = */ kStorageLicense, /* key_set_id = */ "offline_key_set_4", - /* usage_info_file_name = */ "", /* last_use_time = */ 0, /* offline_license_expiry_time = */ kDefaultExpireDuration}; const CdmUsageEntryInfo kUsageEntryInfoOfflineLicense5 = { - /* storage_type = */ kStorageLicense, /* key_set_id = */ "offline_key_set_5", - /* usage_info_file_name = */ "", /* last_use_time = */ 0, /* offline_license_expiry_time = */ kDefaultExpireDuration}; const CdmUsageEntryInfo kUsageEntryInfoOfflineLicense6 = { - /* storage_type = */ kStorageLicense, /* key_set_id = */ "offline_key_set_6", - /* usage_info_file_name = */ "", /* last_use_time = */ 0, /* offline_license_expiry_time = */ kDefaultExpireDuration}; -const CdmUsageEntryInfo kUsageEntryInfoSecureStop1 = { - /* storage_type = */ kStorageUsageInfo, - /* key_set_id = */ "secure_stop_key_set_1", - /* usage_info_file_name = */ "usage_info_file_1", - /* last_use_time = */ 0, - /* offline_license_expiry_time = */ 0}; -const CdmUsageEntryInfo kUsageEntryInfoSecureStop2 = { - /* storage_type = */ kStorageUsageInfo, - /* key_set_id = */ "secure_stop_key_set_2", - /* usage_info_file_name = */ "usage_info_file_2", - /* last_use_time = */ 0, - /* offline_license_expiry_time = */ 0}; -const CdmUsageEntryInfo kUsageEntryInfoSecureStop3 = { - /* storage_type = */ kStorageUsageInfo, - /* key_set_id = */ "secure_stop_key_set_3", - /* usage_info_file_name = */ "usage_info_file_3", - /* last_use_time = */ 0, - /* offline_license_expiry_time = */ 0}; -const CdmUsageEntryInfo kUsageEntryInfoSecureStop4 = { - /* storage_type = */ kStorageUsageInfo, - /* key_set_id = */ "secure_stop_key_set_4", - /* usage_info_file_name = */ "usage_info_file_4", - /* last_use_time = */ 0, - /* offline_license_expiry_time = */ 0}; -const CdmUsageEntryInfo kUsageEntryInfoSecureStop5 = { - /* storage_type = */ kStorageUsageInfo, - /* key_set_id = */ "secure_stop_key_set_5", - /* usage_info_file_name = */ "usage_info_file_5", - /* last_use_time = */ 0, - /* offline_license_expiry_time = */ 0}; -const CdmUsageEntryInfo kUsageEntryInfoStorageTypeUnknown = { - /* storage_type = */ kStorageTypeUnknown, +const CdmUsageEntryInfo kUsageEntryInfoEmpty = { /* key_set_id = */ "", - /* usage_info_file_name = */ "", /* last_use_time = */ 0, /* offline_license_expiry_time = */ 0}; const CdmUsageEntryInfo kDummyUsageEntryInfo = { - /* storage_type = */ kStorageLicense, /* key_set_id = */ "DummyKsid", - /* usage_info_file_name = */ "", /* last_use_time = */ 0, /* offline_license_expiry_time = */ kDefaultExpireDuration}; -const std::vector kEmptyLicenseList; - -const std::string kLicenseArray[] = { - kUsageEntryInfoOfflineLicense1.key_set_id, - kUsageEntryInfoOfflineLicense2.key_set_id, - kUsageEntryInfoOfflineLicense3.key_set_id, -}; -const size_t kLicenseArraySize = wvutil::ArraySize(kLicenseArray); -std::vector kLicenseList; - -const std::vector kEmptyUsageInfoFilesList; - -const std::string kUsageInfoFileArray[] = { - kUsageEntryInfoSecureStop1.usage_info_file_name, - kUsageEntryInfoSecureStop2.usage_info_file_name, - kUsageEntryInfoSecureStop3.usage_info_file_name, -}; -const size_t kUsageInfoFileArraySize = wvutil::ArraySize(kUsageInfoFileArray); -std::vector kUsageInfoFileList; - -const DeviceFiles::CdmUsageData kCdmUsageData1 = { - /* provider_session_token = */ "provider_session_token_1", - /* license_request = */ "license_request_1", - /* license = */ "license_1", - /* key_set_id = */ "key_set_id_1", - /* usage_entry = */ "usage_entry_1", - /* usage_entry_number = */ 0, - /* drm_certificate = */ kDrmCertificate, - /* wrapped_private_key = */ kCryptoWrappedKey, -}; -const DeviceFiles::CdmUsageData kCdmUsageData2 = { - /* provider_session_token = */ "provider_session_token_2", - /* license_request = */ "license_request_2", - /* license = */ "license_2", - /* key_set_id = */ "key_set_id_2", - /* usage_entry = */ "usage_entry_2", - /* usage_entry_number = */ 0, - /* drm_certificate = */ kDrmCertificate, - /* wrapped_private_key = */ kCryptoWrappedKey, -}; -const DeviceFiles::CdmUsageData kCdmUsageData3 = { - /* provider_session_token = */ "provider_session_token_3", - /* license_request = */ "license_request_3", - /* license = */ "license_3", - /* key_set_id = */ "key_set_id_3", - /* usage_entry = */ "usage_entry_3", - /* usage_entry_number = */ 0, - /* drm_certificate = */ kDrmCertificate, - /* wrapped_private_key = */ kCryptoWrappedKey, -}; -const std::vector kEmptyUsageInfoUsageDataList; - const std::vector kEmptyUsageEntryInfoVector; const std::vector kUsageEntryInfoVector = { - kUsageEntryInfoOfflineLicense1, kUsageEntryInfoSecureStop1, - kUsageEntryInfoStorageTypeUnknown}; -const std::vector k10UsageEntryInfoVector = { - kUsageEntryInfoOfflineLicense1, kUsageEntryInfoSecureStop1, - kUsageEntryInfoOfflineLicense2, kUsageEntryInfoSecureStop2, - kUsageEntryInfoOfflineLicense3, kUsageEntryInfoSecureStop3, - kUsageEntryInfoOfflineLicense4, kUsageEntryInfoSecureStop4, - kUsageEntryInfoOfflineLicense5, kUsageEntryInfoSecureStop5, -}; + kUsageEntryInfoOfflineLicense1, kUsageEntryInfoOfflineLicense2, + kUsageEntryInfoEmpty}; const std::vector k5UsageEntryInfoVector = { kUsageEntryInfoOfflineLicense1, kUsageEntryInfoOfflineLicense2, kUsageEntryInfoOfflineLicense3, kUsageEntryInfoOfflineLicense4, kUsageEntryInfoOfflineLicense5, }; -std::vector kOverFullUsageEntryInfoVector; - const CdmOfflineLicenseState kActiveLicenseState = kLicenseStateActive; const CdmInitData kPsshData = "pssh data"; const CdmKeyMessage kKeyRequest = "key request"; @@ -239,21 +132,15 @@ const CdmUsageTableHeader kUpgradableUsageTableHeader = // Usage entries. const CdmUsageEntryInfo kUpgradableUsageEntryInfo1 = { - /* storage_type = */ kStorageLicense, /* key_set_id = */ "offline_key_set_1", - /* usage_info_file_name = */ "", /* 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 = */ "", /* last_use_time = */ 0, /* offline_license_expiry_time = */ 0}; const CdmUsageEntryInfo kUpgradableUsageEntryInfo3 = { - /* storage_type = */ kStorageLicense, /* key_set_id = */ "offline_key_set_3", - /* usage_info_file_name = */ "", /* last_use_time = */ 0, /* offline_license_expiry_time = */ 0}; const std::vector kUpgradableUsageEntryInfoList{ @@ -302,21 +189,15 @@ 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}; @@ -324,11 +205,36 @@ const std::vector kUpgradedUsageEntryInfoList = { kUpgradedUsageEntryInfo1, kUpgradedUsageEntryInfo2, kUpgradedUsageEntryInfo3}; +std::vector CreateOverFullUsageEntryInfoVector() { + std::vector usage_entry_info_vector; + usage_entry_info_vector.reserve(kDefaultTableCapacity + 1); + for (size_t i = 0; i < (kDefaultTableCapacity + 1); ++i) { + switch (i % 4) { + case 0: + usage_entry_info_vector.push_back(kUsageEntryInfoOfflineLicense1); + break; + case 1: + usage_entry_info_vector.push_back(kUsageEntryInfoOfflineLicense2); + break; + case 2: + usage_entry_info_vector.push_back(kUsageEntryInfoOfflineLicense3); + break; + case 3: + usage_entry_info_vector.push_back(kUsageEntryInfoOfflineLicense4); + break; + default: + usage_entry_info_vector.push_back(kUsageEntryInfoEmpty); + break; + } + } + return usage_entry_info_vector; +} + std::vector CreateUpgradableLicenseInfoList() { std::vector 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.key_set_id = kUpgradableUsageEntryInfoList[i].key_set_id(); license_data.state = kActiveLicenseState; license_data.license = kUpgradableLicenseInfoList[i]; license_data.usage_entry_number = static_cast(i); @@ -337,49 +243,6 @@ std::vector CreateUpgradableLicenseInfoList() { return license_data_list; } -void InitVectorConstants() { - kOverFullUsageEntryInfoVector.clear(); - for (size_t i = 0; i < (kDefaultTableCapacity + 1); ++i) { - switch (i % 4) { - case 0: - kOverFullUsageEntryInfoVector.push_back(kUsageEntryInfoOfflineLicense1); - break; - case 1: - kOverFullUsageEntryInfoVector.push_back(kUsageEntryInfoSecureStop1); - break; - case 2: - kOverFullUsageEntryInfoVector.push_back(kUsageEntryInfoOfflineLicense2); - break; - case 3: - kOverFullUsageEntryInfoVector.push_back(kUsageEntryInfoSecureStop2); - break; - default: - kOverFullUsageEntryInfoVector.push_back( - kUsageEntryInfoStorageTypeUnknown); - break; - } - } - - kUsageInfoFileList.clear(); - for (size_t i = 0; i < kUsageInfoFileArraySize; i++) { - kUsageInfoFileList.push_back(kUsageInfoFileArray[i]); - } - - kLicenseList.clear(); - for (size_t i = 0; i < kLicenseArraySize; i++) { - kLicenseList.push_back(kLicenseArray[i]); - } -} - -void ToVector(std::vector& vec, const CdmUsageEntryInfo* arr, - size_t total_size) { - size_t max = total_size / sizeof(CdmUsageEntryInfo); - vec.clear(); - for (size_t i = 0; i < max; i++) { - vec.push_back(arr[i]); - } -} - class MockDeviceFiles : public DeviceFiles { public: MockDeviceFiles() : DeviceFiles(&file_system_) { Init(kSecurityLevelL1); } @@ -490,8 +353,6 @@ class MockUsageTableHeader : public UsageTableHeader { class UsageTableHeaderTest : public WvCdmTestBase { public: - static void SetUpTestCase() { InitVectorConstants(); } - // Useful when UsageTableHeader is mocked void InvalidateEntry(uint32_t usage_entry_number, bool, DeviceFiles*, metrics::CryptoMetrics*) { @@ -588,15 +449,13 @@ TEST_F(UsageTableHeaderTest, InitError) { EXPECT_FALSE( usage_table_header_->Init(kSecurityLevelUnknown, crypto_session_)); EXPECT_FALSE(usage_table_header_->Init(kSecurityLevelL1, nullptr)); - EXPECT_FALSE(usage_table_header_->Init(kSecurityLevelL2, nullptr)); + EXPECT_FALSE(usage_table_header_->Init(kSecurityLevelL3, nullptr)); } class UsageTableHeaderInitializationTest : public UsageTableHeaderTest, public ::testing::WithParamInterface { public: - static void SetUpTestCase() { InitVectorConstants(); } - RequestedSecurityLevel GetSecurityLevel() const { return (GetParam() == kSecurityLevelL3) ? kLevel3 : kLevelDefault; } @@ -775,7 +634,8 @@ TEST_P(UsageTableHeaderInitializationTest, // Restoring table succeeds, and the current table is at capacity. // No special action needs to be taken. TEST_P(UsageTableHeaderInitializationTest, RestoreUsageTable_AtCapacity) { - std::vector usage_entries = kOverFullUsageEntryInfoVector; + std::vector usage_entries = + CreateOverFullUsageEntryInfoVector(); usage_entries.resize(kDefaultTableCapacity); const RequestedSecurityLevel security_level = GetSecurityLevel(); // Expectations for restore: @@ -801,9 +661,10 @@ TEST_P(UsageTableHeaderInitializationTest, RestoreUsageTable_AtCapacity) { TEST_P(UsageTableHeaderInitializationTest, RestoreUsageTable_NoCapacity_UnderMinimum) { crypto_session_->SetMaximumUsageTableEntries(0); // Unlimited. - std::vector usage_entries = kOverFullUsageEntryInfoVector; + std::vector usage_entries = + CreateOverFullUsageEntryInfoVector(); constexpr size_t kHalfMinCapacity = kDefaultTableCapacity / 2; - usage_entries.resize(kHalfMinCapacity); + usage_entries.resize(kHalfMinCapacity); // Trim to half capacity. const RequestedSecurityLevel security_level = GetSecurityLevel(); // Expectations for restore: // 1) Existing table file is retrieved @@ -830,9 +691,10 @@ TEST_P(UsageTableHeaderInitializationTest, TEST_P(UsageTableHeaderInitializationTest, RestoreUsageTable_NoCapacity_AboveMinimum) { crypto_session_->SetMaximumUsageTableEntries(0); // Unlimited. - ASSERT_LT(kDefaultTableCapacity, kOverFullUsageEntryInfoVector.size()); - const uint32_t table_start_size = - static_cast(kOverFullUsageEntryInfoVector.size()); + const std::vector usage_entries = + CreateOverFullUsageEntryInfoVector(); + ASSERT_LT(kDefaultTableCapacity, usage_entries.size()); + const uint32_t table_start_size = static_cast(usage_entries.size()); const RequestedSecurityLevel security_level = GetSecurityLevel(); // Expectations for restore: @@ -844,9 +706,8 @@ TEST_P(UsageTableHeaderInitializationTest, EXPECT_CALL(*device_files_, RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<0>(kUsageTableHeader), - SetArgPointee<1>(kOverFullUsageEntryInfoVector), - SetArgPointee<2>(false), SetArgPointee<3>(false), - Return(true))); + SetArgPointee<1>(usage_entries), SetArgPointee<2>(false), + SetArgPointee<3>(false), Return(true))); EXPECT_CALL(*crypto_session_, LoadUsageTableHeader(security_level, kUsageTableHeader)) .WillOnce(Return(NO_ERROR)); @@ -890,7 +751,9 @@ TEST_P(UsageTableHeaderInitializationTest, // The result is a new usage table. TEST_P(UsageTableHeaderInitializationTest, RestoreUsageTable_AboveCapacity_AddEntryFails) { - ASSERT_LT(kDefaultTableCapacity, kOverFullUsageEntryInfoVector.size()); + const std::vector usage_entries = + CreateOverFullUsageEntryInfoVector(); + ASSERT_LT(kDefaultTableCapacity, usage_entries.size()); const RequestedSecurityLevel security_level = GetSecurityLevel(); // Expectations for restore: @@ -902,9 +765,8 @@ TEST_P(UsageTableHeaderInitializationTest, EXPECT_CALL(*device_files_, RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<0>(kUsageTableHeader), - SetArgPointee<1>(kOverFullUsageEntryInfoVector), - SetArgPointee<2>(false), SetArgPointee<3>(false), - Return(true))); + SetArgPointee<1>(usage_entries), SetArgPointee<2>(false), + SetArgPointee<3>(false), Return(true))); EXPECT_CALL(*crypto_session_, LoadUsageTableHeader(security_level, kUsageTableHeader)) .WillOnce(Return(NO_ERROR)); @@ -941,9 +803,10 @@ TEST_P(UsageTableHeaderInitializationTest, TEST_P(UsageTableHeaderInitializationTest, RestoreUsageTable_NoCapacity_AboveMinimum_InvalidateEntryFails) { crypto_session_->SetMaximumUsageTableEntries(0); // Unlimited. - ASSERT_LT(kDefaultTableCapacity, kOverFullUsageEntryInfoVector.size()); - const uint32_t table_start_size = - static_cast(kOverFullUsageEntryInfoVector.size()); + const std::vector usage_entries = + CreateOverFullUsageEntryInfoVector(); + ASSERT_LT(kDefaultTableCapacity, usage_entries.size()); + const uint32_t table_start_size = static_cast(usage_entries.size()); const RequestedSecurityLevel security_level = GetSecurityLevel(); // Expectations for restore: @@ -955,9 +818,8 @@ TEST_P(UsageTableHeaderInitializationTest, EXPECT_CALL(*device_files_, RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<0>(kUsageTableHeader), - SetArgPointee<1>(kOverFullUsageEntryInfoVector), - SetArgPointee<2>(false), SetArgPointee<3>(false), - Return(true))); + SetArgPointee<1>(usage_entries), SetArgPointee<2>(false), + SetArgPointee<3>(false), Return(true))); EXPECT_CALL(*crypto_session_, LoadUsageTableHeader(security_level, kUsageTableHeader)) .WillOnce(Return(NO_ERROR)); @@ -1043,11 +905,16 @@ TEST_F(UsageTableHeaderTest, AddEntry_CreateUsageEntryFailed_UnknownError) { uint32_t usage_entry_number = 0; EXPECT_NE(NO_ERROR, usage_table_header_->AddEntry( - crypto_session_, kUsageEntryInfoOfflineLicense1.key_set_id, + crypto_session_, kUsageEntryInfoOfflineLicense1.key_set_id(), kEmptyString /* license */, &usage_entry_number)); } -TEST_F(UsageTableHeaderTest, AddEntry_UsageEntryTooSmall) { +// Attempt to create a new entry; however, OEMCrypto returns a usage +// entry number that is smaller than the current table size. +// +// The CDM policy is to drop the new entry. If a later issue arises +// from the entry in that spot, that failure will be handled separately. +TEST_F(UsageTableHeaderTest, AddEntry_UsageEntryNumberTooSmall) { Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector); const uint32_t expect_usage_entry_number = static_cast(kUsageEntryInfoVector.size()) - 1; @@ -1058,7 +925,7 @@ TEST_F(UsageTableHeaderTest, AddEntry_UsageEntryTooSmall) { uint32_t usage_entry_number = 0; EXPECT_NE(NO_ERROR, usage_table_header_->AddEntry( - crypto_session_, kUsageEntryInfoOfflineLicense1.key_set_id, + crypto_session_, kUsageEntryInfoOfflineLicense1.key_set_id(), kEmptyString /* license */, &usage_entry_number)); } @@ -1073,18 +940,18 @@ TEST_F(UsageTableHeaderTest, AddEntry_UsageEntryTooSmall) { // c. Shrink table to remove the now empty entry slot created in (a) // d. Storing the new updated usage table // -// Storage type Usage entries +// Entry type Usage entries // at start at end // ============= ======== ====== // Offline License 1 0 0 -// Secure Stop 1 1 1 -// Storage Type Unknown 2 Replaced -// Offline License 2 DNE 2 +// Offline License 2 1 1 +// Clear entry 2 Replaced +// Offline License 3 DNE 2 // // DNE = Does Not Exist // // # of usage entries 3 3 -TEST_F(UsageTableHeaderTest, AddEntry_NextConsecutiveOfflineUsageEntry) { +TEST_F(UsageTableHeaderTest, AddEntry_NextConsecutiveUsageEntry) { Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector); const uint32_t initial_usage_entry_number = static_cast(kUsageEntryInfoVector.size()); @@ -1093,12 +960,15 @@ TEST_F(UsageTableHeaderTest, AddEntry_NextConsecutiveOfflineUsageEntry) { std::vector expect_usage_entry_info_vector = kUsageEntryInfoVector; expect_usage_entry_info_vector[final_usage_entry_number] = - kUsageEntryInfoOfflineLicense2; + kUsageEntryInfoOfflineLicense3; + // Expectations for new creating entry. EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull())) .WillOnce(DoAll(SetArgPointee<0>(initial_usage_entry_number), Return(NO_ERROR))); + // Expectations for moving the new entry into slot 2. EXPECT_CALL(*crypto_session_, MoveUsageEntry(final_usage_entry_number)) .WillOnce(Return(NO_ERROR)); + // Expectations for resizing the table. EXPECT_CALL(*crypto_session_, ShrinkUsageTableHeader( kLevelDefault, @@ -1117,7 +987,7 @@ TEST_F(UsageTableHeaderTest, AddEntry_NextConsecutiveOfflineUsageEntry) { uint32_t usage_entry_number = 0; EXPECT_EQ(NO_ERROR, usage_table_header_->AddEntry( - crypto_session_, kUsageEntryInfoOfflineLicense2.key_set_id, + crypto_session_, kUsageEntryInfoOfflineLicense3.key_set_id(), kEmptyString /* license */, &usage_entry_number)); EXPECT_EQ(final_usage_entry_number, usage_entry_number); } @@ -1136,16 +1006,16 @@ TEST_F(UsageTableHeaderTest, AddEntry_NextConsecutiveOfflineUsageEntry) { // and the filler gap entries created in (b) // e. Storing the new updated usage table // -// Storage type Usage entries +// Entry type Usage entries // at start at end // ============= ======== ====== // Offline License 1 0 0 -// Secure Stop 1 1 1 -// Storage Type Unknown 2 Replaced -// Storage Type Unknown DNE Removed (never stored) -// Storage Type Unknown DNE Removed (never stored) -// Storage Type Unknown DNE Removed (never stored) -// Offline License 2 DNE 2 +// Offline License 2 1 1 +// Clear entry 2 Replaced +// Non-existing entry DNE Removed (never stored) +// Non-existing entry DNE Removed (never stored) +// Non-existing entry DNE Removed (never stored) +// Offline License 3 DNE 2 // // DNE = Does Not Exist // @@ -1162,11 +1032,16 @@ TEST_F(UsageTableHeaderTest, AddEntry_SkipUsageEntries) { std::vector expect_usage_entry_info_vector = kUsageEntryInfoVector; expect_usage_entry_info_vector[final_usage_entry_number] = - kUsageEntryInfoOfflineLicense2; + kUsageEntryInfoOfflineLicense3; + // Expectations for creating new entry. The returned entry number + // is much larger than what is normally expected (one past the end + // of the table). EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull())) .WillOnce(DoAll(SetArgPointee<0>(initial_usage_entry_number), Return(NO_ERROR))); + // Expectation that the table will attempt to move the new entry + // to available clear entry at the end of the table. EXPECT_CALL(*crypto_session_, MoveUsageEntry(final_usage_entry_number)) .WillOnce(Return(NO_ERROR)); EXPECT_CALL(*crypto_session_, @@ -1187,7 +1062,7 @@ TEST_F(UsageTableHeaderTest, AddEntry_SkipUsageEntries) { uint32_t usage_entry_number = 0; EXPECT_EQ(NO_ERROR, usage_table_header_->AddEntry( - crypto_session_, kUsageEntryInfoOfflineLicense2.key_set_id, + crypto_session_, kUsageEntryInfoOfflineLicense3.key_set_id(), kEmptyString /* license */, &usage_entry_number)); EXPECT_EQ(final_usage_entry_number, usage_entry_number); } @@ -1203,13 +1078,13 @@ TEST_F(UsageTableHeaderTest, AddEntry_SkipUsageEntries) { // due to entry being in use (according to OEMCrypto) // c. Storing the new updated usage table // -// Storage type Usage entries +// Entry type Usage entries // at start at end // ============= ======== ====== // Offline License 1 0 0 -// Secure Stop 1 1 1 -// Storage Type Unknown 2 2 -// Offline License 2 DNE 3 +// Offline License 2 1 1 +// Clear entry 2 2 +// Offline License 3 DNE 3 // // DNE = Does Not Exist // @@ -1222,11 +1097,13 @@ TEST_F(UsageTableHeaderTest, AddEntry_CannotMoveNewEntry) { static_cast(kUsageEntryInfoVector.size()) - 1; std::vector expect_usage_entry_info_vector = kUsageEntryInfoVector; - expect_usage_entry_info_vector.push_back(kUsageEntryInfoOfflineLicense2); + expect_usage_entry_info_vector.push_back(kUsageEntryInfoOfflineLicense3); EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull())) .WillOnce( DoAll(SetArgPointee<0>(final_usage_entry_number), Return(NO_ERROR))); + // Expectations for table attempting the move new entry into the + // clear entry slot. However, this move will fail. EXPECT_CALL(*crypto_session_, MoveUsageEntry(attempted_usage_entry_number)) .WillOnce(Return(MOVE_USAGE_ENTRY_DESTINATION_IN_USE)); EXPECT_CALL(*crypto_session_, UpdateUsageEntry(NotNull(), NotNull())) @@ -1240,7 +1117,7 @@ TEST_F(UsageTableHeaderTest, AddEntry_CannotMoveNewEntry) { uint32_t usage_entry_number = 0; EXPECT_EQ(NO_ERROR, usage_table_header_->AddEntry( - crypto_session_, kUsageEntryInfoOfflineLicense2.key_set_id, + crypto_session_, kUsageEntryInfoOfflineLicense3.key_set_id(), kEmptyString /* license */, &usage_entry_number)); EXPECT_EQ(final_usage_entry_number, usage_entry_number); } @@ -1256,14 +1133,14 @@ TEST_F(UsageTableHeaderTest, AddEntry_CannotMoveNewEntry) { // c. Fail to shrink table due to occupied entry // d. Storing the new updated usage table // -// Storage type Usage entries +// Entry type Usage entries // at start at end // ============= ======== ====== // Offline License 1 0 0 -// Secure Stop 1 1 1 -// Storage Type Unknown 2 Replaced -// Offline License 2 DNE 2 -// Storage Type Unknown DNE 3 (created when new entry moved) +// Offline License 2 1 1 +// Clear entry 2 Replaced +// Offline License 3 DNE 2 +// Clear entry DNE 3 (created when new entry moved) // // DNE = Does Not Exist // @@ -1277,14 +1154,17 @@ TEST_F(UsageTableHeaderTest, AddEntry_CannotShinkAfterMove) { std::vector expect_usage_entry_info_vector = kUsageEntryInfoVector; expect_usage_entry_info_vector[final_usage_entry_number] = - kUsageEntryInfoOfflineLicense2; - expect_usage_entry_info_vector.push_back(kUsageEntryInfoStorageTypeUnknown); + kUsageEntryInfoOfflineLicense3; + expect_usage_entry_info_vector.push_back(kUsageEntryInfoEmpty); EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull())) .WillOnce(DoAll(SetArgPointee<0>(initial_usage_entry_number), Return(NO_ERROR))); + // Expectation for moving new entry into empty entry slot. EXPECT_CALL(*crypto_session_, MoveUsageEntry(final_usage_entry_number)) .WillOnce(Return(NO_ERROR)); + // Expectations that shrinking the table will fail. UsageTableHeader + // will keep an empty entry at the end of the table. EXPECT_CALL( *crypto_session_, ShrinkUsageTableHeader( @@ -1303,7 +1183,7 @@ TEST_F(UsageTableHeaderTest, AddEntry_CannotShinkAfterMove) { uint32_t usage_entry_number = 0; EXPECT_EQ(NO_ERROR, usage_table_header_->AddEntry( - crypto_session_, kUsageEntryInfoOfflineLicense2.key_set_id, + crypto_session_, kUsageEntryInfoOfflineLicense3.key_set_id(), kEmptyString /* license */, &usage_entry_number)); EXPECT_EQ(final_usage_entry_number, usage_entry_number); } @@ -1324,14 +1204,12 @@ TEST_F(UsageTableHeaderTest, AddEntry_CreateUsageEntryFailsOnce_SucceedsSecondTime) { // Initialize and setup MockUsageTableHeader* mock_usage_table_header = SetUpMock(); - Init(kSecurityLevelL1, kUsageTableHeader, k10UsageEntryInfoVector); - std::vector usage_entry_info_vector_at_start = - k10UsageEntryInfoVector; + Init(kSecurityLevelL1, kUsageTableHeader, k5UsageEntryInfoVector); uint32_t invalidated_entry = 0; // Randomly chosen by UsageTableHeader const uint32_t expected_usage_entry_number = - static_cast(k10UsageEntryInfoVector.size()) - 1; + static_cast(k5UsageEntryInfoVector.size()) - 1; EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull())) // First call fails @@ -1357,17 +1235,17 @@ TEST_F(UsageTableHeaderTest, uint32_t usage_entry_number = 0; EXPECT_EQ(NO_ERROR, mock_usage_table_header->SuperAddEntry( - crypto_session_, kUsageEntryInfoOfflineLicense6.key_set_id, + crypto_session_, kUsageEntryInfoOfflineLicense6.key_set_id(), kEmptyString /* license */, &usage_entry_number)); // Verify added/deleted usage entry number and entries EXPECT_EQ(expected_usage_entry_number, usage_entry_number); EXPECT_LE(0u, invalidated_entry); - EXPECT_LE(invalidated_entry, k10UsageEntryInfoVector.size() - 1); + EXPECT_LE(invalidated_entry, k5UsageEntryInfoVector.size() - 1); std::vector expected_usage_entries = - k10UsageEntryInfoVector; + k5UsageEntryInfoVector; expected_usage_entries[invalidated_entry] = expected_usage_entries.back(); expected_usage_entries.pop_back(); @@ -1380,7 +1258,7 @@ TEST_F(UsageTableHeaderTest, TEST_F(UsageTableHeaderTest, AddEntry_CreateUsageEntryFailsEveryTime) { // Initialize and setup MockUsageTableHeader* mock_usage_table_header = SetUpMock(); - Init(kSecurityLevelL1, kUsageTableHeader, k10UsageEntryInfoVector); + Init(kSecurityLevelL1, kUsageTableHeader, k5UsageEntryInfoVector); // Setup expectations EXPECT_CALL(*mock_usage_table_header, @@ -1396,17 +1274,17 @@ TEST_F(UsageTableHeaderTest, AddEntry_CreateUsageEntryFailsEveryTime) { uint32_t usage_entry_number; EXPECT_EQ(INSUFFICIENT_CRYPTO_RESOURCES, mock_usage_table_header->SuperAddEntry( - crypto_session_, kUsageEntryInfoOfflineLicense6.key_set_id, + crypto_session_, kUsageEntryInfoOfflineLicense6.key_set_id(), kEmptyString /* license */, &usage_entry_number)); // Verify the number of entries deleted. constexpr uint32_t kExpectedEntriesDeleted = 1; const std::vector& final_usage_entries = - mock_usage_table_header->usage_entry_info(); + mock_usage_table_header->entry_info_list(); uint32_t invalid_entries = 0; for (const CdmUsageEntryInfo& usage_entry_info : final_usage_entries) { - if (usage_entry_info.storage_type == kStorageTypeUnknown) { + if (usage_entry_info.IsEmpty()) { ++invalid_entries; } } @@ -1414,7 +1292,7 @@ TEST_F(UsageTableHeaderTest, AddEntry_CreateUsageEntryFailsEveryTime) { // marked as invalid plus the number of fewer entries in the table // at the end of the call. const uint32_t entries_deleted = - invalid_entries + static_cast(k10UsageEntryInfoVector.size() - + invalid_entries + static_cast(k5UsageEntryInfoVector.size() - final_usage_entries.size()); EXPECT_EQ(kExpectedEntriesDeleted, entries_deleted); } @@ -1497,46 +1375,45 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_InvalidUsageEntryNumber) { // will occur. // // Attempting to delete the entry in (1) will result in: -// a. The entry will be marked as kStorageTypeUnknown. +// a. The entry will be cleared. // b. The usage table will be requested to shrink both the last entry // and the unknown entry before it. // c. OEMCrypto error will cause the internal entries to remain the // same. -// d. InvalidateEntry() will return NO_ERROR as the storage type is -// changed. +// d. InvalidateEntry() will return NO_ERROR as the entry was cleared. // -// Storage type Usage entries +// Entry type Usage entries // at start at end // ============= ======== ====== // Offline License 1 0 0 -// Secure Stop 1 1 1 -// Storage Type Unknown 2 2 -// Offline License 2 3 3 (Storage Type Unknown) +// Offline License 2 1 1 +// Clear entry 2 2 +// Offline License 3 3 3 (Cleared) // // # of usage entries 4 4 TEST_F(UsageTableHeaderTest, InvalidateEntry_CryptoSessionError) { const std::vector usage_entry_info_vector = { - kUsageEntryInfoOfflineLicense1, kUsageEntryInfoSecureStop1, - kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense2}; + kUsageEntryInfoOfflineLicense1, kUsageEntryInfoOfflineLicense2, + kUsageEntryInfoEmpty, kUsageEntryInfoOfflineLicense3}; Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); const uint32_t usage_entry_number_to_be_deleted = - 3; // kUsageEntryInfoOfflineLicense2 + 3; // kUsageEntryInfoOfflineLicense3 metrics::CryptoMetrics metrics; + // Error when shrinking the table. EXPECT_CALL(*crypto_session_, ShrinkUsageTableHeader(kLevelDefault, 2, NotNull())) .WillOnce(Return(SHRINK_USAGE_TABLE_HEADER_UNKNOWN_ERROR)); // Regardless, the usage table should be updated to reflect the changes - // to the usage entry marked as storage type unknown. - EXPECT_CALL( - *device_files_, - StoreUsageTableInfo(kUsageTableHeader, - ElementsAre(kUsageEntryInfoOfflineLicense1, - kUsageEntryInfoSecureStop1, - kUsageEntryInfoStorageTypeUnknown, - kUsageEntryInfoStorageTypeUnknown))) + // to the usage entry that was cleared. + EXPECT_CALL(*device_files_, + StoreUsageTableInfo( + kUsageTableHeader, + ElementsAre(kUsageEntryInfoOfflineLicense1, + kUsageEntryInfoOfflineLicense2, + kUsageEntryInfoEmpty, kUsageEntryInfoEmpty))) .WillOnce(Return(true)); EXPECT_EQ(NO_ERROR, usage_table_header_->InvalidateEntry( @@ -1544,35 +1421,35 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_CryptoSessionError) { &metrics)); // Check that the list is unchanged. constexpr size_t expected_size = 4; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_header_->entry_info_list().size()); } // Initial Test state: // 1. Entry to be deleted is the last entry and is an offline license. // // Attempting to delete the entry in (1) will result in: -// a. The entry will be marked as kStorageTypeUnknown. +// a. The entry will be cleared. // b. Usage table will be resized to remove the last two entries. // c. Updated table will be saved. // d. InvalidateEntry() will return NO_ERROR. // -// Storage type Usage entries +// Entry type Usage entries // at start at end // ============= ======== ====== // Offline License 1 0 0 -// Secure Stop 1 1 1 -// Storage Type Unknown 2 Deleted -// Offline License 2 3 Deleted +// Offline License 2 1 1 +// Clear entry 2 Deleted +// Offline License 3 3 Deleted // // # of usage entries 4 2 -TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntry_OfflineEntry) { +TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntry) { const std::vector usage_entry_info_vector = { - kUsageEntryInfoOfflineLicense1, kUsageEntryInfoSecureStop1, - kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense2}; + kUsageEntryInfoOfflineLicense1, kUsageEntryInfoOfflineLicense2, + kUsageEntryInfoEmpty, kUsageEntryInfoOfflineLicense3}; Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); const uint32_t usage_entry_number_to_be_deleted = - 3; // kUsageEntryInfoOfflineLicense2 + 3; // kUsageEntryInfoOfflineLicense3 metrics::CryptoMetrics metrics; // Expectations for call to shrink. @@ -1584,7 +1461,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntry_OfflineEntry) { EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader, ElementsAre(kUsageEntryInfoOfflineLicense1, - kUsageEntryInfoSecureStop1))) + kUsageEntryInfoOfflineLicense2))) .WillOnce(Return(true)); EXPECT_EQ(NO_ERROR, usage_table_header_->InvalidateEntry( @@ -1592,55 +1469,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntry_OfflineEntry) { &metrics)); // Check the end state of the usage table. constexpr size_t expected_size = 2; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); -} - -// Initial Test state: -// 1. Entry to be deleted is the last entry and is a secure stop. -// -// Attempting to delete the entry in (1) will result in: -// a. The entry will be marked as kStorageTypeUnknown. -// b. Usage table will be resized to remove the last two entries. -// c. Updated table will be saved. -// d. InvalidateEntry() will return NO_ERROR. -// -// Storage type Usage entries -// at start at end -// ============= ======== ====== -// Offline License 1 0 0 -// Secure Stop 1 1 1 -// Storage Type Unknown 2 Deleted -// Secure Stop 2 3 Deleted -// -// # of usage entries 4 2 -TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntry_SecureStopEntry) { - const std::vector usage_entry_info_vector = { - kUsageEntryInfoOfflineLicense1, kUsageEntryInfoSecureStop1, - kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoSecureStop2}; - - Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); - const uint32_t usage_entry_number_to_be_deleted = - 3; // kUsageEntryInfoSecureStop2 - metrics::CryptoMetrics metrics; - - // Expectation when shrinking table. - EXPECT_CALL(*crypto_session_, - ShrinkUsageTableHeader(kLevelDefault, 2, NotNull())) - .WillOnce( - DoAll(SetArgPointee<2>(kAnotherUsageTableHeader), Return(NO_ERROR))); - - EXPECT_CALL(*device_files_, - StoreUsageTableInfo(kAnotherUsageTableHeader, - ElementsAre(kUsageEntryInfoOfflineLicense1, - kUsageEntryInfoSecureStop1))) - .WillOnce(Return(true)); - - EXPECT_EQ(NO_ERROR, usage_table_header_->InvalidateEntry( - usage_entry_number_to_be_deleted, true, device_files_, - &metrics)); - // Check the end state of the usage table. - constexpr size_t expected_size = 2; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_header_->entry_info_list().size()); } // Initial Test state: @@ -1649,21 +1478,21 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntry_SecureStopEntry) { // 2. Usage entry to be deleted precedes those in (1). // // Attempting to delete the entry in (2) will result in: -// a. The entry will be marked as kStorageTypeUnknown. +// a. The entry will be cleared. // b. While defragging, the last two entries will be selected to // move. // c. Getting the usage entry for the selected entries will fail and -// result in them being set as kStorageTypeUnknown. +// result in them being cleared. // d. No entries will be moved due to (c). // e. Usage table will be resized to have only one entry. // f. Updated table will be saved. // g. InvalidateEntry() will return NO_ERROR. // -// Storage type Usage entries +// Entry type Usage entries // at start at end // ============= ======== ====== -// Secure Stop 1 0 0 -// Storage Type Unknown 1 Deleted +// Offline License 4 0 0 +// Clear entry 1 Deleted // Offline License 1 2 Deleted // Offline License 2 3 Deleted (because missing) // Offline License 3 4 Deleted (because missing) @@ -1672,7 +1501,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntry_SecureStopEntry) { TEST_F(UsageTableHeaderTest, InvalidateEntry_LastOfflineEntriesHaveMissingLicenses) { const std::vector usage_entry_info_vector = { - kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown, + kUsageEntryInfoOfflineLicense4, kUsageEntryInfoEmpty, kUsageEntryInfoOfflineLicense1, kUsageEntryInfoOfflineLicense2, kUsageEntryInfoOfflineLicense3}; @@ -1683,11 +1512,11 @@ TEST_F(UsageTableHeaderTest, // Offline license 2 and 3 cannot be retrieved. EXPECT_CALL(*device_files_, - RetrieveLicense(kUsageEntryInfoOfflineLicense2.key_set_id, + RetrieveLicense(kUsageEntryInfoOfflineLicense2.key_set_id(), NotNull(), NotNull())) .WillOnce(Return(false)); EXPECT_CALL(*device_files_, - RetrieveLicense(kUsageEntryInfoOfflineLicense3.key_set_id, + RetrieveLicense(kUsageEntryInfoOfflineLicense3.key_set_id(), NotNull(), NotNull())) .WillOnce(Return(false)); @@ -1699,7 +1528,7 @@ TEST_F(UsageTableHeaderTest, EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader, - ElementsAre(kUsageEntryInfoSecureStop1))) + ElementsAre(kUsageEntryInfoOfflineLicense4))) .WillOnce(Return(true)); EXPECT_EQ(NO_ERROR, usage_table_header_->InvalidateEntry( @@ -1707,7 +1536,7 @@ TEST_F(UsageTableHeaderTest, &metrics)); // Check the end state of the usage table. constexpr size_t expected_size = 1; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_header_->entry_info_list().size()); } // Initial Test state: @@ -1716,31 +1545,31 @@ TEST_F(UsageTableHeaderTest, // 2. Usage entry to be deleted precedes those in (1). // // Attempting to delete the entry in (2) will result in: -// a. The entry will be marked as kStorageTypeUnknown. +// a. The entry will be cleared. // b. While defragging, the last two entries will be selected to // move. // c. Getting the usage entry for the selected entries will fail due -// to a mismatch in usage entry number and result in them being set -// as kStorageTypeUnknown. +// to a mismatch in usage entry number and result in them being +// cleared. // d. No entries will be moved due to (c). // e. Usage table will be resized to have only one entry. // f. Updated table will be saved. // g. InvalidateEntry() will return NO_ERROR. // -// Storage type Usage entries +// Entry type Usage entries // at start at end // ============= ======== ====== -// Secure Stop 1 0 0 -// Storage Type Unknown 1 Deleted +// Offline License 4 0 0 +// Clear entry 1 Deleted // Offline License 1 2 Deleted // Offline License 2 3 Deleted (because incorrect #) // Offline License 3 4 Deleted (because incorrect #) // // # of usage entries 5 1 TEST_F(UsageTableHeaderTest, - InvalidateEntry_LastOfflineEntriesHaveIncorrectUsageEntryNumber) { + InvalidateEntry_LastEntriesHaveIncorrectUsageEntryNumber) { const std::vector usage_entry_info_vector = { - kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown, + kUsageEntryInfoOfflineLicense4, kUsageEntryInfoEmpty, kUsageEntryInfoOfflineLicense1, kUsageEntryInfoOfflineLicense2, kUsageEntryInfoOfflineLicense3}; Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); @@ -1750,7 +1579,7 @@ TEST_F(UsageTableHeaderTest, // Set offline license file data with mismatched usage entry numbers. const DeviceFiles::CdmLicenseData offline_license_3_data{ - kUsageEntryInfoOfflineLicense3.key_set_id, + kUsageEntryInfoOfflineLicense3.key_set_id(), kActiveLicenseState, kPsshData, kKeyRequest, @@ -1767,12 +1596,12 @@ TEST_F(UsageTableHeaderTest, kDrmCertificate, kCryptoWrappedKey}; EXPECT_CALL(*device_files_, - RetrieveLicense(kUsageEntryInfoOfflineLicense3.key_set_id, + RetrieveLicense(kUsageEntryInfoOfflineLicense3.key_set_id(), NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<1>(offline_license_3_data), Return(true))); const DeviceFiles::CdmLicenseData offline_license_2_data{ - kUsageEntryInfoOfflineLicense2.key_set_id, + kUsageEntryInfoOfflineLicense2.key_set_id(), kActiveLicenseState, kPsshData, kKeyRequest, @@ -1789,7 +1618,7 @@ TEST_F(UsageTableHeaderTest, kDrmCertificate, kCryptoWrappedKey}; EXPECT_CALL(*device_files_, - RetrieveLicense(kUsageEntryInfoOfflineLicense2.key_set_id, + RetrieveLicense(kUsageEntryInfoOfflineLicense2.key_set_id(), NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<1>(offline_license_2_data), Return(true))); @@ -1800,7 +1629,7 @@ TEST_F(UsageTableHeaderTest, DoAll(SetArgPointee<2>(kAnotherUsageTableHeader), Return(NO_ERROR))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader, - ElementsAre(kUsageEntryInfoSecureStop1))) + ElementsAre(kUsageEntryInfoOfflineLicense4))) .WillOnce(Return(true)); EXPECT_EQ(NO_ERROR, usage_table_header_->InvalidateEntry( @@ -1808,15 +1637,15 @@ TEST_F(UsageTableHeaderTest, &metrics)); // Check the end state of the usage table. constexpr size_t expected_size = 1; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_header_->entry_info_list().size()); } // Initial Test state: -// 1. Last few entries are of storage type unknown. +// 1. Last few entries are clear. // 2. Usage entry to be deleted precedes those in (1). // // Attempting to delete the entry in (2) will result in: -// a. The entry will be marked as kStorageTypeUnknown. +// a. The entry will be cleared. // b. While defragging, offline license 2 will be selected to be // moved. // c. The selected entry will have the usage entry loaded from device @@ -1828,24 +1657,27 @@ TEST_F(UsageTableHeaderTest, // g. Updated table will be saved. // h. InvalidateEntry() will return NO_ERROR. // -// Storage type Usage entries +// Entry type Usage entries // at start at end // ============= ======== ====== -// Secure Stop 1 0 0 -// Storage Type Unknown 1 Deleted +// Offline License 4 0 0 +// Clear entry 1 Deleted // Offline License 1 2 2 // Offline License 2 3 1 (Moved) // Offline License 3 4 Deleted -// Storage Type Unknown 5 Deleted -// Storage Type Unknown 6 Deleted +// Clear entry 5 Deleted +// Clear entry 6 Deleted // // # of usage entries 7 3 -TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntriesAreStorageTypeUnknown) { +TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntriesAreClear) { const std::vector usage_entry_info_vector = { - kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown, - kUsageEntryInfoOfflineLicense1, kUsageEntryInfoOfflineLicense2, - kUsageEntryInfoOfflineLicense3, kUsageEntryInfoStorageTypeUnknown, - kUsageEntryInfoStorageTypeUnknown}; + kUsageEntryInfoOfflineLicense4, + kUsageEntryInfoEmpty, + kUsageEntryInfoOfflineLicense1, + kUsageEntryInfoOfflineLicense2, + kUsageEntryInfoOfflineLicense3, + kUsageEntryInfoEmpty, + kUsageEntryInfoEmpty}; Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); const uint32_t usage_entry_number_to_be_deleted = @@ -1854,7 +1686,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntriesAreStorageTypeUnknown) { // Expect calls for moving offline license 2 (position 3) to position 1. const DeviceFiles::CdmLicenseData offline_license_2_data{ - kUsageEntryInfoOfflineLicense2.key_set_id, + kUsageEntryInfoOfflineLicense2.key_set_id(), kActiveLicenseState, kPsshData, kKeyRequest, @@ -1871,7 +1703,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntriesAreStorageTypeUnknown) { kDrmCertificate, kCryptoWrappedKey}; EXPECT_CALL(*device_files_, - RetrieveLicense(kUsageEntryInfoOfflineLicense2.key_set_id, + RetrieveLicense(kUsageEntryInfoOfflineLicense2.key_set_id(), NotNull(), NotNull())) .Times(2) // First to get entry, then again to update. .WillRepeatedly( @@ -1897,7 +1729,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntriesAreStorageTypeUnknown) { EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader, - ElementsAre(kUsageEntryInfoSecureStop1, + ElementsAre(kUsageEntryInfoOfflineLicense4, kUsageEntryInfoOfflineLicense2, kUsageEntryInfoOfflineLicense1))) .WillOnce(Return(true)); @@ -1907,7 +1739,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntriesAreStorageTypeUnknown) { &metrics)); // Check the end state of the usage table. constexpr size_t expected_size = 3; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_header_->entry_info_list().size()); } // Initial Test state: @@ -1916,7 +1748,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntriesAreStorageTypeUnknown) { // OEMCrypto_MoveUsageEntry on it will fail. // // Attempting to delete the entry in (1) will result in: -// a. The entry will be marked as kStorageTypeUnknown. +// a. The entry will be cleared. // b. While defragging, offline license 3 will be selected to be // moved. // c. The selected entry will have the usage entry loaded from device @@ -1927,12 +1759,12 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntriesAreStorageTypeUnknown) { // f. Updated table will be saved. // g. InvalidateEntry() will return NO_ERROR. // -// Storage type Usage entries +// Entry type Usage entries // at start at end // ============= ======== ====== -// Secure Stop 1 0 0 -// Secure Stop 2 1 1 -// Offline License 1 2 2 (storage type unknown) +// Offline License 4 0 0 +// Offline License 5 1 1 +// Offline License 1 2 2 (cleared) // Offline License 2 3 3 // Offline License 3 4 4 // @@ -1940,7 +1772,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntriesAreStorageTypeUnknown) { TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntryIsOffline_MoveOfflineEntryFailed) { const std::vector usage_entry_info_vector = { - kUsageEntryInfoSecureStop1, kUsageEntryInfoSecureStop2, + kUsageEntryInfoOfflineLicense4, kUsageEntryInfoOfflineLicense5, kUsageEntryInfoOfflineLicense1, kUsageEntryInfoOfflineLicense2, kUsageEntryInfoOfflineLicense3}; @@ -1952,7 +1784,7 @@ TEST_F(UsageTableHeaderTest, // Expect calls for moving offline license 3 (position 4), but // failure to move will not result in any calls for updating. const DeviceFiles::CdmLicenseData offline_license_3_data{ - kUsageEntryInfoOfflineLicense3.key_set_id, + kUsageEntryInfoOfflineLicense3.key_set_id(), kActiveLicenseState, kPsshData, kKeyRequest, @@ -1969,7 +1801,7 @@ TEST_F(UsageTableHeaderTest, kDrmCertificate, kCryptoWrappedKey}; EXPECT_CALL(*device_files_, - RetrieveLicense(kUsageEntryInfoOfflineLicense3.key_set_id, + RetrieveLicense(kUsageEntryInfoOfflineLicense3.key_set_id(), NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<1>(offline_license_3_data), Return(true))); @@ -1981,12 +1813,12 @@ TEST_F(UsageTableHeaderTest, // No calls to shrink are expected. // Regardless, the usage table should be updated to reflect the changes - // to the usage entry marked as storage type unknown. + // to the usage entry cleared. EXPECT_CALL(*device_files_, StoreUsageTableInfo(kUsageTableHeader, - ElementsAre(kUsageEntryInfoSecureStop1, - kUsageEntryInfoSecureStop2, - kUsageEntryInfoStorageTypeUnknown, + ElementsAre(kUsageEntryInfoOfflineLicense4, + kUsageEntryInfoOfflineLicense5, + kUsageEntryInfoEmpty, kUsageEntryInfoOfflineLicense2, kUsageEntryInfoOfflineLicense3))) .WillOnce(Return(true)); @@ -1996,17 +1828,17 @@ TEST_F(UsageTableHeaderTest, &metrics)); // Check that the table has been updated as expected. constexpr size_t expected_size = 5; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_header_->entry_info_list().size()); } // Initial Test state: // 1. Usage entry to be deleted is not last (Offline license 1) -// 2. Last few entries are of storage type unknown. +// 2. Last few entries are clear. // 3. Entry that precedes those in (2) are offline license and calling // OEMCrypto_LoadUsageEntry on it will fail. // // Attempting to delete the entry in (1) will result in: -// a. The entry will be marked as kStorageTypeUnknown. +// a. The entry will be cleared. // b. While defragging, offline licenses 2 and 3 will be selected to be // moved. // c. The selected entry will have the usage entry loaded from device @@ -2017,25 +1849,28 @@ TEST_F(UsageTableHeaderTest, // f. Updated table will be saved. // g. InvalidateEntry() will return NO_ERROR. // -// Storage type Usage entries +// Entry type Usage entries // at start at end // ============= ======== ====== -// Secure Stop 1 0 0 -// Storage Type Unknown 1 1 -// Offline License 1 2 2 (storage type unknown) +// Offline License 4 0 0 +// Clear entry 1 1 +// Offline License 1 2 2 (cleared) // Offline License 2 3 3 // Offline License 3 4 4 -// Storage Type Unknown 5 Deleted -// Storage Type Unknown 6 Deleted +// Clear entry 5 Deleted +// Clear entry 6 Deleted // // # of usage entries 7 5 TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntriesAreOfflineAndUnknown_MoveOfflineEntryFailed) { const std::vector usage_entry_info_vector = { - kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown, - kUsageEntryInfoOfflineLicense1, kUsageEntryInfoOfflineLicense2, - kUsageEntryInfoOfflineLicense3, kUsageEntryInfoStorageTypeUnknown, - kUsageEntryInfoStorageTypeUnknown}; + kUsageEntryInfoOfflineLicense4, + kUsageEntryInfoEmpty, + kUsageEntryInfoOfflineLicense1, + kUsageEntryInfoOfflineLicense2, + kUsageEntryInfoOfflineLicense3, + kUsageEntryInfoEmpty, + kUsageEntryInfoEmpty}; Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); const uint32_t usage_entry_number_to_be_deleted = @@ -2049,7 +1884,7 @@ TEST_F(UsageTableHeaderTest, // Expect calls for moving offline license 3 (position 4), but // failure to move will not result in any calls for updating. const DeviceFiles::CdmLicenseData offline_license_3_data{ - kUsageEntryInfoOfflineLicense3.key_set_id, + kUsageEntryInfoOfflineLicense3.key_set_id(), kActiveLicenseState, kPsshData, kKeyRequest, @@ -2066,7 +1901,7 @@ TEST_F(UsageTableHeaderTest, kDrmCertificate, kCryptoWrappedKey}; EXPECT_CALL(*device_files_, - RetrieveLicense(kUsageEntryInfoOfflineLicense3.key_set_id, + RetrieveLicense(kUsageEntryInfoOfflineLicense3.key_set_id(), NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<1>(offline_license_3_data), Return(true))); EXPECT_CALL(*crypto_session_, LoadUsageEntry(4, kUsageEntry)) @@ -2075,7 +1910,7 @@ TEST_F(UsageTableHeaderTest, // Expect calls for moving offline license 2 (position 3), but // failure to move will not result in any calls for updating. const DeviceFiles::CdmLicenseData offline_license_2_data{ - kUsageEntryInfoOfflineLicense2.key_set_id, + kUsageEntryInfoOfflineLicense2.key_set_id(), kActiveLicenseState, kPsshData, kKeyRequest, @@ -2092,28 +1927,28 @@ TEST_F(UsageTableHeaderTest, kDrmCertificate, kCryptoWrappedKey}; EXPECT_CALL(*device_files_, - RetrieveLicense(kUsageEntryInfoOfflineLicense2.key_set_id, + RetrieveLicense(kUsageEntryInfoOfflineLicense2.key_set_id(), NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<1>(offline_license_2_data), Return(true))); EXPECT_CALL(*crypto_session_, LoadUsageEntry(3, kUsageEntry)) .WillOnce(Return(LOAD_USAGE_ENTRY_INVALID_SESSION)); - // Expect a call to shrink table to cut off only the unknown entries + // Expect a call to shrink table to cut off only the clear entries // at the end of the table. EXPECT_CALL(*crypto_session_, ShrinkUsageTableHeader(kLevelDefault, 5, NotNull())) .WillOnce( DoAll(SetArgPointee<2>(kAnotherUsageTableHeader), Return(NO_ERROR))); - // Update table for the entry now marked storage type unknown and - // the entries that were cut off. - EXPECT_CALL(*device_files_, - StoreUsageTableInfo(kAnotherUsageTableHeader, - ElementsAre(kUsageEntryInfoSecureStop1, - kUsageEntryInfoStorageTypeUnknown, - kUsageEntryInfoStorageTypeUnknown, - kUsageEntryInfoOfflineLicense2, - kUsageEntryInfoOfflineLicense3))) + // Update table for the entry now cleared and the entries that + // were cut off. + EXPECT_CALL( + *device_files_, + StoreUsageTableInfo( + kAnotherUsageTableHeader, + ElementsAre(kUsageEntryInfoOfflineLicense4, kUsageEntryInfoEmpty, + kUsageEntryInfoEmpty, kUsageEntryInfoOfflineLicense2, + kUsageEntryInfoOfflineLicense3))) .WillOnce(Return(true)); EXPECT_EQ(NO_ERROR, usage_table_header_->InvalidateEntry( @@ -2121,7 +1956,7 @@ TEST_F(UsageTableHeaderTest, &metrics)); // Check the end state of the usage table. constexpr size_t expected_size = 5; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_header_->entry_info_list().size()); } // Initial Test state: @@ -2129,7 +1964,7 @@ TEST_F(UsageTableHeaderTest, // 2. Last entries are valid offline licenses. // // Attempting to delete the entry in (1) will result in: -// a. The entry will be marked as kStorageTypeUnknown. +// a. The entry will be cleared. // b. While defragging, offline licenses 2 and 3 will be selected to be // moved. // c. The selected entries will be moved. @@ -2137,11 +1972,11 @@ TEST_F(UsageTableHeaderTest, // e. Updated table will be saved. // f. InvalidateEntry() will return NO_ERROR. // -// Storage type Usage entries +// Entry type Usage entries // at start at end // ============= ======== ====== -// Secure Stop 1 0 0 -// Storage Type unknown 1 Deleted +// Offline License 4 0 0 +// Clear entry 1 Deleted // Offline License 1 2 Deleted // Offline License 2 3 2 (moved) // Offline License 3 4 1 (moved) @@ -2149,7 +1984,7 @@ TEST_F(UsageTableHeaderTest, // # of usage entries 5 3 TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntryIsOffline) { const std::vector usage_entry_info_vector = { - kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown, + kUsageEntryInfoOfflineLicense4, kUsageEntryInfoEmpty, kUsageEntryInfoOfflineLicense1, kUsageEntryInfoOfflineLicense2, kUsageEntryInfoOfflineLicense3}; @@ -2160,7 +1995,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntryIsOffline) { // Expect calls for moving offline license 3 (position 4) to position 1. const DeviceFiles::CdmLicenseData offline_license_3_data{ - kUsageEntryInfoOfflineLicense3.key_set_id, + kUsageEntryInfoOfflineLicense3.key_set_id(), kActiveLicenseState, kPsshData, kKeyRequest, @@ -2177,7 +2012,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntryIsOffline) { kDrmCertificate, kCryptoWrappedKey}; EXPECT_CALL(*device_files_, - RetrieveLicense(kUsageEntryInfoOfflineLicense3.key_set_id, + RetrieveLicense(kUsageEntryInfoOfflineLicense3.key_set_id(), NotNull(), NotNull())) .Times(2) // First to get entry, then again to update. .WillRepeatedly( @@ -2188,7 +2023,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntryIsOffline) { // Expect calls for moving offline license 2 (position 3) to position 2. const DeviceFiles::CdmLicenseData offline_license_2_data{ - kUsageEntryInfoOfflineLicense2.key_set_id, + kUsageEntryInfoOfflineLicense2.key_set_id(), kActiveLicenseState, kPsshData, kKeyRequest, @@ -2205,7 +2040,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntryIsOffline) { kDrmCertificate, kCryptoWrappedKey}; EXPECT_CALL(*device_files_, - RetrieveLicense(kUsageEntryInfoOfflineLicense2.key_set_id, + RetrieveLicense(kUsageEntryInfoOfflineLicense2.key_set_id(), NotNull(), NotNull())) .Times(2) // First to get entry, then again to update. .WillRepeatedly( @@ -2237,7 +2072,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntryIsOffline) { DoAll(SetArgPointee<2>(kYetAnotherUsageEntry), Return(NO_ERROR))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kYetAnotherUsageEntry, - ElementsAre(kUsageEntryInfoSecureStop1, + ElementsAre(kUsageEntryInfoOfflineLicense4, kUsageEntryInfoOfflineLicense3, kUsageEntryInfoOfflineLicense2))) .WillOnce(Return(true)); @@ -2247,16 +2082,16 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntryIsOffline) { &metrics)); // Check the end state of the usage table. constexpr size_t expected_size = 3; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_header_->entry_info_list().size()); } // Initial Test state: // 1. Usage entry to be deleted is not last. -// 2. Last few entries are of storage type unknown. +// 2. Last few entries are clear. // 3. Entry that precedes those in (2) is an offline license. // // Attempting to delete the entry in (1) will result in: -// a. The entry will be marked as kStorageTypeUnknown. +// a. The entry will be cleared. // b. While defragging, offline licenses 2 and 3 will be selected to be // moved. // c. The selected entries will be moved. @@ -2264,25 +2099,27 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntryIsOffline) { // e. Updated table will be saved. // f. InvalidateEntry() will return NO_ERROR. // -// Storage type Usage entries +// Entry type Usage entries // at start at end // ============= ======== ====== -// Secure Stop 1 0 0 -// Storage Type Unknown 1 Deleted +// Offline License 4 0 0 +// Clear entry 1 Deleted // Offline License 1 2 Deleted // Offline License 2 3 2 (moved) // Offline License 3 4 1 (moved) -// Storage Type Unknown 5 Deleted -// Storage Type Unknown 6 Deleted +// Clear entry 5 Deleted +// Clear entry 6 Deleted // // # of usage entries 7 4 -TEST_F(UsageTableHeaderTest, - InvalidateEntry_LastEntriesAreOfflineAndUnknknown) { +TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntriesAreOfflineAndClear) { const std::vector usage_entry_info_vector = { - kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown, - kUsageEntryInfoOfflineLicense1, kUsageEntryInfoOfflineLicense2, - kUsageEntryInfoOfflineLicense3, kUsageEntryInfoStorageTypeUnknown, - kUsageEntryInfoStorageTypeUnknown}; + kUsageEntryInfoOfflineLicense4, + kUsageEntryInfoEmpty, + kUsageEntryInfoOfflineLicense1, + kUsageEntryInfoOfflineLicense2, + kUsageEntryInfoOfflineLicense3, + kUsageEntryInfoEmpty, + kUsageEntryInfoEmpty}; Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); const uint32_t usage_entry_number_to_be_deleted = @@ -2291,7 +2128,7 @@ TEST_F(UsageTableHeaderTest, // Expect calls for moving offline license 3 (position 4) to position 1. const DeviceFiles::CdmLicenseData offline_license_3_data{ - kUsageEntryInfoOfflineLicense3.key_set_id, + kUsageEntryInfoOfflineLicense3.key_set_id(), kActiveLicenseState, kPsshData, kKeyRequest, @@ -2308,7 +2145,7 @@ TEST_F(UsageTableHeaderTest, kDrmCertificate, kCryptoWrappedKey}; EXPECT_CALL(*device_files_, - RetrieveLicense(kUsageEntryInfoOfflineLicense3.key_set_id, + RetrieveLicense(kUsageEntryInfoOfflineLicense3.key_set_id(), NotNull(), NotNull())) .Times(2) // First to get entry, then again to update. .WillRepeatedly( @@ -2319,7 +2156,7 @@ TEST_F(UsageTableHeaderTest, // Expect calls for moving offline license 2 (position 3) to position 2. const DeviceFiles::CdmLicenseData offline_license_2_data{ - kUsageEntryInfoOfflineLicense2.key_set_id, + kUsageEntryInfoOfflineLicense2.key_set_id(), kActiveLicenseState, kPsshData, kKeyRequest, @@ -2336,7 +2173,7 @@ TEST_F(UsageTableHeaderTest, kDrmCertificate, kCryptoWrappedKey}; EXPECT_CALL(*device_files_, - RetrieveLicense(kUsageEntryInfoOfflineLicense2.key_set_id, + RetrieveLicense(kUsageEntryInfoOfflineLicense2.key_set_id(), NotNull(), NotNull())) .Times(2) // First to get entry, then again to update. .WillRepeatedly( @@ -2368,7 +2205,7 @@ TEST_F(UsageTableHeaderTest, DoAll(SetArgPointee<2>(kYetAnotherUsageEntry), Return(NO_ERROR))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kYetAnotherUsageEntry, - ElementsAre(kUsageEntryInfoSecureStop1, + ElementsAre(kUsageEntryInfoOfflineLicense4, kUsageEntryInfoOfflineLicense3, kUsageEntryInfoOfflineLicense2))) .WillOnce(Return(true)); @@ -2378,42 +2215,42 @@ TEST_F(UsageTableHeaderTest, &metrics)); // Check the end state of the usage table. constexpr size_t expected_size = 3; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_header_->entry_info_list().size()); } // Initial Test state: -// 1. Usage entry to be deleted is not last (Secure stop 1) +// 1. Usage entry to be deleted is not last (Offline License 1) // 2. All other entries are invalid. // // Attempting to delete the entry in (1) will result in: -// a. The entry will be marked as kStorageTypeUnknown. +// a. The entry will be cleared. // b. Defrag is skipped (no calls to Move()). // c. Usage table will be resized. // e. Updated table will be saved. // f. InvalidateEntry() will return NO_ERROR. // -// Storage type Usage entries +// Entry type Usage entries // at start at end // ============= ======== ====== -// Storage Type Unknown 0 Deleted -// Storage Type Unknown 1 Deleted -// Storage Type Unknown 2 Deleted -// Secure stop 1 3 Deleted -// Storage Type Unknown 4 Deleted -// Storage Type Unknown 5 Deleted -// Storage Type Unknown 6 Deleted +// Clear entry 0 Deleted +// Clear entry 1 Deleted +// Clear entry 2 Deleted +// Offline License 1 3 Deleted +// Clear entry 4 Deleted +// Clear entry 5 Deleted +// Clear entry 6 Deleted // // # of usage entries 7 0 TEST_F(UsageTableHeaderTest, InvalidateEntry_NoValidSessionsAfter) { const std::vector usage_entry_info_vector = { - kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoStorageTypeUnknown, - kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoSecureStop1, - kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoStorageTypeUnknown, - kUsageEntryInfoStorageTypeUnknown}; + kUsageEntryInfoEmpty, kUsageEntryInfoEmpty, + kUsageEntryInfoEmpty, kUsageEntryInfoOfflineLicense1, + kUsageEntryInfoEmpty, kUsageEntryInfoEmpty, + kUsageEntryInfoEmpty}; Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); const uint32_t usage_entry_number_to_be_deleted = - 3; // kUsageEntryInfoSecureStop1 + 3; // kUsageEntryInfoOfflineLicense1 metrics::CryptoMetrics metrics; // No calls related to defragging, just shrinking the table and save. @@ -2429,16 +2266,16 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_NoValidSessionsAfter) { EXPECT_EQ(NO_ERROR, usage_table_header_->InvalidateEntry( usage_entry_number_to_be_deleted, true, device_files_, &metrics)); - EXPECT_TRUE(usage_table_header_->usage_entry_info().empty()); + EXPECT_TRUE(usage_table_header_->entry_info_list().empty()); } -// 1. Usage entry to be deleted is last valid entry (Secure stop 1) +// 1. Usage entry to be deleted is last valid entry (Offline License 2) // 2. There exists an entry to be moved (Offline License 1) // 3. OEMCrypto is at max sessions, and any attempt to open a new session // will fail with INSUFFICIENT_CRYPTO_RESOURCES. // // Attempting to delete the entry in (1) will result in: -// a. The entry will be marked as kStorageTypeUnknown. +// a. The entry will be cleared. // b. Only remaining entry is selected for move (Offline license 1) // c. Opening session for move will fail. // d. Defrag is aborted; but shrink is still made up to last valid. @@ -2446,29 +2283,29 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_NoValidSessionsAfter) { // f. Updated table will be saved. // g. InvalidateEntry() will return NO_ERROR. // -// Storage type Usage entries +// Entry type Usage entries // at start at end // ============= ======== ====== -// Storage Type Unknown 0 0 +// Clear entry 0 0 // Offline License 1 1 1 -// Secure Stop 1 2 Deleted -// Storage Type Unknown 3 Deleted +// Offline License 2 2 Deleted +// Clear entry 3 Deleted // // # of usage entries 4 2 TEST_F(UsageTableHeaderTest, InvalidateEntry_MaxSessionReached) { const std::vector usage_entry_info_vector = { - kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense1, - kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown}; + kUsageEntryInfoEmpty, kUsageEntryInfoOfflineLicense1, + kUsageEntryInfoOfflineLicense2, kUsageEntryInfoEmpty}; Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); const uint32_t usage_entry_number_to_be_deleted = - 2; // kUsageEntryInfoSecureStop1 + 2; // kUsageEntryInfoOfflineLicense2 metrics::CryptoMetrics metrics; // Expected calls for moving offline license 1 (position 1) to position 0. // But will fail when opening a crypto session. const DeviceFiles::CdmLicenseData offline_license_1_data{ - kUsageEntryInfoOfflineLicense1.key_set_id, + kUsageEntryInfoOfflineLicense1.key_set_id(), kActiveLicenseState, kPsshData, kKeyRequest, @@ -2485,7 +2322,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_MaxSessionReached) { kDrmCertificate, kCryptoWrappedKey}; EXPECT_CALL(*device_files_, - RetrieveLicense(kUsageEntryInfoOfflineLicense1.key_set_id, + RetrieveLicense(kUsageEntryInfoOfflineLicense1.key_set_id(), NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<1>(offline_license_1_data), Return(true))); EXPECT_CALL(*crypto_session_, Open(kLevelDefault)) @@ -2499,7 +2336,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_MaxSessionReached) { DoAll(SetArgPointee<2>(kAnotherUsageTableHeader), Return(NO_ERROR))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader, - ElementsAre(kUsageEntryInfoStorageTypeUnknown, + ElementsAre(kUsageEntryInfoEmpty, kUsageEntryInfoOfflineLicense1))) .WillOnce(Return(true)); @@ -2508,46 +2345,46 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_MaxSessionReached) { &metrics)); // Check the end state of the usage table. constexpr size_t expected_size = 2; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_header_->entry_info_list().size()); } -// 1. Usage entry to be deleted is first valid entry (Secure stop 1) -// 2. There exists an entry to be moved (Offline License 1) +// 1. Usage entry to be deleted is first valid entry (Offline License 1) +// 2. There exists an entry to be moved (Offline License 2) // 3. OEMCrypto is at max sessions, and any attempt to open a new session // will fail with INSUFFICIENT_CRYPTO_RESOURCES. // // Attempting to delete the entry in (1) will result in: -// a. The entry will be marked as kStorageTypeUnknown. -// b. Only remaining entry is selected for move (Offline license 1) +// a. The entry will be cleared. +// b. Only remaining entry is selected for move (Offline license 2) // c. Opening session for move will fail. // d. Defrag is aborted; but shrink is still made up to last valid. // e. Usage table will be resized. // f. Updated table will be saved. // g. InvalidateEntry() will return NO_ERROR. // -// Storage type Usage entries +// Entry type Usage entries // at start at end // ============= ======== ====== -// Secure Stop 1 0 0 (Storage type unknown) -// Offline License 1 1 1 (Failed to move) -// Storage Type Unknown 2 Deleted -// Storage Type Unknown 3 Deleted +// Offline License 1 0 0 (cleared) +// Offline License 2 1 1 (Failed to move) +// Clear entry 2 Deleted +// Clear entry 3 Deleted // // # of usage entries 4 2 TEST_F(UsageTableHeaderTest, InvalidateEntry_FirstEntry_MaxSessionReached) { const std::vector usage_entry_info_vector = { - kUsageEntryInfoSecureStop1, kUsageEntryInfoOfflineLicense1, - kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoStorageTypeUnknown}; + kUsageEntryInfoOfflineLicense1, kUsageEntryInfoOfflineLicense2, + kUsageEntryInfoEmpty, kUsageEntryInfoEmpty}; Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); const uint32_t usage_entry_number_to_be_deleted = - 0; // kUsageEntryInfoSecureStop1 + 0; // kUsageEntryInfoOfflineLicense1 metrics::CryptoMetrics metrics; - // Expected calls for moving offline license 1 (position 1) to position 0. + // Expected calls for moving offline license 2 (position 2) to position 0. // But will fail when opening a crypto session. - const DeviceFiles::CdmLicenseData offline_license_1_data{ - kUsageEntryInfoOfflineLicense1.key_set_id, + const DeviceFiles::CdmLicenseData offline_license_2_data{ + kUsageEntryInfoOfflineLicense2.key_set_id(), kActiveLicenseState, kPsshData, kKeyRequest, @@ -2564,9 +2401,9 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_FirstEntry_MaxSessionReached) { kDrmCertificate, kCryptoWrappedKey}; EXPECT_CALL(*device_files_, - RetrieveLicense(kUsageEntryInfoOfflineLicense1.key_set_id, + RetrieveLicense(kUsageEntryInfoOfflineLicense2.key_set_id(), NotNull(), NotNull())) - .WillOnce(DoAll(SetArgPointee<1>(offline_license_1_data), Return(true))); + .WillOnce(DoAll(SetArgPointee<1>(offline_license_2_data), Return(true))); EXPECT_CALL(*crypto_session_, Open(kLevelDefault)) .WillRepeatedly(Return(INSUFFICIENT_CRYPTO_RESOURCES)); @@ -2578,8 +2415,8 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_FirstEntry_MaxSessionReached) { DoAll(SetArgPointee<2>(kAnotherUsageTableHeader), Return(NO_ERROR))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader, - ElementsAre(kUsageEntryInfoStorageTypeUnknown, - kUsageEntryInfoOfflineLicense1))) + ElementsAre(kUsageEntryInfoEmpty, + kUsageEntryInfoOfflineLicense2))) .WillOnce(Return(true)); EXPECT_EQ(NO_ERROR, usage_table_header_->InvalidateEntry( @@ -2587,15 +2424,15 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_FirstEntry_MaxSessionReached) { &metrics)); // Check the end state of the usage table. constexpr size_t expected_size = 2; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_header_->entry_info_list().size()); } -// 1. Usage entry to be deleted is last valid entry (Secure stop 1) +// 1. Usage entry to be deleted is last valid entry (Offline License 2) // 2. There exists an entry to be moved (Offline License 1) // 3. Moving entry will result in a system invalidation error. // // Attempting to delete the entry in (1) will result in: -// a. The entry will be marked as kStorageTypeUnknown. +// a. The entry will be cleared. // b. Only remaining entry is selected for move (Offline license 1) // c. Moving entry will result in system invalidation. // d. Defrag is aborted; no call to Shrink() @@ -2605,26 +2442,26 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_FirstEntry_MaxSessionReached) { // Storage type Usage entries // at start at end // ============= ======== ====== -// Storage Type Unknown 0 0 +// Clear entry 0 0 // Offline License 1 1 1 -// Secure Stop 1 2 2 (Storage Type Unknown) -// Storage Type Unknown 3 3 +// Offline License 2 2 2 (cleared) +// Clear entry 3 3 // // # of usage entries 4 4 TEST_F(UsageTableHeaderTest, InvalidateEntry_SystemInvalidation_OnMove) { const std::vector usage_entry_info_vector = { - kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense1, - kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown}; + kUsageEntryInfoEmpty, kUsageEntryInfoOfflineLicense1, + kUsageEntryInfoOfflineLicense2, kUsageEntryInfoEmpty}; Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); const uint32_t usage_entry_number_to_be_deleted = - 2; // kUsageEntryInfoSecureStop1 + 2; // kUsageEntryInfoOfflineLicense2 metrics::CryptoMetrics metrics; // Expected calls for moving offline license 1 (position 1) to position 0. // But will fail when moving. const DeviceFiles::CdmLicenseData offline_license_1_data{ - kUsageEntryInfoOfflineLicense1.key_set_id, + kUsageEntryInfoOfflineLicense1.key_set_id(), kActiveLicenseState, kPsshData, kKeyRequest, @@ -2641,7 +2478,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_SystemInvalidation_OnMove) { kDrmCertificate, kCryptoWrappedKey}; EXPECT_CALL(*device_files_, - RetrieveLicense(kUsageEntryInfoOfflineLicense1.key_set_id, + RetrieveLicense(kUsageEntryInfoOfflineLicense1.key_set_id(), NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<1>(offline_license_1_data), Return(true))); EXPECT_CALL(*crypto_session_, Open(kLevelDefault)).WillOnce(Return(NO_ERROR)); @@ -2652,11 +2489,10 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_SystemInvalidation_OnMove) { // Defrag is aborted, and table is saved, but no call to shrink(). EXPECT_CALL( *device_files_, - StoreUsageTableInfo(kUsageTableHeader, - ElementsAre(kUsageEntryInfoStorageTypeUnknown, - kUsageEntryInfoOfflineLicense1, - kUsageEntryInfoStorageTypeUnknown, - kUsageEntryInfoStorageTypeUnknown))) + StoreUsageTableInfo( + kUsageTableHeader, + ElementsAre(kUsageEntryInfoEmpty, kUsageEntryInfoOfflineLicense1, + kUsageEntryInfoEmpty, kUsageEntryInfoEmpty))) .WillOnce(Return(true)); EXPECT_EQ(SYSTEM_INVALIDATED_ERROR, usage_table_header_->InvalidateEntry( @@ -2664,10 +2500,10 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_SystemInvalidation_OnMove) { true, device_files_, &metrics)); // Check the end state of the usage table. constexpr size_t expected_size = 4; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_header_->entry_info_list().size()); } -// 1. Usage entry to be deleted is last valid entry (Secure stop 1) +// 1. Usage entry to be deleted is last valid entry (Offline License 2) // 2. There exists an entry to be moved (Offline License 1) // 3. Moving entry will result in a session invalidation error. // @@ -2676,7 +2512,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_SystemInvalidation_OnMove) { // session and is ignored (NO_ERROR returned). // // Attempting to delete the entry in (1) will result in: -// a. The entry will be marked as kStorageTypeUnknown. +// a. The entry will be cleared. // b. Only remaining entry is selected for move (Offline license 1) // c. Moving entry will result in session invalidation. // d. Defrag is aborted; no call to Shrink() @@ -2686,26 +2522,26 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_SystemInvalidation_OnMove) { // Storage type Usage entries // at start at end // ============= ======== ====== -// Storage Type Unknown 0 0 +// Clear entry 0 0 // Offline License 1 1 1 -// Secure Stop 1 2 2 (Storage Type Unknown) -// Storage Type Unknown 3 3 +// Offline License 2 2 2 (cleared) +// Clear entry 3 3 // // # of usage entries 4 4 TEST_F(UsageTableHeaderTest, InvalidateEntry_SessionInvalidation_OnMove) { const std::vector usage_entry_info_vector = { - kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense1, - kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown}; + kUsageEntryInfoEmpty, kUsageEntryInfoOfflineLicense1, + kUsageEntryInfoOfflineLicense2, kUsageEntryInfoEmpty}; Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); const uint32_t usage_entry_number_to_be_deleted = - 2; // kUsageEntryInfoSecureStop1 + 2; // kUsageEntryInfoOfflineLicense2 metrics::CryptoMetrics metrics; // Expected calls for moving offline license 1 (position 1) to position 0. // But will fail when moving. const DeviceFiles::CdmLicenseData offline_license_1_data{ - kUsageEntryInfoOfflineLicense1.key_set_id, + kUsageEntryInfoOfflineLicense1.key_set_id(), kActiveLicenseState, kPsshData, kKeyRequest, @@ -2722,7 +2558,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_SessionInvalidation_OnMove) { kDrmCertificate, kCryptoWrappedKey}; EXPECT_CALL(*device_files_, - RetrieveLicense(kUsageEntryInfoOfflineLicense1.key_set_id, + RetrieveLicense(kUsageEntryInfoOfflineLicense1.key_set_id(), NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<1>(offline_license_1_data), Return(true))); EXPECT_CALL(*crypto_session_, Open(kLevelDefault)).WillOnce(Return(NO_ERROR)); @@ -2733,11 +2569,10 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_SessionInvalidation_OnMove) { // Defrag is aborted, and table is saved, but no call to shrink(). EXPECT_CALL( *device_files_, - StoreUsageTableInfo(kUsageTableHeader, - ElementsAre(kUsageEntryInfoStorageTypeUnknown, - kUsageEntryInfoOfflineLicense1, - kUsageEntryInfoStorageTypeUnknown, - kUsageEntryInfoStorageTypeUnknown))) + StoreUsageTableInfo( + kUsageTableHeader, + ElementsAre(kUsageEntryInfoEmpty, kUsageEntryInfoOfflineLicense1, + kUsageEntryInfoEmpty, kUsageEntryInfoEmpty))) .WillOnce(Return(true)); // The underlying error should not be returned to the caller. @@ -2746,15 +2581,15 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_SessionInvalidation_OnMove) { &metrics)); // Check the end state of the usage table. constexpr size_t expected_size = 4; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_header_->entry_info_list().size()); } -// 1. Usage entry to be deleted is last valid entry (Secure stop 1) +// 1. Usage entry to be deleted is last valid entry (Offline License 2) // 2. There exists an entry to be moved (Offline License 1) // 3. Shrinking table will fail due to an unspecified entry being in use. // // Attempting to delete the entry in (1) will result in: -// a. The entry will be marked as kStorageTypeUnknown. +// a. The entry will be cleared. // b. Only remaining entry is selected for move (Offline license 1) // c. Entry will be moved successfully. // d. Shrinking table fill fail with SHRINK_USAGE_TABLE_HEADER_ENTRY_IN_USE. @@ -2764,25 +2599,25 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_SessionInvalidation_OnMove) { // Storage type Usage entries // at start at end // ============= ======== ====== -// Storage Type Unknown 0 1 (swapped Offline License 1) +// Clear entry 0 1 (swapped with Offline License 1) // Offline License 1 1 0 (moved) -// Secure Stop 1 2 2 (Storage Type Unknown) -// Storage Type Unknown 3 3 +// Offline License 2 2 2 (cleared) +// Clear entry 3 3 // // # of usage entries 4 4 TEST_F(UsageTableHeaderTest, InvalidateEntry_ShrinkFails) { const std::vector usage_entry_info_vector = { - kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense1, - kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown}; + kUsageEntryInfoEmpty, kUsageEntryInfoOfflineLicense1, + kUsageEntryInfoOfflineLicense2, kUsageEntryInfoEmpty}; Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); const uint32_t usage_entry_number_to_be_deleted = - 2; // kUsageEntryInfoSecureStop1 + 2; // kUsageEntryInfoOfflineLicense2 metrics::CryptoMetrics metrics; // Expected calls for moving offline license 1 (position 1) to position 0. const DeviceFiles::CdmLicenseData offline_license_1_data{ - kUsageEntryInfoOfflineLicense1.key_set_id, + kUsageEntryInfoOfflineLicense1.key_set_id(), kActiveLicenseState, kPsshData, kKeyRequest, @@ -2799,7 +2634,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_ShrinkFails) { kDrmCertificate, kCryptoWrappedKey}; EXPECT_CALL(*device_files_, - RetrieveLicense(kUsageEntryInfoOfflineLicense1.key_set_id, + RetrieveLicense(kUsageEntryInfoOfflineLicense1.key_set_id(), NotNull(), NotNull())) .Times(2) // First to get entry, then again to update. .WillRepeatedly( @@ -2812,11 +2647,10 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_ShrinkFails) { SetArgPointee<1>(kUsageEntry), Return(NO_ERROR))); EXPECT_CALL( *device_files_, - StoreUsageTableInfo(kAnotherUsageTableHeader, - ElementsAre(kUsageEntryInfoOfflineLicense1, - kUsageEntryInfoStorageTypeUnknown, - kUsageEntryInfoStorageTypeUnknown, - kUsageEntryInfoStorageTypeUnknown))) + StoreUsageTableInfo( + kAnotherUsageTableHeader, + ElementsAre(kUsageEntryInfoOfflineLicense1, kUsageEntryInfoEmpty, + kUsageEntryInfoEmpty, kUsageEntryInfoEmpty))) .WillOnce(Return(true)); EXPECT_CALL(*device_files_, StoreLicense(_, NotNull())) .WillOnce(Return(true)); @@ -2832,16 +2666,16 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_ShrinkFails) { &metrics)); // Check the end state of the usage table. constexpr size_t expected_size = 4; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_header_->entry_info_list().size()); } -// 1. Usage entry to be deleted is last valid entry (Secure stop 1) +// 1. Usage entry to be deleted is last valid entry (Offline License 2) // 2. There exists an entry to be moved (Offline License 1) // 3. Moving entry cannot be done as the destination is in use. // (this is unexpected but possible in normal operation) // // Attempting to delete the entry in (1) will result in: -// a. The entry will be marked as kStorageTypeUnknown. +// a. The entry will be cleared. // b. Only remaining entry is selected for move (Offline license 1) // c. Call to move will fail with MOVE_USAGE_ENTRY_DESTINATION_IN_USE. // d. Usage table will be resized. @@ -2851,26 +2685,26 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_ShrinkFails) { // Storage type Usage entries // at start at end // ============= ======== ====== -// Storage Type Unknown 0 0 +// Clear entry 0 0 // Offline License 1 1 1 (unable to move) -// Secure Stop 1 2 Deleted -// Storage Type Unknown 3 Deleted +// Offline License 2 2 Deleted +// Clear entry 3 Deleted // // # of usage entries 4 2 TEST_F(UsageTableHeaderTest, InvalidateEntry_DestinationInUse_OnMove) { const std::vector usage_entry_info_vector = { - kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense1, - kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown}; + kUsageEntryInfoEmpty, kUsageEntryInfoOfflineLicense1, + kUsageEntryInfoOfflineLicense2, kUsageEntryInfoEmpty}; Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); const uint32_t usage_entry_number_to_be_deleted = - 2; // kUsageEntryInfoSecureStop1 + 2; // kUsageEntryInfoOfflineLicense2 metrics::CryptoMetrics metrics; // Expected calls for moving offline license 1 (position 1) to position 0. // But will fail due to the destination being in use. const DeviceFiles::CdmLicenseData offline_license_1_data{ - kUsageEntryInfoOfflineLicense1.key_set_id, + kUsageEntryInfoOfflineLicense1.key_set_id(), kActiveLicenseState, kPsshData, kKeyRequest, @@ -2887,7 +2721,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_DestinationInUse_OnMove) { kDrmCertificate, kCryptoWrappedKey}; EXPECT_CALL(*device_files_, - RetrieveLicense(kUsageEntryInfoOfflineLicense1.key_set_id, + RetrieveLicense(kUsageEntryInfoOfflineLicense1.key_set_id(), NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<1>(offline_license_1_data), Return(true))); EXPECT_CALL(*crypto_session_, Open(kLevelDefault)).WillOnce(Return(NO_ERROR)); @@ -2903,7 +2737,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_DestinationInUse_OnMove) { .WillOnce(DoAll(SetArgPointee<2>(kAnotherUsageEntry), Return(NO_ERROR))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageEntry, - ElementsAre(kUsageEntryInfoStorageTypeUnknown, + ElementsAre(kUsageEntryInfoEmpty, kUsageEntryInfoOfflineLicense1))) .WillOnce(Return(true)); @@ -2912,18 +2746,18 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_DestinationInUse_OnMove) { &metrics)); // Check the end state of the usage table. constexpr size_t expected_size = 2; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_header_->entry_info_list().size()); } -// If the crypto session says the usage table header is stale, init should fail. +// If the crypto session says the usage table header is stale +// (generation skew), restoring table should fail. Table will created +// a new usage table / header. TEST_F(UsageTableHeaderTest, StaleHeader) { - std::vector usage_entry_info_vector; - const CdmUsageEntryInfo usage_entry_info_array[] = { - kUsageEntryInfoOfflineLicense1, kUsageEntryInfoSecureStop1, - kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense2}; - ToVector(usage_entry_info_vector, usage_entry_info_array, - sizeof(usage_entry_info_array)); + const std::vector usage_entry_info_vector = { + kUsageEntryInfoOfflineLicense1, kUsageEntryInfoOfflineLicense2, + kUsageEntryInfoEmpty, kUsageEntryInfoOfflineLicense3}; + // Expectations for initial checks. EXPECT_CALL(*crypto_session_, GetNumberOfOpenSessions(kLevelDefault, NotNull())) .WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR))); @@ -2936,6 +2770,7 @@ TEST_F(UsageTableHeaderTest, StaleHeader) { EXPECT_CALL(*crypto_session_, LoadUsageTableHeader(kLevelDefault, kUsageTableHeader)) .WillOnce(Return(LOAD_USAGE_HEADER_GENERATION_SKEW)); + // Expectations for clear old table data and creating new table. ExpectToDeleteUsageTableFiles(); EXPECT_CALL(*crypto_session_, CreateUsageTableHeader(kLevelDefault, NotNull())) @@ -2951,7 +2786,7 @@ TEST_F(UsageTableHeaderTest, StaleHeader) { // Testing of the private function UsageTableHeader::Shrink. // Don't shrink any entries. TEST_F(UsageTableHeaderTest, Shrink_NoneOfTable) { - Init(kSecurityLevelL1, kUsageTableHeader, k10UsageEntryInfoVector); + Init(kSecurityLevelL1, kUsageTableHeader, k5UsageEntryInfoVector); metrics::CryptoMetrics metrics; // These calls are "expensive" and should be avoided if possible. @@ -2966,11 +2801,11 @@ TEST_F(UsageTableHeaderTest, Shrink_NoneOfTable) { // Shrink some of the table, but not all of it. TEST_F(UsageTableHeaderTest, Shrink_PartOfTable) { - Init(kSecurityLevelL1, kUsageTableHeader, k10UsageEntryInfoVector); + Init(kSecurityLevelL1, kUsageTableHeader, k5UsageEntryInfoVector); const uint32_t to_shink = 5; const std::vector shrunken_entries( - k10UsageEntryInfoVector.cbegin(), - k10UsageEntryInfoVector.cend() - to_shink); + k5UsageEntryInfoVector.cbegin(), + k5UsageEntryInfoVector.cend() - to_shink); metrics::CryptoMetrics metrics; EXPECT_CALL(*crypto_session_, @@ -2987,7 +2822,7 @@ TEST_F(UsageTableHeaderTest, Shrink_PartOfTable) { // Shrink all of the table, no entries left. TEST_F(UsageTableHeaderTest, Shrink_AllOfTable) { - Init(kSecurityLevelL1, kUsageTableHeader, k10UsageEntryInfoVector); + Init(kSecurityLevelL1, kUsageTableHeader, k5UsageEntryInfoVector); metrics::CryptoMetrics metrics; EXPECT_CALL(*crypto_session_, @@ -2997,16 +2832,15 @@ TEST_F(UsageTableHeaderTest, Shrink_AllOfTable) { kEmptyUsageEntryInfoVector)) .WillOnce(Return(true)); - EXPECT_EQ( - usage_table_header_->Shrink( - &metrics, static_cast(k10UsageEntryInfoVector.size())), - NO_ERROR); + EXPECT_EQ(usage_table_header_->Shrink( + &metrics, static_cast(k5UsageEntryInfoVector.size())), + NO_ERROR); } // Request to shrink more entries than there are in the table; should remove // all entries, but log a warning. TEST_F(UsageTableHeaderTest, Shrink_MoreThanTable) { - Init(kSecurityLevelL1, kUsageTableHeader, k10UsageEntryInfoVector); + Init(kSecurityLevelL1, kUsageTableHeader, k5UsageEntryInfoVector); metrics::CryptoMetrics metrics; EXPECT_CALL(*crypto_session_, ShrinkUsageTableHeader(kLevelDefault, 0, NotNull())) @@ -3017,7 +2851,7 @@ TEST_F(UsageTableHeaderTest, Shrink_MoreThanTable) { EXPECT_EQ( usage_table_header_->Shrink( - &metrics, static_cast(k10UsageEntryInfoVector.size()) + 10), + &metrics, static_cast(k5UsageEntryInfoVector.size()) + 10), NO_ERROR); } @@ -3045,7 +2879,7 @@ TEST_F(UsageTableHeaderTest, LruUsageTableUpgrade_NoAction) { EXPECT_CALL(*device_files_, RetrieveLicense(_, _, _)).Times(0); EXPECT_TRUE(usage_table_header_->Init(kSecurityLevelL1, crypto_session_)); - EXPECT_EQ(usage_table_header_->usage_entry_info(), + EXPECT_EQ(usage_table_header_->entry_info_list(), kUpgradableUsageEntryInfoList); } @@ -3074,17 +2908,17 @@ TEST_F(UsageTableHeaderTest, LruUsageTableUpgrade_Succeed) { for (size_t i = 0; i < kUpgradableUsageEntryInfoList.size(); ++i) { const CdmUsageEntryInfo& info = kUpgradableUsageEntryInfoList[i]; - if (info.storage_type == kStorageLicense) { - // Only offline licenses are supported. + if (info.HasKeySetId()) { + // Only entries with a key set ID will be retrieved. EXPECT_CALL(*device_files_, - RetrieveLicense(info.key_set_id, NotNull(), NotNull())) + RetrieveLicense(info.key_set_id(), NotNull(), NotNull())) .WillOnce( DoAll(SetArgPointee<1>(license_info_list[i]), Return(true))); } } EXPECT_TRUE(usage_table_header_->Init(kSecurityLevelL1, crypto_session_)); - EXPECT_EQ(usage_table_header_->usage_entry_info(), + EXPECT_EQ(usage_table_header_->entry_info_list(), kUpgradedUsageEntryInfoList); } @@ -3092,19 +2926,17 @@ TEST_F(UsageTableHeaderTest, LruUsageTableUpgrade_Succeed) { // Table info is load from device files and must be upgraded. // A few entries have the unknown storage type value. // -// Entry# Storage type Result info +// Entry# Entry type Result info // ====== ============ =========== // 0 Offline Upgraded -// 1 Unknown Cleared -// 2 Unknown Cleared +// 1 Clear Cleared +// 2 Clear Cleared TEST_F(UsageTableHeaderTest, LruUsageTableUpgrade_PartialSucceedWithUnknownStorageTypes) { const std::vector upgradable_usage_entry_info_list = { - kUpgradableUsageEntryInfo1, kUsageEntryInfoStorageTypeUnknown, - kUsageEntryInfoStorageTypeUnknown}; + kUpgradableUsageEntryInfo1, kUsageEntryInfoEmpty, kUsageEntryInfoEmpty}; const std::vector upgraded_usage_entry_info_list = { - kUpgradedUsageEntryInfo1, kUsageEntryInfoStorageTypeUnknown, - kUsageEntryInfoStorageTypeUnknown}; + kUpgradedUsageEntryInfo1, kUsageEntryInfoEmpty, kUsageEntryInfoEmpty}; // Load table expectations. EXPECT_CALL(*crypto_session_, @@ -3124,13 +2956,13 @@ TEST_F(UsageTableHeaderTest, const std::vector license_info_list = CreateUpgradableLicenseInfoList(); EXPECT_CALL(*device_files_, - RetrieveLicense(upgradable_usage_entry_info_list[0].key_set_id, + RetrieveLicense(upgradable_usage_entry_info_list[0].key_set_id(), NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<1>(license_info_list[0]), Return(true))); EXPECT_TRUE(usage_table_header_->Init(kSecurityLevelL1, crypto_session_)); EXPECT_EQ(upgraded_usage_entry_info_list, - usage_table_header_->usage_entry_info()); + usage_table_header_->entry_info_list()); } // Initial Test state: @@ -3139,10 +2971,10 @@ TEST_F(UsageTableHeaderTest, // 2. During the LRU upgrade process, any license that cannot be // validated are cleared, and marked to be deleted. // -// Entry# Storage type License Issue Result info +// Entry# Entry type License Issue Result info // ====== ============ ============= =========== // 0 Offline No signature Cleared -// 1 Unknown Clear entry Cleared +// 1 Clear Clear entry Cleared // 2 Offline Upgraded TEST_F(UsageTableHeaderTest, LruUsageTableUpgrade_PartialSucceedWithLicenseParseIssues) { @@ -3179,9 +3011,9 @@ TEST_F(UsageTableHeaderTest, for (size_t i = 0; i < upgradable_usage_entry_info_list.size(); ++i) { const CdmUsageEntryInfo& info = upgradable_usage_entry_info_list[i]; - if (info.storage_type == kStorageLicense) { + if (info.HasKeySetId()) { EXPECT_CALL(*device_files_, - RetrieveLicense(info.key_set_id, NotNull(), NotNull())) + RetrieveLicense(info.key_set_id(), NotNull(), NotNull())) .WillOnce( DoAll(SetArgPointee<1>(license_data_list[i]), Return(true))); } @@ -3190,12 +3022,12 @@ TEST_F(UsageTableHeaderTest, // For the entries which failed, there should be an attempt to delete the // files associated with them. EXPECT_CALL(*device_files_, - DeleteLicense(upgradable_usage_entry_info_list[0].key_set_id)) + DeleteLicense(upgradable_usage_entry_info_list[0].key_set_id())) .WillOnce(Return(true)); EXPECT_TRUE(usage_table_header_->Init(kSecurityLevelL1, crypto_session_)); EXPECT_EQ(upgraded_usage_entry_info_list, - usage_table_header_->usage_entry_info()); + usage_table_header_->entry_info_list()); } // Initial Test state: @@ -3219,9 +3051,9 @@ TEST_F(UsageTableHeaderTest, LruUsageTableUpgrade_AllFailure) { for (size_t i = 0; i < kUpgradableUsageEntryInfoList.size(); ++i) { const CdmUsageEntryInfo& info = kUpgradableUsageEntryInfoList[i]; - if (info.storage_type == kStorageLicense) { + if (info.HasKeySetId()) { EXPECT_CALL(*device_files_, - RetrieveLicense(info.key_set_id, NotNull(), NotNull())) + RetrieveLicense(info.key_set_id(), NotNull(), NotNull())) .WillOnce(Return(false)); } } @@ -3246,12 +3078,11 @@ TEST_F(UsageTableHeaderTest, LruLastUsedTime_CreateLicenseEntry) { // Expected values. const uint32_t expected_usage_entry_number = static_cast(kUpgradedUsageEntryInfoList.size()); - const CdmUsageEntryInfo expected_new_entry = { - kStorageLicense, "offline_key_set_4", "", kLruBaseTime, - kLruBaseTime + kDefaultExpireDuration}; - std::vector expected_usage_info_list = + const CdmUsageEntryInfo expected_new_entry( + "offline_key_set_4", kLruBaseTime, kLruBaseTime + kDefaultExpireDuration); + std::vector expected_entry_info_list = kUpgradedUsageEntryInfoList; - expected_usage_info_list.push_back(expected_new_entry); + expected_entry_info_list.push_back(expected_new_entry); // AddKey expectations EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull())) @@ -3268,29 +3099,29 @@ TEST_F(UsageTableHeaderTest, LruLastUsedTime_CreateLicenseEntry) { // The Call. uint32_t usage_entry_number = 0; EXPECT_EQ(NO_ERROR, usage_table_header_->AddEntry( - crypto_session_, expected_new_entry.key_set_id, + crypto_session_, expected_new_entry.key_set_id(), 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()); + EXPECT_EQ(expected_entry_info_list, usage_table_header_->entry_info_list()); } TEST_F(UsageTableHeaderTest, LruLastUsedTime_UpdateEntry) { Init(kSecurityLevelL1, kUpgradedUsageTableHeader, kUpgradedUsageEntryInfoList); - std::vector expected_usage_info_list = + std::vector expected_entry_info_list = kUpgradedUsageEntryInfoList; MockClock mock_clock; usage_table_header_->SetClock(&mock_clock); const int64_t expected_update_time = kLruBaseTime + 60 * 60; // Any value larger than the original works. for (uint32_t usage_entry_number = 0; - usage_entry_number < expected_usage_info_list.size(); + usage_entry_number < expected_entry_info_list.size(); ++usage_entry_number) { // Update expected values. - expected_usage_info_list[usage_entry_number].last_use_time = - expected_update_time; + expected_entry_info_list[usage_entry_number].SetLastUseTime( + expected_update_time); // Update expectations EXPECT_CALL(*crypto_session_, UpdateUsageEntry(NotNull(), NotNull())) @@ -3304,8 +3135,7 @@ TEST_F(UsageTableHeaderTest, LruLastUsedTime_UpdateEntry) { CdmUsageEntry usage_entry; EXPECT_EQ(NO_ERROR, usage_table_header_->UpdateEntry( usage_entry_number, crypto_session_, &usage_entry)); - EXPECT_EQ(expected_usage_info_list, - usage_table_header_->usage_entry_info()); + EXPECT_EQ(expected_entry_info_list, usage_table_header_->entry_info_list()); } } @@ -3313,18 +3143,18 @@ TEST_F(UsageTableHeaderTest, LruLastUsedTime_LoadEntry) { Init(kSecurityLevelL1, kUpgradedUsageTableHeader, kUpgradedUsageEntryInfoList); - std::vector expected_usage_info_list = + std::vector expected_entry_info_list = kUpgradedUsageEntryInfoList; MockClock mock_clock; usage_table_header_->SetClock(&mock_clock); const int64_t expected_update_time = kLruBaseTime + 60 * 60; // Any value larger than the original works. for (uint32_t usage_entry_number = 0; - usage_entry_number < expected_usage_info_list.size(); + usage_entry_number < expected_entry_info_list.size(); ++usage_entry_number) { // Update expected values. - expected_usage_info_list[usage_entry_number].last_use_time = - expected_update_time; + expected_entry_info_list[usage_entry_number].SetLastUseTime( + expected_update_time); // Update expectations EXPECT_CALL(*crypto_session_, LoadUsageEntry(usage_entry_number, _)) @@ -3336,8 +3166,7 @@ TEST_F(UsageTableHeaderTest, LruLastUsedTime_LoadEntry) { CdmUsageEntry usage_entry; EXPECT_EQ(NO_ERROR, usage_table_header_->LoadEntry( crypto_session_, kEmptyString, usage_entry_number)); - EXPECT_EQ(expected_usage_info_list, - usage_table_header_->usage_entry_info()); + EXPECT_EQ(expected_entry_info_list, usage_table_header_->entry_info_list()); } } @@ -3361,7 +3190,7 @@ TEST_F(UsageTableHeaderTest, DetermineLicenseToRemove_InvalidInput) { } // Check that the major priority buckets are respected. -// Expects that unknown entries to be chosen above all others. +// Expects that clear entries to be chosen above all others. // Unexpired licenses should only be considered if the threshold // is met. TEST_F(UsageTableHeaderTest, DetermineLicenseToRemove_BasicPriorities) { @@ -3371,30 +3200,22 @@ TEST_F(UsageTableHeaderTest, DetermineLicenseToRemove_BasicPriorities) { std::vector usage_entry_info_list; // 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; + const CdmUsageEntryInfo unexpired_entry_info( + "unexpired_key_set_id", /* last_use_time */ kLruBaseTime, + /* license_expiry_time */ kLruBaseTime + 2 * kOneDay); usage_entry_info_list.push_back(unexpired_entry_info); constexpr uint32_t unexpired_entry_number = 0; // 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; + const CdmUsageEntryInfo expired_entry_info( + "expired_key_set_id", /* last_use_time */ kLruBaseTime, + /* license_expiry_time */ kLruBaseTime); usage_entry_info_list.push_back(expired_entry_info); constexpr uint32_t expired_entry_number = 1; - // 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; + // Clear entry. + usage_entry_info_list.push_back(kUsageEntryInfoEmpty); + constexpr uint32_t clear_entry_number = 2; // Case 1: If there is a clear entry, it should be selected above // any other entry. @@ -3404,7 +3225,7 @@ TEST_F(UsageTableHeaderTest, DetermineLicenseToRemove_BasicPriorities) { EXPECT_TRUE(UsageTableHeader::DetermineLicenseToRemoveForTesting( usage_entry_info_list, kCurrentTime, /* unexpired_threshold = */ 3, &entry_to_remove)); - EXPECT_EQ(unknown_entry_number, entry_to_remove); + EXPECT_EQ(clear_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 @@ -3428,7 +3249,7 @@ TEST_F(UsageTableHeaderTest, DetermineLicenseToRemove_BasicPriorities) { // Case 3a: Threshold not met, expired entry is the most stale. entry_to_remove = kInvalidEntry; - usage_entry_info_list[expired_entry_number].last_use_time--; + usage_entry_info_list[expired_entry_number].DecLastUseTime(); EXPECT_TRUE(UsageTableHeader::DetermineLicenseToRemoveForTesting( usage_entry_info_list, kCurrentTime, /* unexpired_threshold = */ 3, &entry_to_remove)); @@ -3436,8 +3257,8 @@ TEST_F(UsageTableHeaderTest, DetermineLicenseToRemove_BasicPriorities) { // Case 3b: Threshold not met, unexpired entry is the most stale. entry_to_remove = kInvalidEntry; - usage_entry_info_list[expired_entry_number].last_use_time++; - usage_entry_info_list[unexpired_entry_number].last_use_time--; + usage_entry_info_list[expired_entry_number].IncLastUseTime(); + usage_entry_info_list[unexpired_entry_number].DecLastUseTime(); EXPECT_TRUE(UsageTableHeader::DetermineLicenseToRemoveForTesting( usage_entry_info_list, kCurrentTime, /* unexpired_threshold = */ 3, &entry_to_remove)); @@ -3452,8 +3273,8 @@ TEST_F(UsageTableHeaderTest, DetermineLicenseToRemove_BasicPriorities) { // Case 3d: Threshold met, expired entry is the most stale. entry_to_remove = kInvalidEntry; - usage_entry_info_list[expired_entry_number].last_use_time--; - usage_entry_info_list[unexpired_entry_number].last_use_time++; + usage_entry_info_list[expired_entry_number].DecLastUseTime(); + usage_entry_info_list[unexpired_entry_number].IncLastUseTime(); EXPECT_TRUE(UsageTableHeader::DetermineLicenseToRemoveForTesting( usage_entry_info_list, kCurrentTime, /* unexpired_threshold = */ 0, &entry_to_remove)); @@ -3499,11 +3320,10 @@ TEST_F(UsageTableHeaderTest, // Create a set of all offline licenses. 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.last_use_time = kLruBaseTime; - usage_entry_info.offline_license_expiry_time = - kCurrentTime + kDefaultExpireDuration; + usage_entry_info.SetKeySetId("unexpired_offline"); + usage_entry_info.SetLastUseTime(kLruBaseTime); + usage_entry_info.SetLicenseExpiryTime(kCurrentTime + + kDefaultExpireDuration); } // Mark three licenses as expired. @@ -3513,11 +3333,11 @@ TEST_F(UsageTableHeaderTest, static_cast(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() != "unexpired_offline") 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; - usage_entry_info.key_set_id = "expired_offline"; + usage_entry_info.SetKeySetId("expired_offline"); + usage_entry_info.SetLastUseTime(kLruBaseTime + kOneDay); + usage_entry_info.SetLicenseExpiryTime(kCurrentTime - kOneDay); expired_license_numbers.push_back(i); } @@ -3565,11 +3385,10 @@ TEST_F(UsageTableHeaderTest, DetermineLicenseToRemove_LargeMixedSet) { // Create a set of unexpired license 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.last_use_time = kLruBaseTime + kOneDay; - usage_entry_info.offline_license_expiry_time = - kCurrentTime + kDefaultExpireDuration; + usage_entry_info.SetKeySetId("unexpired_offline"); + usage_entry_info.SetLastUseTime(kLruBaseTime + kOneDay); + usage_entry_info.SetLicenseExpiryTime(kCurrentTime + + kDefaultExpireDuration); } // Select a offline license to be even more stale, but unexpired. @@ -3577,8 +3396,8 @@ TEST_F(UsageTableHeaderTest, DetermineLicenseToRemove_LargeMixedSet) { 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"; + usage_entry_info.SetKeySetId("stale_offline"); + usage_entry_info.SetLastUseTime(kLruBaseTime); // Case 1: Most stale license is selected. uint32_t entry_to_remove = kInvalidEntry; @@ -3601,8 +3420,8 @@ TEST_F(UsageTableHeaderTest, DetermineLicenseToRemove_LargeMixedSet) { const uint32_t i = static_cast( 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; + if (usage_entry_info_list[i].key_set_id() != "unexpired_offline") continue; + usage_entry_info_list[i].SetLicenseExpiryTime(kLruBaseTime); expired_offline_license_number = i; } diff --git a/libwvdrmengine/cdm/metrics/test/metrics_collections_unittest.cpp b/libwvdrmengine/cdm/metrics/test/metrics_collections_unittest.cpp index b3931e60..fbfb100c 100644 --- a/libwvdrmengine/cdm/metrics/test/metrics_collections_unittest.cpp +++ b/libwvdrmengine/cdm/metrics/test/metrics_collections_unittest.cpp @@ -358,8 +358,7 @@ TEST_F(CryptoMetricsTest, AllCryptoMetrics) { crypto_metrics.usage_table_header_lru_usage_info_count_.Record(150); crypto_metrics.usage_table_header_lru_offline_license_count_.Record(50); crypto_metrics.usage_table_header_lru_evicted_entry_staleness_.Record(259200); - crypto_metrics.usage_table_header_lru_evicted_entry_type_.Record( - kStorageUsageInfo); + crypto_metrics.usage_table_header_lru_evicted_entry_type_.Record(1); // Oem crypto metrics. crypto_metrics.oemcrypto_api_version_.Record(123); @@ -482,8 +481,7 @@ TEST_F(CryptoMetricsTest, AllCryptoMetrics) { EXPECT_EQ( 259200, actual.usage_table_header_lru_evicted_entry_staleness_s().int_value()); - EXPECT_EQ(kStorageUsageInfo, - actual.usage_table_header_lru_evicted_entry_type().int_value()); + EXPECT_EQ(1, actual.usage_table_header_lru_evicted_entry_type().int_value()); // Oem crypto metrics. EXPECT_EQ(123, actual.oemcrypto_api_version().int_value());