Corrections for big usage table support in L3
[ Merge of http://go/wvgerrit/26421 ] * Corrects usage_table_header lifetime management. Earlier the UsageTableHeader class was a singleton tied to the CdmEngine lifetime. With SPOIDs there might be multiple concurrent CdmEngine objects. The UsageTableHeader class is now associated with OEMCrypto lifetime. There are two UsageTableHeader objects one for each L1 and L3. These get allocated/deallocated on OEMCrypto Initialization/Termination respectively. * UsageTableHeader requires OEMCrypto, file read/writes and metric gathering to perform its required functionality. Because of the lifetime changes, CryptoSession, DeviceFiles and MetricsGroup objects need to passed to the methods rather than at Creation time. * Miscellaneous fixes, when moving or deleteing entries. * Adds usage_table_header_unittests. * Addresses failures with request_license_test with secure stop in L3. b/36858906 b/36855557 b/36048120 b/38341136 b/37100505 b/35946047 Test: Verified by unit and integration tests. Added new usage_table_header_unittests Change-Id: I20e396ab2c0afbd14372dd93b969e5b0f1ccd291
This commit is contained in:
@@ -88,6 +88,7 @@ try_adb_push $OUT/vendor/bin/license_unittest
|
|||||||
try_adb_push $OUT/vendor/bin/license_keys_unittest
|
try_adb_push $OUT/vendor/bin/license_keys_unittest
|
||||||
try_adb_push $OUT/vendor/bin/initialization_data_unittest
|
try_adb_push $OUT/vendor/bin/initialization_data_unittest
|
||||||
try_adb_push $OUT/vendor/bin/device_files_unittest
|
try_adb_push $OUT/vendor/bin/device_files_unittest
|
||||||
|
try_adb_push $OUT/vendor/bin/usage_table_header_unittest
|
||||||
try_adb_push $OUT/vendor/bin/service_certificate_unittest
|
try_adb_push $OUT/vendor/bin/service_certificate_unittest
|
||||||
try_adb_push $OUT/vendor/bin/timer_unittest
|
try_adb_push $OUT/vendor/bin/timer_unittest
|
||||||
try_adb_push $OUT/vendor/bin/libwvdrmengine_test
|
try_adb_push $OUT/vendor/bin/libwvdrmengine_test
|
||||||
|
|||||||
@@ -82,8 +82,7 @@ class CdmSession {
|
|||||||
// ReleaseKey() - Accept response and release key.
|
// ReleaseKey() - Accept response and release key.
|
||||||
virtual CdmResponseType ReleaseKey(const CdmKeyResponse& key_response);
|
virtual CdmResponseType ReleaseKey(const CdmKeyResponse& key_response);
|
||||||
|
|
||||||
virtual CdmResponseType DeleteUsageEntry(
|
virtual CdmResponseType DeleteUsageEntry(uint32_t usage_entry_number);
|
||||||
const DeviceFiles::CdmUsageData& usage_data);
|
|
||||||
|
|
||||||
virtual bool IsKeyLoaded(const KeyId& key_id);
|
virtual bool IsKeyLoaded(const KeyId& key_id);
|
||||||
virtual int64_t GetDurationRemaining();
|
virtual int64_t GetDurationRemaining();
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
namespace wvcdm {
|
namespace wvcdm {
|
||||||
|
|
||||||
class CryptoKey;
|
class CryptoKey;
|
||||||
|
class UsageTableHeader;
|
||||||
|
|
||||||
typedef std::map<CryptoKeyId, CryptoKey*> CryptoKeyMap;
|
typedef std::map<CryptoKeyId, CryptoKey*> CryptoKeyMap;
|
||||||
|
|
||||||
class CryptoSession {
|
class CryptoSession {
|
||||||
@@ -142,6 +144,9 @@ class CryptoSession {
|
|||||||
const std::string& signature);
|
const std::string& signature);
|
||||||
|
|
||||||
// Usage table header and usage entry related methods
|
// Usage table header and usage entry related methods
|
||||||
|
virtual UsageTableHeader* GetUsageTableHeader() {
|
||||||
|
return usage_table_header_;
|
||||||
|
}
|
||||||
virtual CdmResponseType GetUsageSupportType(CdmUsageSupportType* type);
|
virtual CdmResponseType GetUsageSupportType(CdmUsageSupportType* type);
|
||||||
virtual CdmResponseType CreateUsageTableHeader(
|
virtual CdmResponseType CreateUsageTableHeader(
|
||||||
CdmUsageTableHeader* usage_table_header);
|
CdmUsageTableHeader* usage_table_header);
|
||||||
@@ -217,6 +222,9 @@ class CryptoSession {
|
|||||||
|
|
||||||
bool is_usage_support_type_valid_;
|
bool is_usage_support_type_valid_;
|
||||||
CdmUsageSupportType usage_support_type_;
|
CdmUsageSupportType usage_support_type_;
|
||||||
|
UsageTableHeader* usage_table_header_;
|
||||||
|
static UsageTableHeader* usage_table_header_l1_;
|
||||||
|
static UsageTableHeader* usage_table_header_l3_;
|
||||||
|
|
||||||
uint64_t request_id_base_;
|
uint64_t request_id_base_;
|
||||||
static uint64_t request_id_index_;
|
static uint64_t request_id_index_;
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ namespace wvcdm {
|
|||||||
class Clock;
|
class Clock;
|
||||||
class CryptoSession;
|
class CryptoSession;
|
||||||
class PolicyEngine;
|
class PolicyEngine;
|
||||||
|
class CdmSession;
|
||||||
|
|
||||||
class CdmLicense {
|
class CdmLicense {
|
||||||
public:
|
public:
|
||||||
@@ -37,7 +38,8 @@ class CdmLicense {
|
|||||||
std::string* server_url);
|
std::string* server_url);
|
||||||
virtual CdmResponseType PrepareKeyUpdateRequest(
|
virtual CdmResponseType PrepareKeyUpdateRequest(
|
||||||
bool is_renewal, const CdmAppParameterMap& app_parameters,
|
bool is_renewal, const CdmAppParameterMap& app_parameters,
|
||||||
CdmKeyMessage* signed_request, std::string* server_url);
|
CdmSession* cdm_session, CdmKeyMessage* signed_request,
|
||||||
|
std::string* server_url);
|
||||||
virtual CdmResponseType HandleKeyResponse(
|
virtual CdmResponseType HandleKeyResponse(
|
||||||
const CdmKeyResponse& license_response);
|
const CdmKeyResponse& license_response);
|
||||||
virtual CdmResponseType HandleKeyUpdateResponse(
|
virtual CdmResponseType HandleKeyUpdateResponse(
|
||||||
|
|||||||
@@ -7,36 +7,48 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "device_files.h"
|
#include "device_files.h"
|
||||||
|
#include "file_store.h"
|
||||||
#include "lock.h"
|
#include "lock.h"
|
||||||
#include "metrics_group.h"
|
#include "metrics_group.h"
|
||||||
#include "scoped_ptr.h"
|
#include "scoped_ptr.h"
|
||||||
#include "timer_metric.h"
|
|
||||||
#include "wv_cdm_types.h"
|
#include "wv_cdm_types.h"
|
||||||
|
|
||||||
namespace wvcdm {
|
namespace wvcdm {
|
||||||
|
|
||||||
class FileSystem;
|
|
||||||
class CryptoSession;
|
class CryptoSession;
|
||||||
|
|
||||||
// The UsageTableHeader class is a singleton that CDM sessions will share.
|
// Offline licenses/secure stops may be securely tracked using usage
|
||||||
// A separate object will be created for each security level.
|
// tables (OEMCrypto v9-12) or usage table headers+usage entries
|
||||||
// The class synchronizes access to usage table header and associated
|
// (OEMCrypto v13+). This class assists with the latter, synchronizing
|
||||||
// data-structures and controls when they are read in or written out to
|
// access to usage table header and associated data-structures and controlling
|
||||||
// non-secure persistent storage.
|
// when they are read in or written out to non-secure persistent storage.
|
||||||
|
//
|
||||||
|
// Each OEMCrypto (for each security level) will maintain its own usage table
|
||||||
|
// header. Each license will have an associated usage entry that is also
|
||||||
|
// stored in persistent memory and is noted in the usage table header.
|
||||||
|
// Usage entry information will be verified when licenses are loaded.
|
||||||
|
//
|
||||||
|
// OEMCrypto for each security level have their own usage table
|
||||||
|
// headers. They are loaded on initialization and written out periodically.
|
||||||
|
// The lifecycle of this class is tied to when OEMCrypto is
|
||||||
|
// initialized/terminated.
|
||||||
|
//
|
||||||
|
// Sessions and licenses are however handled by CdmSession and so most
|
||||||
|
// calls to maniplate the usage table header related to usage entries
|
||||||
|
// are by CdmSession.
|
||||||
|
//
|
||||||
// Upgrades from a fixed size usage table (supported by previous
|
// Upgrades from a fixed size usage table (supported by previous
|
||||||
// versions of the OEMCrypto API v9-12) are handled by this class.
|
// 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 |usage_entry_number|s need to be saved in the license
|
||||||
// and usage info records by the caller.
|
// and usage info records by the caller.
|
||||||
class UsageTableHeader {
|
class UsageTableHeader {
|
||||||
public:
|
public:
|
||||||
// This methods instantiates or retrieves a usage table header singleton of
|
UsageTableHeader();
|
||||||
// appropriate security level as specified by the |crypto_session|
|
virtual ~UsageTableHeader() {}
|
||||||
// object.
|
|
||||||
// |crypto_session| is used to create or load a usage master table and
|
// |crypto_session| is used to create or load a usage master table and
|
||||||
// not cached beyound this call.
|
// not cached beyound this call.
|
||||||
static UsageTableHeader* GetInstance(FileSystem* file_system,
|
bool Init(CdmSecurityLevel security_level, CryptoSession* crypto_session);
|
||||||
CryptoSession* crypto_session_);
|
|
||||||
virtual ~UsageTableHeader() {}
|
|
||||||
|
|
||||||
// |persistent_license| false indicates usage info record
|
// |persistent_license| false indicates usage info record
|
||||||
CdmResponseType AddEntry(CryptoSession* crypto_session,
|
CdmResponseType AddEntry(CryptoSession* crypto_session,
|
||||||
@@ -53,54 +65,67 @@ class UsageTableHeader {
|
|||||||
// The licenses or usage info records specified by |usage_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
|
// should not be in use by any open CryptoSession objects when calls
|
||||||
// to DeleteEntry and MoveEntry are made.
|
// to DeleteEntry and MoveEntry are made.
|
||||||
CdmResponseType DeleteEntry(uint32_t usage_entry_number);
|
CdmResponseType DeleteEntry(uint32_t usage_entry_number, DeviceFiles* handle,
|
||||||
CdmResponseType MoveEntry(uint32_t from_usage_entry_number,
|
metrics::MetricsGroup* metrics);
|
||||||
const CdmUsageEntry& from_usage_entry,
|
|
||||||
uint32_t to_usage_entry_number);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
UsageTableHeader(FileSystem* file_system, CryptoSession* crypto_session,
|
CdmResponseType MoveEntry(uint32_t from /* usage entry number */,
|
||||||
CdmSecurityLevel security_level);
|
const CdmUsageEntry& from_usage_entry,
|
||||||
|
uint32_t to /* usage entry number */,
|
||||||
|
DeviceFiles* handle,
|
||||||
|
metrics::MetricsGroup* metrics);
|
||||||
|
|
||||||
CdmResponseType GetEntry(uint32_t usage_entry_number,
|
CdmResponseType GetEntry(uint32_t usage_entry_number, DeviceFiles* handle,
|
||||||
CdmUsageEntry* usage_entry);
|
CdmUsageEntry* usage_entry);
|
||||||
CdmResponseType StoreEntry(uint32_t usage_entry_number,
|
CdmResponseType StoreEntry(uint32_t usage_entry_number, DeviceFiles* handle,
|
||||||
const CdmUsageEntry& usage_entry);
|
const CdmUsageEntry& usage_entry);
|
||||||
|
|
||||||
bool DeleteLastEntry();
|
CdmResponseType Shrink(metrics::MetricsGroup* metrics,
|
||||||
|
uint32_t number_of_usage_entries_to_delete);
|
||||||
|
|
||||||
CdmResponseType UpgradeFromUsageTable();
|
CdmResponseType UpgradeFromUsageTable(DeviceFiles* handle,
|
||||||
bool UpgradeLicensesFromUsageTable();
|
metrics::MetricsGroup* metrics);
|
||||||
bool UpgradeUsageInfoFromUsageTable();
|
bool UpgradeLicensesFromUsageTable(DeviceFiles* handle,
|
||||||
|
metrics::MetricsGroup* metrics);
|
||||||
|
bool UpgradeUsageInfoFromUsageTable(DeviceFiles* handle,
|
||||||
|
metrics::MetricsGroup* metrics);
|
||||||
|
|
||||||
virtual bool is_inited() { return is_inited_; }
|
virtual bool is_inited() { return is_inited_; }
|
||||||
|
|
||||||
SecurityLevel GetSecurityLevel() {
|
// This handle and file system is only to be used when accessing
|
||||||
return security_level_ == kSecurityLevelL3 ? kLevel3 : kLevelDefault;
|
// usage_table_header. Usage entries should use the file system provided
|
||||||
}
|
// by CdmSession.
|
||||||
|
|
||||||
static UsageTableHeader* usage_table_header_l1_;
|
|
||||||
static UsageTableHeader* usage_table_header_l3_;
|
|
||||||
|
|
||||||
scoped_ptr<DeviceFiles> file_handle_;
|
scoped_ptr<DeviceFiles> file_handle_;
|
||||||
|
scoped_ptr<FileSystem> file_system_;
|
||||||
CdmSecurityLevel security_level_;
|
CdmSecurityLevel security_level_;
|
||||||
|
SecurityLevel requested_security_level_;
|
||||||
|
|
||||||
CdmUsageTableHeader usage_table_header_;
|
CdmUsageTableHeader usage_table_header_;
|
||||||
std::vector<CdmUsageEntryInfo> usage_entry_info_;
|
std::vector<CdmUsageEntryInfo> usage_entry_info_;
|
||||||
|
|
||||||
metrics::MetricsGroup metrics_;
|
|
||||||
metrics::TimerMetric life_span_;
|
|
||||||
|
|
||||||
// Lock to ensure that a single object is created for each security level
|
// Lock to ensure that a single object is created for each security level
|
||||||
// and data member to represent whether an object has been correctly
|
// and data member to represent whether an object has been correctly
|
||||||
// initialized.
|
// initialized.
|
||||||
bool is_inited_;
|
bool is_inited_;
|
||||||
static Lock initialization_lock_;
|
|
||||||
|
|
||||||
// Synchonizes access to the Usage Table Header and bookkeeping
|
// Synchonizes access to the Usage Table Header and bookkeeping
|
||||||
// data-structures
|
// data-structures
|
||||||
Lock usage_table_header_lock_;
|
Lock usage_table_header_lock_;
|
||||||
|
|
||||||
|
// Test related declarations
|
||||||
|
friend class UsageTableHeaderTest;
|
||||||
|
|
||||||
|
// These setters are for testing only. Takes ownership of the pointers.
|
||||||
|
void SetDeviceFiles(DeviceFiles* device_files) {
|
||||||
|
file_handle_.reset(device_files);
|
||||||
|
}
|
||||||
|
void SetCryptoSession(CryptoSession* crypto_session) {
|
||||||
|
test_crypto_session_.reset(crypto_session);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test related data members
|
||||||
|
scoped_ptr<CryptoSession> test_crypto_session_;
|
||||||
|
|
||||||
CORE_DISALLOW_COPY_AND_ASSIGN(UsageTableHeader);
|
CORE_DISALLOW_COPY_AND_ASSIGN(UsageTableHeader);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -297,6 +297,7 @@ enum CdmResponseType {
|
|||||||
INCORRECT_USAGE_SUPPORT_TYPE_2,
|
INCORRECT_USAGE_SUPPORT_TYPE_2,
|
||||||
KEY_PROHIBITED_FOR_SECURITY_LEVEL, /* 255 */
|
KEY_PROHIBITED_FOR_SECURITY_LEVEL, /* 255 */
|
||||||
KEY_NOT_FOUND_IN_SESSION,
|
KEY_NOT_FOUND_IN_SESSION,
|
||||||
|
NO_USAGE_ENTRIES,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum CdmKeyStatus {
|
enum CdmKeyStatus {
|
||||||
@@ -392,6 +393,12 @@ struct CdmUsageEntryInfo {
|
|||||||
CdmUsageEntryStorageType storage_type;
|
CdmUsageEntryStorageType storage_type;
|
||||||
CdmKeySetId key_set_id;
|
CdmKeySetId key_set_id;
|
||||||
std::string usage_info_file_name;
|
std::string usage_info_file_name;
|
||||||
|
bool operator==(const CdmUsageEntryInfo& other) const {
|
||||||
|
return storage_type == other.storage_type &&
|
||||||
|
key_set_id == other.key_set_id &&
|
||||||
|
(storage_type != kStorageUsageInfo ||
|
||||||
|
usage_info_file_name == other.usage_info_file_name);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class CdmKeyAllowedUsage {
|
class CdmKeyAllowedUsage {
|
||||||
|
|||||||
@@ -1132,7 +1132,8 @@ CdmResponseType CdmEngine::ReleaseAllUsageInfo(const std::string& app_id) {
|
|||||||
} else {
|
} else {
|
||||||
for (size_t k = 0; k < usage_data.size(); ++k) {
|
for (size_t k = 0; k < usage_data.size(); ++k) {
|
||||||
CdmResponseType status2 =
|
CdmResponseType status2 =
|
||||||
usage_session_->DeleteUsageEntry(usage_data[k]);
|
usage_session_->DeleteUsageEntry(
|
||||||
|
usage_data[k].usage_entry_number);
|
||||||
if (status == NO_ERROR && status2 != NO_ERROR)
|
if (status == NO_ERROR && status2 != NO_ERROR)
|
||||||
status = status2;
|
status = status2;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,15 +44,6 @@ CdmSession::CdmSession(FileSystem* file_system) :
|
|||||||
usage_entry_number_(0),
|
usage_entry_number_(0),
|
||||||
mock_license_parser_in_use_(false),
|
mock_license_parser_in_use_(false),
|
||||||
mock_policy_engine_in_use_(false) {
|
mock_policy_engine_in_use_(false) {
|
||||||
CdmResponseType sts =
|
|
||||||
crypto_session_->GetUsageSupportType(&usage_support_type_);
|
|
||||||
|
|
||||||
if (sts != NO_ERROR) {
|
|
||||||
LOGW("CdmSession::CdmSession: Failed to get usage support type");
|
|
||||||
}
|
|
||||||
if (usage_support_type_ == kUsageEntrySupport)
|
|
||||||
usage_table_header_ = UsageTableHeader::GetInstance(file_system,
|
|
||||||
crypto_session_.get());
|
|
||||||
life_span_.Start();
|
life_span_.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,6 +95,13 @@ CdmResponseType CdmSession::Init(CdmClientPropertySet* cdm_client_property_set,
|
|||||||
return SESSION_FILE_HANDLE_INIT_ERROR;
|
return SESSION_FILE_HANDLE_INIT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (crypto_session_->GetUsageSupportType(&usage_support_type_) == NO_ERROR) {
|
||||||
|
if (usage_support_type_ == kUsageEntrySupport)
|
||||||
|
usage_table_header_ = crypto_session_->GetUsageTableHeader();
|
||||||
|
} else {
|
||||||
|
usage_support_type_ = kNonSecureUsageSupport;
|
||||||
|
}
|
||||||
|
|
||||||
// Device Provisioning state is not yet known.
|
// Device Provisioning state is not yet known.
|
||||||
// If not using certificates, then Keybox is client token for license
|
// If not using certificates, then Keybox is client token for license
|
||||||
// requests.
|
// requests.
|
||||||
@@ -447,7 +445,8 @@ CdmResponseType CdmSession::AddKey(const CdmKeyResponse& key_response) {
|
|||||||
!provider_session_token.empty()) {
|
!provider_session_token.empty()) {
|
||||||
if (sts != KEY_ADDED) {
|
if (sts != KEY_ADDED) {
|
||||||
CdmResponseType sts =
|
CdmResponseType sts =
|
||||||
usage_table_header_->DeleteEntry(usage_entry_number_);
|
usage_table_header_->DeleteEntry(usage_entry_number_,
|
||||||
|
file_handle_.get(), &metrics_);
|
||||||
if (sts != NO_ERROR) {
|
if (sts != NO_ERROR) {
|
||||||
LOGW("CdmSession::AddKey: Delete usage entry failed = %d", sts);
|
LOGW("CdmSession::AddKey: Delete usage entry failed = %d", sts);
|
||||||
}
|
}
|
||||||
@@ -589,7 +588,7 @@ CdmResponseType CdmSession::Decrypt(const CdmDecryptionParameters& params) {
|
|||||||
CdmResponseType CdmSession::GenerateRenewalRequest(
|
CdmResponseType CdmSession::GenerateRenewalRequest(
|
||||||
CdmKeyRequest* key_request) {
|
CdmKeyRequest* key_request) {
|
||||||
CdmResponseType status = license_parser_->PrepareKeyUpdateRequest(
|
CdmResponseType status = license_parser_->PrepareKeyUpdateRequest(
|
||||||
true, app_parameters_, &key_request->message, &key_request->url);
|
true, app_parameters_, NULL, &key_request->message, &key_request->url);
|
||||||
|
|
||||||
key_request->type = kKeyRequestTypeRenewal;
|
key_request->type = kKeyRequestTypeRenewal;
|
||||||
|
|
||||||
@@ -619,8 +618,8 @@ CdmResponseType CdmSession::GenerateReleaseRequest(
|
|||||||
CdmKeyRequest* key_request) {
|
CdmKeyRequest* key_request) {
|
||||||
is_release_ = true;
|
is_release_ = true;
|
||||||
CdmResponseType status = license_parser_->PrepareKeyUpdateRequest(
|
CdmResponseType status = license_parser_->PrepareKeyUpdateRequest(
|
||||||
false, app_parameters_, &key_request->message,
|
false, app_parameters_, usage_table_header_ == NULL ? NULL : this,
|
||||||
&key_request->url);
|
&key_request->message, &key_request->url);
|
||||||
|
|
||||||
key_request->type = kKeyRequestTypeRelease;
|
key_request->type = kKeyRequestTypeRelease;
|
||||||
|
|
||||||
@@ -657,34 +656,50 @@ CdmResponseType CdmSession::ReleaseKey(const CdmKeyResponse& key_response) {
|
|||||||
if (is_offline_ || has_provider_session_token()) {
|
if (is_offline_ || has_provider_session_token()) {
|
||||||
DeleteLicense();
|
DeleteLicense();
|
||||||
|
|
||||||
// Deletion of usage entry cannot occur while in use by a crypto session.
|
|
||||||
// So close and reopen after deletion.
|
|
||||||
if (usage_support_type_ == kUsageEntrySupport) {
|
if (usage_support_type_ == kUsageEntrySupport) {
|
||||||
crypto_session_->Close();
|
sts = DeleteUsageEntry(usage_entry_number_);
|
||||||
CdmResponseType sts = usage_table_header_->DeleteEntry(usage_entry_number_);
|
|
||||||
if (sts != NO_ERROR) return sts;
|
|
||||||
|
|
||||||
M_TIME(
|
|
||||||
sts = crypto_session_->Open(requested_security_level_),
|
|
||||||
&metrics_,
|
|
||||||
crypto_session_open_,
|
|
||||||
sts,
|
|
||||||
requested_security_level_);
|
|
||||||
if (NO_ERROR != sts) return sts;
|
if (NO_ERROR != sts) return sts;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
CdmResponseType CdmSession::DeleteUsageEntry(
|
CdmResponseType CdmSession::DeleteUsageEntry(uint32_t usage_entry_number) {
|
||||||
const DeviceFiles::CdmUsageData& usage_data) {
|
|
||||||
if (usage_support_type_ != kUsageEntrySupport) {
|
if (usage_support_type_ != kUsageEntrySupport) {
|
||||||
LOGE("CdmSession::DeleteUsageEntry: Unexpected usage type supported: %d",
|
LOGE("CdmSession::DeleteUsageEntry: Unexpected usage type supported: %d",
|
||||||
usage_support_type_);
|
usage_support_type_);
|
||||||
return INCORRECT_USAGE_SUPPORT_TYPE_1;
|
return INCORRECT_USAGE_SUPPORT_TYPE_1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return usage_table_header_->DeleteEntry(usage_data.usage_entry_number);
|
// The usage entry cannot be deleted if it has a crypto session handling
|
||||||
|
// it, so close and reopen session.
|
||||||
|
CdmResponseType sts;
|
||||||
|
crypto_session_->Close();
|
||||||
|
crypto_session_.reset(new CryptoSession(&metrics_));
|
||||||
|
M_TIME(
|
||||||
|
sts = crypto_session_->Open(requested_security_level_),
|
||||||
|
&metrics_,
|
||||||
|
crypto_session_open_,
|
||||||
|
sts,
|
||||||
|
requested_security_level_);
|
||||||
|
if (sts != NO_ERROR) return sts;
|
||||||
|
|
||||||
|
usage_table_header_ = NULL;
|
||||||
|
if (crypto_session_->GetUsageSupportType(&usage_support_type_) == NO_ERROR) {
|
||||||
|
if (usage_support_type_ == kUsageEntrySupport)
|
||||||
|
usage_table_header_ = crypto_session_->GetUsageTableHeader();
|
||||||
|
} else {
|
||||||
|
usage_support_type_ = kNonSecureUsageSupport;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (usage_table_header_ == NULL) {
|
||||||
|
LOGE("CdmSession::DeleteUsageEntry: Usage table header unavailable");
|
||||||
|
return INCORRECT_USAGE_SUPPORT_TYPE_1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return usage_table_header_->DeleteEntry(usage_entry_number,
|
||||||
|
file_handle_.get(),
|
||||||
|
&metrics_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CdmSession::IsKeyLoaded(const KeyId& key_id) {
|
bool CdmSession::IsKeyLoaded(const KeyId& key_id) {
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include "properties.h"
|
#include "properties.h"
|
||||||
#include "pst_report.h"
|
#include "pst_report.h"
|
||||||
#include "string_conversions.h"
|
#include "string_conversions.h"
|
||||||
|
#include "usage_table_header.h"
|
||||||
#include "wv_cdm_constants.h"
|
#include "wv_cdm_constants.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@@ -41,6 +42,8 @@ Lock CryptoSession::crypto_lock_;
|
|||||||
bool CryptoSession::initialized_ = false;
|
bool CryptoSession::initialized_ = false;
|
||||||
int CryptoSession::session_count_ = 0;
|
int CryptoSession::session_count_ = 0;
|
||||||
uint64_t CryptoSession::request_id_index_ = 0;
|
uint64_t CryptoSession::request_id_index_ = 0;
|
||||||
|
UsageTableHeader* CryptoSession::usage_table_header_l1_ = NULL;
|
||||||
|
UsageTableHeader* CryptoSession::usage_table_header_l3_ = NULL;
|
||||||
|
|
||||||
CryptoSession::CryptoSession(metrics::MetricsGroup* metrics)
|
CryptoSession::CryptoSession(metrics::MetricsGroup* metrics)
|
||||||
: metrics_(metrics),
|
: metrics_(metrics),
|
||||||
@@ -50,6 +53,7 @@ CryptoSession::CryptoSession(metrics::MetricsGroup* metrics)
|
|||||||
requested_security_level_(kLevelDefault),
|
requested_security_level_(kLevelDefault),
|
||||||
is_usage_support_type_valid_(false),
|
is_usage_support_type_valid_(false),
|
||||||
usage_support_type_(kNonSecureUsageSupport),
|
usage_support_type_(kNonSecureUsageSupport),
|
||||||
|
usage_table_header_(NULL),
|
||||||
request_id_base_(0),
|
request_id_base_(0),
|
||||||
cipher_mode_(kCipherModeCtr) {
|
cipher_mode_(kCipherModeCtr) {
|
||||||
Init();
|
Init();
|
||||||
@@ -120,6 +124,16 @@ void CryptoSession::Terminate() {
|
|||||||
if (OEMCrypto_SUCCESS != sts) {
|
if (OEMCrypto_SUCCESS != sts) {
|
||||||
LOGE("OEMCrypto_Terminate failed: %d", sts);
|
LOGE("OEMCrypto_Terminate failed: %d", sts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (usage_table_header_l1_ != NULL) {
|
||||||
|
delete usage_table_header_l1_;
|
||||||
|
usage_table_header_l1_ = NULL;
|
||||||
|
}
|
||||||
|
if (usage_table_header_l3_ != NULL) {
|
||||||
|
delete usage_table_header_l3_;
|
||||||
|
usage_table_header_l3_ = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
initialized_ = false;
|
initialized_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,8 +224,7 @@ bool CryptoSession::GetProvisioningToken(std::string* token) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CdmSecurityLevel CryptoSession::GetSecurityLevel() {
|
CdmSecurityLevel CryptoSession::GetSecurityLevel() {
|
||||||
LOGV("CryptoSession::GetSecurityLevel: Lock");
|
LOGV("CryptoSession::GetSecurityLevel");
|
||||||
AutoLock auto_lock(crypto_lock_);
|
|
||||||
if (!initialized_) {
|
if (!initialized_) {
|
||||||
return kSecurityLevelUninitialized;
|
return kSecurityLevelUninitialized;
|
||||||
}
|
}
|
||||||
@@ -421,7 +434,8 @@ uint8_t CryptoSession::GetSecurityPatchLevel() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CdmResponseType CryptoSession::Open(SecurityLevel requested_security_level) {
|
CdmResponseType CryptoSession::Open(SecurityLevel requested_security_level) {
|
||||||
LOGV("CryptoSession::Open: Lock");
|
LOGV("CryptoSession::Open: Lock: requested_security_level: %d",
|
||||||
|
requested_security_level);
|
||||||
AutoLock auto_lock(crypto_lock_);
|
AutoLock auto_lock(crypto_lock_);
|
||||||
if (!initialized_) return UNKNOWN_ERROR;
|
if (!initialized_) return UNKNOWN_ERROR;
|
||||||
if (open_) return NO_ERROR;
|
if (open_) return NO_ERROR;
|
||||||
@@ -461,6 +475,35 @@ CdmResponseType CryptoSession::Open(SecurityLevel requested_security_level) {
|
|||||||
random_sts,
|
random_sts,
|
||||||
metrics::Pow2Bucket(sizeof(request_id_base_)));
|
metrics::Pow2Bucket(sizeof(request_id_base_)));
|
||||||
++request_id_index_;
|
++request_id_index_;
|
||||||
|
|
||||||
|
CdmUsageSupportType usage_support_type;
|
||||||
|
if (GetUsageSupportType(&usage_support_type) == NO_ERROR) {
|
||||||
|
if (usage_support_type == kUsageEntrySupport) {
|
||||||
|
CdmSecurityLevel security_level = GetSecurityLevel();
|
||||||
|
if (security_level == kSecurityLevelL1 ||
|
||||||
|
security_level == kSecurityLevelL3) {
|
||||||
|
UsageTableHeader* header = security_level == kSecurityLevelL1 ?
|
||||||
|
usage_table_header_l1_ : usage_table_header_l3_;
|
||||||
|
if (header == NULL) {
|
||||||
|
header = new UsageTableHeader();
|
||||||
|
// Ignore errors since we do not know when a session is opened,
|
||||||
|
// if it is intended to be used for offline/usage session related
|
||||||
|
// or otherwise.
|
||||||
|
if (!header->Init(security_level, this)) {
|
||||||
|
delete header;
|
||||||
|
usage_table_header_ = NULL;
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
|
if (security_level == kSecurityLevelL1)
|
||||||
|
usage_table_header_l1_ = header;
|
||||||
|
else
|
||||||
|
usage_table_header_l3_ = header;
|
||||||
|
}
|
||||||
|
usage_table_header_ = header;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1085,9 +1128,7 @@ CdmResponseType CryptoSession::UpdateUsageInformation() {
|
|||||||
AutoLock auto_lock(crypto_lock_);
|
AutoLock auto_lock(crypto_lock_);
|
||||||
if (!initialized_) return UNKNOWN_ERROR;
|
if (!initialized_) return UNKNOWN_ERROR;
|
||||||
|
|
||||||
CdmUsageSupportType usage_support_type;
|
if (usage_table_header_ != NULL) {
|
||||||
if (GetUsageSupportType(&usage_support_type) == NO_ERROR &&
|
|
||||||
usage_support_type == kUsageEntrySupport) {
|
|
||||||
LOGV("UpdateUsageInformation: deprecated for OEMCrypto v13+");
|
LOGV("UpdateUsageInformation: deprecated for OEMCrypto v13+");
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
@@ -1248,6 +1289,11 @@ CdmResponseType CryptoSession::ReleaseUsageInformation(
|
|||||||
LOGV("ReleaseUsageInformation: id=%ld", (uint32_t)oec_session_id_);
|
LOGV("ReleaseUsageInformation: id=%ld", (uint32_t)oec_session_id_);
|
||||||
{
|
{
|
||||||
AutoLock auto_lock(crypto_lock_);
|
AutoLock auto_lock(crypto_lock_);
|
||||||
|
if (usage_table_header_ != NULL) {
|
||||||
|
LOGW("ReleaseUsageInformation: deprecated for OEMCrypto v13+");
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
const uint8_t* msg = reinterpret_cast<const uint8_t*>(message.data());
|
const uint8_t* msg = reinterpret_cast<const uint8_t*>(message.data());
|
||||||
const uint8_t* sig = reinterpret_cast<const uint8_t*>(signature.data());
|
const uint8_t* sig = reinterpret_cast<const uint8_t*>(signature.data());
|
||||||
const uint8_t* pst = msg + GetOffset(message, provider_session_token);
|
const uint8_t* pst = msg + GetOffset(message, provider_session_token);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "clock.h"
|
#include "clock.h"
|
||||||
|
#include "cdm_session.h"
|
||||||
#include "crypto_key.h"
|
#include "crypto_key.h"
|
||||||
#include "crypto_session.h"
|
#include "crypto_session.h"
|
||||||
#include "device_files.h"
|
#include "device_files.h"
|
||||||
@@ -287,7 +288,8 @@ CdmResponseType CdmLicense::PrepareKeyRequest(
|
|||||||
|
|
||||||
CdmResponseType CdmLicense::PrepareKeyUpdateRequest(
|
CdmResponseType CdmLicense::PrepareKeyUpdateRequest(
|
||||||
bool is_renewal, const CdmAppParameterMap& app_parameters,
|
bool is_renewal, const CdmAppParameterMap& app_parameters,
|
||||||
CdmKeyMessage* signed_request, std::string* server_url) {
|
CdmSession* cdm_session, CdmKeyMessage* signed_request,
|
||||||
|
std::string* server_url) {
|
||||||
if (!initialized_) {
|
if (!initialized_) {
|
||||||
LOGE("CdmLicense::PrepareKeyUpdateRequest: not initialized");
|
LOGE("CdmLicense::PrepareKeyUpdateRequest: not initialized");
|
||||||
return LICENSE_PARSER_NOT_INITIALIZED_1;
|
return LICENSE_PARSER_NOT_INITIALIZED_1;
|
||||||
@@ -346,6 +348,12 @@ CdmResponseType CdmLicense::PrepareKeyUpdateRequest(
|
|||||||
if (NO_ERROR != status) return status;
|
if (NO_ERROR != status) return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(rfrias): Refactor to avoid needing to call CdmSession
|
||||||
|
if (cdm_session) {
|
||||||
|
CdmResponseType status = cdm_session->UpdateUsageEntryInformation();
|
||||||
|
if (NO_ERROR != status) return status;
|
||||||
|
}
|
||||||
|
|
||||||
std::string usage_report;
|
std::string usage_report;
|
||||||
CdmResponseType status = crypto_session_->GenerateUsageReport(
|
CdmResponseType status = crypto_session_->GenerateUsageReport(
|
||||||
provider_session_token_, &usage_report, &usage_duration_status,
|
provider_session_token_, &usage_report, &usage_duration_status,
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "crypto_session.h"
|
#include "crypto_session.h"
|
||||||
#include "license.h"
|
#include "license.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "metrics_group.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
std::string kEmptyString;
|
std::string kEmptyString;
|
||||||
@@ -12,78 +13,66 @@ std::string kEmptyString;
|
|||||||
|
|
||||||
namespace wvcdm {
|
namespace wvcdm {
|
||||||
|
|
||||||
UsageTableHeader* UsageTableHeader::usage_table_header_l1_ = NULL;
|
UsageTableHeader::UsageTableHeader()
|
||||||
UsageTableHeader* UsageTableHeader::usage_table_header_l3_ = NULL;
|
: security_level_(kSecurityLevelUninitialized),
|
||||||
|
requested_security_level_(kLevelDefault),
|
||||||
|
is_inited_(false) {
|
||||||
|
file_system_.reset(new FileSystem());
|
||||||
|
file_handle_.reset(new DeviceFiles(file_system_.get()));
|
||||||
|
}
|
||||||
|
|
||||||
Lock UsageTableHeader::initialization_lock_;
|
bool UsageTableHeader::Init(CdmSecurityLevel security_level,
|
||||||
|
|
||||||
UsageTableHeader* UsageTableHeader::GetInstance(FileSystem* file_system,
|
|
||||||
CryptoSession* crypto_session) {
|
CryptoSession* crypto_session) {
|
||||||
LOGV("UsageTableHeader::GetInstance");
|
LOGV("UsageTableHeader::Init: security level: %d", security_level);
|
||||||
AutoLock auto_lock(initialization_lock_);
|
if (crypto_session == NULL) {
|
||||||
CdmSecurityLevel security_level = crypto_session->GetSecurityLevel();
|
LOGE("UsageTableHeader::Init: no crypto session provided");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
switch (security_level) {
|
switch (security_level) {
|
||||||
case kSecurityLevelL1:
|
case kSecurityLevelL1:
|
||||||
if (usage_table_header_l1_ != NULL)
|
|
||||||
return usage_table_header_l1_;
|
|
||||||
break;
|
|
||||||
case kSecurityLevelL3:
|
case kSecurityLevelL3:
|
||||||
if (usage_table_header_l3_ != NULL)
|
|
||||||
return usage_table_header_l3_;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOGE("UsageTableHeader::GetInstance: unsupported security level: %d",
|
LOGE("UsageTableHeader::Init: invalid security level provided: %d",
|
||||||
security_level);
|
security_level);
|
||||||
return NULL;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
UsageTableHeader* header =
|
security_level_ = security_level;
|
||||||
new UsageTableHeader(file_system, crypto_session, security_level);
|
|
||||||
if (!header->is_inited()) {
|
|
||||||
delete header;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (security_level == kSecurityLevelL1)
|
if (!file_handle_->Init(security_level)) {
|
||||||
usage_table_header_l1_ = header;
|
LOGE("UsageTableHeader::Init: device files initialization failed");
|
||||||
else
|
return false;
|
||||||
usage_table_header_l3_ = header;
|
|
||||||
return header;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UsageTableHeader::UsageTableHeader(FileSystem* file_system,
|
|
||||||
CryptoSession* crypto_session,
|
|
||||||
CdmSecurityLevel security_level)
|
|
||||||
: file_handle_(new DeviceFiles(file_system)),
|
|
||||||
security_level_(security_level),
|
|
||||||
is_inited_(false) {
|
|
||||||
LOGV("UsageTableHeader::UsageTablerHeader: security level: %d",
|
|
||||||
security_level);
|
|
||||||
|
|
||||||
if (!file_handle_->RetrieveUsageTableInfo(&usage_table_header_,
|
if (!file_handle_->RetrieveUsageTableInfo(&usage_table_header_,
|
||||||
&usage_entry_info_)) {
|
&usage_entry_info_)) {
|
||||||
CdmResponseType status =
|
CdmResponseType status =
|
||||||
crypto_session->CreateUsageTableHeader(&usage_table_header_);
|
crypto_session->CreateUsageTableHeader(&usage_table_header_);
|
||||||
if (status != NO_ERROR) return;
|
if (status != NO_ERROR) return false;
|
||||||
|
file_handle_->StoreUsageTableInfo(usage_table_header_, usage_entry_info_);
|
||||||
} else {
|
} else {
|
||||||
CdmResponseType status =
|
CdmResponseType status =
|
||||||
crypto_session->LoadUsageTableHeader(usage_table_header_);
|
crypto_session->LoadUsageTableHeader(usage_table_header_);
|
||||||
if (status != NO_ERROR) {
|
if (status != NO_ERROR) {
|
||||||
LOGE(
|
LOGE(
|
||||||
"UsageTableHeader::UsageTablerHeader: load usage table failed, "
|
"UsageTableHeader::Init: load usage table failed, security level: %d",
|
||||||
"security level: %d",
|
|
||||||
security_level);
|
security_level);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
requested_security_level_ =
|
||||||
|
security_level_ == kSecurityLevelL3 ? kLevel3 : kLevelDefault;
|
||||||
is_inited_ = true;
|
is_inited_ = true;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
CdmResponseType UsageTableHeader::AddEntry(
|
CdmResponseType UsageTableHeader::AddEntry(
|
||||||
CryptoSession* crypto_session, bool persistent_license,
|
CryptoSession* crypto_session, bool persistent_license,
|
||||||
const CdmKeySetId& key_set_id, const std::string& usage_info_file_name,
|
const CdmKeySetId& key_set_id, const std::string& usage_info_file_name,
|
||||||
uint32_t* usage_entry_number) {
|
uint32_t* usage_entry_number) {
|
||||||
LOGV("UsageTableHeader::AddEntry");
|
LOGV("UsageTableHeader::AddEntry: Lock");
|
||||||
AutoLock auto_lock(usage_table_header_lock_);
|
AutoLock auto_lock(usage_table_header_lock_);
|
||||||
CdmResponseType status = crypto_session->CreateUsageEntry(usage_entry_number);
|
CdmResponseType status = crypto_session->CreateUsageEntry(usage_entry_number);
|
||||||
|
|
||||||
@@ -120,14 +109,16 @@ CdmResponseType UsageTableHeader::AddEntry(
|
|||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
CdmResponseType UsageTableHeader::LoadEntry(
|
CdmResponseType UsageTableHeader::LoadEntry(CryptoSession* crypto_session,
|
||||||
CryptoSession* crypto_session, const CdmUsageEntry& usage_entry,
|
const CdmUsageEntry& usage_entry,
|
||||||
uint32_t usage_entry_number) {
|
uint32_t usage_entry_number) {
|
||||||
LOGV("UsageTableHeader::LoadEntry");
|
LOGV("UsageTableHeader::LoadEntry: Lock");
|
||||||
AutoLock auto_lock(usage_table_header_lock_);
|
AutoLock auto_lock(usage_table_header_lock_);
|
||||||
|
|
||||||
if (usage_entry_number >= usage_entry_info_.size()) {
|
if (usage_entry_number >= usage_entry_info_.size()) {
|
||||||
LOGE("UsageTableHeader::LoadEntry: usage entry number %d larger than table size: %d",
|
LOGE(
|
||||||
|
"UsageTableHeader::LoadEntry: usage entry number %d larger than table "
|
||||||
|
"size: %d",
|
||||||
usage_entry_number, usage_entry_info_.size());
|
usage_entry_number, usage_entry_info_.size());
|
||||||
return USAGE_INVALID_LOAD_ENTRY;
|
return USAGE_INVALID_LOAD_ENTRY;
|
||||||
}
|
}
|
||||||
@@ -136,20 +127,21 @@ CdmResponseType UsageTableHeader::LoadEntry(
|
|||||||
|
|
||||||
CdmResponseType UsageTableHeader::UpdateEntry(CryptoSession* crypto_session,
|
CdmResponseType UsageTableHeader::UpdateEntry(CryptoSession* crypto_session,
|
||||||
CdmUsageEntry* usage_entry) {
|
CdmUsageEntry* usage_entry) {
|
||||||
LOGV("UsageTableHeader::UpdateEntry");
|
LOGV("UsageTableHeader::UpdateEntryL: Lock");
|
||||||
AutoLock auto_lock(usage_table_header_lock_);
|
AutoLock auto_lock(usage_table_header_lock_);
|
||||||
CdmUsageTableHeader usage_table_header;
|
|
||||||
CdmResponseType status =
|
CdmResponseType status =
|
||||||
crypto_session->UpdateUsageEntry(&usage_table_header_, usage_entry);
|
crypto_session->UpdateUsageEntry(&usage_table_header_, usage_entry);
|
||||||
|
|
||||||
if (status != NO_ERROR) return status;
|
if (status != NO_ERROR) return status;
|
||||||
|
|
||||||
file_handle_->StoreUsageTableInfo(usage_table_header, usage_entry_info_);
|
file_handle_->StoreUsageTableInfo(usage_table_header_, usage_entry_info_);
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
CdmResponseType UsageTableHeader::DeleteEntry(uint32_t usage_entry_number) {
|
CdmResponseType UsageTableHeader::DeleteEntry(uint32_t usage_entry_number,
|
||||||
LOGV("UsageTableHeader::DeleteEntry");
|
DeviceFiles* handle,
|
||||||
|
metrics::MetricsGroup* metrics) {
|
||||||
|
LOGV("UsageTableHeader::DeleteEntry: Lock");
|
||||||
AutoLock auto_lock(usage_table_header_lock_);
|
AutoLock auto_lock(usage_table_header_lock_);
|
||||||
if (usage_entry_number >= usage_entry_info_.size())
|
if (usage_entry_number >= usage_entry_info_.size())
|
||||||
return USAGE_INVALID_PARAMETERS_1;
|
return USAGE_INVALID_PARAMETERS_1;
|
||||||
@@ -159,12 +151,12 @@ CdmResponseType UsageTableHeader::DeleteEntry(uint32_t usage_entry_number) {
|
|||||||
CdmUsageEntry swap_usage_entry;
|
CdmUsageEntry swap_usage_entry;
|
||||||
bool swap_usage_entry_valid = false;
|
bool swap_usage_entry_valid = false;
|
||||||
|
|
||||||
for (; !swap_usage_entry_valid && swap_entry_number > usage_entry_number;
|
while (!swap_usage_entry_valid && swap_entry_number > usage_entry_number) {
|
||||||
--swap_entry_number) {
|
|
||||||
switch (usage_entry_info_[swap_entry_number].storage_type) {
|
switch (usage_entry_info_[swap_entry_number].storage_type) {
|
||||||
case kStorageLicense:
|
case kStorageLicense:
|
||||||
case kStorageUsageInfo: {
|
case kStorageUsageInfo: {
|
||||||
CdmResponseType status = GetEntry(swap_entry_number, &swap_usage_entry);
|
CdmResponseType status =
|
||||||
|
GetEntry(swap_entry_number, handle, &swap_usage_entry);
|
||||||
if (status == NO_ERROR) swap_usage_entry_valid = true;
|
if (status == NO_ERROR) swap_usage_entry_valid = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -172,37 +164,54 @@ CdmResponseType UsageTableHeader::DeleteEntry(uint32_t usage_entry_number) {
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (!swap_usage_entry_valid) --swap_entry_number;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t new_usage_table_size = 0;
|
uint32_t number_of_entries_to_be_deleted =
|
||||||
|
usage_entry_info_.size() - usage_entry_number;
|
||||||
|
|
||||||
if (swap_usage_entry_valid) {
|
if (swap_usage_entry_valid) {
|
||||||
MoveEntry(swap_entry_number, swap_usage_entry, usage_entry_number);
|
CdmResponseType status = MoveEntry(swap_entry_number, swap_usage_entry,
|
||||||
new_usage_table_size = swap_entry_number;
|
usage_entry_number, handle, metrics);
|
||||||
|
// If unable to move entry, unset storage type of entry to be deleted and
|
||||||
|
// resize |usage_entry_info_| so that swap usage entry is the last entry.
|
||||||
|
if (status != NO_ERROR) {
|
||||||
|
usage_entry_info_[usage_entry_number].storage_type = kStorageUnknown;
|
||||||
|
usage_entry_info_[usage_entry_number].key_set_id.clear();
|
||||||
|
if (usage_entry_info_.size() - 1 == swap_entry_number) {
|
||||||
|
file_handle_->StoreUsageTableInfo(usage_table_header_,
|
||||||
|
usage_entry_info_);
|
||||||
} else {
|
} else {
|
||||||
// No valid usage entries before entry to be deleted
|
Shrink(metrics, usage_entry_info_.size() - swap_entry_number - 1);
|
||||||
new_usage_table_size = usage_entry_number;
|
|
||||||
}
|
}
|
||||||
usage_entry_info_.resize(new_usage_table_size);
|
|
||||||
CryptoSession crypto_session(&metrics_);
|
|
||||||
crypto_session.Open(GetSecurityLevel());
|
|
||||||
crypto_session.ShrinkUsageTableHeader(new_usage_table_size,
|
|
||||||
&usage_table_header_);
|
|
||||||
file_handle_->StoreUsageTableInfo(usage_table_header_, usage_entry_info_);
|
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
number_of_entries_to_be_deleted =
|
||||||
|
usage_entry_info_.size() - swap_entry_number;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Shrink(metrics, number_of_entries_to_be_deleted);
|
||||||
|
}
|
||||||
|
|
||||||
CdmResponseType UsageTableHeader::MoveEntry(
|
CdmResponseType UsageTableHeader::MoveEntry(
|
||||||
uint32_t from_usage_entry_number, const CdmUsageEntry& from_usage_entry,
|
uint32_t from_usage_entry_number, const CdmUsageEntry& from_usage_entry,
|
||||||
uint32_t to_usage_entry_number) {
|
uint32_t to_usage_entry_number, DeviceFiles* handle,
|
||||||
|
metrics::MetricsGroup* metrics) {
|
||||||
LOGV("UsageTableHeader::MoveEntry");
|
LOGV("UsageTableHeader::MoveEntry");
|
||||||
AutoLock auto_lock(usage_table_header_lock_);
|
|
||||||
|
|
||||||
CryptoSession crypto_session(&metrics_);
|
// crypto_session points to an object whose scope is this method or a test
|
||||||
crypto_session.Open(GetSecurityLevel());
|
// object whose scope is the lifetime of this class
|
||||||
|
scoped_ptr<CryptoSession> scoped_crypto_session;
|
||||||
|
CryptoSession* crypto_session = test_crypto_session_.get();
|
||||||
|
if (crypto_session == NULL) {
|
||||||
|
scoped_crypto_session.reset((new CryptoSession(metrics)));
|
||||||
|
crypto_session = scoped_crypto_session.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
crypto_session->Open(requested_security_level_);
|
||||||
|
|
||||||
CdmResponseType status =
|
CdmResponseType status =
|
||||||
crypto_session.LoadUsageEntry(from_usage_entry_number, from_usage_entry);
|
crypto_session->LoadUsageEntry(from_usage_entry_number, from_usage_entry);
|
||||||
|
|
||||||
if (status != NO_ERROR) {
|
if (status != NO_ERROR) {
|
||||||
LOGE("UsageTableHeader::MoveEntry: Failed to load usage entry: %d",
|
LOGE("UsageTableHeader::MoveEntry: Failed to load usage entry: %d",
|
||||||
@@ -210,7 +219,7 @@ CdmResponseType UsageTableHeader::MoveEntry(
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = crypto_session.MoveUsageEntry(to_usage_entry_number);
|
status = crypto_session->MoveUsageEntry(to_usage_entry_number);
|
||||||
|
|
||||||
if (status != NO_ERROR) {
|
if (status != NO_ERROR) {
|
||||||
LOGE("UsageTableHeader::MoveEntry: Failed to move usage entry: %d->%d",
|
LOGE("UsageTableHeader::MoveEntry: Failed to move usage entry: %d->%d",
|
||||||
@@ -222,7 +231,7 @@ CdmResponseType UsageTableHeader::MoveEntry(
|
|||||||
usage_entry_info_[from_usage_entry_number];
|
usage_entry_info_[from_usage_entry_number];
|
||||||
|
|
||||||
CdmUsageEntry usage_entry;
|
CdmUsageEntry usage_entry;
|
||||||
status = crypto_session.UpdateUsageEntry(&usage_table_header_, &usage_entry);
|
status = crypto_session->UpdateUsageEntry(&usage_table_header_, &usage_entry);
|
||||||
|
|
||||||
if (status != NO_ERROR) {
|
if (status != NO_ERROR) {
|
||||||
LOGE("UsageTableHeader::MoveEntry: Failed to update usage entry: %d",
|
LOGE("UsageTableHeader::MoveEntry: Failed to update usage entry: %d",
|
||||||
@@ -232,12 +241,13 @@ CdmResponseType UsageTableHeader::MoveEntry(
|
|||||||
|
|
||||||
file_handle_->StoreUsageTableInfo(usage_table_header_, usage_entry_info_);
|
file_handle_->StoreUsageTableInfo(usage_table_header_, usage_entry_info_);
|
||||||
|
|
||||||
StoreEntry(to_usage_entry_number, usage_entry);
|
StoreEntry(to_usage_entry_number, handle, usage_entry);
|
||||||
|
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
CdmResponseType UsageTableHeader::GetEntry(uint32_t usage_entry_number,
|
CdmResponseType UsageTableHeader::GetEntry(uint32_t usage_entry_number,
|
||||||
|
DeviceFiles* handle,
|
||||||
CdmUsageEntry* usage_entry) {
|
CdmUsageEntry* usage_entry) {
|
||||||
uint32_t entry_number;
|
uint32_t entry_number;
|
||||||
switch (usage_entry_info_[usage_entry_number].storage_type) {
|
switch (usage_entry_info_[usage_entry_number].storage_type) {
|
||||||
@@ -247,7 +257,7 @@ CdmResponseType UsageTableHeader::GetEntry(uint32_t usage_entry_number,
|
|||||||
std::string key_renewal_response, release_server_url;
|
std::string key_renewal_response, release_server_url;
|
||||||
int64_t playback_start_time, last_playback_time, grace_period_end_time;
|
int64_t playback_start_time, last_playback_time, grace_period_end_time;
|
||||||
CdmAppParameterMap app_parameters;
|
CdmAppParameterMap app_parameters;
|
||||||
if (!file_handle_->RetrieveLicense(
|
if (!handle->RetrieveLicense(
|
||||||
usage_entry_info_[usage_entry_number].key_set_id, &license_state,
|
usage_entry_info_[usage_entry_number].key_set_id, &license_state,
|
||||||
&init_data, &key_request, &key_response, &key_renewal_request,
|
&init_data, &key_request, &key_response, &key_renewal_request,
|
||||||
&key_renewal_response, &release_server_url, &playback_start_time,
|
&key_renewal_response, &release_server_url, &playback_start_time,
|
||||||
@@ -263,7 +273,7 @@ CdmResponseType UsageTableHeader::GetEntry(uint32_t usage_entry_number,
|
|||||||
CdmKeyMessage license_request;
|
CdmKeyMessage license_request;
|
||||||
CdmKeyResponse license_response;
|
CdmKeyResponse license_response;
|
||||||
|
|
||||||
if (!file_handle_->RetrieveUsageInfoByKeySetId(
|
if (!handle->RetrieveUsageInfoByKeySetId(
|
||||||
usage_entry_info_[usage_entry_number].usage_info_file_name,
|
usage_entry_info_[usage_entry_number].usage_info_file_name,
|
||||||
usage_entry_info_[usage_entry_number].key_set_id,
|
usage_entry_info_[usage_entry_number].key_set_id,
|
||||||
&provider_session_token, &license_request, &license_response,
|
&provider_session_token, &license_request, &license_response,
|
||||||
@@ -293,6 +303,7 @@ CdmResponseType UsageTableHeader::GetEntry(uint32_t usage_entry_number,
|
|||||||
}
|
}
|
||||||
|
|
||||||
CdmResponseType UsageTableHeader::StoreEntry(uint32_t usage_entry_number,
|
CdmResponseType UsageTableHeader::StoreEntry(uint32_t usage_entry_number,
|
||||||
|
DeviceFiles* handle,
|
||||||
const CdmUsageEntry& usage_entry) {
|
const CdmUsageEntry& usage_entry) {
|
||||||
uint32_t entry_number;
|
uint32_t entry_number;
|
||||||
switch (usage_entry_info_[usage_entry_number].storage_type) {
|
switch (usage_entry_info_[usage_entry_number].storage_type) {
|
||||||
@@ -303,7 +314,7 @@ CdmResponseType UsageTableHeader::StoreEntry(uint32_t usage_entry_number,
|
|||||||
int64_t playback_start_time, last_playback_time, grace_period_end_time;
|
int64_t playback_start_time, last_playback_time, grace_period_end_time;
|
||||||
CdmAppParameterMap app_parameters;
|
CdmAppParameterMap app_parameters;
|
||||||
CdmUsageEntry entry;
|
CdmUsageEntry entry;
|
||||||
if (!file_handle_->RetrieveLicense(
|
if (!handle->RetrieveLicense(
|
||||||
usage_entry_info_[usage_entry_number].key_set_id, &license_state,
|
usage_entry_info_[usage_entry_number].key_set_id, &license_state,
|
||||||
&init_data, &key_request, &key_response, &key_renewal_request,
|
&init_data, &key_request, &key_response, &key_renewal_request,
|
||||||
&key_renewal_response, &release_server_url, &playback_start_time,
|
&key_renewal_response, &release_server_url, &playback_start_time,
|
||||||
@@ -312,7 +323,7 @@ CdmResponseType UsageTableHeader::StoreEntry(uint32_t usage_entry_number,
|
|||||||
LOGE("UsageTableHeader::StoreEntry: Failed to retrieve license");
|
LOGE("UsageTableHeader::StoreEntry: Failed to retrieve license");
|
||||||
return USAGE_RETRIEVE_LICENSE_FAILED;
|
return USAGE_RETRIEVE_LICENSE_FAILED;
|
||||||
}
|
}
|
||||||
if (!file_handle_->StoreLicense(
|
if (!handle->StoreLicense(
|
||||||
usage_entry_info_[usage_entry_number].key_set_id, license_state,
|
usage_entry_info_[usage_entry_number].key_set_id, license_state,
|
||||||
init_data, key_request, key_response, key_renewal_request,
|
init_data, key_request, key_response, key_renewal_request,
|
||||||
key_renewal_response, release_server_url, playback_start_time,
|
key_renewal_response, release_server_url, playback_start_time,
|
||||||
@@ -327,7 +338,7 @@ CdmResponseType UsageTableHeader::StoreEntry(uint32_t usage_entry_number,
|
|||||||
CdmUsageEntry entry;
|
CdmUsageEntry entry;
|
||||||
std::string provider_session_token, init_data, key_request, key_response,
|
std::string provider_session_token, init_data, key_request, key_response,
|
||||||
key_renewal_request;
|
key_renewal_request;
|
||||||
if (!file_handle_->RetrieveUsageInfoByKeySetId(
|
if (!handle->RetrieveUsageInfoByKeySetId(
|
||||||
usage_entry_info_[usage_entry_number].usage_info_file_name,
|
usage_entry_info_[usage_entry_number].usage_info_file_name,
|
||||||
usage_entry_info_[usage_entry_number].key_set_id,
|
usage_entry_info_[usage_entry_number].key_set_id,
|
||||||
&provider_session_token, &key_request, &key_response, &entry,
|
&provider_session_token, &key_request, &key_response, &entry,
|
||||||
@@ -337,10 +348,10 @@ CdmResponseType UsageTableHeader::StoreEntry(uint32_t usage_entry_number,
|
|||||||
"information");
|
"information");
|
||||||
return USAGE_RETRIEVE_USAGE_INFO_FAILED;
|
return USAGE_RETRIEVE_USAGE_INFO_FAILED;
|
||||||
}
|
}
|
||||||
file_handle_->DeleteUsageInfo(
|
handle->DeleteUsageInfo(
|
||||||
usage_entry_info_[usage_entry_number].usage_info_file_name,
|
usage_entry_info_[usage_entry_number].usage_info_file_name,
|
||||||
provider_session_token);
|
provider_session_token);
|
||||||
if (!file_handle_->StoreUsageInfo(
|
if (!handle->StoreUsageInfo(
|
||||||
provider_session_token, key_request, key_response,
|
provider_session_token, key_request, key_response,
|
||||||
usage_entry_info_[usage_entry_number].usage_info_file_name,
|
usage_entry_info_[usage_entry_number].usage_info_file_name,
|
||||||
usage_entry_info_[usage_entry_number].key_set_id, usage_entry,
|
usage_entry_info_[usage_entry_number].key_set_id, usage_entry,
|
||||||
@@ -361,41 +372,56 @@ CdmResponseType UsageTableHeader::StoreEntry(uint32_t usage_entry_number,
|
|||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UsageTableHeader::DeleteLastEntry() {
|
CdmResponseType UsageTableHeader::Shrink(
|
||||||
|
metrics::MetricsGroup* metrics,
|
||||||
|
uint32_t number_of_usage_entries_to_delete) {
|
||||||
if (usage_entry_info_.empty()) {
|
if (usage_entry_info_.empty()) {
|
||||||
|
LOGE("UsageTableHeader::Shrink: usage entry info table unexpectedly empty");
|
||||||
|
return NO_USAGE_ENTRIES;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (usage_entry_info_.size() < number_of_usage_entries_to_delete) {
|
||||||
LOGW(
|
LOGW(
|
||||||
"UsageTableHeader::DeleteLastEntry: usage entry info table "
|
"UsageTableHeader::Shrink: cannot delete %d entries when usage entry "
|
||||||
"unexpectedly empty");
|
"table size is %d", number_of_usage_entries_to_delete,
|
||||||
return false;
|
usage_entry_info_.size());
|
||||||
}
|
|
||||||
|
|
||||||
usage_entry_info_.resize(usage_entry_info_.size() - 1);
|
|
||||||
|
|
||||||
CryptoSession crypto_session(&metrics_);
|
|
||||||
crypto_session.Open(GetSecurityLevel());
|
|
||||||
crypto_session.ShrinkUsageTableHeader(usage_entry_info_.size(),
|
|
||||||
&usage_table_header_);
|
|
||||||
file_handle_->StoreUsageTableInfo(usage_table_header_, usage_entry_info_);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
CdmResponseType UsageTableHeader::UpgradeFromUsageTable() {
|
|
||||||
CryptoSession crypto_session(&metrics_);
|
|
||||||
CdmResponseType status = crypto_session.Open(GetSecurityLevel());
|
|
||||||
|
|
||||||
if (status != NO_ERROR) return status;
|
|
||||||
|
|
||||||
status = crypto_session.CreateUsageTableHeader(&usage_table_header_);
|
|
||||||
if (status != NO_ERROR) return status;
|
|
||||||
|
|
||||||
crypto_session.Close();
|
|
||||||
|
|
||||||
UpgradeLicensesFromUsageTable();
|
|
||||||
UpgradeUsageInfoFromUsageTable();
|
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UsageTableHeader::UpgradeLicensesFromUsageTable() {
|
if (number_of_usage_entries_to_delete == 0) return NO_ERROR;
|
||||||
|
|
||||||
|
usage_entry_info_.resize(usage_entry_info_.size() -
|
||||||
|
number_of_usage_entries_to_delete);
|
||||||
|
|
||||||
|
// crypto_session points to an object whose scope is this method or a test
|
||||||
|
// object whose scope is the lifetime of this class
|
||||||
|
scoped_ptr<CryptoSession> scoped_crypto_session;
|
||||||
|
CryptoSession* crypto_session = test_crypto_session_.get();
|
||||||
|
if (crypto_session == NULL) {
|
||||||
|
scoped_crypto_session.reset((new CryptoSession(metrics)));
|
||||||
|
crypto_session = scoped_crypto_session.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
CdmResponseType status = crypto_session->Open(requested_security_level_);
|
||||||
|
if (status != NO_ERROR) return status;
|
||||||
|
|
||||||
|
status = crypto_session->ShrinkUsageTableHeader(usage_entry_info_.size(),
|
||||||
|
&usage_table_header_);
|
||||||
|
if (status != NO_ERROR) return status;
|
||||||
|
|
||||||
|
file_handle_->StoreUsageTableInfo(usage_table_header_, usage_entry_info_);
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
CdmResponseType UsageTableHeader::UpgradeFromUsageTable(
|
||||||
|
DeviceFiles* handle, metrics::MetricsGroup* metrics) {
|
||||||
|
UpgradeLicensesFromUsageTable(handle, metrics);
|
||||||
|
UpgradeUsageInfoFromUsageTable(handle, metrics);
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UsageTableHeader::UpgradeLicensesFromUsageTable(
|
||||||
|
DeviceFiles* handle, metrics::MetricsGroup* metrics) {
|
||||||
// Fetch the key set IDs for each offline license. For each license
|
// Fetch the key set IDs for each offline license. For each license
|
||||||
// * retrieve the provider session token,
|
// * retrieve the provider session token,
|
||||||
// * create a new usage entry
|
// * create a new usage entry
|
||||||
@@ -404,7 +430,7 @@ bool UsageTableHeader::UpgradeLicensesFromUsageTable() {
|
|||||||
// * save the usage table header and store the usage entry number and
|
// * save the usage table header and store the usage entry number and
|
||||||
// usage entry along with the license to persistent memory
|
// usage entry along with the license to persistent memory
|
||||||
std::vector<std::string> key_set_ids;
|
std::vector<std::string> key_set_ids;
|
||||||
if (file_handle_->ListLicenses(&key_set_ids)) {
|
if (handle->ListLicenses(&key_set_ids)) {
|
||||||
LOGW(
|
LOGW(
|
||||||
"UpgradeUsageTableHeader::UpgradeLicensesFromUsageTable: unable to "
|
"UpgradeUsageTableHeader::UpgradeLicensesFromUsageTable: unable to "
|
||||||
"retrieve list of licenses");
|
"retrieve list of licenses");
|
||||||
@@ -419,7 +445,7 @@ bool UsageTableHeader::UpgradeLicensesFromUsageTable() {
|
|||||||
CdmAppParameterMap app_parameters;
|
CdmAppParameterMap app_parameters;
|
||||||
CdmUsageEntry usage_entry;
|
CdmUsageEntry usage_entry;
|
||||||
uint32_t usage_entry_number;
|
uint32_t usage_entry_number;
|
||||||
if (!file_handle_->RetrieveLicense(
|
if (!handle->RetrieveLicense(
|
||||||
key_set_ids[i], &license_state, &init_data, &key_request,
|
key_set_ids[i], &license_state, &init_data, &key_request,
|
||||||
&key_response, &key_renewal_request, &key_renewal_response,
|
&key_response, &key_renewal_request, &key_renewal_response,
|
||||||
&release_server_url, &playback_start_time, &last_playback_time,
|
&release_server_url, &playback_start_time, &last_playback_time,
|
||||||
@@ -442,8 +468,8 @@ bool UsageTableHeader::UpgradeLicensesFromUsageTable() {
|
|||||||
|
|
||||||
if (provider_session_token.empty()) continue;
|
if (provider_session_token.empty()) continue;
|
||||||
|
|
||||||
CryptoSession crypto_session(&metrics_);
|
CryptoSession crypto_session(metrics);
|
||||||
CdmResponseType status = crypto_session.Open(GetSecurityLevel());
|
CdmResponseType status = crypto_session.Open(requested_security_level_);
|
||||||
|
|
||||||
if (status != NO_ERROR) continue;
|
if (status != NO_ERROR) continue;
|
||||||
|
|
||||||
@@ -456,7 +482,7 @@ bool UsageTableHeader::UpgradeLicensesFromUsageTable() {
|
|||||||
|
|
||||||
if (status != NO_ERROR) {
|
if (status != NO_ERROR) {
|
||||||
crypto_session.Close();
|
crypto_session.Close();
|
||||||
DeleteLastEntry();
|
Shrink(metrics, 1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -464,16 +490,18 @@ bool UsageTableHeader::UpgradeLicensesFromUsageTable() {
|
|||||||
|
|
||||||
if (status != NO_ERROR) {
|
if (status != NO_ERROR) {
|
||||||
crypto_session.Close();
|
crypto_session.Close();
|
||||||
DeleteLastEntry();
|
Shrink(metrics, 1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!file_handle_->StoreLicense(
|
if (!handle->StoreLicense(
|
||||||
key_set_ids[i], license_state, init_data, key_request, key_response,
|
key_set_ids[i], license_state, init_data, key_request, key_response,
|
||||||
key_renewal_request, key_renewal_response, release_server_url,
|
key_renewal_request, key_renewal_response, release_server_url,
|
||||||
playback_start_time, last_playback_time, grace_period_end_time,
|
playback_start_time, last_playback_time, grace_period_end_time,
|
||||||
app_parameters, usage_entry, usage_entry_number)) {
|
app_parameters, usage_entry, usage_entry_number)) {
|
||||||
LOGE("UsageTableHeader::StoreEntry: Failed to store license");
|
LOGE(
|
||||||
|
"UsageTableHeader::UpgradeLicensesFromUsageTable: Failed to store "
|
||||||
|
"license");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -481,7 +509,8 @@ bool UsageTableHeader::UpgradeLicensesFromUsageTable() {
|
|||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UsageTableHeader::UpgradeUsageInfoFromUsageTable() {
|
bool UsageTableHeader::UpgradeUsageInfoFromUsageTable(
|
||||||
|
DeviceFiles* handle, metrics::MetricsGroup* metrics) {
|
||||||
// Fetch all usage files. For each file retrieve all the usage info records
|
// Fetch all usage files. For each file retrieve all the usage info records
|
||||||
// within the file. For each piece of usage information
|
// within the file. For each piece of usage information
|
||||||
// * create a new usage entry
|
// * create a new usage entry
|
||||||
@@ -492,7 +521,7 @@ bool UsageTableHeader::UpgradeUsageInfoFromUsageTable() {
|
|||||||
// information to persistent memory along with usage entry number and usage
|
// information to persistent memory along with usage entry number and usage
|
||||||
// entry.
|
// entry.
|
||||||
std::vector<std::string> usage_info_file_names;
|
std::vector<std::string> usage_info_file_names;
|
||||||
if (file_handle_->ListUsageInfoFiles(&usage_info_file_names)) {
|
if (handle->ListUsageInfoFiles(&usage_info_file_names)) {
|
||||||
LOGW(
|
LOGW(
|
||||||
"UpgradeUsageTableHeader::UpgradeUsageInfoFromUsageTable: Unable to "
|
"UpgradeUsageTableHeader::UpgradeUsageInfoFromUsageTable: Unable to "
|
||||||
"retrieve list of usage info file names");
|
"retrieve list of usage info file names");
|
||||||
@@ -501,8 +530,7 @@ bool UsageTableHeader::UpgradeUsageInfoFromUsageTable() {
|
|||||||
|
|
||||||
for (size_t i = 0; i < usage_info_file_names.size(); ++i) {
|
for (size_t i = 0; i < usage_info_file_names.size(); ++i) {
|
||||||
std::vector<DeviceFiles::CdmUsageData> usage_data;
|
std::vector<DeviceFiles::CdmUsageData> usage_data;
|
||||||
if (!file_handle_->RetrieveUsageInfo(usage_info_file_names[i],
|
if (!handle->RetrieveUsageInfo(usage_info_file_names[i], &usage_data)) {
|
||||||
&usage_data)) {
|
|
||||||
LOGW(
|
LOGW(
|
||||||
"UsageTableHeader::UpgradeUsageInfoFromUsageTable: Failed to "
|
"UsageTableHeader::UpgradeUsageInfoFromUsageTable: Failed to "
|
||||||
"retrieve usage records from %s",
|
"retrieve usage records from %s",
|
||||||
@@ -518,8 +546,8 @@ bool UsageTableHeader::UpgradeUsageInfoFromUsageTable() {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
CryptoSession crypto_session(&metrics_);
|
CryptoSession crypto_session(metrics);
|
||||||
CdmResponseType status = crypto_session.Open(GetSecurityLevel());
|
CdmResponseType status = crypto_session.Open(requested_security_level_);
|
||||||
|
|
||||||
if (status != NO_ERROR) continue;
|
if (status != NO_ERROR) continue;
|
||||||
|
|
||||||
@@ -536,7 +564,7 @@ bool UsageTableHeader::UpgradeUsageInfoFromUsageTable() {
|
|||||||
|
|
||||||
if (status != NO_ERROR) {
|
if (status != NO_ERROR) {
|
||||||
crypto_session.Close();
|
crypto_session.Close();
|
||||||
DeleteLastEntry();
|
Shrink(metrics, 1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -544,12 +572,12 @@ bool UsageTableHeader::UpgradeUsageInfoFromUsageTable() {
|
|||||||
|
|
||||||
if (status != NO_ERROR) {
|
if (status != NO_ERROR) {
|
||||||
crypto_session.Close();
|
crypto_session.Close();
|
||||||
DeleteLastEntry();
|
Shrink(metrics, 1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!file_handle_->StoreUsageInfo(usage_info_file_names[i], usage_data)) {
|
if (!handle->StoreUsageInfo(usage_info_file_names[i], usage_data)) {
|
||||||
LOGE(
|
LOGE(
|
||||||
"UsageTableHeader::StoreUsageInfo: Failed to store usage records to "
|
"UsageTableHeader::StoreUsageInfo: Failed to store usage records to "
|
||||||
"%s",
|
"%s",
|
||||||
|
|||||||
@@ -574,6 +574,9 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) {
|
|||||||
case KEY_NOT_FOUND_IN_SESSION:
|
case KEY_NOT_FOUND_IN_SESSION:
|
||||||
*os << "KEY_NOT_FOUND_IN_SESSION";
|
*os << "KEY_NOT_FOUND_IN_SESSION";
|
||||||
break;
|
break;
|
||||||
|
case NO_USAGE_ENTRIES:
|
||||||
|
*os << "NO_USAGE_ENTRIES";
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
*os << "Unknown CdmResponseType";
|
*os << "Unknown CdmResponseType";
|
||||||
|
|||||||
1563
libwvdrmengine/cdm/core/test/usage_table_header_unittest.cpp
Normal file
1563
libwvdrmengine/cdm/core/test/usage_table_header_unittest.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -71,6 +71,10 @@ test_name := timer_unittest
|
|||||||
test_src_dir := .
|
test_src_dir := .
|
||||||
include $(LOCAL_PATH)/unit-test.mk
|
include $(LOCAL_PATH)/unit-test.mk
|
||||||
|
|
||||||
|
test_name := usage_table_header_unittest
|
||||||
|
test_src_dir := ../core/test
|
||||||
|
include $(LOCAL_PATH)/unit-test.mk
|
||||||
|
|
||||||
test_name := distribution_test
|
test_name := distribution_test
|
||||||
test_src_dir := ../metrics/test
|
test_src_dir := ../metrics/test
|
||||||
include $(LOCAL_PATH)/unit-test.mk
|
include $(LOCAL_PATH)/unit-test.mk
|
||||||
|
|||||||
@@ -2617,6 +2617,11 @@ TEST_P(WvCdmUsageInfoTest, UsageInfo) {
|
|||||||
key_id.append(1, ch);
|
key_id.append(1, ch);
|
||||||
|
|
||||||
GenerateKeyRequest(key_id, kLicenseTypeStreaming, property_set);
|
GenerateKeyRequest(key_id, kLicenseTypeStreaming, property_set);
|
||||||
|
|
||||||
|
// TODO(rfrias): streaming_clip6 is a streaming license without a pst
|
||||||
|
if (ch == '6')
|
||||||
|
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
|
||||||
|
else
|
||||||
VerifyUsageKeyRequestResponse(g_license_server, g_client_auth);
|
VerifyUsageKeyRequestResponse(g_license_server, g_client_auth);
|
||||||
|
|
||||||
std::vector<uint8_t> decrypt_buffer(data->encrypt_data.size());
|
std::vector<uint8_t> decrypt_buffer(data->encrypt_data.size());
|
||||||
@@ -2693,6 +2698,10 @@ TEST_F(WvCdmRequestLicenseTest, UsageReleaseAllTest) {
|
|||||||
key_id.append(1, ch);
|
key_id.append(1, ch);
|
||||||
|
|
||||||
GenerateKeyRequest(key_id, kLicenseTypeStreaming, &property_set);
|
GenerateKeyRequest(key_id, kLicenseTypeStreaming, &property_set);
|
||||||
|
// TODO(rfrias): streaming_clip6 is a streaming license without a pst
|
||||||
|
if (ch == '6')
|
||||||
|
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
|
||||||
|
else
|
||||||
VerifyUsageKeyRequestResponse(g_license_server, g_client_auth);
|
VerifyUsageKeyRequestResponse(g_license_server, g_client_auth);
|
||||||
|
|
||||||
std::vector<uint8_t> decrypt_buffer(data->encrypt_data.size());
|
std::vector<uint8_t> decrypt_buffer(data->encrypt_data.size());
|
||||||
|
|||||||
@@ -259,10 +259,11 @@ enum {
|
|||||||
kReleaseUsageInfoFailed = ERROR_DRM_VENDOR_MIN + 246,
|
kReleaseUsageInfoFailed = ERROR_DRM_VENDOR_MIN + 246,
|
||||||
kIncorrectUsageSupportType1 = ERROR_DRM_VENDOR_MIN + 247,
|
kIncorrectUsageSupportType1 = ERROR_DRM_VENDOR_MIN + 247,
|
||||||
kIncorrectUsageSupportType2 = ERROR_DRM_VENDOR_MIN + 248,
|
kIncorrectUsageSupportType2 = ERROR_DRM_VENDOR_MIN + 248,
|
||||||
|
kNoUsageEntries = ERROR_DRM_VENDOR_MIN + 249,
|
||||||
|
|
||||||
// This should always follow the last error code.
|
// This should always follow the last error code.
|
||||||
// The offset value should be updated each time a new error code is added.
|
// The offset value should be updated each time a new error code is added.
|
||||||
kErrorWVDrmMaxErrorUsed = ERROR_DRM_VENDOR_MIN + 248,
|
kErrorWVDrmMaxErrorUsed = ERROR_DRM_VENDOR_MIN + 249,
|
||||||
|
|
||||||
// Used by crypto test mode
|
// Used by crypto test mode
|
||||||
kErrorTestMode = ERROR_DRM_VENDOR_MAX,
|
kErrorTestMode = ERROR_DRM_VENDOR_MAX,
|
||||||
|
|||||||
@@ -503,6 +503,8 @@ static android::status_t mapCdmResponseType(wvcdm::CdmResponseType res) {
|
|||||||
return kIncorrectUsageSupportType1;
|
return kIncorrectUsageSupportType1;
|
||||||
case wvcdm::INCORRECT_USAGE_SUPPORT_TYPE_2:
|
case wvcdm::INCORRECT_USAGE_SUPPORT_TYPE_2:
|
||||||
return kIncorrectUsageSupportType2;
|
return kIncorrectUsageSupportType2;
|
||||||
|
case wvcdm::NO_USAGE_ENTRIES:
|
||||||
|
return kNoUsageEntries;
|
||||||
|
|
||||||
case wvcdm::UNUSED_1:
|
case wvcdm::UNUSED_1:
|
||||||
case wvcdm::UNUSED_2:
|
case wvcdm::UNUSED_2:
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ adb_shell_run license_unittest
|
|||||||
adb_shell_run license_keys_unittest
|
adb_shell_run license_keys_unittest
|
||||||
adb_shell_run initialization_data_unittest
|
adb_shell_run initialization_data_unittest
|
||||||
adb_shell_run device_files_unittest
|
adb_shell_run device_files_unittest
|
||||||
|
adb_shell_run usage_table_header_unittest
|
||||||
adb_shell_run service_certificate_unittest
|
adb_shell_run service_certificate_unittest
|
||||||
adb_shell_run timer_unittest
|
adb_shell_run timer_unittest
|
||||||
adb_shell_run buffer_reader_test
|
adb_shell_run buffer_reader_test
|
||||||
|
|||||||
Reference in New Issue
Block a user