Revert "Core CDM: Remove usage info as a run-time type."
This reverts commit 5dd2b07286.
Reason for revert: Feature rejected by Android
Bug: 242289743
Change-Id: I8dc95139d113ad1d44acd2e8dd6cbda604b6c073
This commit is contained in:
committed by
Android (Google) Code Review
parent
5dd2b07286
commit
1ea92c34c8
@@ -103,6 +103,17 @@ 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();
|
||||
|
||||
@@ -168,7 +179,7 @@ class DeviceFiles {
|
||||
|
||||
virtual bool StoreUsageTableInfo(
|
||||
const CdmUsageTableHeader& usage_table_header,
|
||||
const std::vector<CdmUsageEntryInfo>& usage_entry_info_list);
|
||||
const std::vector<CdmUsageEntryInfo>& usage_entry_info);
|
||||
|
||||
// When retrieving usage table information from the file system; any
|
||||
// table that has yet to be updated for the LRU attributes will be
|
||||
@@ -179,7 +190,7 @@ class DeviceFiles {
|
||||
// is set to true if any are detected.
|
||||
virtual bool RetrieveUsageTableInfo(
|
||||
CdmUsageTableHeader* usage_table_header,
|
||||
std::vector<CdmUsageEntryInfo>* usage_entry_info_list, bool* lru_upgrade,
|
||||
std::vector<CdmUsageEntryInfo>* usage_entry_info, bool* lru_upgrade,
|
||||
bool* has_usage_info_entries);
|
||||
|
||||
virtual bool DeleteUsageTableInfo();
|
||||
@@ -251,6 +262,10 @@ 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);
|
||||
@@ -260,7 +275,11 @@ 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<std::string> reserved_license_ids_;
|
||||
|
||||
@@ -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 |entry_number|s need to be saved in the license
|
||||
// |usage_entry| and |usage_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 |entry_number|.
|
||||
// usage entry will be returned by |usage_entry_number|.
|
||||
//
|
||||
// Threading: Method takes exclusive use of |table_lock_|.
|
||||
// Threading: Method takes exclusive use of |usage_table_header_lock_|.
|
||||
virtual CdmResponseType AddEntry(CryptoSession* crypto_session,
|
||||
const CdmKeySetId& key_set_id,
|
||||
const CdmKeyResponse& license_message,
|
||||
uint32_t* entry_number);
|
||||
// Threading: Method takes exclusive use of |table_lock_|.
|
||||
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 entry_number);
|
||||
// Threading: Method takes exclusive use of |table_lock_|.
|
||||
virtual CdmResponseType UpdateEntry(uint32_t entry_number,
|
||||
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);
|
||||
|
||||
// The licenses or usage info records specified by |entry_number|
|
||||
// The licenses or usage info records specified by |usage_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 |table_lock_|.
|
||||
virtual CdmResponseType InvalidateEntry(uint32_t entry_number,
|
||||
// Threading: Method takes exclusive use of |usage_table_header_lock_|.
|
||||
virtual CdmResponseType InvalidateEntry(uint32_t usage_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 entry_number);
|
||||
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 entry_info_list_.size(); }
|
||||
size_t size() { return usage_entry_info_.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 populated (non-empty).
|
||||
size_t OccupiedEntryCount() const;
|
||||
// are related to offline licenses.
|
||||
size_t OfflineEntryCount() const;
|
||||
|
||||
const std::vector<CdmUsageEntryInfo>& entry_info_list() const {
|
||||
return entry_info_list_;
|
||||
const std::vector<CdmUsageEntryInfo>& usage_entry_info() const {
|
||||
return usage_entry_info_;
|
||||
}
|
||||
|
||||
// Set the reference clock used for the method GetCurrentTime().
|
||||
@@ -132,10 +132,10 @@ class UsageTableHeader {
|
||||
}
|
||||
|
||||
static bool DetermineLicenseToRemoveForTesting(
|
||||
const std::vector<CdmUsageEntryInfo>& entry_info_list,
|
||||
const std::vector<CdmUsageEntryInfo>& usage_entry_info_list,
|
||||
int64_t current_time, size_t unexpired_threshold,
|
||||
uint32_t* entry_to_remove) {
|
||||
return DetermineLicenseToRemove(entry_info_list, current_time,
|
||||
return DetermineLicenseToRemove(usage_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 |table_lock_|
|
||||
// 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 |table_lock_|
|
||||
// Threading: Method takes exclusive use of |usage_table_header_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
|
||||
// |table_lock_|.
|
||||
// |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
|
||||
// |table_lock_|.
|
||||
// |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 |table_lock_|.
|
||||
// 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* entry_number);
|
||||
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.
|
||||
// |entry_number| is treated as both an input and output.
|
||||
// |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* entry_number);
|
||||
uint32_t* usage_entry_number);
|
||||
|
||||
// Checks if the specified |entry_number| is known to be
|
||||
// Checks if the specified |usage_entry_number| is known to be
|
||||
// unoccupied (released).
|
||||
bool IsEntryUnoccupied(const uint32_t entry_number) const;
|
||||
bool IsEntryUnoccupied(const uint32_t usage_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 entry_number,
|
||||
void SetOfflineEntryInfo(const uint32_t usage_entry_number,
|
||||
const std::string& key_set_id,
|
||||
const CdmKeyResponse& license_message);
|
||||
|
||||
// Shrinks the table, removing all trailing unoccupied entries.
|
||||
// |entry_info_| will be resized appropriately.
|
||||
// |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 entry_number, bool defrag_table, DeviceFiles* device_files,
|
||||
uint32_t usage_entry_number, bool defrag_table, DeviceFiles* device_files,
|
||||
metrics::CryptoMetrics* metrics);
|
||||
|
||||
CdmResponseType MoveEntry(uint32_t from /* usage entry number */,
|
||||
@@ -218,9 +218,11 @@ class UsageTableHeader {
|
||||
DeviceFiles* device_files,
|
||||
metrics::CryptoMetrics* metrics);
|
||||
|
||||
CdmResponseType GetEntry(uint32_t entry_number, DeviceFiles* device_files,
|
||||
CdmResponseType GetEntry(uint32_t usage_entry_number,
|
||||
DeviceFiles* device_files,
|
||||
CdmUsageEntry* usage_entry);
|
||||
CdmResponseType StoreEntry(uint32_t entry_number, DeviceFiles* device_files,
|
||||
CdmResponseType StoreEntry(uint32_t usage_entry_number,
|
||||
DeviceFiles* device_files,
|
||||
const CdmUsageEntry& usage_entry);
|
||||
|
||||
// Stores the usage table and it's info. This will increment
|
||||
@@ -271,7 +273,7 @@ class UsageTableHeader {
|
||||
// types.
|
||||
//
|
||||
// Parameters:
|
||||
// [in] entry_info_list: The complete list of known usage
|
||||
// [in] usage_entry_info_list: The complete list of known usage
|
||||
// entries.
|
||||
// [in] current_time: The current time to compare expiration times
|
||||
// against.
|
||||
@@ -286,20 +288,20 @@ class UsageTableHeader {
|
||||
// |true| if an entry has been determined to be removed.
|
||||
// Otherwise returns |false|.
|
||||
static bool DetermineLicenseToRemove(
|
||||
const std::vector<CdmUsageEntryInfo>& entry_info_list,
|
||||
const std::vector<CdmUsageEntryInfo>& usage_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
|
||||
// |table_header|. Usage entries should use the file system provided
|
||||
// usage_table_header. Usage entries should use the file system provided
|
||||
// by CdmSession.
|
||||
std::unique_ptr<DeviceFiles> device_files_;
|
||||
std::unique_ptr<wvutil::FileSystem> file_system_;
|
||||
CdmSecurityLevel security_level_ = kSecurityLevelUninitialized;
|
||||
RequestedSecurityLevel requested_security_level_ = kLevelDefault;
|
||||
|
||||
CdmUsageTableHeader table_header_;
|
||||
std::vector<CdmUsageEntryInfo> entry_info_list_;
|
||||
CdmUsageTableHeader usage_table_header_;
|
||||
std::vector<CdmUsageEntryInfo> usage_entry_info_;
|
||||
|
||||
// Table is sync with persistent storage and can be used by the CDM
|
||||
// to interact with OEMCrypto.
|
||||
@@ -307,7 +309,7 @@ class UsageTableHeader {
|
||||
|
||||
// Synchonizes access to the Usage Table Header and bookkeeping
|
||||
// data-structures
|
||||
mutable std::mutex table_lock_;
|
||||
mutable std::mutex usage_table_header_lock_;
|
||||
|
||||
metrics::CryptoMetrics alternate_crypto_metrics_;
|
||||
|
||||
|
||||
@@ -537,71 +537,44 @@ enum CdmUsageSupportType : int32_t {
|
||||
kUnknownUsageSupport,
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
enum CdmUsageEntryStorageType : int32_t {
|
||||
kStorageLicense,
|
||||
kStorageUsageInfo,
|
||||
kStorageTypeUnknown,
|
||||
};
|
||||
|
||||
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 (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_) {
|
||||
if (storage_type != other.storage_type || key_set_id != other.key_set_id ||
|
||||
last_use_time != other.last_use_time) {
|
||||
return false;
|
||||
}
|
||||
return last_use_time_ == other.last_use_time_ &&
|
||||
license_expiry_time_ == other.license_expiry_time_;
|
||||
// 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;
|
||||
}
|
||||
|
||||
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;
|
||||
void Clear() {
|
||||
storage_type = kStorageTypeUnknown;
|
||||
key_set_id.clear();
|
||||
usage_info_file_name.clear();
|
||||
last_use_time = 0;
|
||||
offline_license_expiry_time = 0;
|
||||
}
|
||||
};
|
||||
|
||||
enum CdmKeySecurityLevel : int32_t {
|
||||
@@ -873,6 +846,7 @@ 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);
|
||||
|
||||
Reference in New Issue
Block a user