Source release 17.1.0

This commit is contained in:
John "Juce" Bruce
2022-07-07 17:14:31 -07:00
parent 8c17574083
commit 694cf6fb25
2233 changed files with 272026 additions and 223371 deletions

View File

@@ -1,6 +1,6 @@
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
// source code may only be used and distributed under the Widevine License
// Agreement.
#ifndef WVCDM_CORE_USAGE_TABLE_HEADER_H_
#define WVCDM_CORE_USAGE_TABLE_HEADER_H_
@@ -41,7 +41,7 @@ namespace wvcdm {
// initialized/terminated.
//
// Sessions and licenses are however handled by CdmSession and so most
// calls to maniplate the usage table header related to usage entries
// calls to manipulate the usage table header related to usage entries
// are by CdmSession.
//
// Upgrades from a fixed size usage table (supported by previous
@@ -53,20 +53,36 @@ class UsageTableHeader {
UsageTableHeader();
virtual ~UsageTableHeader() {}
// |crypto_session| is used to create or load a usage master table and
// not cached beyound this call.
// |crypto_session| is used to create or load a usage master table
// and not cached beyound this call.
// First attempts to restore the usage table from the device files.
// If restoring fails, then a new usage table is created.
// Note: No OEMCrypto session for the same security level should be
// opened before calling.
// Threading: Method requires care of caller for exclusive access
// (ie. test setup or CryptoSession).
bool Init(CdmSecurityLevel security_level, CryptoSession* crypto_session);
// |persistent_license| false indicates usage info record
// 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|.
//
// Type of entry depends on the value of |persistent_license|:
// false - usage info / secure stop record
// true - offline license
//
// Threading: Method takes exclusive use of |usage_table_header_lock_|.
virtual CdmResponseType AddEntry(CryptoSession* crypto_session,
bool persistent_license,
const CdmKeySetId& key_set_id,
const std::string& usage_info_filename,
const CdmKeyResponse& license_message,
uint32_t* usage_entry_number);
// Threading: Method takes exclusive use of |usage_table_header_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,
CryptoSession* crypto_session,
CdmUsageEntry* usage_entry);
@@ -76,6 +92,8 @@ class UsageTableHeader {
// 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,
bool defrag_table,
DeviceFiles* device_files,
@@ -87,8 +105,14 @@ class UsageTableHeader {
// when InvalidateEntry is mocked. This allows one to test methods that are
// dependent on InvalidateEntry without having to set expectations
// for the objects that InvalidateEntry depends on.
//
// Threading: Method requires care of caller for exclusive access.
void InvalidateEntryForTest(uint32_t usage_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 potential_table_capacity() const { return potential_table_capacity_; }
@@ -109,7 +133,7 @@ class UsageTableHeader {
}
// Set the reference clock used for the method GetCurrentTime().
void SetClock(Clock* clock) {
void SetClock(wvutil::Clock* clock) {
if (clock != nullptr)
clock_ref_ = clock;
else
@@ -125,6 +149,81 @@ class UsageTableHeader {
}
private:
// == Initialization methods ==
// These should only be called during table initialization.
// All parameters are assumed valid.
// Creates a new, empty usage table. Any existing usage table files
// will be deleted.
// Threading: Method takes exclusive use of |usage_table_header_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_|
// when required.
bool RestoreTable(CryptoSession* const crypto_session);
// Performs a check that there are no open OEMCrypto sessions for
// the current security level of the usage table.
// Threading: No special threading requirements.
bool OpenSessionCheck(CryptoSession* const crypto_session);
// Performs a check that the OEMCrypto table can support at least
// 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_|.
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_|.
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_|.
// 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);
// 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.
// 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);
// Checks if the specified |usage_entry_number| is known to be
// unoccupied (released).
bool IsEntryUnoccupied(const uint32_t usage_entry_number) const;
// SetOfflineEntryInfo() and SetUsageInfoEntryInfo() populate the
// entry meta-data with the required information based on the type
// of entry.
void SetOfflineEntryInfo(const uint32_t usage_entry_number,
const std::string& key_set_id,
const CdmKeyResponse& license_message);
void SetUsageInfoEntryInfo(const uint32_t usage_entry_number,
const std::string& key_set_id,
const std::string& usage_info_file_name);
// Shrinks the table, removing all trailing unoccupied entries.
// |usage_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,
metrics::CryptoMetrics* metrics);
CdmResponseType MoveEntry(uint32_t from /* usage entry number */,
const CdmUsageEntry& from_usage_entry,
uint32_t to /* usage entry number */,
@@ -140,7 +239,7 @@ class UsageTableHeader {
// Stores the usage table and it's info. This will increment
// |store_table_counter_| if successful.
bool StoreTable(DeviceFiles* device_files);
bool StoreTable();
CdmResponseType Shrink(metrics::CryptoMetrics* metrics,
uint32_t number_of_usage_entries_to_delete);
@@ -153,8 +252,6 @@ class UsageTableHeader {
// evicted.
CdmResponseType ReleaseOldestEntry(metrics::CryptoMetrics* metrics);
virtual bool is_inited() { return is_inited_; }
// Performs and LRU upgrade on all loaded CdmUsageEntryInfo from a
// device file that had not yet been upgraded to use the LRU data.
virtual bool LruUpgradeAllUsageEntries();
@@ -212,17 +309,16 @@ class UsageTableHeader {
// usage_table_header. Usage entries should use the file system provided
// by CdmSession.
std::unique_ptr<DeviceFiles> device_files_;
std::unique_ptr<FileSystem> file_system_;
CdmSecurityLevel security_level_;
SecurityLevel requested_security_level_;
std::unique_ptr<wvutil::FileSystem> file_system_;
CdmSecurityLevel security_level_ = kSecurityLevelUninitialized;
RequestedSecurityLevel requested_security_level_ = kLevelDefault;
CdmUsageTableHeader usage_table_header_;
std::vector<CdmUsageEntryInfo> usage_entry_info_;
// Lock to ensure that a single object is created for each security level
// and data member to represent whether an object has been correctly
// initialized.
bool is_inited_;
// Table is sync with persistent storage and can be used by the CDM
// to interact with OEMCrypto.
bool is_initialized_ = false;
// Synchonizes access to the Usage Table Header and bookkeeping
// data-structures
@@ -232,11 +328,11 @@ class UsageTableHeader {
// |clock_| represents the system's "wall clock". For the clock's purpose
// we do not need a more secure clock.
Clock clock_;
wvutil::Clock clock_;
// |clock_ref_| is a pointer to the clock which is to be used for
// obtaining the current time. By default, this points to the internal
// |clock_| variable, however, it can be overrided for testing purpose.
Clock* clock_ref_;
// |clock_| variable, however, it can be overridden for testing purpose.
wvutil::Clock* clock_ref_;
// The maximum number of entries that the underlying OEMCrypto
// implementation can support. Some implementations might not
@@ -252,6 +348,7 @@ class UsageTableHeader {
#if defined(UNIT_TEST)
// Test related declarations
friend class UsageTableHeaderTest;
FRIEND_TEST(UsageTableHeaderTest, Shrink_NoneOfTable);
FRIEND_TEST(UsageTableHeaderTest, Shrink_PartOfTable);
FRIEND_TEST(UsageTableHeaderTest, Shrink_AllOfTable);