|
|
|
|
@@ -7,6 +7,7 @@
|
|
|
|
|
#include "initialization_data.h"
|
|
|
|
|
#include "license.h"
|
|
|
|
|
#include "log.h"
|
|
|
|
|
#include "metrics_front_end.h"
|
|
|
|
|
#include "properties.h"
|
|
|
|
|
#include "service_certificate.h"
|
|
|
|
|
#include "wv_cdm_constants.h"
|
|
|
|
|
@@ -20,10 +21,22 @@ namespace wvcdm {
|
|
|
|
|
|
|
|
|
|
Lock WvContentDecryptionModule::session_sharing_id_generation_lock_;
|
|
|
|
|
|
|
|
|
|
WvContentDecryptionModule::WvContentDecryptionModule() {}
|
|
|
|
|
WvContentDecryptionModule::WvContentDecryptionModule() {
|
|
|
|
|
// TODO (b/36497276)
|
|
|
|
|
// replace call to new AmiAdapter() and remove ami_apdater.*
|
|
|
|
|
report_root_ = NULL; // new AmiAdapter();
|
|
|
|
|
front_end_ = new metrics::MetricsFrontEnd(report_root_);
|
|
|
|
|
metrics::MetricsFrontEnd::OverrideInstance(front_end_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WvContentDecryptionModule::~WvContentDecryptionModule() {
|
|
|
|
|
DisablePolicyTimer(true /* Force. */);
|
|
|
|
|
DisablePolicyTimer(true);
|
|
|
|
|
|
|
|
|
|
metrics::MetricsFrontEnd::OverrideInstance(NULL);
|
|
|
|
|
delete front_end_;
|
|
|
|
|
delete report_root_;
|
|
|
|
|
front_end_ = NULL;
|
|
|
|
|
report_root_ = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool WvContentDecryptionModule::IsSupported(const std::string& init_data_type) {
|
|
|
|
|
@@ -53,9 +66,16 @@ CdmResponseType WvContentDecryptionModule::OpenSession(
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CdmEngine* cdm_engine = EnsureCdmForIdentifier(identifier);
|
|
|
|
|
CdmResponseType sts = cdm_engine->OpenSession(key_system, property_set,
|
|
|
|
|
event_listener, session_id);
|
|
|
|
|
cdm_engine->GetMetrics()->cdm_engine_open_session_.Increment(sts);
|
|
|
|
|
CdmResponseType sts;
|
|
|
|
|
M_TIME(
|
|
|
|
|
sts = cdm_engine->OpenSession(
|
|
|
|
|
key_system,
|
|
|
|
|
property_set,
|
|
|
|
|
event_listener,
|
|
|
|
|
session_id),
|
|
|
|
|
cdm_engine->GetMetrics(),
|
|
|
|
|
cdm_engine_open_session_,
|
|
|
|
|
sts);
|
|
|
|
|
if (sts == NO_ERROR) {
|
|
|
|
|
cdm_by_session_id_[*session_id] = cdm_engine;
|
|
|
|
|
}
|
|
|
|
|
@@ -64,18 +84,20 @@ CdmResponseType WvContentDecryptionModule::OpenSession(
|
|
|
|
|
|
|
|
|
|
CdmResponseType WvContentDecryptionModule::CloseSession(
|
|
|
|
|
const CdmSessionId& session_id) {
|
|
|
|
|
LOGV("WvContentDecryptionModule::CloseSession. id: %s", session_id.c_str());
|
|
|
|
|
CdmEngine* cdm_engine = GetCdmForSessionId(session_id);
|
|
|
|
|
// TODO(rfrias): Avoid reusing the error codes from CdmEngine.
|
|
|
|
|
if (!cdm_engine) return SESSION_NOT_FOUND_1;
|
|
|
|
|
CdmResponseType sts = cdm_engine->CloseSession(session_id);
|
|
|
|
|
cdm_engine->GetMetrics()->cdm_engine_close_session_.Increment(sts);
|
|
|
|
|
CdmResponseType sts;
|
|
|
|
|
M_TIME(
|
|
|
|
|
sts = cdm_engine->CloseSession(
|
|
|
|
|
session_id),
|
|
|
|
|
cdm_engine->GetMetrics(),
|
|
|
|
|
cdm_engine_close_session_,
|
|
|
|
|
sts);
|
|
|
|
|
if (sts == NO_ERROR) {
|
|
|
|
|
cdm_by_session_id_.erase(session_id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DisablePolicyTimer(false /* Do not force. */);
|
|
|
|
|
|
|
|
|
|
DisablePolicyTimer(false);
|
|
|
|
|
return sts;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -93,8 +115,14 @@ CdmResponseType WvContentDecryptionModule::GenerateKeyRequest(
|
|
|
|
|
CdmEngine* cdm_engine = EnsureCdmForIdentifier(identifier);
|
|
|
|
|
CdmResponseType sts;
|
|
|
|
|
if (license_type == kLicenseTypeRelease) {
|
|
|
|
|
sts = cdm_engine->OpenKeySetSession(key_set_id, property_set, NULL);
|
|
|
|
|
cdm_engine->GetMetrics()->cdm_engine_open_key_set_session_.Increment(sts);
|
|
|
|
|
M_TIME(
|
|
|
|
|
sts = cdm_engine->OpenKeySetSession(
|
|
|
|
|
key_set_id,
|
|
|
|
|
property_set,
|
|
|
|
|
NULL),
|
|
|
|
|
cdm_engine->GetMetrics(),
|
|
|
|
|
cdm_engine_open_key_set_session_,
|
|
|
|
|
sts);
|
|
|
|
|
if (sts != NO_ERROR) return sts;
|
|
|
|
|
cdm_by_session_id_[key_set_id] = cdm_engine;
|
|
|
|
|
}
|
|
|
|
|
@@ -132,11 +160,6 @@ CdmResponseType WvContentDecryptionModule::AddKey(
|
|
|
|
|
CdmEngine* cdm_engine = session_id.empty() ? GetCdmForSessionId(*key_set_id)
|
|
|
|
|
: GetCdmForSessionId(session_id);
|
|
|
|
|
if (!cdm_engine) return SESSION_NOT_FOUND_3;
|
|
|
|
|
// Save key_set_id, as CDM will return an empty key_set_id on release
|
|
|
|
|
CdmKeySetId release_key_set_id;
|
|
|
|
|
if (session_id.empty() && key_set_id != NULL) {
|
|
|
|
|
release_key_set_id = *key_set_id;
|
|
|
|
|
}
|
|
|
|
|
CdmResponseType sts;
|
|
|
|
|
M_TIME(
|
|
|
|
|
sts = cdm_engine->AddKey(
|
|
|
|
|
@@ -147,8 +170,8 @@ CdmResponseType WvContentDecryptionModule::AddKey(
|
|
|
|
|
cdm_engine_add_key_,
|
|
|
|
|
sts);
|
|
|
|
|
if (sts == KEY_ADDED && session_id.empty()) { // license type release
|
|
|
|
|
cdm_engine->CloseKeySetSession(release_key_set_id);
|
|
|
|
|
cdm_by_session_id_.erase(release_key_set_id);
|
|
|
|
|
cdm_engine->CloseKeySetSession(*key_set_id);
|
|
|
|
|
cdm_by_session_id_.erase(*key_set_id);
|
|
|
|
|
}
|
|
|
|
|
return sts;
|
|
|
|
|
}
|
|
|
|
|
@@ -175,8 +198,13 @@ CdmResponseType WvContentDecryptionModule::RemoveKeys(
|
|
|
|
|
const CdmSessionId& session_id) {
|
|
|
|
|
CdmEngine* cdm_engine = GetCdmForSessionId(session_id);
|
|
|
|
|
if (!cdm_engine) return SESSION_NOT_FOUND_5;
|
|
|
|
|
CdmResponseType sts = cdm_engine->RemoveKeys(session_id);
|
|
|
|
|
cdm_engine->GetMetrics()->cdm_engine_remove_keys_.Increment(sts);
|
|
|
|
|
CdmResponseType sts;
|
|
|
|
|
M_TIME(
|
|
|
|
|
sts = cdm_engine->RemoveKeys(
|
|
|
|
|
session_id),
|
|
|
|
|
cdm_engine->GetMetrics(),
|
|
|
|
|
cdm_engine_remove_keys_,
|
|
|
|
|
sts);
|
|
|
|
|
return sts;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -258,15 +286,20 @@ CdmResponseType WvContentDecryptionModule::HandleProvisioningResponse(
|
|
|
|
|
CdmResponseType WvContentDecryptionModule::Unprovision(
|
|
|
|
|
CdmSecurityLevel level, const CdmIdentifier& identifier) {
|
|
|
|
|
CdmEngine* cdm_engine = EnsureCdmForIdentifier(identifier);
|
|
|
|
|
CdmResponseType sts = cdm_engine->Unprovision(level);
|
|
|
|
|
cdm_engine->GetMetrics()->cdm_engine_unprovision_.Increment(sts, level);
|
|
|
|
|
CdmResponseType sts;
|
|
|
|
|
M_TIME(
|
|
|
|
|
sts = cdm_engine->Unprovision(
|
|
|
|
|
level),
|
|
|
|
|
cdm_engine->GetMetrics(),
|
|
|
|
|
cdm_engine_unprovision_,
|
|
|
|
|
sts,
|
|
|
|
|
level);
|
|
|
|
|
return sts;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CdmResponseType WvContentDecryptionModule::GetUsageInfo(
|
|
|
|
|
const std::string& app_id, const CdmIdentifier& identifier,
|
|
|
|
|
CdmUsageInfo* usage_info) {
|
|
|
|
|
CdmEngine* cdm_engine = EnsureCdmForIdentifier(identifier);
|
|
|
|
|
const std::string& app_id, CdmUsageInfo* usage_info) {
|
|
|
|
|
CdmEngine* cdm_engine = EnsureCdmForIdentifier(kDefaultCdmIdentifier);
|
|
|
|
|
CdmResponseType sts;
|
|
|
|
|
M_TIME(
|
|
|
|
|
sts = cdm_engine->GetUsageInfo(
|
|
|
|
|
@@ -281,9 +314,8 @@ CdmResponseType WvContentDecryptionModule::GetUsageInfo(
|
|
|
|
|
CdmResponseType WvContentDecryptionModule::GetUsageInfo(
|
|
|
|
|
const std::string& app_id,
|
|
|
|
|
const CdmSecureStopId& ssid,
|
|
|
|
|
const CdmIdentifier& identifier,
|
|
|
|
|
CdmUsageInfo* usage_info) {
|
|
|
|
|
CdmEngine* cdm_engine = EnsureCdmForIdentifier(identifier);
|
|
|
|
|
CdmEngine* cdm_engine = EnsureCdmForIdentifier(kDefaultCdmIdentifier);
|
|
|
|
|
CdmResponseType sts;
|
|
|
|
|
M_TIME(
|
|
|
|
|
sts = cdm_engine->GetUsageInfo(
|
|
|
|
|
@@ -297,19 +329,28 @@ CdmResponseType WvContentDecryptionModule::GetUsageInfo(
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CdmResponseType WvContentDecryptionModule::ReleaseAllUsageInfo(
|
|
|
|
|
const std::string& app_id, const CdmIdentifier& identifier) {
|
|
|
|
|
CdmEngine* cdm_engine = EnsureCdmForIdentifier(identifier);
|
|
|
|
|
CdmResponseType sts = cdm_engine->ReleaseAllUsageInfo(app_id);
|
|
|
|
|
cdm_engine->GetMetrics()->cdm_engine_release_all_usage_info_.Increment(sts);
|
|
|
|
|
const std::string& app_id) {
|
|
|
|
|
CdmEngine* cdm_engine = EnsureCdmForIdentifier(kDefaultCdmIdentifier);
|
|
|
|
|
CdmResponseType sts;
|
|
|
|
|
M_TIME(
|
|
|
|
|
sts = cdm_engine->ReleaseAllUsageInfo(
|
|
|
|
|
app_id),
|
|
|
|
|
cdm_engine->GetMetrics(),
|
|
|
|
|
cdm_engine_release_all_usage_info_,
|
|
|
|
|
sts);
|
|
|
|
|
return sts;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CdmResponseType WvContentDecryptionModule::ReleaseUsageInfo(
|
|
|
|
|
const CdmUsageInfoReleaseMessage& message,
|
|
|
|
|
const CdmIdentifier& identifier) {
|
|
|
|
|
CdmEngine* cdm_engine = EnsureCdmForIdentifier(identifier);
|
|
|
|
|
CdmResponseType sts = cdm_engine->ReleaseUsageInfo(message);
|
|
|
|
|
cdm_engine->GetMetrics()->cdm_engine_release_usage_info_.Increment(sts);
|
|
|
|
|
const CdmUsageInfoReleaseMessage& message) {
|
|
|
|
|
CdmEngine* cdm_engine = EnsureCdmForIdentifier(kDefaultCdmIdentifier);
|
|
|
|
|
CdmResponseType sts;
|
|
|
|
|
M_TIME(
|
|
|
|
|
sts = cdm_engine->ReleaseUsageInfo(
|
|
|
|
|
message),
|
|
|
|
|
cdm_engine->GetMetrics(),
|
|
|
|
|
cdm_engine_release_usage_info_,
|
|
|
|
|
sts);
|
|
|
|
|
return sts;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -325,11 +366,15 @@ CdmResponseType WvContentDecryptionModule::Decrypt(
|
|
|
|
|
CdmSessionId local_session_id = session_id;
|
|
|
|
|
if (validate_key_id &&
|
|
|
|
|
Properties::GetSessionSharingId(session_id) != 0) {
|
|
|
|
|
bool status = cdm_engine->FindSessionForKey(
|
|
|
|
|
*parameters.key_id, &local_session_id);
|
|
|
|
|
cdm_engine->GetMetrics()->cdm_engine_find_session_for_key_
|
|
|
|
|
.Increment(status);
|
|
|
|
|
if (!status && parameters.is_encrypted) return KEY_NOT_FOUND_IN_SESSION;
|
|
|
|
|
bool status;
|
|
|
|
|
M_TIME(
|
|
|
|
|
status = cdm_engine->FindSessionForKey(
|
|
|
|
|
*parameters.key_id,
|
|
|
|
|
&local_session_id),
|
|
|
|
|
cdm_engine->GetMetrics(),
|
|
|
|
|
cdm_engine_find_session_for_key_,
|
|
|
|
|
status);
|
|
|
|
|
if (!status) return KEY_NOT_FOUND_IN_SESSION;
|
|
|
|
|
}
|
|
|
|
|
CdmResponseType sts;
|
|
|
|
|
M_TIME(
|
|
|
|
|
@@ -338,8 +383,7 @@ CdmResponseType WvContentDecryptionModule::Decrypt(
|
|
|
|
|
parameters),
|
|
|
|
|
cdm_engine->GetMetrics(),
|
|
|
|
|
cdm_engine_decrypt_,
|
|
|
|
|
sts,
|
|
|
|
|
metrics::Pow2Bucket(parameters.encrypt_length));
|
|
|
|
|
sts);
|
|
|
|
|
return sts;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -356,15 +400,7 @@ bool WvContentDecryptionModule::IsValidServiceCertificate(
|
|
|
|
|
ServiceCertificate cert;
|
|
|
|
|
CdmResponseType status = cert.Init(certificate);
|
|
|
|
|
if (status != NO_ERROR) return false;
|
|
|
|
|
return cert.HasCertificate();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void WvContentDecryptionModule::GetSerializedMetrics(
|
|
|
|
|
std::string* serialized_metrics) {
|
|
|
|
|
AutoLock auto_lock(cdms_lock_);
|
|
|
|
|
CloseCdmsWithoutSessions();
|
|
|
|
|
metrics_.SerializeToString(serialized_metrics);
|
|
|
|
|
metrics_.Clear();
|
|
|
|
|
return cert.HasCertificate();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WvContentDecryptionModule::CdmInfo::CdmInfo()
|
|
|
|
|
@@ -382,14 +418,9 @@ CdmEngine* WvContentDecryptionModule::EnsureCdmForIdentifier(
|
|
|
|
|
cdms_[identifier].file_system.SetOrigin(identifier.origin);
|
|
|
|
|
cdms_[identifier].file_system.SetIdentifier(
|
|
|
|
|
identifier.spoid + identifier.origin);
|
|
|
|
|
|
|
|
|
|
// Set the app package name for use by metrics.
|
|
|
|
|
cdms_[identifier].cdm_engine->GetMetrics()
|
|
|
|
|
->SetAppPackageName(identifier.app_package_name);
|
|
|
|
|
}
|
|
|
|
|
CdmEngine* cdm_engine = cdms_[identifier].cdm_engine.get();
|
|
|
|
|
|
|
|
|
|
return cdm_engine;
|
|
|
|
|
return cdms_[identifier].cdm_engine.get();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CdmEngine* WvContentDecryptionModule::GetCdmForSessionId(
|
|
|
|
|
@@ -400,34 +431,6 @@ CdmEngine* WvContentDecryptionModule::GetCdmForSessionId(
|
|
|
|
|
return it->second;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// This method requires that the caller first acquire cdms_lock_.
|
|
|
|
|
void WvContentDecryptionModule::CloseCdmsWithoutSessions() {
|
|
|
|
|
for (auto it = cdms_.begin(); it != cdms_.end();) {
|
|
|
|
|
if (it->second.cdm_engine->SessionSize() != 0) {
|
|
|
|
|
++it;
|
|
|
|
|
} else {
|
|
|
|
|
// Retrieve the metrics from the engine and any completed
|
|
|
|
|
// sessions. Clear the metrics from any completed sessions.
|
|
|
|
|
metrics::EngineMetrics* engine_metrics =
|
|
|
|
|
it->second.cdm_engine->GetMetrics();
|
|
|
|
|
// engine_metrics should never be null.
|
|
|
|
|
if (engine_metrics != NULL) {
|
|
|
|
|
engine_metrics->Serialize(
|
|
|
|
|
metrics_.add_metric_sub_group(),
|
|
|
|
|
false, // Report complete AND incomplete sessions.
|
|
|
|
|
true); // Clear session metrics after reporting.
|
|
|
|
|
} else {
|
|
|
|
|
// Engine metrics should never be null.
|
|
|
|
|
LOGI("WvContentDecryptionModule::CloseCdmsWithoutSessions."
|
|
|
|
|
"engine_metrics was unexpectedly NULL.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// The CDM is no longer used for this identifier, delete it.
|
|
|
|
|
it = cdms_.erase(it);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void WvContentDecryptionModule::EnablePolicyTimer() {
|
|
|
|
|
AutoLock auto_lock(policy_timer_lock_);
|
|
|
|
|
if (!policy_timer_.IsRunning())
|
|
|
|
|
@@ -435,19 +438,23 @@ void WvContentDecryptionModule::EnablePolicyTimer() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void WvContentDecryptionModule::DisablePolicyTimer(bool force) {
|
|
|
|
|
bool cdms_is_empty = false;
|
|
|
|
|
bool has_sessions = false;
|
|
|
|
|
{
|
|
|
|
|
AutoLock auto_lock(cdms_lock_);
|
|
|
|
|
CloseCdmsWithoutSessions();
|
|
|
|
|
cdms_is_empty = cdms_.empty();
|
|
|
|
|
for (auto it = cdms_.begin(); it != cdms_.end();) {
|
|
|
|
|
if (it->second.cdm_engine->SessionSize() != 0) {
|
|
|
|
|
has_sessions = true;
|
|
|
|
|
++it;
|
|
|
|
|
} else {
|
|
|
|
|
// The CDM is no longer used for this identifier, delete it.
|
|
|
|
|
it = cdms_.erase(it);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AutoLock auto_lock(policy_timer_lock_);
|
|
|
|
|
if(force || cdms_is_empty) {
|
|
|
|
|
if (policy_timer_.IsRunning()) {
|
|
|
|
|
policy_timer_.Stop();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if ((!has_sessions || force) && policy_timer_.IsRunning())
|
|
|
|
|
policy_timer_.Stop();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void WvContentDecryptionModule::OnTimerEvent() {
|
|
|
|
|
|