Source release 17.1.0
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user