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());