Source release v3.2.0

This commit is contained in:
Gene Morgan
2017-02-01 16:36:41 -08:00
parent 643b91b616
commit 2fde891c01
370 changed files with 40622 additions and 276133 deletions

View File

@@ -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 = "";