Merge "Corrections for big usage table support in L3" into oc-dev am: 9edaf2ab39
am: 97a77d4c2c
Change-Id: Ie8949a574ae8ea3c9219fe483eeae985a54b05cd
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);
|
||||||
}
|
}
|
||||||
@@ -588,7 +587,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;
|
||||||
|
|
||||||
@@ -618,8 +617,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;
|
||||||
|
|
||||||
@@ -656,34 +655,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),
|
||||||
Lock UsageTableHeader::initialization_lock_;
|
is_inited_(false) {
|
||||||
|
file_system_.reset(new FileSystem());
|
||||||
UsageTableHeader* UsageTableHeader::GetInstance(FileSystem* file_system,
|
file_handle_.reset(new DeviceFiles(file_system_.get()));
|
||||||
CryptoSession* crypto_session) {
|
|
||||||
LOGV("UsageTableHeader::GetInstance");
|
|
||||||
AutoLock auto_lock(initialization_lock_);
|
|
||||||
CdmSecurityLevel security_level = crypto_session->GetSecurityLevel();
|
|
||||||
switch (security_level) {
|
|
||||||
case kSecurityLevelL1:
|
|
||||||
if (usage_table_header_l1_ != NULL)
|
|
||||||
return usage_table_header_l1_;
|
|
||||||
break;
|
|
||||||
case kSecurityLevelL3:
|
|
||||||
if (usage_table_header_l3_ != NULL)
|
|
||||||
return usage_table_header_l3_;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOGE("UsageTableHeader::GetInstance: unsupported security level: %d",
|
|
||||||
security_level);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
UsageTableHeader* header =
|
|
||||||
new UsageTableHeader(file_system, crypto_session, security_level);
|
|
||||||
if (!header->is_inited()) {
|
|
||||||
delete header;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (security_level == kSecurityLevelL1)
|
|
||||||
usage_table_header_l1_ = header;
|
|
||||||
else
|
|
||||||
usage_table_header_l3_ = header;
|
|
||||||
return header;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UsageTableHeader::UsageTableHeader(FileSystem* file_system,
|
bool UsageTableHeader::Init(CdmSecurityLevel security_level,
|
||||||
CryptoSession* crypto_session,
|
CryptoSession* crypto_session) {
|
||||||
CdmSecurityLevel security_level)
|
LOGV("UsageTableHeader::Init: security level: %d", security_level);
|
||||||
: file_handle_(new DeviceFiles(file_system)),
|
if (crypto_session == NULL) {
|
||||||
security_level_(security_level),
|
LOGE("UsageTableHeader::Init: no crypto session provided");
|
||||||
is_inited_(false) {
|
return false;
|
||||||
LOGV("UsageTableHeader::UsageTablerHeader: security level: %d",
|
}
|
||||||
|
|
||||||
|
switch (security_level) {
|
||||||
|
case kSecurityLevelL1:
|
||||||
|
case kSecurityLevelL3:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOGE("UsageTableHeader::Init: invalid security level provided: %d",
|
||||||
security_level);
|
security_level);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
security_level_ = security_level;
|
||||||
|
|
||||||
|
if (!file_handle_->Init(security_level)) {
|
||||||
|
LOGE("UsageTableHeader::Init: device files initialization failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
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()) {
|
||||||
LOGW(
|
LOGE("UsageTableHeader::Shrink: usage entry info table unexpectedly empty");
|
||||||
"UsageTableHeader::DeleteLastEntry: usage entry info table "
|
return NO_USAGE_ENTRIES;
|
||||||
"unexpectedly empty");
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
usage_entry_info_.resize(usage_entry_info_.size() - 1);
|
if (usage_entry_info_.size() < number_of_usage_entries_to_delete) {
|
||||||
|
LOGW(
|
||||||
|
"UsageTableHeader::Shrink: cannot delete %d entries when usage entry "
|
||||||
|
"table size is %d", number_of_usage_entries_to_delete,
|
||||||
|
usage_entry_info_.size());
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
CryptoSession crypto_session(&metrics_);
|
if (number_of_usage_entries_to_delete == 0) return NO_ERROR;
|
||||||
crypto_session.Open(GetSecurityLevel());
|
|
||||||
crypto_session.ShrinkUsageTableHeader(usage_entry_info_.size(),
|
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_);
|
&usage_table_header_);
|
||||||
|
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 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() {
|
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