Revert "Core CDM: Remove secure stop from LRU algorithm."
This reverts commit 7a34c1748c.
Reason for revert: Feature rejected by Android
Bug: 242289743
Change-Id: I63a730a6e5fa16d0d2425d216fd7f0fff8c09a4c
This commit is contained in:
committed by
Android (Google) Code Review
parent
7a34c1748c
commit
0c353d6851
@@ -96,6 +96,41 @@ bool RetrieveOfflineLicense(DeviceFiles* device_files,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RetrieveUsageInfoLicense(DeviceFiles* device_files,
|
||||
const std::string& usage_info_file_name,
|
||||
const std::string& key_set_id,
|
||||
CdmKeyResponse* license_message,
|
||||
uint32_t* usage_entry_number) {
|
||||
if (device_files == nullptr) {
|
||||
LOGE("DeviceFiles handle is null");
|
||||
return false;
|
||||
}
|
||||
if (license_message == nullptr) {
|
||||
LOGE("Output parameter |license_message| is null");
|
||||
return false;
|
||||
}
|
||||
if (usage_entry_number == nullptr) {
|
||||
LOGE("Output parameter |usage_entry_number| is null");
|
||||
return false;
|
||||
}
|
||||
CdmUsageEntry usage_entry;
|
||||
std::string provider_session_token;
|
||||
CdmKeyMessage license_request;
|
||||
std::string drm_certificate;
|
||||
CryptoWrappedKey wrapped_private_key;
|
||||
if (!device_files->RetrieveUsageInfoByKeySetId(
|
||||
usage_info_file_name, key_set_id, &provider_session_token,
|
||||
&license_request, license_message, &usage_entry, usage_entry_number,
|
||||
&drm_certificate, &wrapped_private_key)) {
|
||||
LOGW(
|
||||
"Failed to retrieve usage information: "
|
||||
"key_set_id = %s, usage_info_file_name = %s",
|
||||
IdToString(key_set_id), IdToString(usage_info_file_name));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EntryIsUsageInfo(const CdmUsageEntryInfo& info) {
|
||||
// Used for stl filters.
|
||||
return info.storage_type == kStorageUsageInfo;
|
||||
@@ -1128,6 +1163,7 @@ CdmResponseType UsageTableHeader::ReleaseOldestEntry(
|
||||
// Capture metric values now, as the |usage_entry_info| reference will
|
||||
// change after the call to invalidate.
|
||||
const int64_t staleness = current_time - usage_entry_info.last_use_time;
|
||||
const CdmUsageEntryStorageType storage_type = usage_entry_info.storage_type;
|
||||
|
||||
const CdmResponseType status =
|
||||
InvalidateEntryInternal(entry_number_to_delete, /* defrag_table = */ true,
|
||||
@@ -1140,7 +1176,7 @@ CdmResponseType UsageTableHeader::ReleaseOldestEntry(
|
||||
}
|
||||
|
||||
// Record metrics on success.
|
||||
RecordLruEventMetrics(metrics, staleness);
|
||||
RecordLruEventMetrics(metrics, staleness, storage_type);
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
@@ -1173,16 +1209,34 @@ bool UsageTableHeader::LruUpgradeAllUsageEntries() {
|
||||
usage_entry_number < usage_entry_info_.size(); ++usage_entry_number) {
|
||||
CdmUsageEntryInfo& usage_entry_info = usage_entry_info_[usage_entry_number];
|
||||
|
||||
if (usage_entry_info.storage_type != kStorageLicense) {
|
||||
bad_license_file_entries.push_back(usage_entry_number);
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t retrieved_entry_number;
|
||||
CdmKeyResponse license_message;
|
||||
const bool retrieve_response =
|
||||
RetrieveOfflineLicense(device_files_.get(), usage_entry_info.key_set_id,
|
||||
&license_message, &retrieved_entry_number);
|
||||
bool retrieve_response = false;
|
||||
switch (usage_entry_info.storage_type) {
|
||||
case kStorageLicense: {
|
||||
retrieve_response = RetrieveOfflineLicense(
|
||||
device_files_.get(), usage_entry_info.key_set_id, &license_message,
|
||||
&retrieved_entry_number);
|
||||
break;
|
||||
}
|
||||
case kStorageUsageInfo: {
|
||||
retrieve_response = RetrieveUsageInfoLicense(
|
||||
device_files_.get(), usage_entry_info.usage_info_file_name,
|
||||
usage_entry_info.key_set_id, &license_message,
|
||||
&retrieved_entry_number);
|
||||
break;
|
||||
}
|
||||
case kStorageTypeUnknown:
|
||||
bad_license_file_entries.push_back(usage_entry_number);
|
||||
continue;
|
||||
default: {
|
||||
LOGW("Unknown usage entry storage type: %d, usage_entry_number = %u",
|
||||
static_cast<int>(usage_entry_info.storage_type),
|
||||
usage_entry_number);
|
||||
bad_license_file_entries.push_back(usage_entry_number);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!retrieve_response) {
|
||||
LOGW("Could not retrieve license message: usage_entry_number = %u",
|
||||
usage_entry_number);
|
||||
@@ -1211,18 +1265,22 @@ bool UsageTableHeader::LruUpgradeAllUsageEntries() {
|
||||
// for replacement above all others.
|
||||
usage_entry_info.last_use_time = license.license_start_time();
|
||||
|
||||
// Only offline licenses need |offline_license_expiry_time| set.
|
||||
const video_widevine::License::Policy& policy = license.policy();
|
||||
// TODO(b/139372190): Change how these fields are set once feature is
|
||||
// implemented.
|
||||
if (policy.license_duration_seconds() == 0) {
|
||||
// Zero implies unlimited license duration.
|
||||
usage_entry_info.offline_license_expiry_time =
|
||||
license.license_start_time() + policy.rental_duration_seconds() +
|
||||
policy.playback_duration_seconds();
|
||||
if (usage_entry_info.storage_type == kStorageLicense) {
|
||||
// Only offline licenses need |offline_license_expiry_time| set.
|
||||
const video_widevine::License::Policy& policy = license.policy();
|
||||
// TODO(b/139372190): Change how these fields are set once feature is
|
||||
// implemented.
|
||||
if (policy.license_duration_seconds() == 0) {
|
||||
// Zero implies unlimited license duration.
|
||||
usage_entry_info.offline_license_expiry_time =
|
||||
license.license_start_time() + policy.rental_duration_seconds() +
|
||||
policy.playback_duration_seconds();
|
||||
} else {
|
||||
usage_entry_info.offline_license_expiry_time =
|
||||
license.license_start_time() + policy.license_duration_seconds();
|
||||
}
|
||||
} else {
|
||||
usage_entry_info.offline_license_expiry_time =
|
||||
license.license_start_time() + policy.license_duration_seconds();
|
||||
usage_entry_info.offline_license_expiry_time = 0;
|
||||
}
|
||||
} // End for loop.
|
||||
|
||||
@@ -1232,14 +1290,31 @@ bool UsageTableHeader::LruUpgradeAllUsageEntries() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Maps <usage_info_file_name> -> [<key_set_id>].
|
||||
std::map<std::string, std::vector<std::string>> usage_info_clean_up;
|
||||
for (size_t usage_entry_number : bad_license_file_entries) {
|
||||
CdmUsageEntryInfo& usage_entry_info = usage_entry_info_[usage_entry_number];
|
||||
if (usage_entry_info.storage_type == kStorageLicense) {
|
||||
device_files_->DeleteLicense(usage_entry_info.key_set_id);
|
||||
}
|
||||
} else if (usage_entry_info.storage_type == kStorageUsageInfo) {
|
||||
// To reduce write cycles, the deletion of usage info will be done
|
||||
// in bulk.
|
||||
auto it = usage_info_clean_up.find(usage_entry_info.usage_info_file_name);
|
||||
if (it == usage_info_clean_up.end()) {
|
||||
it = usage_info_clean_up
|
||||
.emplace(usage_entry_info.usage_info_file_name,
|
||||
std::vector<std::string>())
|
||||
.first;
|
||||
}
|
||||
it->second.push_back(usage_entry_info.key_set_id);
|
||||
} // else kStorageUnknown { Nothing special }.
|
||||
usage_entry_info.Clear();
|
||||
}
|
||||
|
||||
for (const auto& p : usage_info_clean_up) {
|
||||
device_files_->DeleteMultipleUsageInfoByKeySetIds(p.first, p.second);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1252,18 +1327,16 @@ bool UsageTableHeader::GetRemovalCandidate(uint32_t* entry_to_remove) {
|
||||
lru_unexpired_threshold, entry_to_remove);
|
||||
}
|
||||
|
||||
void UsageTableHeader::RecordLruEventMetrics(metrics::CryptoMetrics* metrics,
|
||||
uint64_t staleness) {
|
||||
void UsageTableHeader::RecordLruEventMetrics(
|
||||
metrics::CryptoMetrics* metrics, uint64_t staleness,
|
||||
CdmUsageEntryStorageType storage_type) {
|
||||
if (metrics == nullptr) return;
|
||||
// Usage info are deprecated, always record 0.
|
||||
metrics->usage_table_header_lru_usage_info_count_.Record(0);
|
||||
metrics->usage_table_header_lru_usage_info_count_.Record(UsageInfoCount());
|
||||
metrics->usage_table_header_lru_offline_license_count_.Record(
|
||||
OfflineEntryCount());
|
||||
metrics->usage_table_header_lru_evicted_entry_staleness_.Record(staleness);
|
||||
// Can be assumed that only offline licenses are removed.
|
||||
constexpr int kDefaultEntryType = 0;
|
||||
metrics->usage_table_header_lru_evicted_entry_type_.Record(
|
||||
static_cast<int>(kDefaultEntryType));
|
||||
static_cast<int>(storage_type));
|
||||
}
|
||||
|
||||
// Static.
|
||||
@@ -1286,13 +1359,14 @@ bool UsageTableHeader::DetermineLicenseToRemove(
|
||||
usage_entry_info_list[j].last_use_time;
|
||||
};
|
||||
|
||||
// Find the most stale expired offline license and the
|
||||
// Find the most stale expired offline / streaming license and the
|
||||
// most stale unexpired offline entry. Count the number of unexpired
|
||||
// entries. If any entry is not of storage type license, then it should
|
||||
// entries. If any entry is of storage type unknown, then it should
|
||||
// be removed.
|
||||
constexpr uint32_t kNoEntry = std::numeric_limits<uint32_t>::max();
|
||||
uint32_t stalest_expired_offline_license = kNoEntry;
|
||||
uint32_t stalest_unexpired_offline_license = kNoEntry;
|
||||
uint32_t stalest_streaming_license = kNoEntry;
|
||||
size_t unexpired_license_count = 0;
|
||||
|
||||
for (uint32_t entry_number = 0; entry_number < usage_entry_info_list.size();
|
||||
@@ -1300,28 +1374,37 @@ bool UsageTableHeader::DetermineLicenseToRemove(
|
||||
const CdmUsageEntryInfo& usage_entry_info =
|
||||
usage_entry_info_list[entry_number];
|
||||
|
||||
if (usage_entry_info.storage_type != kStorageLicense) {
|
||||
// Non-license storage type entries. Remove this entry.
|
||||
if (usage_entry_info.storage_type != kStorageLicense &&
|
||||
usage_entry_info.storage_type != kStorageUsageInfo) {
|
||||
// Unknown storage type entries. Remove this entry.
|
||||
*entry_to_remove = entry_number;
|
||||
return true;
|
||||
}
|
||||
if (usage_entry_info.offline_license_expiry_time > current_time) {
|
||||
if (usage_entry_info.storage_type == kStorageLicense &&
|
||||
usage_entry_info.offline_license_expiry_time > current_time) {
|
||||
// Unexpired offline.
|
||||
++unexpired_license_count;
|
||||
if (stalest_unexpired_offline_license == kNoEntry ||
|
||||
is_more_stale(entry_number, stalest_unexpired_offline_license)) {
|
||||
stalest_unexpired_offline_license = entry_number;
|
||||
}
|
||||
} else {
|
||||
} else if (usage_entry_info.storage_type == kStorageLicense) {
|
||||
// Expired offline.
|
||||
if (stalest_expired_offline_license == kNoEntry ||
|
||||
is_more_stale(entry_number, stalest_expired_offline_license)) {
|
||||
stalest_expired_offline_license = entry_number;
|
||||
}
|
||||
} else {
|
||||
// Streaming.
|
||||
if (stalest_streaming_license == kNoEntry ||
|
||||
is_more_stale(entry_number, stalest_streaming_license)) {
|
||||
stalest_streaming_license = entry_number;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (stalest_expired_offline_license == kNoEntry &&
|
||||
stalest_streaming_license == kNoEntry &&
|
||||
unexpired_license_count <= unexpired_threshold) {
|
||||
// Unexpected situation, could be an issue with the threshold.
|
||||
LOGW(
|
||||
@@ -1341,10 +1424,12 @@ bool UsageTableHeader::DetermineLicenseToRemove(
|
||||
|
||||
// Only consider an unexpired entry if the threshold is reached.
|
||||
if (unexpired_license_count > unexpired_threshold) {
|
||||
*entry_to_remove = select_most_stale(stalest_unexpired_offline_license,
|
||||
stalest_expired_offline_license);
|
||||
const uint32_t temp = select_most_stale(stalest_unexpired_offline_license,
|
||||
stalest_streaming_license);
|
||||
*entry_to_remove = select_most_stale(temp, stalest_expired_offline_license);
|
||||
} else {
|
||||
*entry_to_remove = stalest_expired_offline_license;
|
||||
*entry_to_remove = select_most_stale(stalest_streaming_license,
|
||||
stalest_expired_offline_license);
|
||||
}
|
||||
|
||||
if (*entry_to_remove == kNoEntry) {
|
||||
|
||||
Reference in New Issue
Block a user