Source release v3.2.0
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
#include "wv_cdm_event_listener.h"
|
||||
|
||||
namespace {
|
||||
const uint64_t kReleaseSessionTimeToLive = 60; // seconds
|
||||
const uint32_t kUpdateUsageInformationPeriod = 60; // seconds
|
||||
const size_t kUsageReportsPerRequest = 1;
|
||||
} // namespace
|
||||
@@ -54,17 +55,17 @@ class UsagePropertySet : public CdmClientPropertySet {
|
||||
|
||||
bool CdmEngine::seeded_ = false;
|
||||
|
||||
CdmEngine::CdmEngine(FileSystem* file_system)
|
||||
CdmEngine::CdmEngine(FileSystem* file_system, const std::string& spoid)
|
||||
: cert_provisioning_(NULL),
|
||||
cert_provisioning_requested_security_level_(kLevelDefault),
|
||||
file_system_(file_system),
|
||||
spoid_(spoid),
|
||||
usage_session_(NULL),
|
||||
last_usage_information_update_time_(0) {
|
||||
assert(file_system);
|
||||
Properties::Init();
|
||||
if (!seeded_) {
|
||||
Clock clock;
|
||||
srand(clock.GetCurrentTime());
|
||||
srand(clock_.GetCurrentTime());
|
||||
seeded_ = true;
|
||||
}
|
||||
}
|
||||
@@ -78,27 +79,28 @@ CdmEngine::~CdmEngine() {
|
||||
sessions_.clear();
|
||||
}
|
||||
|
||||
CdmResponseType CdmEngine::OpenSession(const CdmKeySystem& key_system,
|
||||
CdmClientPropertySet* property_set,
|
||||
const CdmSessionId& forced_session_id,
|
||||
WvCdmEventListener* event_listener) {
|
||||
CdmResponseType CdmEngine::SetServiceCertificate(
|
||||
const std::string& certificate) {
|
||||
return service_certificate_.Init(certificate);
|
||||
}
|
||||
|
||||
CdmResponseType CdmEngine::OpenSession(
|
||||
const CdmKeySystem& key_system, CdmClientPropertySet* property_set,
|
||||
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, 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) {
|
||||
CdmResponseType CdmEngine::OpenSession(
|
||||
const CdmKeySystem& key_system, CdmClientPropertySet* property_set,
|
||||
WvCdmEventListener* event_listener, const CdmSessionId* forced_session_id,
|
||||
CdmSessionId* session_id) {
|
||||
LOGI("CdmEngine::OpenSession");
|
||||
|
||||
if (!ValidateKeySystem(key_system)) {
|
||||
@@ -117,10 +119,11 @@ CdmResponseType CdmEngine::OpenSession(const CdmKeySystem& key_system,
|
||||
}
|
||||
}
|
||||
|
||||
scoped_ptr<CdmSession> new_session(new CdmSession(file_system_));
|
||||
CloseExpiredReleaseSessions();
|
||||
|
||||
CdmResponseType sts = new_session->Init(property_set, forced_session_id,
|
||||
event_listener);
|
||||
scoped_ptr<CdmSession> new_session(new CdmSession(file_system_));
|
||||
CdmResponseType sts = new_session->Init(&service_certificate_, property_set,
|
||||
forced_session_id, event_listener);
|
||||
if (sts != NO_ERROR) {
|
||||
if (sts == NEED_PROVISIONING) {
|
||||
cert_provisioning_requested_security_level_ =
|
||||
@@ -151,13 +154,27 @@ CdmResponseType CdmEngine::OpenKeySetSession(
|
||||
return EMPTY_KEYSET_ID_ENG_1;
|
||||
}
|
||||
|
||||
// If in-use, release key set before re-opening, to avoid leaking
|
||||
// resources (CryptoSession etc).
|
||||
bool key_set_in_use = false;
|
||||
{
|
||||
AutoLock lock(release_key_sets_lock_);
|
||||
key_set_in_use =
|
||||
release_key_sets_.find(key_set_id) != release_key_sets_.end();
|
||||
}
|
||||
if (key_set_in_use)
|
||||
CloseKeySetSession(key_set_id);
|
||||
|
||||
CdmSessionId session_id;
|
||||
CdmResponseType sts = OpenSession(KEY_SYSTEM, property_set, event_listener,
|
||||
NULL /* forced_session_id */, &session_id);
|
||||
|
||||
if (sts != NO_ERROR) return sts;
|
||||
|
||||
release_key_sets_[key_set_id] = session_id;
|
||||
AutoLock lock(release_key_sets_lock_);
|
||||
release_key_sets_[key_set_id] = std::make_pair(session_id,
|
||||
clock_.GetCurrentTime() + kReleaseSessionTimeToLive);
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
@@ -178,19 +195,30 @@ CdmResponseType CdmEngine::CloseSession(const CdmSessionId& session_id) {
|
||||
CdmResponseType CdmEngine::CloseKeySetSession(const CdmKeySetId& key_set_id) {
|
||||
LOGI("CdmEngine::CloseKeySetSession");
|
||||
|
||||
CdmReleaseKeySetMap::iterator iter = release_key_sets_.find(key_set_id);
|
||||
if (iter == release_key_sets_.end()) {
|
||||
LOGE("CdmEngine::CloseKeySetSession: key set id not found = %s",
|
||||
key_set_id.c_str());
|
||||
return KEYSET_ID_NOT_FOUND_1;
|
||||
CdmSessionId session_id;
|
||||
{
|
||||
AutoLock lock(release_key_sets_lock_);
|
||||
CdmReleaseKeySetMap::iterator iter = release_key_sets_.find(key_set_id);
|
||||
if (iter == release_key_sets_.end()) {
|
||||
LOGE("CdmEngine::CloseKeySetSession: key set id not found = %s",
|
||||
key_set_id.c_str());
|
||||
return KEYSET_ID_NOT_FOUND_1;
|
||||
}
|
||||
session_id = iter->second.first;
|
||||
}
|
||||
|
||||
CdmResponseType sts = CloseSession(iter->second);
|
||||
release_key_sets_.erase(iter);
|
||||
CdmResponseType sts = CloseSession(session_id);
|
||||
|
||||
AutoLock lock(release_key_sets_lock_);
|
||||
CdmReleaseKeySetMap::iterator iter = release_key_sets_.find(key_set_id);
|
||||
if (iter != release_key_sets_.end()) {
|
||||
release_key_sets_.erase(iter);
|
||||
}
|
||||
return sts;
|
||||
}
|
||||
|
||||
bool CdmEngine::IsOpenSession(const CdmSessionId& session_id) {
|
||||
AutoLock lock(session_list_lock_);
|
||||
CdmSessionMap::iterator iter = sessions_.find(session_id);
|
||||
return iter != sessions_.end();
|
||||
}
|
||||
@@ -219,6 +247,7 @@ CdmResponseType CdmEngine::GenerateKeyRequest(
|
||||
return INVALID_SESSION_ID;
|
||||
}
|
||||
|
||||
AutoLock lock(release_key_sets_lock_);
|
||||
CdmReleaseKeySetMap::iterator iter = release_key_sets_.find(key_set_id);
|
||||
if (iter == release_key_sets_.end()) {
|
||||
LOGE("CdmEngine::GenerateKeyRequest: key set ID not found = %s",
|
||||
@@ -226,7 +255,7 @@ CdmResponseType CdmEngine::GenerateKeyRequest(
|
||||
return KEYSET_ID_NOT_FOUND_2;
|
||||
}
|
||||
|
||||
id = iter->second;
|
||||
id = iter->second.first;
|
||||
}
|
||||
|
||||
CdmSessionMap::iterator iter = sessions_.find(id);
|
||||
@@ -292,13 +321,14 @@ CdmResponseType CdmEngine::AddKey(const CdmSessionId& session_id,
|
||||
return EMPTY_KEYSET_ID_ENG_3;
|
||||
}
|
||||
|
||||
AutoLock lock(release_key_sets_lock_);
|
||||
CdmReleaseKeySetMap::iterator iter = release_key_sets_.find(*key_set_id);
|
||||
if (iter == release_key_sets_.end()) {
|
||||
LOGE("CdmEngine::AddKey: key set id not found = %s", key_set_id->c_str());
|
||||
return KEYSET_ID_NOT_FOUND_3;
|
||||
}
|
||||
|
||||
id = iter->second;
|
||||
id = iter->second.first;
|
||||
}
|
||||
|
||||
CdmSessionMap::iterator iter = sessions_.find(id);
|
||||
@@ -466,7 +496,7 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level,
|
||||
} else if (query_token == QUERY_KEY_DEVICE_ID) {
|
||||
std::string deviceId;
|
||||
if (!crypto_session.GetDeviceUniqueId(&deviceId)) {
|
||||
LOGW("CdmEngine::QueryStatus: GetDeviceUniqueId failed");
|
||||
LOGW("CdmEngine::QueryStatus: QUERY_KEY_DEVICE_ID unknown failure");
|
||||
return UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
@@ -474,7 +504,7 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level,
|
||||
} else if (query_token == QUERY_KEY_SYSTEM_ID) {
|
||||
uint32_t system_id;
|
||||
if (!crypto_session.GetSystemId(&system_id)) {
|
||||
LOGW("CdmEngine::QueryStatus: GetSystemId failed");
|
||||
LOGW("CdmEngine::QueryStatus: QUERY_KEY_SYSTEM_ID unknown failure");
|
||||
return UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
@@ -681,11 +711,12 @@ CdmResponseType CdmEngine::GetProvisioningRequest(
|
||||
DeleteAllUsageReportsUponFactoryReset();
|
||||
|
||||
if (NULL == cert_provisioning_.get()) {
|
||||
cert_provisioning_.reset(new CertificateProvisioning());
|
||||
cert_provisioning_.reset(
|
||||
new CertificateProvisioning(&service_certificate_));
|
||||
}
|
||||
CdmResponseType ret = cert_provisioning_->GetProvisioningRequest(
|
||||
cert_provisioning_requested_security_level_, cert_type, cert_authority,
|
||||
file_system_->origin(), request, default_url);
|
||||
file_system_->origin(), spoid_, request, default_url);
|
||||
if (ret != NO_ERROR) {
|
||||
cert_provisioning_.reset(NULL); // Release resources.
|
||||
}
|
||||
@@ -707,14 +738,14 @@ CdmResponseType CdmEngine::HandleProvisioningResponse(
|
||||
cert_provisioning_.reset(NULL);
|
||||
return EMPTY_PROVISIONING_RESPONSE;
|
||||
}
|
||||
if (NULL == cert) {
|
||||
if (cert == NULL) {
|
||||
LOGE(
|
||||
"CdmEngine::HandleProvisioningResponse: invalid certificate "
|
||||
"destination");
|
||||
cert_provisioning_.reset(NULL);
|
||||
return INVALID_PROVISIONING_PARAMETERS_1;
|
||||
}
|
||||
if (NULL == wrapped_key) {
|
||||
if (wrapped_key == NULL) {
|
||||
LOGE("CdmEngine::HandleProvisioningResponse: invalid wrapped key "
|
||||
"destination");
|
||||
cert_provisioning_.reset(NULL);
|
||||
@@ -768,7 +799,7 @@ CdmResponseType CdmEngine::Unprovision(CdmSecurityLevel security_level) {
|
||||
return UNPROVISION_ERROR_1;
|
||||
}
|
||||
|
||||
if (!file_system_->origin().empty()) {
|
||||
if (!file_system_->IsGlobal()) {
|
||||
if (!handle.RemoveCertificate()) {
|
||||
LOGE("CdmEngine::Unprovision: unable to delete certificate");
|
||||
return UNPROVISION_ERROR_2;
|
||||
@@ -779,22 +810,44 @@ CdmResponseType CdmEngine::Unprovision(CdmSecurityLevel security_level) {
|
||||
LOGE("CdmEngine::Unprovision: unable to delete files");
|
||||
return UNPROVISION_ERROR_3;
|
||||
}
|
||||
|
||||
scoped_ptr<CryptoSession> crypto_session(new CryptoSession());
|
||||
CdmResponseType status = crypto_session->Open(
|
||||
security_level == kSecurityLevelL3 ? kLevel3 : kLevelDefault);
|
||||
if (NO_ERROR != status) {
|
||||
LOGE("CdmEngine::Unprovision: error opening crypto session: %d", status);
|
||||
return UNPROVISION_ERROR_4;
|
||||
}
|
||||
status = crypto_session->DeleteAllUsageReports();
|
||||
if (status != NO_ERROR) {
|
||||
LOGE("CdmEngine::Unprovision: error deleteing usage reports: %d", status);
|
||||
}
|
||||
return status;
|
||||
return DeleteUsageTable(security_level);
|
||||
}
|
||||
}
|
||||
|
||||
CdmResponseType CdmEngine::DeleteUsageTable(CdmSecurityLevel security_level) {
|
||||
scoped_ptr<CryptoSession> crypto_session(new CryptoSession());
|
||||
CdmResponseType status = crypto_session->Open(
|
||||
security_level == kSecurityLevelL3 ? kLevel3 : kLevelDefault);
|
||||
if (NO_ERROR != status) {
|
||||
LOGE("CdmEngine::DeleteUsageTable: error opening crypto session: %d",
|
||||
status);
|
||||
return UNPROVISION_ERROR_4;
|
||||
}
|
||||
status = crypto_session->DeleteAllUsageReports();
|
||||
if (status != NO_ERROR) {
|
||||
LOGE("CdmEngine::DeleteUsageTable: error deleting usage reports: %d",
|
||||
status);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
CdmResponseType CdmEngine::ListStoredLicenses(
|
||||
CdmSecurityLevel security_level, std::vector<std::string>* key_set_ids) {
|
||||
DeviceFiles handle(file_system_);
|
||||
if (!key_set_ids) {
|
||||
LOGE("CdmEngine::QueryStoredLicenses: no response destination");
|
||||
return INVALID_PARAMETERS_ENG_17;
|
||||
}
|
||||
if (!handle.Init(security_level)) {
|
||||
LOGE("CdmEngine::ListStoredLicenses: unable to initialize device files");
|
||||
return STORE_LICENSE_ERROR_3;
|
||||
}
|
||||
if (!handle.ListLicenses(key_set_ids)) {
|
||||
return UNKNOWN_ERROR;
|
||||
}
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
|
||||
const CdmSecureStopId& ssid,
|
||||
CdmUsageInfo* usage_info) {
|
||||
@@ -1234,12 +1287,14 @@ bool CdmEngine::FindSessionForKey(const KeyId& key_id,
|
||||
return false;
|
||||
}
|
||||
|
||||
void CdmEngine::NotifyResolution(const CdmSessionId& session_id, uint32_t width,
|
||||
bool CdmEngine::NotifyResolution(const CdmSessionId& session_id, uint32_t width,
|
||||
uint32_t height) {
|
||||
CdmSessionMap::iterator iter = sessions_.find(session_id);
|
||||
if (iter != sessions_.end()) {
|
||||
iter->second->NotifyResolution(width, height);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CdmEngine::ValidateKeySystem(const CdmKeySystem& key_system) {
|
||||
@@ -1289,6 +1344,8 @@ void CdmEngine::OnTimerEvent() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CloseExpiredReleaseSessions();
|
||||
}
|
||||
|
||||
void CdmEngine::OnKeyReleaseEvent(const CdmKeySetId& key_set_id) {
|
||||
@@ -1318,6 +1375,29 @@ std::string CdmEngine::MapHdcpVersion(
|
||||
return "";
|
||||
}
|
||||
|
||||
void CdmEngine::CloseExpiredReleaseSessions() {
|
||||
int64_t current_time = clock_.GetCurrentTime();
|
||||
|
||||
std::set<CdmSessionId> close_session_set;
|
||||
{
|
||||
AutoLock lock(release_key_sets_lock_);
|
||||
for (CdmReleaseKeySetMap::iterator iter = release_key_sets_.begin();
|
||||
iter != release_key_sets_.end();) {
|
||||
if (iter->second.second < current_time) {
|
||||
close_session_set.insert(iter->second.first);
|
||||
release_key_sets_.erase(iter++);
|
||||
} else {
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (std::set<CdmSessionId>::iterator iter = close_session_set.begin();
|
||||
iter != close_session_set.end(); ++iter) {
|
||||
CloseSession(*iter);
|
||||
}
|
||||
}
|
||||
|
||||
void CdmEngine::DeleteAllUsageReportsUponFactoryReset() {
|
||||
std::string device_base_path_level1 = "";
|
||||
std::string device_base_path_level3 = "";
|
||||
|
||||
Reference in New Issue
Block a user