Source release 14.2.0

This commit is contained in:
John W. Bruce
2018-10-12 19:55:47 -07:00
parent c32e8d0490
commit f51edaba5a
632 changed files with 196557 additions and 66444 deletions

View File

@@ -85,7 +85,10 @@ CdmEngine::CdmEngine(FileSystem* file_system, const std::string& spoid)
}
}
CdmEngine::~CdmEngine() {}
CdmEngine::~CdmEngine() {
AutoLock lock(session_map_lock_);
session_map_.Terminate();
}
CdmResponseType CdmEngine::OpenSession(
const CdmKeySystem& key_system, CdmClientPropertySet* property_set,
@@ -143,6 +146,7 @@ CdmResponseType CdmEngine::OpenSession(
CdmSessionId id = new_session->session_id();
LOGI("CdmEngine::OpenSession: %s", id.c_str());
AutoLock lock(session_map_lock_);
session_map_.Add(id, new_session.release());
if (session_id) *session_id = id;
return NO_ERROR;
@@ -184,6 +188,7 @@ CdmResponseType CdmEngine::OpenKeySetSession(
CdmResponseType CdmEngine::CloseSession(const CdmSessionId& session_id) {
LOGI("CdmEngine::CloseSession: %s", session_id.c_str());
AutoLock lock(session_map_lock_);
if (!session_map_.CloseSession(session_id)) {
LOGE("CdmEngine::CloseSession: session not found = %s", session_id.c_str());
return SESSION_NOT_FOUND_1;
@@ -217,6 +222,7 @@ CdmResponseType CdmEngine::CloseKeySetSession(const CdmKeySetId& key_set_id) {
}
bool CdmEngine::IsOpenSession(const CdmSessionId& session_id) {
AutoLock lock(session_map_lock_);
return session_map_.Exists(session_id);
}
@@ -486,10 +492,11 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level,
const std::string& query_token,
std::string* query_response) {
LOGI("CdmEngine::QueryStatus");
CryptoSession crypto_session(metrics_.GetCryptoMetrics());
scoped_ptr<CryptoSession> crypto_session(
CryptoSession::MakeCryptoSession(metrics_.GetCryptoMetrics()));
CdmResponseType status;
M_TIME(
status = crypto_session.Open(
status = crypto_session->Open(
security_level),
metrics_.GetCryptoMetrics(),
crypto_session_open_,
@@ -505,7 +512,7 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level,
if (query_token == QUERY_KEY_SECURITY_LEVEL) {
CdmSecurityLevel found_security_level =
crypto_session.GetSecurityLevel();
crypto_session->GetSecurityLevel();
switch (found_security_level) {
case kSecurityLevelL1:
*query_response = QUERY_VALUE_SECURITY_LEVEL_L1;
@@ -527,7 +534,7 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level,
}
} else if (query_token == QUERY_KEY_DEVICE_ID) {
std::string deviceId;
bool got_id = crypto_session.GetExternalDeviceUniqueId(&deviceId);
bool got_id = crypto_session->GetExternalDeviceUniqueId(&deviceId);
metrics_.GetCryptoMetrics()->crypto_session_get_device_unique_id_
.Increment(got_id);
if (!got_id) {
@@ -538,7 +545,7 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level,
*query_response = deviceId;
} else if (query_token == QUERY_KEY_SYSTEM_ID) {
uint32_t system_id;
bool got_id = crypto_session.GetSystemId(&system_id);
bool got_id = crypto_session->GetSystemId(&system_id);
if (!got_id) {
LOGW("CdmEngine::QueryStatus: QUERY_KEY_SYSTEM_ID unknown failure");
return UNKNOWN_ERROR;
@@ -549,7 +556,7 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level,
*query_response = system_id_stream.str();
} else if (query_token == QUERY_KEY_PROVISIONING_ID) {
std::string provisioning_id;
if (!crypto_session.GetProvisioningId(&provisioning_id)) {
if (!crypto_session->GetProvisioningId(&provisioning_id)) {
LOGW("CdmEngine::QueryStatus: GetProvisioningId failed");
return UNKNOWN_ERROR;
}
@@ -559,7 +566,7 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level,
query_token == QUERY_KEY_MAX_HDCP_LEVEL) {
CryptoSession::HdcpCapability current_hdcp;
CryptoSession::HdcpCapability max_hdcp;
if (!crypto_session.GetHdcpCapabilities(&current_hdcp, &max_hdcp)) {
if (!crypto_session->GetHdcpCapabilities(&current_hdcp, &max_hdcp)) {
LOGW("CdmEngine::QueryStatus: GetHdcpCapabilities failed");
return UNKNOWN_ERROR;
}
@@ -568,7 +575,7 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level,
current_hdcp : max_hdcp);
} else if (query_token == QUERY_KEY_USAGE_SUPPORT) {
bool supports_usage_reporting;
bool got_info = crypto_session.UsageInformationSupport(
bool got_info = crypto_session->UsageInformationSupport(
&supports_usage_reporting);
if (!got_info) {
@@ -584,7 +591,7 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level,
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)) {
if (!crypto_session->GetNumberOfOpenSessions(&number_of_open_sessions)) {
LOGW("CdmEngine::QueryStatus: GetNumberOfOpenSessions failed");
return UNKNOWN_ERROR;
}
@@ -594,7 +601,7 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level,
*query_response = open_sessions_stream.str();
} else if (query_token == QUERY_KEY_MAX_NUMBER_OF_SESSIONS) {
size_t maximum_number_of_sessions = 0;
if (!crypto_session.GetMaxNumberOfSessions(&maximum_number_of_sessions)) {
if (!crypto_session->GetMaxNumberOfSessions(&maximum_number_of_sessions)) {
LOGW("CdmEngine::QueryStatus: GetMaxNumberOfOpenSessions failed");
return UNKNOWN_ERROR;
}
@@ -604,7 +611,7 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level,
*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)) {
if (!crypto_session->GetApiVersion(&api_version)) {
LOGW("CdmEngine::QueryStatus: GetApiVersion failed");
return UNKNOWN_ERROR;
}
@@ -614,7 +621,7 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level,
*query_response = api_version_stream.str();
} else if (query_token == QUERY_KEY_CURRENT_SRM_VERSION) {
uint16_t current_srm_version;
if (!crypto_session.GetSrmVersion(&current_srm_version)) {
if (!crypto_session->GetSrmVersion(&current_srm_version)) {
LOGW("CdmEngine::QueryStatus: GetCurrentSRMVersion failed");
return UNKNOWN_ERROR;
}
@@ -623,7 +630,7 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level,
current_srm_version_stream << current_srm_version;
*query_response = current_srm_version_stream.str();
} else if (query_token == QUERY_KEY_SRM_UPDATE_SUPPORT) {
bool is_srm_update_supported = crypto_session.IsSrmUpdateSupported();
bool is_srm_update_supported = crypto_session->IsSrmUpdateSupported();
*query_response =
is_srm_update_supported ? QUERY_VALUE_TRUE : QUERY_VALUE_FALSE;
} else if (query_token == QUERY_KEY_WVCDM_VERSION) {
@@ -827,10 +834,11 @@ CdmResponseType CdmEngine::HandleProvisioningResponse(
if (NULL == cert_provisioning_.get()) {
// Certificate provisioning object has been released. Check if a concurrent
// provisioning attempt has succeeded before declaring failure.
CryptoSession crypto_session(metrics_.GetCryptoMetrics());
scoped_ptr<CryptoSession> crypto_session(
CryptoSession::MakeCryptoSession(metrics_.GetCryptoMetrics()));
CdmResponseType status;
M_TIME(
status = crypto_session.Open(
status = crypto_session->Open(
cert_provisioning_requested_security_level_),
metrics_.GetCryptoMetrics(),
crypto_session_open_,
@@ -842,7 +850,7 @@ CdmResponseType CdmEngine::HandleProvisioningResponse(
"missing and crypto session open failed.");
return EMPTY_PROVISIONING_CERTIFICATE_2;
}
CdmSecurityLevel security_level = crypto_session.GetSecurityLevel();
CdmSecurityLevel security_level = crypto_session->GetSecurityLevel();
if (!IsProvisioned(security_level)) {
LOGE(
"CdmEngine::HandleProvisioningResponse: provisioning object "
@@ -882,9 +890,10 @@ bool CdmEngine::IsProvisioned(CdmSecurityLevel security_level) {
CdmResponseType CdmEngine::Unprovision(CdmSecurityLevel security_level) {
// Devices with baked-in DRM certs cannot be reprovisioned and therefore must
// not be unprovisioned.
CryptoSession crypto_session(metrics_.GetCryptoMetrics());
scoped_ptr<CryptoSession> crypto_session(
CryptoSession::MakeCryptoSession(metrics_.GetCryptoMetrics()));
CdmClientTokenType token_type = kClientTokenUninitialized;
CdmResponseType res = crypto_session.GetProvisioningMethod(
CdmResponseType res = crypto_session->GetProvisioningMethod(
security_level == kSecurityLevelL3 ? kLevel3 : kLevelDefault,
&token_type);
if (res != NO_ERROR) {
@@ -915,10 +924,11 @@ CdmResponseType CdmEngine::Unprovision(CdmSecurityLevel security_level) {
}
CdmResponseType CdmEngine::DeleteUsageTable(CdmSecurityLevel security_level) {
CryptoSession crypto_session(metrics_.GetCryptoMetrics());
scoped_ptr<CryptoSession> crypto_session(
CryptoSession::MakeCryptoSession(metrics_.GetCryptoMetrics()));
CdmResponseType status;
M_TIME(
status = crypto_session.Open(
status = crypto_session->Open(
security_level == kSecurityLevelL3 ?
kLevel3 :
kLevelDefault),
@@ -931,7 +941,7 @@ CdmResponseType CdmEngine::DeleteUsageTable(CdmSecurityLevel security_level) {
status);
return UNPROVISION_ERROR_4;
}
status = crypto_session.DeleteAllUsageReports();
status = crypto_session->DeleteAllUsageReports();
metrics_.GetCryptoMetrics()->crypto_session_delete_all_usage_reports_
.Increment(status);
if (status != NO_ERROR) {
@@ -998,7 +1008,7 @@ CdmResponseType CdmEngine::DeleteUsageRecord(const std::string& app_id,
// Got provider token. Remove from OEMCrypto.
scoped_ptr<CryptoSession> crypto_session(
new CryptoSession(metrics_.GetCryptoMetrics()));
CryptoSession::MakeCryptoSession(metrics_.GetCryptoMetrics()));
CdmResponseType status = crypto_session->Open(
security_level == kSecurityLevelL3 ? kLevel3 : kLevelDefault);
if (status == NO_ERROR) {
@@ -1207,7 +1217,7 @@ CdmResponseType CdmEngine::RemoveAllUsageInfo(
// Got at least one provider token. Remove from OEMCrypto.
scoped_ptr<CryptoSession> crypto_session(
new CryptoSession(metrics_.GetCryptoMetrics()));
CryptoSession::MakeCryptoSession(metrics_.GetCryptoMetrics()));
CdmResponseType status = crypto_session->Open(
security_level == kSecurityLevelL3 ? kLevel3 : kLevelDefault);
if (status == NO_ERROR) {
@@ -1361,7 +1371,7 @@ CdmResponseType CdmEngine::RemoveUsageInfo(
DeviceFiles::GetUsageInfoFileName(app_id),
provider_session_token);
scoped_ptr<CryptoSession> crypto_session(
new CryptoSession(metrics_.GetCryptoMetrics()));
CryptoSession::MakeCryptoSession(metrics_.GetCryptoMetrics()));
status = crypto_session->Open(
static_cast<CdmSecurityLevel>(j) == kSecurityLevelL3
? kLevel3 : kLevelDefault);
@@ -1499,6 +1509,7 @@ CdmResponseType CdmEngine::Decrypt(const CdmSessionId& session_id,
// else we must be level 1 direct and we don't need to return a buffer.
}
AutoLock lock(session_map_lock_);
shared_ptr<CdmSession> session;
if (session_id.empty()) {
CdmSessionList sessions;
@@ -1619,6 +1630,7 @@ bool CdmEngine::FindSessionForKey(const KeyId& key_id,
uint32_t session_sharing_id = Properties::GetSessionSharingId(*session_id);
AutoLock lock(session_map_lock_);
CdmSessionList sessions;
session_map_.GetSessionList(sessions);
@@ -1664,9 +1676,6 @@ void CdmEngine::OnTimerEvent() {
Clock clock;
uint64_t current_time = clock.GetCurrentTime();
CdmSessionList sessions;
session_map_.GetSessionList(sessions);
bool usage_update_period_expired = false;
if (current_time - last_usage_information_update_time_ >
kUpdateUsageInformationPeriod) {
@@ -1677,47 +1686,54 @@ void CdmEngine::OnTimerEvent() {
bool is_initial_usage_update = false;
bool is_usage_update_needed = false;
while (!sessions.empty()) {
is_initial_usage_update =
is_initial_usage_update || sessions.front()->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();
}
if (is_usage_update_needed &&
(usage_update_period_expired || is_initial_usage_update)) {
bool has_usage_been_updated = false;
// Session list may have changed. Rebuild.
{
AutoLock lock(session_map_lock_);
CdmSessionList sessions;
session_map_.GetSessionList(sessions);
for (CdmSessionList::iterator iter = sessions.begin();
iter != sessions.end(); ++iter) {
(*iter)->reset_usage_flags();
switch ((*iter)->get_usage_support_type()) {
case kUsageEntrySupport:
if ((*iter)->has_provider_session_token()) {
(*iter)->UpdateUsageEntryInformation();
}
break;
case kUsageTableSupport:
if (!has_usage_been_updated) {
// usage is updated for all sessions so this needs to be
// called only once per update usage information period
CdmResponseType status = (*iter)->UpdateUsageTableInformation();
if (NO_ERROR != status) {
LOGW("Update usage information failed: %d", status);
} else {
has_usage_been_updated = true;
while (!sessions.empty()) {
is_initial_usage_update =
is_initial_usage_update ||
sessions.front()->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();
}
if (is_usage_update_needed &&
(usage_update_period_expired || is_initial_usage_update)) {
bool has_usage_been_updated = false;
// Session list may have changed. Rebuild.
session_map_.GetSessionList(sessions);
for (CdmSessionList::iterator iter = sessions.begin();
iter != sessions.end(); ++iter) {
(*iter)->reset_usage_flags();
switch ((*iter)->get_usage_support_type()) {
case kUsageEntrySupport:
if ((*iter)->has_provider_session_token()) {
(*iter)->UpdateUsageEntryInformation();
}
}
break;
default:
// Ignore
break;
break;
case kUsageTableSupport:
if (!has_usage_been_updated) {
// usage is updated for all sessions so this needs to be
// called only once per update usage information period
CdmResponseType status = (*iter)->UpdateUsageTableInformation();
if (NO_ERROR != status) {
LOGW("Update usage information failed: %d", status);
} else {
has_usage_been_updated = true;
}
}
break;
default:
// Ignore
break;
}
}
}
}
@@ -1793,7 +1809,7 @@ void CdmEngine::DeleteAllUsageReportsUponFactoryReset() {
if (!file_system_->Exists(device_base_path_level1) &&
!file_system_->Exists(device_base_path_level3)) {
scoped_ptr<CryptoSession> crypto_session(
new CryptoSession(metrics_.GetCryptoMetrics()));
CryptoSession::MakeCryptoSession(metrics_.GetCryptoMetrics()));
CdmResponseType status;
M_TIME(
status = crypto_session->Open(