Source release v3.1.0

This commit is contained in:
Gene Morgan
2016-07-19 18:43:15 -07:00
parent 7a7f78d654
commit 643b91b616
108 changed files with 16537 additions and 7174 deletions

View File

@@ -15,7 +15,6 @@
#include "license_protocol.pb.h"
#include "log.h"
#include "properties.h"
#include "scoped_ptr.h"
#include "string_conversions.h"
#include "wv_cdm_constants.h"
#include "wv_cdm_event_listener.h"
@@ -55,11 +54,13 @@ class UsagePropertySet : public CdmClientPropertySet {
bool CdmEngine::seeded_ = false;
CdmEngine::CdmEngine()
CdmEngine::CdmEngine(FileSystem* file_system)
: cert_provisioning_(NULL),
cert_provisioning_requested_security_level_(kLevelDefault),
file_system_(file_system),
usage_session_(NULL),
last_usage_information_update_time_(0) {
assert(file_system);
Properties::Init();
if (!seeded_) {
Clock clock;
@@ -79,7 +80,22 @@ CdmEngine::~CdmEngine() {
CdmResponseType CdmEngine::OpenSession(const CdmKeySystem& key_system,
CdmClientPropertySet* property_set,
const std::string& origin,
const CdmSessionId& forced_session_id,
WvCdmEventListener* event_listener) {
return OpenSession(key_system, property_set, event_listener,
&forced_session_id, NULL);
}
CdmResponseType CdmEngine::OpenSession(const CdmKeySystem& key_system,
CdmClientPropertySet* property_set,
WvCdmEventListener* event_listener,
CdmSessionId* session_id) {
return OpenSession(key_system, property_set, event_listener, NULL,
session_id);
}
CdmResponseType CdmEngine::OpenSession(const CdmKeySystem& key_system,
CdmClientPropertySet* property_set,
WvCdmEventListener* event_listener,
const CdmSessionId* forced_session_id,
CdmSessionId* session_id) {
@@ -90,8 +106,8 @@ CdmResponseType CdmEngine::OpenSession(const CdmKeySystem& key_system,
return INVALID_KEY_SYSTEM;
}
if (!session_id) {
LOGE("CdmEngine::OpenSession: no session ID destination provided");
if (!session_id && !forced_session_id) {
LOGE("CdmEngine::OpenSession: no (forced/)session ID destination provided");
return INVALID_PARAMETERS_ENG_1;
}
@@ -101,32 +117,33 @@ CdmResponseType CdmEngine::OpenSession(const CdmKeySystem& key_system,
}
}
scoped_ptr<CdmSession> new_session(
new CdmSession(property_set, origin, event_listener, forced_session_id));
if (new_session->session_id().empty()) {
LOGE("CdmEngine::OpenSession: failure to generate session ID");
return EMPTY_SESSION_ID;
}
scoped_ptr<CdmSession> new_session(new CdmSession(file_system_));
CdmResponseType sts = new_session->Init();
CdmResponseType sts = new_session->Init(property_set, forced_session_id,
event_listener);
if (sts != NO_ERROR) {
if (sts == NEED_PROVISIONING) {
cert_provisioning_requested_security_level_ =
new_session->GetRequestedSecurityLevel();
// Reserve a session ID so the CDM can return success.
if (session_id)
*session_id = new_session->GenerateSessionId();
} else {
LOGE("CdmEngine::OpenSession: bad session init: %d", sts);
}
return sts;
}
*session_id = new_session->session_id();
CdmSessionId id = new_session->session_id();
AutoLock lock(session_list_lock_);
sessions_[*session_id] = new_session.release();
sessions_[id] = new_session.release();
if (session_id) *session_id = id;
return NO_ERROR;
}
CdmResponseType CdmEngine::OpenKeySetSession(
const CdmKeySetId& key_set_id, CdmClientPropertySet* property_set,
const std::string& origin, WvCdmEventListener* event_listener) {
WvCdmEventListener* event_listener) {
LOGI("CdmEngine::OpenKeySetSession");
if (key_set_id.empty()) {
@@ -135,9 +152,8 @@ CdmResponseType CdmEngine::OpenKeySetSession(
}
CdmSessionId session_id;
CdmResponseType sts =
OpenSession(KEY_SYSTEM, property_set, origin, event_listener,
NULL /* forced_session_id */, &session_id);
CdmResponseType sts = OpenSession(KEY_SYSTEM, property_set, event_listener,
NULL /* forced_session_id */, &session_id);
if (sts != NO_ERROR) return sts;
@@ -182,9 +198,7 @@ bool CdmEngine::IsOpenSession(const CdmSessionId& session_id) {
CdmResponseType CdmEngine::GenerateKeyRequest(
const CdmSessionId& session_id, const CdmKeySetId& key_set_id,
const InitializationData& init_data, const CdmLicenseType license_type,
CdmAppParameterMap& app_parameters, CdmKeyMessage* key_request,
CdmKeyRequestType* key_request_type, std::string* server_url,
CdmKeySetId* key_set_id_out) {
CdmAppParameterMap& app_parameters, CdmKeyRequest* key_request) {
LOGI("CdmEngine::GenerateKeyRequest");
CdmSessionId id = session_id;
@@ -223,11 +237,11 @@ CdmResponseType CdmEngine::GenerateKeyRequest(
}
if (!key_request) {
LOGE("CdmEngine::GenerateKeyRequest: no key request destination provided");
LOGE("CdmEngine::GenerateKeyRequest: output destination provided");
return INVALID_PARAMETERS_ENG_2;
}
key_request->clear();
key_request->message.clear();
if (license_type == kLicenseTypeRelease &&
!iter->second->license_received()) {
@@ -240,8 +254,7 @@ CdmResponseType CdmEngine::GenerateKeyRequest(
}
sts = iter->second->GenerateKeyRequest(
init_data, license_type, app_parameters, key_request, key_request_type,
server_url, key_set_id_out);
init_data, license_type, app_parameters, key_request);
if (KEY_MESSAGE != sts) {
if (sts == NEED_PROVISIONING) {
@@ -300,7 +313,10 @@ CdmResponseType CdmEngine::AddKey(const CdmSessionId& session_id,
return EMPTY_KEY_DATA_1;
}
CdmResponseType sts = iter->second->AddKey(key_data, key_set_id);
CdmResponseType sts = iter->second->AddKey(key_data);
if (key_set_id) {
*key_set_id = iter->second->key_set_id();
}
switch (sts) {
case KEY_ADDED:
@@ -359,8 +375,7 @@ CdmResponseType CdmEngine::RemoveKeys(const CdmSessionId& session_id) {
}
CdmResponseType CdmEngine::GenerateRenewalRequest(
const CdmSessionId& session_id, CdmKeyMessage* key_request,
std::string* server_url) {
const CdmSessionId& session_id, CdmKeyRequest* key_request) {
LOGI("CdmEngine::GenerateRenewalRequest");
CdmSessionMap::iterator iter = sessions_.find(session_id);
@@ -371,14 +386,13 @@ CdmResponseType CdmEngine::GenerateRenewalRequest(
}
if (!key_request) {
LOGE("CdmEngine::GenerateRenewalRequest: no key request destination");
LOGE("CdmEngine::GenerateRenewalRequest: no request destination");
return INVALID_PARAMETERS_ENG_4;
}
key_request->clear();
key_request->message.clear();
CdmResponseType sts =
iter->second->GenerateRenewalRequest(key_request, server_url);
CdmResponseType sts = iter->second->GenerateRenewalRequest(key_request);
if (KEY_MESSAGE != sts) {
LOGE("CdmEngine::GenerateRenewalRequest: key request gen. failed, sts=%d",
@@ -414,8 +428,8 @@ CdmResponseType CdmEngine::RenewKey(const CdmSessionId& session_id,
}
CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level,
const std::string& key,
std::string* value) {
const std::string& query_token,
std::string* query_response) {
LOGI("CdmEngine::QueryStatus");
CryptoSession crypto_session;
if (security_level == kLevel3) {
@@ -423,36 +437,41 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level,
if (NO_ERROR != status) return INVALID_QUERY_STATUS;
}
if (key == QUERY_KEY_SECURITY_LEVEL) {
if (!query_response) {
LOGE("CdmEngine::QueryStatus: no query response destination");
return INVALID_PARAMETERS_ENG_6;
}
if (query_token == QUERY_KEY_SECURITY_LEVEL) {
CdmSecurityLevel security_level = crypto_session.GetSecurityLevel();
switch (security_level) {
case kSecurityLevelL1:
*value = QUERY_VALUE_SECURITY_LEVEL_L1;
*query_response = QUERY_VALUE_SECURITY_LEVEL_L1;
break;
case kSecurityLevelL2:
*value = QUERY_VALUE_SECURITY_LEVEL_L2;
*query_response = QUERY_VALUE_SECURITY_LEVEL_L2;
break;
case kSecurityLevelL3:
*value = QUERY_VALUE_SECURITY_LEVEL_L3;
*query_response = QUERY_VALUE_SECURITY_LEVEL_L3;
break;
case kSecurityLevelUninitialized:
case kSecurityLevelUnknown:
*value = QUERY_VALUE_SECURITY_LEVEL_UNKNOWN;
*query_response = QUERY_VALUE_SECURITY_LEVEL_UNKNOWN;
break;
default:
LOGW("CdmEngine::QueryStatus: Unknown security level: %d",
security_level);
return UNKNOWN_ERROR;
}
} else if (key == QUERY_KEY_DEVICE_ID) {
} else if (query_token == QUERY_KEY_DEVICE_ID) {
std::string deviceId;
if (!crypto_session.GetDeviceUniqueId(&deviceId)) {
LOGW("CdmEngine::QueryStatus: GetDeviceUniqueId failed");
return UNKNOWN_ERROR;
}
*value = deviceId;
} else if (key == QUERY_KEY_SYSTEM_ID) {
*query_response = deviceId;
} else if (query_token == QUERY_KEY_SYSTEM_ID) {
uint32_t system_id;
if (!crypto_session.GetSystemId(&system_id)) {
LOGW("CdmEngine::QueryStatus: GetSystemId failed");
@@ -461,35 +480,36 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level,
std::ostringstream system_id_stream;
system_id_stream << system_id;
*value = system_id_stream.str();
} else if (key == QUERY_KEY_PROVISIONING_ID) {
*query_response = system_id_stream.str();
} else if (query_token == QUERY_KEY_PROVISIONING_ID) {
std::string provisioning_id;
if (!crypto_session.GetProvisioningId(&provisioning_id)) {
LOGW("CdmEngine::QueryStatus: GetProvisioningId failed");
return UNKNOWN_ERROR;
}
*value = provisioning_id;
} else if (key == QUERY_KEY_CURRENT_HDCP_LEVEL ||
key == QUERY_KEY_MAX_HDCP_LEVEL) {
*query_response = provisioning_id;
} else if (query_token == QUERY_KEY_CURRENT_HDCP_LEVEL ||
query_token == QUERY_KEY_MAX_HDCP_LEVEL) {
CryptoSession::HdcpCapability current_hdcp;
CryptoSession::HdcpCapability max_hdcp;
if (!crypto_session.GetHdcpCapabilities(&current_hdcp, &max_hdcp)) {
LOGW("CdmEngine::QueryStatus: GetHdcpCapabilities failed");
return UNKNOWN_ERROR;
}
*value = MapHdcpVersion(key == QUERY_KEY_CURRENT_HDCP_LEVEL ? current_hdcp
: max_hdcp);
} else if (key == QUERY_KEY_USAGE_SUPPORT) {
*query_response =
MapHdcpVersion(query_token == QUERY_KEY_CURRENT_HDCP_LEVEL ?
current_hdcp : max_hdcp);
} else if (query_token == QUERY_KEY_USAGE_SUPPORT) {
bool supports_usage_reporting;
if (!crypto_session.UsageInformationSupport(&supports_usage_reporting)) {
LOGW("CdmEngine::QueryStatus: UsageInformationSupport failed");
return UNKNOWN_ERROR;
}
*value = supports_usage_reporting ? QUERY_VALUE_TRUE : QUERY_VALUE_FALSE;
} else if (key == QUERY_KEY_NUMBER_OF_OPEN_SESSIONS) {
*query_response =
supports_usage_reporting ? QUERY_VALUE_TRUE : QUERY_VALUE_FALSE;
} else if (query_token == QUERY_KEY_NUMBER_OF_OPEN_SESSIONS) {
size_t number_of_open_sessions;
if (!crypto_session.GetNumberOfOpenSessions(&number_of_open_sessions)) {
LOGW("CdmEngine::QueryStatus: GetNumberOfOpenSessions failed");
@@ -498,8 +518,8 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level,
std::ostringstream open_sessions_stream;
open_sessions_stream << number_of_open_sessions;
*value = open_sessions_stream.str();
} else if (key == QUERY_KEY_MAX_NUMBER_OF_SESSIONS) {
*query_response = open_sessions_stream.str();
} else if (query_token == QUERY_KEY_MAX_NUMBER_OF_SESSIONS) {
size_t maximum_number_of_sessions;
if (!crypto_session.GetMaxNumberOfSessions(&maximum_number_of_sessions)) {
LOGW("CdmEngine::QueryStatus: GetMaxNumberOfOpenSessions failed");
@@ -508,8 +528,8 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level,
std::ostringstream max_sessions_stream;
max_sessions_stream << maximum_number_of_sessions;
*value = max_sessions_stream.str();
} else if (key == QUERY_KEY_OEMCRYPTO_API_VERSION) {
*query_response = max_sessions_stream.str();
} else if (query_token == QUERY_KEY_OEMCRYPTO_API_VERSION) {
uint32_t api_version;
if (!crypto_session.GetApiVersion(&api_version)) {
LOGW("CdmEngine::QueryStatus: GetApiVersion failed");
@@ -518,10 +538,10 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level,
std::ostringstream api_version_stream;
api_version_stream << api_version;
*value = api_version_stream.str();
*query_response = api_version_stream.str();
} else {
LOGW("CdmEngine::QueryStatus: Unknown status requested, key = %s",
key.c_str());
LOGW("CdmEngine::QueryStatus: Unknown status requested, token = %s",
query_token.c_str());
return INVALID_QUERY_KEY;
}
@@ -529,7 +549,7 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level,
}
CdmResponseType CdmEngine::QuerySessionStatus(const CdmSessionId& session_id,
CdmQueryMap* key_info) {
CdmQueryMap* query_response) {
LOGI("CdmEngine::QuerySessionStatus");
CdmSessionMap::iterator iter = sessions_.find(session_id);
if (iter == sessions_.end()) {
@@ -537,7 +557,7 @@ CdmResponseType CdmEngine::QuerySessionStatus(const CdmSessionId& session_id,
session_id.c_str());
return SESSION_NOT_FOUND_8;
}
return iter->second->QueryStatus(key_info);
return iter->second->QueryStatus(query_response);
}
bool CdmEngine::IsReleaseSession(const CdmSessionId& session_id) {
@@ -563,7 +583,7 @@ bool CdmEngine::IsOfflineSession(const CdmSessionId& session_id) {
}
CdmResponseType CdmEngine::QueryKeyStatus(const CdmSessionId& session_id,
CdmQueryMap* key_info) {
CdmQueryMap* query_response) {
LOGI("CdmEngine::QueryKeyStatus");
CdmSessionMap::iterator iter = sessions_.find(session_id);
if (iter == sessions_.end()) {
@@ -571,19 +591,72 @@ CdmResponseType CdmEngine::QueryKeyStatus(const CdmSessionId& session_id,
session_id.c_str());
return SESSION_NOT_FOUND_9;
}
return iter->second->QueryKeyStatus(key_info);
return iter->second->QueryKeyStatus(query_response);
}
CdmResponseType CdmEngine::QueryKeyControlInfo(const CdmSessionId& session_id,
CdmQueryMap* key_info) {
LOGI("CdmEngine::QueryKeyControlInfo");
CdmResponseType CdmEngine::QueryKeyAllowedUsage(const CdmSessionId& session_id,
const std::string& key_id,
CdmKeyAllowedUsage* key_usage) {
LOGI("CdmEngine::QueryKeyAllowedUsage");
if (!key_usage) {
LOGE("CdmEngine::QueryKeyAllowedUsage: no response destination");
return INVALID_PARAMETERS_ENG_12;
}
CdmSessionMap::iterator iter = sessions_.find(session_id);
if (iter == sessions_.end()) {
LOGE("CdmEngine::QueryKeyControlInfo: session_id not found = %s",
LOGE("CdmEngine::QueryKeyAllowedUsage: session_id not found = %s",
session_id.c_str());
return SESSION_NOT_FOUND_12;
}
return iter->second->QueryKeyAllowedUsage(key_id, key_usage);
}
CdmResponseType CdmEngine::QueryKeyAllowedUsage(const std::string& key_id,
CdmKeyAllowedUsage* key_usage) {
LOGI("CdmEngine::QueryKeyAllowedUsage (all sessions)");
CdmResponseType session_sts;
CdmKeyAllowedUsage found_in_this_session;
bool found = false;
if (!key_usage) {
LOGE("CdmEngine::QueryKeyAllowedUsage: no response destination");
return INVALID_PARAMETERS_ENG_7;
}
key_usage->Clear();
for (CdmSessionMap::iterator iter = sessions_.begin();
iter != sessions_.end(); ++iter) {
session_sts = iter->second->QueryKeyAllowedUsage(key_id,
&found_in_this_session);
if (session_sts == NO_ERROR) {
if (found) {
// Found another key. If usage settings do not match, fail.
if (!key_usage->Equals(found_in_this_session)) {
key_usage->Clear();
return KEY_CONFLICT_1;
}
} else {
*key_usage = found_in_this_session;
found = true;
}
} else if (session_sts != KEY_NOT_FOUND_1) {
LOGE("CdmEngine::QueryKeyAllowedUsage (all sessions) FAILED = %d",
session_sts);
key_usage->Clear();
return session_sts;
}
}
return (found) ? NO_ERROR : KEY_NOT_FOUND_2;
}
CdmResponseType CdmEngine::QueryOemCryptoSessionId(
const CdmSessionId& session_id, CdmQueryMap* query_response) {
LOGI("CdmEngine::QueryOemCryptoSessionId");
CdmSessionMap::iterator iter = sessions_.find(session_id);
if (iter == sessions_.end()) {
LOGE("CdmEngine::QueryOemCryptoSessionId: session_id not found = %s",
session_id.c_str());
return SESSION_NOT_FOUND_10;
}
return iter->second->QueryKeyControlInfo(key_info);
return iter->second->QueryOemCryptoSessionId(query_response);
}
/*
@@ -595,8 +668,7 @@ CdmResponseType CdmEngine::QueryKeyControlInfo(const CdmSessionId& session_id,
*/
CdmResponseType CdmEngine::GetProvisioningRequest(
CdmCertificateType cert_type, const std::string& cert_authority,
const std::string& origin, CdmProvisioningRequest* request,
std::string* default_url) {
CdmProvisioningRequest* request, std::string* default_url) {
if (!request) {
LOGE("CdmEngine::GetProvisioningRequest: invalid output parameters");
return INVALID_PROVISIONING_REQUEST_PARAM_1;
@@ -613,7 +685,7 @@ CdmResponseType CdmEngine::GetProvisioningRequest(
}
CdmResponseType ret = cert_provisioning_->GetProvisioningRequest(
cert_provisioning_requested_security_level_, cert_type, cert_authority,
origin, request, default_url);
file_system_->origin(), request, default_url);
if (ret != NO_ERROR) {
cert_provisioning_.reset(NULL); // Release resources.
}
@@ -628,8 +700,8 @@ CdmResponseType CdmEngine::GetProvisioningRequest(
* Returns NO_ERROR for success and CdmResponseType error code if fails.
*/
CdmResponseType CdmEngine::HandleProvisioningResponse(
const std::string& origin, const CdmProvisioningResponse& response,
std::string* cert, std::string* wrapped_key) {
const CdmProvisioningResponse& response, std::string* cert,
std::string* wrapped_key) {
if (response.empty()) {
LOGE("CdmEngine::HandleProvisioningResponse: Empty provisioning response.");
cert_provisioning_.reset(NULL);
@@ -661,7 +733,7 @@ CdmResponseType CdmEngine::HandleProvisioningResponse(
return EMPTY_PROVISIONING_CERTIFICATE_2;
}
CdmSecurityLevel security_level = crypto_session.GetSecurityLevel();
if (!IsProvisioned(security_level, origin)) {
if (!IsProvisioned(security_level)) {
LOGE(
"CdmEngine::HandleProvisioningResponse: provisioning object "
"missing.");
@@ -671,7 +743,7 @@ CdmResponseType CdmEngine::HandleProvisioningResponse(
}
CdmResponseType ret = cert_provisioning_->HandleProvisioningResponse(
origin, response, cert, wrapped_key);
file_system_, response, cert, wrapped_key);
// Release resources only on success. It is possible that a provisioning
// attempt was made after this one was requested but before the response was
// received, which will cause this attempt to fail. Not releasing will
@@ -680,28 +752,25 @@ CdmResponseType CdmEngine::HandleProvisioningResponse(
return ret;
}
bool CdmEngine::IsProvisioned(CdmSecurityLevel security_level,
const std::string& origin) {
DeviceFiles handle;
bool CdmEngine::IsProvisioned(CdmSecurityLevel security_level) {
DeviceFiles handle(file_system_);
if (!handle.Init(security_level)) {
LOGE("CdmEngine::IsProvisioned: unable to initialize device files");
return false;
}
return handle.HasCertificate(origin);
return handle.HasCertificate();
}
CdmResponseType CdmEngine::Unprovision(CdmSecurityLevel security_level,
const std::string& origin) {
DeviceFiles handle;
CdmResponseType CdmEngine::Unprovision(CdmSecurityLevel security_level) {
DeviceFiles handle(file_system_);
if (!handle.Init(security_level)) {
LOGE("CdmEngine::Unprovision: unable to initialize device files");
return UNPROVISION_ERROR_1;
}
if (origin != EMPTY_ORIGIN) {
if (!handle.RemoveCertificate(origin)) {
LOGE("CdmEngine::Unprovision: unable to delete certificate for origin %s",
origin.c_str());
if (!file_system_->origin().empty()) {
if (!handle.RemoveCertificate()) {
LOGE("CdmEngine::Unprovision: unable to delete certificate");
return UNPROVISION_ERROR_2;
}
return NO_ERROR;
@@ -732,16 +801,19 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
if (NULL == usage_property_set_.get()) {
usage_property_set_.reset(new UsagePropertySet());
}
if (!usage_info) {
LOGE("CdmEngine::GetUsageInfo: no usage info destination");
return INVALID_PARAMETERS_ENG_8;
}
usage_property_set_->set_security_level(kLevelDefault);
usage_property_set_->set_app_id(app_id);
usage_session_.reset(
new CdmSession(usage_property_set_.get(), EMPTY_ORIGIN, NULL, NULL));
CdmResponseType status = usage_session_->Init();
usage_session_.reset(new CdmSession(file_system_));
CdmResponseType status = usage_session_->Init(usage_property_set_.get());
if (NO_ERROR != status) {
LOGE("CdmEngine::GetUsageInfo: session init error");
return status;
}
DeviceFiles handle;
DeviceFiles handle(file_system_);
if (!handle.Init(usage_session_->GetSecurityLevel())) {
LOGE("CdmEngine::GetUsageInfo: device file init error");
return GET_USAGE_INFO_ERROR_1;
@@ -753,9 +825,8 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
&license_response)) {
usage_property_set_->set_security_level(kLevel3);
usage_property_set_->set_app_id(app_id);
usage_session_.reset(
new CdmSession(usage_property_set_.get(), EMPTY_ORIGIN, NULL, NULL));
status = usage_session_->Init();
usage_session_.reset(new CdmSession(file_system_));
status = usage_session_->Init(usage_property_set_.get());
if (NO_ERROR != status) {
LOGE("CdmEngine::GetUsageInfo: session init error");
return status;
@@ -771,18 +842,20 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
}
}
std::string server_url;
usage_info->resize(1);
status =
usage_session_->RestoreUsageSession(license_request, license_response);
usage_session_->RestoreUsageSession(license_request,license_response);
if (KEY_ADDED != status) {
LOGE("CdmEngine::GetUsageInfo: restore usage session error %d", status);
usage_info->clear();
return status;
}
status =
usage_session_->GenerateReleaseRequest(&(*usage_info)[0], &server_url);
CdmKeyRequest request;
status = usage_session_->GenerateReleaseRequest(&request);
usage_info->clear();
usage_info->push_back(request.message);
if (KEY_MESSAGE != status) {
LOGE("CdmEngine::GetUsageInfo: generate release request error: %d", status);
@@ -797,6 +870,10 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
// Return a random usage report from a random security level
SecurityLevel security_level = ((rand() % 2) == 0) ? kLevelDefault : kLevel3;
CdmResponseType status = UNKNOWN_ERROR;
if (!usage_info) {
LOGE("CdmEngine::GetUsageInfo: no usage info destination");
return INVALID_PARAMETERS_ENG_9;
}
do {
status = GetUsageInfo(app_id, security_level, usage_info);
@@ -822,16 +899,15 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
usage_property_set_->set_security_level(requested_security_level);
usage_property_set_->set_app_id(app_id);
usage_session_.reset(
new CdmSession(usage_property_set_.get(), EMPTY_ORIGIN, NULL, NULL));
usage_session_.reset(new CdmSession(file_system_));
CdmResponseType status = usage_session_->Init();
CdmResponseType status = usage_session_->Init(usage_property_set_.get());
if (NO_ERROR != status) {
LOGE("CdmEngine::GetUsageInfo: session init error");
return status;
}
DeviceFiles handle;
DeviceFiles handle(file_system_);
if (!handle.Init(usage_session_->GetSecurityLevel())) {
LOGE("CdmEngine::GetUsageInfo: unable to initialize device files");
return GET_USAGE_INFO_ERROR_3;
@@ -843,12 +919,15 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
return GET_USAGE_INFO_ERROR_4;
}
if (!usage_info) {
LOGE("CdmEngine::GetUsageInfo: no usage info destination");
return INVALID_PARAMETERS_ENG_10;
}
if (0 == license_info.size()) {
usage_info->resize(0);
return NO_ERROR;
}
std::string server_url;
usage_info->resize(kUsageReportsPerRequest);
uint32_t index = rand() % license_info.size();
@@ -861,8 +940,11 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
return status;
}
status =
usage_session_->GenerateReleaseRequest(&(*usage_info)[0], &server_url);
CdmKeyRequest request;
status = usage_session_->GenerateReleaseRequest(&request);
usage_info->clear();
usage_info->push_back(request.message);
switch (status) {
case KEY_MESSAGE:
@@ -888,7 +970,7 @@ CdmResponseType CdmEngine::ReleaseAllUsageInfo(const std::string& app_id) {
CdmResponseType status = NO_ERROR;
for (int j = kSecurityLevelL1; j < kSecurityLevelUnknown; ++j) {
DeviceFiles handle;
DeviceFiles handle(file_system_);
if (handle.Init(static_cast<CdmSecurityLevel>(j))) {
std::vector<std::string> provider_session_tokens;
if (!handle.DeleteAllUsageInfoForApp(app_id, &provider_session_tokens)) {
@@ -901,9 +983,8 @@ CdmResponseType CdmEngine::ReleaseAllUsageInfo(const std::string& app_id) {
? kLevel3
: kLevelDefault;
usage_property_set_->set_security_level(security_level);
usage_session_.reset(
new CdmSession(usage_property_set_.get(),
EMPTY_ORIGIN, NULL, NULL));
usage_session_.reset(new CdmSession(file_system_));
usage_session_->Init(usage_property_set_.get());
CdmResponseType status2 = usage_session_->
DeleteMultipleUsageInformation(provider_session_tokens);
if (status2 != NO_ERROR) {
@@ -954,7 +1035,12 @@ CdmResponseType CdmEngine::LoadUsageSession(const CdmKeySetId& key_set_id,
return SESSION_NOT_FOUND_11;
}
DeviceFiles handle;
if (!release_message) {
LOGE("CdmEngine::LoadUsageSession: no release message destination");
return INVALID_PARAMETERS_ENG_11;
}
DeviceFiles handle(file_system_);
if (!handle.Init(iter->second->GetSecurityLevel())) {
LOGE("CdmEngine::LoadUsageSession: unable to initialize device files");
return LOAD_USAGE_INFO_FILE_ERROR;
@@ -978,8 +1064,9 @@ CdmResponseType CdmEngine::LoadUsageSession(const CdmKeySetId& key_set_id,
return status;
}
std::string server_url;
status = iter->second->GenerateReleaseRequest(release_message, &server_url);
CdmKeyRequest request;
status = iter->second->GenerateReleaseRequest(&request);
*release_message = request.message;
switch (status) {
case KEY_MESSAGE:
@@ -1021,24 +1108,86 @@ CdmResponseType CdmEngine::Decrypt(const CdmSessionId& session_id,
// else we must be level 1 direct and we don't need to return a buffer.
}
CdmSessionMap::iterator iter;
CdmSessionMap::iterator session_iter = sessions_.end();
if (session_id.empty()) {
// Loop through the sessions to find the session containing the key_id.
for (iter = sessions_.begin(); iter != sessions_.end(); ++iter) {
// Loop through the sessions to find the session containing the key_id
// with the longest remaining license validity.
int64_t seconds_remaining = 0;
for (CdmSessionMap::iterator iter = sessions_.begin();
iter != sessions_.end(); ++iter) {
if (iter->second->IsKeyLoaded(*parameters.key_id)) {
break;
int64_t duration = iter->second->GetDurationRemaining();
if (duration > seconds_remaining) {
session_iter = iter;
seconds_remaining = duration;
}
}
}
} else {
iter = sessions_.find(session_id);
session_iter = sessions_.find(session_id);
}
if (iter == sessions_.end()) {
if (session_iter == sessions_.end()) {
LOGE("CdmEngine::Decrypt: session not found: id=%s, id size=%d",
session_id.c_str(), session_id.size());
return SESSION_NOT_FOUND_FOR_DECRYPT;
}
return iter->second->Decrypt(parameters);
return session_iter->second->Decrypt(parameters);
}
CdmResponseType CdmEngine::GenericEncrypt(
const std::string& session_id, const std::string& in_buffer,
const std::string& key_id, const std::string& iv,
CdmEncryptionAlgorithm algorithm, std::string* out_buffer) {
CdmSessionMap::iterator iter = sessions_.find(session_id);
if (iter == sessions_.end()) {
LOGE("CdmEngine::GenericEncrypt: session_id not found = %s ",
session_id.c_str());
return SESSION_NOT_FOUND_13;
}
return iter->second->GenericEncrypt(in_buffer, key_id, iv, algorithm,
out_buffer);
}
CdmResponseType CdmEngine::GenericDecrypt(
const std::string& session_id, const std::string& in_buffer,
const std::string& key_id, const std::string& iv,
CdmEncryptionAlgorithm algorithm,
std::string* out_buffer) {
CdmSessionMap::iterator iter = sessions_.find(session_id);
if (iter == sessions_.end()) {
LOGE("CdmEngine::GenericDecrypt: session_id not found = %s ",
session_id.c_str());
return SESSION_NOT_FOUND_14;
}
return iter->second->GenericDecrypt(in_buffer, key_id, iv, algorithm,
out_buffer);
}
CdmResponseType CdmEngine::GenericSign(
const std::string& session_id, const std::string& message,
const std::string& key_id, CdmSigningAlgorithm algorithm,
std::string* signature) {
CdmSessionMap::iterator iter = sessions_.find(session_id);
if (iter == sessions_.end()) {
LOGE("CdmEngine::GenericSign: session_id not found = %s ",
session_id.c_str());
return SESSION_NOT_FOUND_15;
}
return iter->second->GenericSign(message, key_id, algorithm, signature);
}
CdmResponseType CdmEngine::GenericVerify(
const std::string& session_id, const std::string& message,
const std::string& key_id, CdmSigningAlgorithm algorithm,
const std::string& signature) {
CdmSessionMap::iterator iter = sessions_.find(session_id);
if (iter == sessions_.end()) {
LOGE("CdmEngine::GenericVerify: session_id not found = %s ",
session_id.c_str());
return SESSION_NOT_FOUND_16;
}
return iter->second->GenericVerify(message, key_id, algorithm, signature);
}
bool CdmEngine::IsKeyLoaded(const KeyId& key_id) {
@@ -1058,25 +1207,30 @@ bool CdmEngine::FindSessionForKey(const KeyId& key_id,
return false;
}
CdmSessionMap::iterator iter = sessions_.find(*session_id);
if (iter != sessions_.end()) {
if (iter->second->IsKeyLoaded(key_id)) {
return true;
}
}
uint32_t session_sharing_id = Properties::GetSessionSharingId(*session_id);
for (iter = sessions_.begin(); iter != sessions_.end(); ++iter) {
CdmSessionMap::iterator session_iter = sessions_.end();
int64_t seconds_remaining = 0;
for (CdmSessionMap::iterator iter = sessions_.begin();
iter != sessions_.end(); ++iter) {
CdmSessionId local_session_id = iter->second->session_id();
if (Properties::GetSessionSharingId(local_session_id) ==
session_sharing_id) {
if (iter->second->IsKeyLoaded(key_id)) {
*session_id = local_session_id;
return true;
int64_t duration = iter->second->GetDurationRemaining();
if (duration > seconds_remaining) {
session_iter = iter;
seconds_remaining = duration;
}
}
}
}
if (session_iter != sessions_.end()) {
*session_id = session_iter->second->session_id();
return true;
}
return false;
}
@@ -1172,9 +1326,8 @@ void CdmEngine::DeleteAllUsageReportsUponFactoryReset() {
Properties::GetDeviceFilesBasePath(kSecurityLevelL3,
&device_base_path_level3);
File file;
if (!file.Exists(device_base_path_level1) &&
!file.Exists(device_base_path_level3)) {
if (!file_system_->Exists(device_base_path_level1) &&
!file_system_->Exists(device_base_path_level3)) {
scoped_ptr<CryptoSession> crypto_session(new CryptoSession());
CdmResponseType status = crypto_session->Open(
cert_provisioning_requested_security_level_);