Merge "Revert "Core CDM: Removed ability to add secure stop entry.""
This commit is contained in:
@@ -484,8 +484,9 @@ CdmResponseType CdmSession::AddKeyInternal(const CdmKeyResponse& key_response) {
|
||||
LOGE("CDM does not support secure stop licenses");
|
||||
return ADD_KEY_ERROR;
|
||||
}
|
||||
sts = usage_table_header_->AddEntry(crypto_session_.get(), key_set_id_,
|
||||
key_response, &usage_entry_number_);
|
||||
sts = usage_table_header_->AddEntry(
|
||||
crypto_session_.get(), /* is_persistent */ true, key_set_id_,
|
||||
/* usage_info_filename */ "", key_response, &usage_entry_number_);
|
||||
crypto_metrics_->usage_table_header_add_entry_.Increment(sts);
|
||||
if (sts != NO_ERROR) return sts;
|
||||
provider_session_token_ = std::move(provider_session_token);
|
||||
|
||||
@@ -96,12 +96,17 @@ bool RetrieveOfflineLicense(DeviceFiles* device_files,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EntryIsUsageInfo(const CdmUsageEntryInfo& info) {
|
||||
// Used for stl filters.
|
||||
return info.storage_type == kStorageUsageInfo;
|
||||
}
|
||||
|
||||
bool EntryIsOfflineLicense(const CdmUsageEntryInfo& info) {
|
||||
// Used for stl filters.
|
||||
return info.storage_type == kStorageLicense;
|
||||
}
|
||||
|
||||
bool IsValidCdmSecurityLevelForUsageTable(CdmSecurityLevel security_level) {
|
||||
bool IsValidCdmSecurityLevelForUsageInfo(CdmSecurityLevel security_level) {
|
||||
return security_level == kSecurityLevelL1 ||
|
||||
security_level == kSecurityLevelL3;
|
||||
}
|
||||
@@ -129,7 +134,7 @@ bool UsageTableHeader::Init(CdmSecurityLevel security_level,
|
||||
CdmSecurityLevelToString(security_level));
|
||||
return false;
|
||||
}
|
||||
if (!IsValidCdmSecurityLevelForUsageTable(security_level)) {
|
||||
if (!IsValidCdmSecurityLevelForUsageInfo(security_level)) {
|
||||
LOGE("Invalid security level provided: security_level = %s",
|
||||
CdmSecurityLevelToString(security_level));
|
||||
return false;
|
||||
@@ -221,9 +226,11 @@ bool UsageTableHeader::CreateNewTable(CryptoSession* const crypto_session) {
|
||||
}
|
||||
|
||||
CdmResponseType UsageTableHeader::AddEntry(
|
||||
CryptoSession* crypto_session, const CdmKeySetId& key_set_id,
|
||||
CryptoSession* crypto_session, bool persistent_license,
|
||||
const CdmKeySetId& key_set_id, const std::string& usage_info_file_name,
|
||||
const CdmKeyResponse& license_message, uint32_t* usage_entry_number) {
|
||||
LOGD("key_set_id = %s, current_size = %zu", IdToString(key_set_id),
|
||||
LOGD("key_set_id = %s, type = %s, current_size = %zu", IdToString(key_set_id),
|
||||
persistent_license ? "OfflineLicense" : "Streaming",
|
||||
usage_entry_info_.size());
|
||||
|
||||
metrics::CryptoMetrics* metrics = crypto_session->GetCryptoMetrics();
|
||||
@@ -244,11 +251,15 @@ CdmResponseType UsageTableHeader::AddEntry(
|
||||
status = RelocateNewEntry(crypto_session, usage_entry_number);
|
||||
if (status != NO_ERROR) return status;
|
||||
|
||||
SetOfflineEntryInfo(*usage_entry_number, key_set_id, license_message);
|
||||
if (persistent_license) {
|
||||
SetOfflineEntryInfo(*usage_entry_number, key_set_id, license_message);
|
||||
} else {
|
||||
SetUsageInfoEntryInfo(*usage_entry_number, key_set_id,
|
||||
usage_info_file_name);
|
||||
}
|
||||
|
||||
status = RefitTable(crypto_session);
|
||||
if (status != NO_ERROR) {
|
||||
// Clear new entry on failure.
|
||||
usage_entry_info_[*usage_entry_number].Clear();
|
||||
return status;
|
||||
}
|
||||
@@ -369,6 +380,12 @@ CdmResponseType UsageTableHeader::InvalidateEntryInternal(
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
size_t UsageTableHeader::UsageInfoCount() const {
|
||||
LOGV("Locking to count usage info (streaming license) entries");
|
||||
return std::count_if(usage_entry_info_.cbegin(), usage_entry_info_.cend(),
|
||||
EntryIsUsageInfo);
|
||||
}
|
||||
|
||||
size_t UsageTableHeader::OfflineEntryCount() const {
|
||||
LOGV("Locking to count offline license entries");
|
||||
return std::count_if(usage_entry_info_.cbegin(), usage_entry_info_.cend(),
|
||||
@@ -424,8 +441,8 @@ bool UsageTableHeader::CapacityCheck(CryptoSession* const crypto_session) {
|
||||
}
|
||||
|
||||
uint32_t temporary_usage_entry_number;
|
||||
status = AddEntry(local_crypto_session, kDummyKeySetId, kEmptyString,
|
||||
&temporary_usage_entry_number);
|
||||
status = AddEntry(local_crypto_session, true, kDummyKeySetId, kEmptyString,
|
||||
kEmptyString, &temporary_usage_entry_number);
|
||||
if (status != NO_ERROR) {
|
||||
LOGE("Failed to add entry for capacity test: sts = %d",
|
||||
static_cast<int>(status));
|
||||
@@ -579,6 +596,17 @@ void UsageTableHeader::SetOfflineEntryInfo(
|
||||
}
|
||||
}
|
||||
|
||||
void UsageTableHeader::SetUsageInfoEntryInfo(
|
||||
const uint32_t usage_entry_number, const std::string& key_set_id,
|
||||
const std::string& usage_info_file_name) {
|
||||
CdmUsageEntryInfo& entry_info = usage_entry_info_[usage_entry_number];
|
||||
entry_info.Clear();
|
||||
entry_info.storage_type = kStorageUsageInfo;
|
||||
entry_info.key_set_id = key_set_id;
|
||||
entry_info.last_use_time = GetCurrentTime();
|
||||
entry_info.usage_info_file_name = usage_info_file_name;
|
||||
}
|
||||
|
||||
CdmResponseType UsageTableHeader::RefitTable(
|
||||
CryptoSession* const crypto_session) {
|
||||
// Remove all unoccupied entries at end of the table.
|
||||
@@ -679,39 +707,57 @@ CdmResponseType UsageTableHeader::GetEntry(uint32_t usage_entry_number,
|
||||
usage_entry_number < usage_entry_info_.size()
|
||||
? usage_entry_info_[usage_entry_number].storage_type
|
||||
: kStorageTypeUnknown));
|
||||
if (usage_entry_number >= usage_entry_info_.size()) {
|
||||
LOGE("Entry out of bounds: usage_entry_number = %u, table_size = %zu",
|
||||
usage_entry_number, usage_entry_info_.size());
|
||||
return USAGE_GET_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE;
|
||||
uint32_t entry_number;
|
||||
switch (usage_entry_info_[usage_entry_number].storage_type) {
|
||||
case kStorageLicense: {
|
||||
DeviceFiles::CdmLicenseData license_data;
|
||||
DeviceFiles::ResponseType sub_error_code = DeviceFiles::kNoError;
|
||||
if (!device_files->RetrieveLicense(
|
||||
usage_entry_info_[usage_entry_number].key_set_id, &license_data,
|
||||
&sub_error_code)) {
|
||||
LOGE("Failed to retrieve license: status = %d",
|
||||
static_cast<int>(sub_error_code));
|
||||
return USAGE_GET_ENTRY_RETRIEVE_LICENSE_FAILED;
|
||||
}
|
||||
|
||||
entry_number = license_data.usage_entry_number;
|
||||
*usage_entry = std::move(license_data.usage_entry);
|
||||
break;
|
||||
}
|
||||
case kStorageUsageInfo: {
|
||||
std::string provider_session_token;
|
||||
CdmKeyMessage license_request;
|
||||
CdmKeyResponse license;
|
||||
std::string drm_certificate;
|
||||
CryptoWrappedKey wrapped_private_key;
|
||||
|
||||
if (!device_files->RetrieveUsageInfoByKeySetId(
|
||||
usage_entry_info_[usage_entry_number].usage_info_file_name,
|
||||
usage_entry_info_[usage_entry_number].key_set_id,
|
||||
&provider_session_token, &license_request, &license, usage_entry,
|
||||
&entry_number, &drm_certificate, &wrapped_private_key)) {
|
||||
LOGE("Failed to retrieve usage information");
|
||||
return USAGE_GET_ENTRY_RETRIEVE_USAGE_INFO_FAILED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kStorageTypeUnknown:
|
||||
default:
|
||||
LOGE(
|
||||
"Cannot retrieve usage information with unknown storage type: "
|
||||
"storage_type = %d",
|
||||
static_cast<int>(usage_entry_info_[usage_entry_number].storage_type));
|
||||
return USAGE_GET_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE;
|
||||
}
|
||||
CdmUsageEntryInfo& entry_info = usage_entry_info_[usage_entry_number];
|
||||
if (entry_info.storage_type != kStorageLicense) {
|
||||
LOGE(
|
||||
"Cannot retrieve information not associated without a license: "
|
||||
"usage_entry_number = %u",
|
||||
usage_entry_number);
|
||||
return USAGE_GET_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE;
|
||||
}
|
||||
// Retrieve license.
|
||||
DeviceFiles::CdmLicenseData license_data;
|
||||
DeviceFiles::ResponseType sub_error_code = DeviceFiles::kNoError;
|
||||
if (!device_files->RetrieveLicense(
|
||||
usage_entry_info_[usage_entry_number].key_set_id, &license_data,
|
||||
&sub_error_code)) {
|
||||
LOGE("Failed to retrieve license: status = %d",
|
||||
static_cast<int>(sub_error_code));
|
||||
return USAGE_GET_ENTRY_RETRIEVE_LICENSE_FAILED;
|
||||
}
|
||||
// Validate entry number.
|
||||
if (usage_entry_number != license_data.usage_entry_number) {
|
||||
|
||||
if (usage_entry_number != entry_number) {
|
||||
LOGE(
|
||||
"Usage entry number mismatch: expected_usage_entry_number = %u, "
|
||||
"retrieved_usage_entry_number = %u",
|
||||
usage_entry_number, license_data.usage_entry_number);
|
||||
usage_entry_number, entry_number);
|
||||
return USAGE_ENTRY_NUMBER_MISMATCH;
|
||||
}
|
||||
|
||||
*usage_entry = std::move(license_data.usage_entry);
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
@@ -723,37 +769,66 @@ CdmResponseType UsageTableHeader::StoreEntry(uint32_t usage_entry_number,
|
||||
usage_entry_number < usage_entry_info_.size()
|
||||
? usage_entry_info_[usage_entry_number].storage_type
|
||||
: kStorageTypeUnknown));
|
||||
if (usage_entry_number >= usage_entry_info_.size()) {
|
||||
LOGE("Entry out of bounds: usage_entry_number = %u, table_size = %zu",
|
||||
usage_entry_number, usage_entry_info_.size());
|
||||
return USAGE_STORE_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE;
|
||||
}
|
||||
CdmUsageEntryInfo& entry_info = usage_entry_info_[usage_entry_number];
|
||||
if (entry_info.storage_type != kStorageLicense) {
|
||||
LOGE(
|
||||
"Cannot store information not associated without a license: "
|
||||
"usage_entry_number = %u",
|
||||
usage_entry_number);
|
||||
return USAGE_STORE_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE;
|
||||
}
|
||||
// Retrieve existing.
|
||||
DeviceFiles::CdmLicenseData license_data;
|
||||
DeviceFiles::ResponseType sub_error_code = DeviceFiles::kNoError;
|
||||
if (!device_files->RetrieveLicense(
|
||||
usage_entry_info_[usage_entry_number].key_set_id, &license_data,
|
||||
&sub_error_code)) {
|
||||
LOGE("Failed to retrieve license: status = %s",
|
||||
DeviceFiles::ResponseTypeToString(sub_error_code));
|
||||
return USAGE_STORE_ENTRY_RETRIEVE_LICENSE_FAILED;
|
||||
}
|
||||
// Update.
|
||||
license_data.usage_entry = usage_entry;
|
||||
license_data.usage_entry_number = usage_entry_number;
|
||||
|
||||
if (!device_files->StoreLicense(license_data, &sub_error_code)) {
|
||||
LOGE("Failed to store license: status = %s",
|
||||
DeviceFiles::ResponseTypeToString(sub_error_code));
|
||||
return USAGE_STORE_LICENSE_FAILED;
|
||||
switch (usage_entry_info_[usage_entry_number].storage_type) {
|
||||
case kStorageLicense: {
|
||||
DeviceFiles::CdmLicenseData license_data;
|
||||
DeviceFiles::ResponseType sub_error_code = DeviceFiles::kNoError;
|
||||
|
||||
if (!device_files->RetrieveLicense(
|
||||
usage_entry_info_[usage_entry_number].key_set_id, &license_data,
|
||||
&sub_error_code)) {
|
||||
LOGE("Failed to retrieve license: status = %s",
|
||||
DeviceFiles::ResponseTypeToString(sub_error_code));
|
||||
return USAGE_STORE_ENTRY_RETRIEVE_LICENSE_FAILED;
|
||||
}
|
||||
|
||||
// Update.
|
||||
license_data.usage_entry = usage_entry;
|
||||
license_data.usage_entry_number = usage_entry_number;
|
||||
|
||||
if (!device_files->StoreLicense(license_data, &sub_error_code)) {
|
||||
LOGE("Failed to store license: status = %s",
|
||||
DeviceFiles::ResponseTypeToString(sub_error_code));
|
||||
return USAGE_STORE_LICENSE_FAILED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kStorageUsageInfo: {
|
||||
CdmUsageEntry entry;
|
||||
uint32_t entry_number;
|
||||
std::string provider_session_token, init_data, key_request, key_response,
|
||||
key_renewal_request;
|
||||
std::string drm_certificate;
|
||||
CryptoWrappedKey wrapped_private_key;
|
||||
if (!device_files->RetrieveUsageInfoByKeySetId(
|
||||
usage_entry_info_[usage_entry_number].usage_info_file_name,
|
||||
usage_entry_info_[usage_entry_number].key_set_id,
|
||||
&provider_session_token, &key_request, &key_response, &entry,
|
||||
&entry_number, &drm_certificate, &wrapped_private_key)) {
|
||||
LOGE("Failed to retrieve usage information");
|
||||
return USAGE_STORE_ENTRY_RETRIEVE_USAGE_INFO_FAILED;
|
||||
}
|
||||
device_files->DeleteUsageInfo(
|
||||
usage_entry_info_[usage_entry_number].usage_info_file_name,
|
||||
provider_session_token);
|
||||
if (!device_files->StoreUsageInfo(
|
||||
provider_session_token, key_request, key_response,
|
||||
usage_entry_info_[usage_entry_number].usage_info_file_name,
|
||||
usage_entry_info_[usage_entry_number].key_set_id, usage_entry,
|
||||
usage_entry_number, drm_certificate, wrapped_private_key)) {
|
||||
LOGE("Failed to store usage information");
|
||||
return USAGE_STORE_USAGE_INFO_FAILED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kStorageTypeUnknown:
|
||||
default:
|
||||
LOGE(
|
||||
"Cannot retrieve usage information with unknown storage type: "
|
||||
"storage_type = %d",
|
||||
static_cast<int>(usage_entry_info_[usage_entry_number].storage_type));
|
||||
return USAGE_STORE_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE;
|
||||
}
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user