Core CDM: Removed secure stop support.
[ Merge of http://go/wvgerrit/158721 ] This CL removes support for secure stop / usage info sessions from the CDM engine and CDM session. APIs for related to secure stop operations will return NOT_IMPLEMENTED_ERROR. New secure stop licenses will be rejected by the CDM when added. Bug: 242289743 Test: run_x86_64_tests request_license_test Change-Id: I30cd47e580d63014e001c903382a28238746f6d4
This commit is contained in:
@@ -31,8 +31,8 @@
|
||||
|
||||
namespace wvcdm {
|
||||
namespace {
|
||||
const uint64_t kReleaseSessionTimeToLive = 60; // seconds
|
||||
const uint32_t kUpdateUsageInformationPeriod = 60; // seconds
|
||||
constexpr uint64_t kReleaseSessionTimeToLive = 60; // seconds
|
||||
constexpr uint32_t kUpdateUsageInfoPeriod = 60; // seconds
|
||||
} // namespace
|
||||
|
||||
class UsagePropertySet : public CdmClientPropertySet {
|
||||
@@ -67,16 +67,12 @@ CdmEngine::CdmEngine(wvutil::FileSystem* file_system,
|
||||
: metrics_(metrics),
|
||||
cert_provisioning_(),
|
||||
file_system_(file_system),
|
||||
spoid_(EMPTY_SPOID),
|
||||
usage_session_(),
|
||||
usage_property_set_(),
|
||||
last_usage_information_update_time_(0) {
|
||||
spoid_(EMPTY_SPOID) {
|
||||
assert(file_system);
|
||||
Properties::Init();
|
||||
}
|
||||
|
||||
CdmEngine::~CdmEngine() {
|
||||
usage_session_.reset();
|
||||
std::unique_lock<std::recursive_mutex> lock(session_map_lock_);
|
||||
session_map_.Terminate();
|
||||
}
|
||||
@@ -415,8 +411,7 @@ CdmResponseType CdmEngine::AddKey(const CdmSessionId& session_id,
|
||||
}
|
||||
|
||||
if (key_set_id != nullptr) {
|
||||
if ((session->is_offline() || session->has_provider_session_token()) &&
|
||||
!license_type_release) {
|
||||
if ((session->is_offline()) && !license_type_release) {
|
||||
*key_set_id = session->key_set_id();
|
||||
LOGI("key_set_id = %s", IdPtrToString(key_set_id));
|
||||
} else {
|
||||
@@ -1284,50 +1279,21 @@ CdmResponseType CdmEngine::ListStoredLicenses(
|
||||
|
||||
CdmResponseType CdmEngine::ListUsageIds(
|
||||
const std::string& app_id, CdmSecurityLevel security_level,
|
||||
std::vector<std::string>* ksids,
|
||||
std::vector<std::string>* provider_session_tokens) {
|
||||
if (!ksids && !provider_session_tokens) {
|
||||
LOGE("Outputs |ksids| and |provider_session_tokens| are null");
|
||||
return INVALID_PARAMETERS_ENG_23;
|
||||
}
|
||||
if (security_level == kSecurityLevelL1 && OkpIsInFallbackMode()) {
|
||||
LOGD("OKP fallback to L3");
|
||||
security_level = kSecurityLevelL3;
|
||||
}
|
||||
DeviceFiles handle(file_system_);
|
||||
if (!handle.Init(security_level)) {
|
||||
LOGE("Unable to initialize device files");
|
||||
return LIST_USAGE_ERROR_1;
|
||||
}
|
||||
if (!handle.ListUsageIds(app_id, ksids, provider_session_tokens)) {
|
||||
LOGE("Failed: app_id = %s, security_level = %s", IdToString(app_id),
|
||||
CdmSecurityLevelToString(security_level));
|
||||
return LIST_USAGE_ERROR_2;
|
||||
}
|
||||
return NO_ERROR;
|
||||
std::vector<std::string>* /* ksids */,
|
||||
std::vector<std::string>* /* provider_session_tokens */) {
|
||||
LOGI("app_id = %s, security_level = %s", IdToString(app_id),
|
||||
CdmSecurityLevelToString(security_level));
|
||||
LOGW("API not supported");
|
||||
return NOT_IMPLEMENTED_ERROR;
|
||||
}
|
||||
|
||||
CdmResponseType CdmEngine::DeleteUsageRecord(const std::string& app_id,
|
||||
CdmSecurityLevel security_level,
|
||||
const std::string& key_set_id) {
|
||||
LOGI("app_id = %s, key_set_id = %s", IdToString(app_id),
|
||||
IdToString(key_set_id));
|
||||
if (security_level == kSecurityLevelL1 && OkpIsInFallbackMode()) {
|
||||
LOGD("OKP fallback to L3");
|
||||
security_level = kSecurityLevelL3;
|
||||
}
|
||||
DeviceFiles handle(file_system_);
|
||||
if (!handle.Init(security_level)) {
|
||||
LOGE("Unable to initialize device files");
|
||||
return DELETE_USAGE_ERROR_1;
|
||||
}
|
||||
std::string provider_session_token;
|
||||
if (!handle.GetProviderSessionToken(app_id, key_set_id,
|
||||
&provider_session_token)) {
|
||||
LOGE("GetProviderSessionToken failed");
|
||||
return DELETE_USAGE_ERROR_2;
|
||||
}
|
||||
return RemoveUsageInfo(app_id, provider_session_token);
|
||||
LOGI("app_id = %s, security_level = %s, key_set_id = %s", IdToString(app_id),
|
||||
CdmSecurityLevelToString(security_level), IdToString(key_set_id));
|
||||
LOGW("API not supported");
|
||||
return NOT_IMPLEMENTED_ERROR;
|
||||
}
|
||||
|
||||
CdmResponseType CdmEngine::GetOfflineLicenseState(
|
||||
@@ -1397,7 +1363,7 @@ CdmResponseType CdmEngine::RemoveOfflineLicense(
|
||||
}
|
||||
} else if (sts == LICENSE_USAGE_ENTRY_MISSING) {
|
||||
// It is possible that the CDM is tracking a key set ID, but has
|
||||
// removed the usage information associated with it. In this case,
|
||||
// removed the usage entry associated with it. In this case,
|
||||
// it will no longer be possible to load the license for release;
|
||||
// and the file should simply be deleted.
|
||||
LOGW("License usage entry is missing, deleting license file");
|
||||
@@ -1415,415 +1381,66 @@ CdmResponseType CdmEngine::RemoveOfflineLicense(
|
||||
|
||||
CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
|
||||
const CdmSecureStopId& ssid,
|
||||
int* error_detail,
|
||||
CdmUsageInfo* usage_info) {
|
||||
// Try to find usage info at the default security level. If the
|
||||
// security level is unprovisioned or we are unable to find it,
|
||||
// try L3.
|
||||
CdmResponseType status =
|
||||
GetUsageInfo(app_id, ssid, kLevelDefault, error_detail, usage_info);
|
||||
switch (status) {
|
||||
case NEED_PROVISIONING:
|
||||
case GET_USAGE_INFO_ERROR_1:
|
||||
case GET_USAGE_INFO_ERROR_2:
|
||||
case USAGE_INFO_NOT_FOUND:
|
||||
status = GetUsageInfo(app_id, ssid, kLevel3, error_detail, usage_info);
|
||||
return status;
|
||||
default:
|
||||
return status;
|
||||
}
|
||||
int* /* error_detail */,
|
||||
CdmUsageInfo* /* usage_info */) {
|
||||
LOGI("app_id = %s, ssid = %s", IdToString(app_id), IdToString(ssid));
|
||||
LOGE("API not supported");
|
||||
return NOT_IMPLEMENTED_ERROR;
|
||||
}
|
||||
|
||||
CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
|
||||
const CdmSecureStopId& ssid,
|
||||
RequestedSecurityLevel security_level,
|
||||
int* error_detail,
|
||||
CdmUsageInfo* usage_info) {
|
||||
LOGI("app_id = %s, ssid = %s", IdToString(app_id), IdToString(ssid));
|
||||
if (!usage_property_set_) {
|
||||
usage_property_set_.reset(new UsagePropertySet());
|
||||
}
|
||||
if (usage_info == nullptr) {
|
||||
LOGE("Output |usage_info| is null");
|
||||
return PARAMETER_NULL;
|
||||
}
|
||||
usage_property_set_->set_security_level(security_level);
|
||||
usage_property_set_->set_app_id(app_id);
|
||||
usage_session_.reset(new CdmSession(file_system_, metrics_->AddSession()));
|
||||
CdmResponseType status = usage_session_->Init(usage_property_set_.get());
|
||||
if (NO_ERROR != status) {
|
||||
LOGE("Session init error: status = %d", static_cast<int>(status));
|
||||
return status;
|
||||
}
|
||||
DeviceFiles handle(file_system_);
|
||||
if (!handle.Init(usage_session_->GetSecurityLevel())) {
|
||||
LOGE("Device file init error");
|
||||
return GET_USAGE_INFO_ERROR_1;
|
||||
}
|
||||
|
||||
DeviceFiles::CdmUsageData usage_data;
|
||||
if (!handle.RetrieveUsageInfo(DeviceFiles::GetUsageInfoFileName(app_id), ssid,
|
||||
&usage_data)) {
|
||||
usage_property_set_->set_security_level(kLevel3);
|
||||
usage_property_set_->set_app_id(app_id);
|
||||
usage_session_.reset(new CdmSession(file_system_, metrics_->AddSession()));
|
||||
status = usage_session_->Init(usage_property_set_.get());
|
||||
if (NO_ERROR != status) {
|
||||
LOGE("Session init error: status = %d", static_cast<int>(status));
|
||||
return status;
|
||||
}
|
||||
if (!handle.Reset(usage_session_->GetSecurityLevel())) {
|
||||
LOGE("Device file init error");
|
||||
return GET_USAGE_INFO_ERROR_2;
|
||||
}
|
||||
if (!handle.RetrieveUsageInfo(DeviceFiles::GetUsageInfoFileName(app_id),
|
||||
ssid, &usage_data)) {
|
||||
// No entry found for that ssid.
|
||||
return USAGE_INFO_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
status = usage_session_->RestoreUsageSession(usage_data, error_detail);
|
||||
|
||||
if (KEY_ADDED != status) {
|
||||
LOGE("RestoreUsageSession failed: status = %d", static_cast<int>(status));
|
||||
usage_info->clear();
|
||||
return status;
|
||||
}
|
||||
|
||||
CdmKeyRequest request;
|
||||
status = usage_session_->GenerateReleaseRequest(&request);
|
||||
|
||||
usage_info->clear();
|
||||
usage_info->push_back(request.message);
|
||||
|
||||
if (KEY_MESSAGE != status) {
|
||||
LOGE("GenerateReleaseRequest failed: status = %d",
|
||||
static_cast<int>(status));
|
||||
usage_info->clear();
|
||||
return status;
|
||||
}
|
||||
|
||||
return KEY_MESSAGE;
|
||||
int* /* error_detail */,
|
||||
CdmUsageInfo* /* usage_info */) {
|
||||
LOGI("app_id = %s, ssid = %s, security_level = %s", IdToString(app_id),
|
||||
IdToString(ssid), RequestedSecurityLevelToString(security_level));
|
||||
LOGE("API not supported");
|
||||
return NOT_IMPLEMENTED_ERROR;
|
||||
}
|
||||
|
||||
CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
|
||||
int* error_detail,
|
||||
CdmUsageInfo* usage_info) {
|
||||
int* /* error_detail */,
|
||||
CdmUsageInfo* /* usage_info */) {
|
||||
LOGI("app_id = %s", IdToString(app_id));
|
||||
if (usage_info == nullptr) {
|
||||
LOGE("Output |usage_info| is null");
|
||||
return PARAMETER_NULL;
|
||||
}
|
||||
// Return a random usage report from a random security level
|
||||
RequestedSecurityLevel security_level =
|
||||
wvutil::CdmRandom::RandomBool() ? kLevelDefault : kLevel3;
|
||||
CdmResponseType status = UNKNOWN_ERROR;
|
||||
do {
|
||||
status = GetUsageInfo(app_id, security_level, error_detail, usage_info);
|
||||
if (KEY_MESSAGE == status && !usage_info->empty()) {
|
||||
return status;
|
||||
}
|
||||
} while (KEY_CANCELED == status);
|
||||
|
||||
security_level = (kLevel3 == security_level) ? kLevelDefault : kLevel3;
|
||||
do {
|
||||
status = GetUsageInfo(app_id, security_level, error_detail, usage_info);
|
||||
if (NEED_PROVISIONING == status)
|
||||
return NO_ERROR; // Valid scenario that one of the security
|
||||
// levels has not been provisioned
|
||||
} while (KEY_CANCELED == status);
|
||||
return status;
|
||||
}
|
||||
|
||||
CdmResponseType CdmEngine::GetUsageInfo(
|
||||
const std::string& app_id, RequestedSecurityLevel requested_security_level,
|
||||
int* error_detail, CdmUsageInfo* usage_info) {
|
||||
LOGI("app_id = %s, security_level = %s", IdToString(app_id),
|
||||
RequestedSecurityLevelToString(requested_security_level));
|
||||
if (usage_info == nullptr) {
|
||||
LOGE("Output |usage_info| is null");
|
||||
return PARAMETER_NULL;
|
||||
}
|
||||
if (requested_security_level == kLevelDefault && OkpIsInFallbackMode()) {
|
||||
LOGD("OKP fallback to L3");
|
||||
requested_security_level = kLevel3;
|
||||
}
|
||||
if (!usage_property_set_) {
|
||||
usage_property_set_.reset(new UsagePropertySet());
|
||||
}
|
||||
usage_property_set_->set_security_level(requested_security_level);
|
||||
usage_property_set_->set_app_id(app_id);
|
||||
|
||||
usage_session_.reset(new CdmSession(file_system_, metrics_->AddSession()));
|
||||
|
||||
CdmResponseType status = usage_session_->Init(usage_property_set_.get());
|
||||
if (NO_ERROR != status) {
|
||||
LOGE("Session init error");
|
||||
return status;
|
||||
}
|
||||
|
||||
DeviceFiles handle(file_system_);
|
||||
if (!handle.Init(usage_session_->GetSecurityLevel())) {
|
||||
LOGE("Unable to initialize device files");
|
||||
return GET_USAGE_INFO_ERROR_3;
|
||||
}
|
||||
|
||||
std::vector<DeviceFiles::CdmUsageData> usage_data;
|
||||
if (!handle.RetrieveUsageInfo(DeviceFiles::GetUsageInfoFileName(app_id),
|
||||
&usage_data)) {
|
||||
LOGE("Unable to read usage information");
|
||||
return GET_USAGE_INFO_ERROR_4;
|
||||
}
|
||||
|
||||
if (usage_data.empty()) {
|
||||
usage_info->clear();
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
const size_t index = wvutil::CdmRandom::RandomInRange(usage_data.size() - 1);
|
||||
status = usage_session_->RestoreUsageSession(usage_data[index], error_detail);
|
||||
if (KEY_ADDED != status) {
|
||||
// TODO(b/141704872): Make multiple attempts.
|
||||
LOGE("RestoreUsageSession failed: index = %zu, status = %d", index,
|
||||
static_cast<int>(status));
|
||||
usage_info->clear();
|
||||
return status;
|
||||
}
|
||||
|
||||
CdmKeyRequest request;
|
||||
status = usage_session_->GenerateReleaseRequest(&request);
|
||||
|
||||
usage_info->clear();
|
||||
usage_info->push_back(request.message);
|
||||
|
||||
switch (status) {
|
||||
case KEY_MESSAGE:
|
||||
break;
|
||||
case KEY_CANCELED: // usage information not present in
|
||||
usage_session_->DeleteLicenseFile(); // OEMCrypto, delete and try again
|
||||
usage_info->clear();
|
||||
break;
|
||||
default:
|
||||
LOGE("GenerateReleaseRequest failed: status = %d",
|
||||
static_cast<int>(status));
|
||||
usage_info->clear();
|
||||
break;
|
||||
}
|
||||
return status;
|
||||
LOGE("API not supported");
|
||||
return NOT_IMPLEMENTED_ERROR;
|
||||
}
|
||||
|
||||
CdmResponseType CdmEngine::RemoveAllUsageInfo(
|
||||
const std::string& app_id, CdmSecurityLevel cdm_security_level) {
|
||||
LOGI("app_id = %s, security_level = %s", IdToString(app_id),
|
||||
CdmSecurityLevelToString(cdm_security_level));
|
||||
if (!usage_property_set_) {
|
||||
usage_property_set_.reset(new UsagePropertySet());
|
||||
}
|
||||
usage_property_set_->set_app_id(app_id);
|
||||
|
||||
CdmResponseType status = NO_ERROR;
|
||||
DeviceFiles handle(file_system_);
|
||||
if (handle.Init(cdm_security_level)) {
|
||||
const RequestedSecurityLevel security_level =
|
||||
cdm_security_level == kSecurityLevelL3 ? kLevel3 : kLevelDefault;
|
||||
usage_property_set_->set_security_level(security_level);
|
||||
usage_session_.reset(new CdmSession(file_system_, metrics_->AddSession()));
|
||||
usage_session_->Init(usage_property_set_.get());
|
||||
|
||||
if (usage_session_->supports_usage_info()) {
|
||||
std::vector<DeviceFiles::CdmUsageData> usage_data;
|
||||
// Retrieve all usage information but delete only one before
|
||||
// refetching. This is because deleting the usage entry
|
||||
// might cause other entries to be shifted and information updated.
|
||||
do {
|
||||
if (!handle.RetrieveUsageInfo(DeviceFiles::GetUsageInfoFileName(app_id),
|
||||
&usage_data)) {
|
||||
LOGW("Failed to retrieve usage info");
|
||||
break;
|
||||
}
|
||||
|
||||
if (usage_data.empty()) break;
|
||||
|
||||
CdmResponseType res =
|
||||
usage_session_->DeleteUsageEntry(usage_data[0].usage_entry_number);
|
||||
|
||||
if (res != NO_ERROR) {
|
||||
LOGW("Failed to delete usage entry: status = %d",
|
||||
static_cast<int>(res));
|
||||
break;
|
||||
}
|
||||
|
||||
if (!handle.DeleteUsageInfo(DeviceFiles::GetUsageInfoFileName(app_id),
|
||||
usage_data[0].provider_session_token)) {
|
||||
LOGW("Failed to delete usage info");
|
||||
break;
|
||||
}
|
||||
} while (!usage_data.empty());
|
||||
|
||||
std::vector<std::string> provider_session_tokens;
|
||||
if (!handle.DeleteAllUsageInfoForApp(
|
||||
DeviceFiles::GetUsageInfoFileName(app_id),
|
||||
&provider_session_tokens)) {
|
||||
status = REMOVE_ALL_USAGE_INFO_ERROR_5;
|
||||
}
|
||||
}
|
||||
}
|
||||
usage_session_.reset();
|
||||
return status;
|
||||
LOGE("API not supported");
|
||||
return NOT_IMPLEMENTED_ERROR;
|
||||
}
|
||||
|
||||
CdmResponseType CdmEngine::RemoveAllUsageInfo(const std::string& app_id) {
|
||||
LOGI("app_id = %s", IdToString(app_id));
|
||||
const CdmResponseType status_l1 =
|
||||
RemoveAllUsageInfo(app_id, kSecurityLevelL1);
|
||||
const CdmResponseType status_l3 =
|
||||
RemoveAllUsageInfo(app_id, kSecurityLevelL3);
|
||||
// Prioritizing L1 status.
|
||||
if (status_l1 != NO_ERROR) {
|
||||
return status_l1;
|
||||
}
|
||||
return status_l3;
|
||||
LOGE("API not supported");
|
||||
return NOT_IMPLEMENTED_ERROR;
|
||||
}
|
||||
|
||||
CdmResponseType CdmEngine::RemoveUsageInfo(
|
||||
const std::string& app_id, const CdmSecureStopId& provider_session_token) {
|
||||
LOGI("app_id = %s, pst = %s", IdToString(app_id),
|
||||
IdToString(provider_session_token));
|
||||
if (!usage_property_set_) {
|
||||
usage_property_set_.reset(new UsagePropertySet());
|
||||
}
|
||||
usage_property_set_->set_app_id(app_id);
|
||||
|
||||
CdmResponseType status = NO_ERROR;
|
||||
for (int j = kSecurityLevelL1; j < kSecurityLevelUnknown; ++j) {
|
||||
DeviceFiles handle(file_system_);
|
||||
if (handle.Init(static_cast<CdmSecurityLevel>(j))) {
|
||||
RequestedSecurityLevel security_level =
|
||||
static_cast<CdmSecurityLevel>(j) == kSecurityLevelL3 ? kLevel3
|
||||
: kLevelDefault;
|
||||
usage_property_set_->set_security_level(security_level);
|
||||
usage_session_.reset(
|
||||
new CdmSession(file_system_, metrics_->AddSession()));
|
||||
usage_session_->Init(usage_property_set_.get());
|
||||
|
||||
CdmKeyMessage license_request;
|
||||
CdmKeyResponse license_response;
|
||||
CdmUsageEntry usage_entry;
|
||||
uint32_t usage_entry_number;
|
||||
std::string drm_certificate;
|
||||
CryptoWrappedKey wrapped_private_key;
|
||||
|
||||
if (!handle.RetrieveUsageInfo(
|
||||
DeviceFiles::GetUsageInfoFileName(app_id), provider_session_token,
|
||||
&license_request, &license_response, &usage_entry,
|
||||
&usage_entry_number, &drm_certificate, &wrapped_private_key)) {
|
||||
// Try other security level
|
||||
continue;
|
||||
}
|
||||
|
||||
if (usage_session_->supports_usage_info()) {
|
||||
status = usage_session_->DeleteUsageEntry(usage_entry_number);
|
||||
if (!handle.DeleteUsageInfo(DeviceFiles::GetUsageInfoFileName(app_id),
|
||||
provider_session_token)) {
|
||||
status = REMOVE_USAGE_INFO_ERROR_1;
|
||||
}
|
||||
usage_session_.reset();
|
||||
return status;
|
||||
}
|
||||
} else {
|
||||
LOGE("Failed to initialize L%d device files", j);
|
||||
status = REMOVE_USAGE_INFO_ERROR_2;
|
||||
}
|
||||
}
|
||||
usage_session_.reset();
|
||||
return REMOVE_USAGE_INFO_ERROR_3;
|
||||
LOGE("API not supported");
|
||||
return NOT_IMPLEMENTED_ERROR;
|
||||
}
|
||||
|
||||
CdmResponseType CdmEngine::ReleaseUsageInfo(
|
||||
const CdmUsageInfoReleaseMessage& message) {
|
||||
LOGI("message_size = %zu", message.size());
|
||||
if (!usage_session_) {
|
||||
LOGE("Usage session not initialized");
|
||||
return RELEASE_USAGE_INFO_ERROR;
|
||||
}
|
||||
const CdmResponseType status = usage_session_->ReleaseKey(message);
|
||||
usage_session_.reset();
|
||||
if (NO_ERROR != status) {
|
||||
LOGE("ReleaseKey failed: status = %d", status);
|
||||
}
|
||||
return status;
|
||||
LOGE("API not supported");
|
||||
return NOT_IMPLEMENTED_ERROR;
|
||||
}
|
||||
|
||||
CdmResponseType CdmEngine::LoadUsageSession(const CdmKeySetId& key_set_id,
|
||||
CdmKeyMessage* release_message) {
|
||||
CdmResponseType CdmEngine::LoadUsageSession(
|
||||
const CdmKeySetId& key_set_id, CdmKeyMessage* /* release_message */) {
|
||||
LOGI("key_set_id = %s", IdToString(key_set_id));
|
||||
// This method is currently only used by the CE CDM, in which all session IDs
|
||||
// are key set IDs.
|
||||
assert(Properties::AlwaysUseKeySetIds());
|
||||
if (key_set_id.empty()) {
|
||||
LOGE("Invalid key set ID");
|
||||
return EMPTY_KEYSET_ID_ENG_5;
|
||||
}
|
||||
if (release_message == nullptr) {
|
||||
LOGE("Output |release_message| is null");
|
||||
return PARAMETER_NULL;
|
||||
}
|
||||
|
||||
std::shared_ptr<CdmSession> session;
|
||||
if (!session_map_.FindSession(key_set_id, &session)) {
|
||||
LOGE("Session not found: key_set_id = %s", IdToString(key_set_id));
|
||||
return SESSION_NOT_FOUND_11;
|
||||
}
|
||||
|
||||
DeviceFiles handle(file_system_);
|
||||
if (!handle.Init(session->GetSecurityLevel())) {
|
||||
LOGE("Unable to initialize device files");
|
||||
return LOAD_USAGE_INFO_FILE_ERROR;
|
||||
}
|
||||
|
||||
std::string app_id;
|
||||
session->GetApplicationId(&app_id);
|
||||
|
||||
DeviceFiles::CdmUsageData usage_data;
|
||||
if (!handle.RetrieveUsageInfoByKeySetId(
|
||||
DeviceFiles::GetUsageInfoFileName(app_id), key_set_id,
|
||||
&(usage_data.provider_session_token), &(usage_data.license_request),
|
||||
&(usage_data.license), &(usage_data.usage_entry),
|
||||
&(usage_data.usage_entry_number), &(usage_data.drm_certificate),
|
||||
&(usage_data.wrapped_private_key))) {
|
||||
LOGE("Unable to find usage information");
|
||||
return LOAD_USAGE_INFO_MISSING;
|
||||
}
|
||||
|
||||
int error_detail = NO_ERROR;
|
||||
usage_data.key_set_id = key_set_id;
|
||||
CdmResponseType status =
|
||||
session->RestoreUsageSession(usage_data, &error_detail);
|
||||
session->GetMetrics()->cdm_session_restore_usage_session_.Increment(
|
||||
status, error_detail);
|
||||
if (KEY_ADDED != status) {
|
||||
LOGE("Restore failed: key_set_id = %s, status = %d", IdToString(key_set_id),
|
||||
static_cast<int>(status));
|
||||
return status;
|
||||
}
|
||||
|
||||
CdmKeyRequest request;
|
||||
status = session->GenerateReleaseRequest(&request);
|
||||
*release_message = std::move(request.message);
|
||||
switch (status) {
|
||||
case KEY_MESSAGE:
|
||||
break;
|
||||
case KEY_CANCELED:
|
||||
// usage information not present in OEMCrypto, delete and try again
|
||||
session->DeleteLicenseFile();
|
||||
break;
|
||||
default:
|
||||
LOGE("GenerateReleaseRequest failed: status = %d",
|
||||
static_cast<int>(status));
|
||||
break;
|
||||
}
|
||||
return status;
|
||||
LOGE("API not supported");
|
||||
return NOT_IMPLEMENTED_ERROR;
|
||||
}
|
||||
|
||||
CdmResponseType CdmEngine::DecryptV16(
|
||||
@@ -2072,6 +1689,7 @@ bool CdmEngine::FindSessionForKey(const KeyId& key_id,
|
||||
|
||||
bool CdmEngine::NotifyResolution(const CdmSessionId& session_id, uint32_t width,
|
||||
uint32_t height) {
|
||||
std::unique_lock<std::recursive_mutex> lock(session_map_lock_);
|
||||
std::shared_ptr<CdmSession> session;
|
||||
if (session_map_.FindSession(session_id, &session)) {
|
||||
session->NotifyResolution(width, height);
|
||||
@@ -2088,10 +1706,9 @@ void CdmEngine::OnTimerEvent() {
|
||||
wvutil::Clock clock;
|
||||
const uint64_t current_time = clock.GetCurrentTime();
|
||||
bool usage_update_period_expired = false;
|
||||
if (current_time - last_usage_information_update_time_ >
|
||||
kUpdateUsageInformationPeriod) {
|
||||
if (current_time - last_usage_info_update_time_ > kUpdateUsageInfoPeriod) {
|
||||
usage_update_period_expired = true;
|
||||
last_usage_information_update_time_ = current_time;
|
||||
last_usage_info_update_time_ = current_time;
|
||||
}
|
||||
|
||||
bool is_initial_usage_update = false;
|
||||
@@ -2101,27 +1718,24 @@ void CdmEngine::OnTimerEvent() {
|
||||
CdmSessionList sessions;
|
||||
session_map_.GetSessionList(sessions);
|
||||
|
||||
while (!sessions.empty()) {
|
||||
is_initial_usage_update = is_initial_usage_update ||
|
||||
sessions.front()->is_initial_usage_update();
|
||||
for (auto& session : sessions) {
|
||||
is_initial_usage_update =
|
||||
is_initial_usage_update || session->is_initial_usage_update();
|
||||
is_usage_update_needed =
|
||||
is_usage_update_needed || sessions.front()->is_usage_update_needed();
|
||||
|
||||
sessions.front()->OnTimerEvent(usage_update_period_expired);
|
||||
sessions.pop_front();
|
||||
is_usage_update_needed || session->is_usage_update_needed();
|
||||
session->OnTimerEvent(usage_update_period_expired);
|
||||
}
|
||||
|
||||
if (is_usage_update_needed &&
|
||||
(usage_update_period_expired || is_initial_usage_update)) {
|
||||
// Session list may have changed. Rebuild.
|
||||
sessions.clear();
|
||||
session_map_.GetSessionList(sessions);
|
||||
|
||||
for (CdmSessionList::iterator iter = sessions.begin();
|
||||
iter != sessions.end(); ++iter) {
|
||||
(*iter)->reset_usage_flags();
|
||||
if ((*iter)->supports_usage_info() &&
|
||||
(*iter)->has_provider_session_token()) {
|
||||
(*iter)->UpdateUsageEntryInformation();
|
||||
for (auto& session : sessions) {
|
||||
session->ResetUsageFlags();
|
||||
if (session->SupportsUsageEntries() && session->HasUsageEntry()) {
|
||||
session->UpdateUsageEntryInformation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user