Merge "Handle unlimited usage table capacity."
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
@@ -696,6 +697,12 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level,
|
||||
LOGW("GetMaxUsageTableEntries failed");
|
||||
return UNKNOWN_ERROR;
|
||||
}
|
||||
if (max_number_of_usage_entries == 0) {
|
||||
// Zero indicates that the table is dynamically allocated and does
|
||||
// not have a defined limit. Setting to max value of int32_t to
|
||||
// be able to fit into a Java int.
|
||||
max_number_of_usage_entries = std::numeric_limits<int32_t>::max();
|
||||
}
|
||||
*query_response = std::to_string(max_number_of_usage_entries);
|
||||
return NO_ERROR;
|
||||
} else if (query_token == QUERY_KEY_OEMCRYPTO_API_MINOR_VERSION) {
|
||||
|
||||
@@ -2008,6 +2008,11 @@ bool CryptoSession::GetMaximumUsageTableEntries(SecurityLevel security_level,
|
||||
metrics_->oemcrypto_maximum_usage_table_header_size_.Record(
|
||||
*number_of_entries);
|
||||
|
||||
if (*number_of_entries == 0) {
|
||||
// Special value, indicating that the table size is not directly
|
||||
// limited.
|
||||
return true;
|
||||
}
|
||||
return *number_of_entries >= kMinimumUsageTableEntriesSupported;
|
||||
}
|
||||
|
||||
|
||||
@@ -176,13 +176,23 @@ bool UsageTableHeader::Init(CdmSecurityLevel security_level,
|
||||
|
||||
if (!crypto_session->GetMaximumUsageTableEntries(
|
||||
requested_security_level_, &potential_table_capacity_)) {
|
||||
LOGW(
|
||||
"Could not determine usage table capacity, assuming default: "
|
||||
"default = %zu",
|
||||
kMinimumUsageTableEntriesSupported);
|
||||
potential_table_capacity_ = kMinimumUsageTableEntriesSupported;
|
||||
} else if (potential_table_capacity_ == 0) {
|
||||
LOGD("Usage table capacity is unlimited: security_level = %d",
|
||||
static_cast<int>(security_level));
|
||||
} else if (potential_table_capacity_ < kMinimumUsageTableEntriesSupported) {
|
||||
LOGW(
|
||||
"Reported usage table capacity is smaller than minimally required: "
|
||||
"capacity = %zu, minimum = %zu",
|
||||
potential_table_capacity_, kMinimumUsageTableEntriesSupported);
|
||||
potential_table_capacity_ = kMinimumUsageTableEntriesSupported;
|
||||
} else {
|
||||
LOGD("Usage table capacity: %zu, security_level = %d",
|
||||
potential_table_capacity_, static_cast<int>(security_level));
|
||||
}
|
||||
|
||||
if (!device_files_->Init(security_level)) {
|
||||
@@ -213,11 +223,21 @@ bool UsageTableHeader::Init(CdmSecurityLevel security_level,
|
||||
}
|
||||
}
|
||||
|
||||
// If the usage table header has been successfully loaded, and is at
|
||||
// minimum capacity (>200), we need to make sure we can still add and
|
||||
// remove entries. If not, clear files/data and recreate usage header table.
|
||||
// If the usage table header has been successfully loaded, and is
|
||||
// at minimum capacity (>200) or the table size does not have a
|
||||
// hard limit, we need to make sure we can still add and remove
|
||||
// entries. If not, clear files/data and recreate usage header
|
||||
// table.
|
||||
if (status == NO_ERROR && lru_success) {
|
||||
if (usage_entry_info_.size() > potential_table_capacity()) {
|
||||
if ((HasUnlimitedTableCapacity() &&
|
||||
usage_entry_info_.size() > kMinimumUsageTableEntriesSupported) ||
|
||||
(!HasUnlimitedTableCapacity() &&
|
||||
usage_entry_info_.size() > potential_table_capacity())) {
|
||||
LOGD("Checking if new entry can be added: size = %zu, capacity = %s",
|
||||
usage_entry_info_.size(),
|
||||
HasUnlimitedTableCapacity()
|
||||
? "unlimited"
|
||||
: std::to_string(potential_table_capacity()).c_str());
|
||||
uint32_t temporary_usage_entry_number;
|
||||
|
||||
// Create a new temporary usage entry, close the session and then
|
||||
@@ -359,6 +379,18 @@ CdmResponseType UsageTableHeader::AddEntry(
|
||||
}
|
||||
}
|
||||
|
||||
// Call to update the usage table header, but don't store the usage
|
||||
// entry. If the entry is used by the CDM, the CDM session will make
|
||||
// subsequent calls to update the usage entry and store that entry.
|
||||
std::string usage_entry;
|
||||
status = crypto_session->UpdateUsageEntry(&usage_table_header_, &usage_entry);
|
||||
if (status != NO_ERROR) {
|
||||
LOGE("Failed to update new usage entry: usage_entry_number = %u",
|
||||
*usage_entry_number);
|
||||
usage_entry_info_[*usage_entry_number].Clear();
|
||||
return status;
|
||||
}
|
||||
|
||||
LOGI("New usage entry: usage_entry_number = %u", *usage_entry_number);
|
||||
StoreTable(device_files_.get());
|
||||
return NO_ERROR;
|
||||
@@ -1115,7 +1147,9 @@ bool UsageTableHeader::GetRemovalCandidate(uint32_t* entry_to_remove) {
|
||||
LOGI("Locking to determine removal candidates");
|
||||
std::unique_lock<std::mutex> auto_lock(usage_table_header_lock_);
|
||||
const size_t lru_unexpired_threshold =
|
||||
kLruUnexpiredThresholdFraction * potential_table_capacity();
|
||||
HasUnlimitedTableCapacity()
|
||||
? kLruUnexpiredThresholdFraction * size()
|
||||
: kLruUnexpiredThresholdFraction * potential_table_capacity();
|
||||
return DetermineLicenseToRemove(usage_entry_info_, GetCurrentTime(),
|
||||
lru_unexpired_threshold, entry_to_remove);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user