These are a set of CLs merged from the wv cdm repo to the android repo. * Android build fixes Author: Rahul Frias <rfrias@google.com> [ Merge of http://go/wvgerrit/36322 ] * Address android compilation errors and warnings Author: Rahul Frias <rfrias@google.com> [ Merge of http://go/wvgerrit/36300 ] * Gyp cleanup and OpenSSL v10.1 support. Author: Gene Morgan <gmorgan@google.com> [ Merge of http://go/wvgerrit/36001 ] OpenSSL 10.1 has a small number of incompatible changes. A desktop system upgrade exposed some issue in the build scripts. Specifically, the linux build was using both third_party/protobufs (2.6.1) and the version installed on the system (3.0 in this case). The linux cdm.gyp depended on cdm/cdm.gyp which caused that plus some additional issues. These changes are necessary to support g++ version: g++ (Debian 6.3.0-18) 6.3.0 20170516 Also did some cosmetic rework on run_current_tests to make it easier to figure out what is going on when something fails. Also tweaked some of the compiler settings for g++ support (revisit this later). * Refactored Service Certificate encryption to allow encryption of arbitrary data. Author: Thomas Inskip <tinskip@google.com> [ Merge of http://go/wvgerrit/36141 ] * Send cdm test requests to UAT. Author: Jeff Fore <jfore@google.com> [ Merge of http://go/wvgerrit/36221 ] This change resolves the all of the CdmDecryptTest/CdmTestWithDecryptParam.DecryptToClearBuffer tests. The license servers will return different keys and keyids. Sending the request to staging returned key ids and keys that were not matching what was expected in the unit tests. * Fix for building L3 OEMCrypto with clang and libc++ Author: yucliu <yucliu@google.com> [ Merge of http://go/wvgerrit/35740 ] 1. Include <time.h> for time(time_t*). 2. Create endian check union on stack. Clang may create const union somewhere else, which may cause crash. * Remove error result when a sublicense session does not exist. This is not considered an error. Author: Jeff Fore <jfore@google.com> [ Merge of http://go/wvgerrit/36080 ] * Set default mock handler for GetSupportedCertificateTypes for all unit tests and removed the use of StrictMock from MockCryptoSession. Author: Jeff Fore <jfore@google.com> [ Merge of http://go/wvgerrit/35922 ] The handler for this was only set for one test and resulted in a number of failures. * Set default handler for GetHdcpCapabilities. For now the default action is to call the real GetHdcpCapabilities of crypto_session. Author: Jeff Fore <jfore@google.com> [ Merge of http://go/wvgerrit/36140 ] I also changed the mock to a NiceMock to silence responses to unexpected calls to GetHdcpCapabilities. The default handler can be overridden as needed in the individual tests. This resolves the policy engine test failures. * Finalize merge of cdm_partner_3.4 to master. Author: Gene Morgan <gmorgan@google.com> [ Merge of http://go/wvgerrit/35360 ] This is the final set of updates to merge all v3.4.1 changes into master. * Embedded license: Sublicense rotation. Author: Jeff Fore <jfore@google.com> [ Merge of http://go/wvgerrit/35360 ] Handle sublicense rotation event. * Embedded license: Initial license phase. Author: Jeff Fore <jfore@google.com> [ Merge of http://go/wvgerrit/34280 ] Initial license phase - key loading subsession. * Embedded license: generate session data. Author: Jeff Fore <jfore@google.com> [ Merge of http://go/wvgerrit/33722 ] Generate session data and add it to the license request for any embedded license material. * Resolve missing symbol when building cd-cdm Author: Jeff Fore <jfore@google.com> [ Merge of http://go/wvgerrit/35840 ] * C++11: Replace OVERRIDE def with override keyword Author: Gene Morgan <gmorgan@google.com> [ Merge of http://go/wvgerrit/35400 ] BUG: 71650075 Test: Not currently passing. Will be addressed in a subsequent commit in the chain. Change-Id: I37d0cb17f255ac6389030047d616ad69f895748c
519 lines
16 KiB
C++
519 lines
16 KiB
C++
// Copyright 2013 Google Inc. All Rights Reserved.
|
|
|
|
#include "wv_content_decryption_module.h"
|
|
|
|
#include "cdm_client_property_set.h"
|
|
#include "cdm_engine.h"
|
|
#include "initialization_data.h"
|
|
#include "license.h"
|
|
#include "log.h"
|
|
#include "metrics.pb.h"
|
|
#include "properties.h"
|
|
#include "service_certificate.h"
|
|
#include "wv_cdm_constants.h"
|
|
#include "wv_cdm_event_listener.h"
|
|
|
|
namespace {
|
|
const int kCdmPolicyTimerDurationSeconds = 1;
|
|
}
|
|
|
|
namespace wvcdm {
|
|
|
|
Lock WvContentDecryptionModule::session_sharing_id_generation_lock_;
|
|
|
|
WvContentDecryptionModule::WvContentDecryptionModule() {}
|
|
|
|
WvContentDecryptionModule::~WvContentDecryptionModule() {
|
|
ForceDisablePolicyTimer();
|
|
}
|
|
|
|
bool WvContentDecryptionModule::IsSupported(const std::string& init_data_type) {
|
|
return InitializationData(init_data_type).is_supported();
|
|
}
|
|
|
|
bool WvContentDecryptionModule::IsCenc(const std::string& init_data_type) {
|
|
return InitializationData(init_data_type).is_cenc();
|
|
}
|
|
|
|
bool WvContentDecryptionModule::IsWebm(const std::string& init_data_type) {
|
|
return InitializationData(init_data_type).is_webm();
|
|
}
|
|
|
|
bool WvContentDecryptionModule::IsHls(const std::string& init_data_type) {
|
|
return InitializationData(init_data_type).is_hls();
|
|
}
|
|
|
|
CdmResponseType WvContentDecryptionModule::OpenSession(
|
|
const CdmKeySystem& key_system, CdmClientPropertySet* property_set,
|
|
const CdmIdentifier& identifier, WvCdmEventListener* event_listener,
|
|
CdmSessionId* session_id) {
|
|
if (property_set && property_set->is_session_sharing_enabled()) {
|
|
AutoLock auto_lock(session_sharing_id_generation_lock_);
|
|
if (property_set->session_sharing_id() == 0)
|
|
property_set->set_session_sharing_id(GenerateSessionSharingId());
|
|
}
|
|
|
|
CdmEngine* cdm_engine = EnsureCdmForIdentifier(identifier);
|
|
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;
|
|
}
|
|
return sts;
|
|
}
|
|
|
|
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;
|
|
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();
|
|
|
|
return sts;
|
|
}
|
|
|
|
bool WvContentDecryptionModule::IsOpenSession(const CdmSessionId& session_id) {
|
|
CdmEngine* cdm_engine = GetCdmForSessionId(session_id);
|
|
return cdm_engine && cdm_engine->IsOpenSession(session_id);
|
|
}
|
|
|
|
CdmResponseType WvContentDecryptionModule::GenerateKeyRequest(
|
|
const CdmSessionId& session_id, const CdmKeySetId& key_set_id,
|
|
const std::string& init_data_type, const CdmInitData& init_data,
|
|
const CdmLicenseType license_type, CdmAppParameterMap& app_parameters,
|
|
CdmClientPropertySet* property_set, const CdmIdentifier& identifier,
|
|
CdmKeyRequest* key_request) {
|
|
CdmEngine* cdm_engine = EnsureCdmForIdentifier(identifier);
|
|
CdmResponseType sts;
|
|
if (license_type == kLicenseTypeRelease) {
|
|
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;
|
|
}
|
|
InitializationData initialization_data(init_data_type, init_data);
|
|
M_TIME(
|
|
sts = cdm_engine->GenerateKeyRequest(
|
|
session_id,
|
|
key_set_id,
|
|
initialization_data,
|
|
license_type,
|
|
app_parameters,
|
|
key_request),
|
|
cdm_engine->GetMetrics(),
|
|
cdm_engine_generate_key_request_,
|
|
sts);
|
|
switch(license_type) {
|
|
case kLicenseTypeRelease:
|
|
if (sts != KEY_MESSAGE) {
|
|
cdm_engine->CloseKeySetSession(key_set_id);
|
|
cdm_by_session_id_.erase(key_set_id);
|
|
}
|
|
break;
|
|
default:
|
|
if (sts == KEY_MESSAGE)
|
|
EnablePolicyTimer();
|
|
break;
|
|
}
|
|
return sts;
|
|
}
|
|
|
|
CdmResponseType WvContentDecryptionModule::AddKey(
|
|
const CdmSessionId& session_id,
|
|
const CdmKeyResponse& key_data,
|
|
CdmKeySetId* key_set_id) {
|
|
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(
|
|
session_id,
|
|
key_data,
|
|
key_set_id),
|
|
cdm_engine->GetMetrics(),
|
|
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);
|
|
}
|
|
return sts;
|
|
}
|
|
|
|
CdmResponseType WvContentDecryptionModule::RestoreKey(
|
|
const CdmSessionId& session_id,
|
|
const CdmKeySetId& key_set_id) {
|
|
CdmEngine* cdm_engine = GetCdmForSessionId(session_id);
|
|
if (!cdm_engine) return SESSION_NOT_FOUND_4;
|
|
CdmResponseType sts;
|
|
M_TIME(
|
|
sts = cdm_engine->RestoreKey(
|
|
session_id,
|
|
key_set_id),
|
|
cdm_engine->GetMetrics(),
|
|
cdm_engine_restore_key_,
|
|
sts);
|
|
if (sts == KEY_ADDED)
|
|
EnablePolicyTimer();
|
|
return sts;
|
|
}
|
|
|
|
CdmResponseType WvContentDecryptionModule::RemoveKeys(
|
|
const CdmSessionId& session_id) {
|
|
CdmEngine* cdm_engine = GetCdmForSessionId(session_id);
|
|
if (!cdm_engine) return SESSION_NOT_FOUND_5;
|
|
CdmResponseType sts;
|
|
M_TIME(
|
|
sts = cdm_engine->RemoveKeys(
|
|
session_id),
|
|
cdm_engine->GetMetrics(),
|
|
cdm_engine_remove_keys_,
|
|
sts);
|
|
return sts;
|
|
}
|
|
|
|
CdmResponseType WvContentDecryptionModule::QueryStatus(
|
|
SecurityLevel security_level,
|
|
const std::string& key,
|
|
std::string* value) {
|
|
CdmEngine* cdm_engine = EnsureCdmForIdentifier(kDefaultCdmIdentifier);
|
|
return cdm_engine->QueryStatus(security_level, key, value);
|
|
}
|
|
|
|
CdmResponseType WvContentDecryptionModule::QuerySessionStatus(
|
|
const CdmSessionId& session_id, CdmQueryMap* key_info) {
|
|
CdmEngine* cdm_engine = GetCdmForSessionId(session_id);
|
|
if (!cdm_engine) return SESSION_NOT_FOUND_8;
|
|
return cdm_engine->QuerySessionStatus(session_id, key_info);
|
|
}
|
|
|
|
CdmResponseType WvContentDecryptionModule::QueryKeyStatus(
|
|
const CdmSessionId& session_id, CdmQueryMap* key_info) {
|
|
CdmEngine* cdm_engine = GetCdmForSessionId(session_id);
|
|
if (!cdm_engine) return SESSION_NOT_FOUND_9;
|
|
CdmResponseType sts;
|
|
M_TIME(
|
|
sts = cdm_engine->QueryKeyStatus(
|
|
session_id,
|
|
key_info),
|
|
cdm_engine->GetMetrics(),
|
|
cdm_engine_query_key_status_,
|
|
sts);
|
|
return sts;
|
|
}
|
|
|
|
CdmResponseType WvContentDecryptionModule::QueryOemCryptoSessionId(
|
|
const CdmSessionId& session_id, CdmQueryMap* response) {
|
|
CdmEngine* cdm_engine = GetCdmForSessionId(session_id);
|
|
if (!cdm_engine) return SESSION_NOT_FOUND_10;
|
|
return cdm_engine->QueryOemCryptoSessionId(session_id, response);
|
|
}
|
|
|
|
CdmResponseType WvContentDecryptionModule::GetProvisioningRequest(
|
|
CdmCertificateType cert_type,
|
|
const std::string& cert_authority,
|
|
const CdmIdentifier& identifier,
|
|
CdmProvisioningRequest* request,
|
|
std::string* default_url) {
|
|
CdmEngine* cdm_engine = EnsureCdmForIdentifier(identifier);
|
|
CdmResponseType sts;
|
|
M_TIME(
|
|
sts = cdm_engine->GetProvisioningRequest(
|
|
cert_type,
|
|
cert_authority,
|
|
request,
|
|
default_url),
|
|
cdm_engine->GetMetrics(),
|
|
cdm_engine_get_provisioning_request_,
|
|
sts);
|
|
return sts;
|
|
}
|
|
|
|
CdmResponseType WvContentDecryptionModule::HandleProvisioningResponse(
|
|
const CdmIdentifier& identifier,
|
|
CdmProvisioningResponse& response,
|
|
std::string* cert,
|
|
std::string* wrapped_key) {
|
|
CdmEngine* cdm_engine = EnsureCdmForIdentifier(identifier);
|
|
CdmResponseType sts;
|
|
M_TIME(
|
|
sts = cdm_engine->HandleProvisioningResponse(
|
|
response,
|
|
cert,
|
|
wrapped_key),
|
|
cdm_engine->GetMetrics(),
|
|
cdm_engine_handle_provisioning_response_,
|
|
sts);
|
|
return sts;
|
|
}
|
|
|
|
CdmResponseType WvContentDecryptionModule::Unprovision(
|
|
CdmSecurityLevel level, const CdmIdentifier& identifier) {
|
|
CdmEngine* cdm_engine = EnsureCdmForIdentifier(identifier);
|
|
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);
|
|
CdmResponseType sts;
|
|
M_TIME(
|
|
sts = cdm_engine->GetUsageInfo(
|
|
app_id,
|
|
usage_info),
|
|
cdm_engine->GetMetrics(),
|
|
cdm_engine_get_usage_info_,
|
|
sts);
|
|
return sts;
|
|
}
|
|
|
|
CdmResponseType WvContentDecryptionModule::GetUsageInfo(
|
|
const std::string& app_id,
|
|
const CdmSecureStopId& ssid,
|
|
const CdmIdentifier& identifier,
|
|
CdmUsageInfo* usage_info) {
|
|
CdmEngine* cdm_engine = EnsureCdmForIdentifier(identifier);
|
|
CdmResponseType sts;
|
|
M_TIME(
|
|
sts = cdm_engine->GetUsageInfo(
|
|
app_id,
|
|
ssid,
|
|
usage_info),
|
|
cdm_engine->GetMetrics(),
|
|
cdm_engine_get_usage_info_,
|
|
sts);
|
|
return sts;
|
|
}
|
|
|
|
CdmResponseType WvContentDecryptionModule::ReleaseAllUsageInfo(
|
|
const std::string& app_id, const CdmIdentifier& identifier) {
|
|
CdmEngine* cdm_engine = EnsureCdmForIdentifier(identifier);
|
|
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;
|
|
M_TIME(
|
|
sts = cdm_engine->ReleaseUsageInfo(
|
|
message),
|
|
cdm_engine->GetMetrics(),
|
|
cdm_engine_release_usage_info_,
|
|
sts);
|
|
return sts;
|
|
}
|
|
|
|
CdmResponseType WvContentDecryptionModule::Decrypt(
|
|
const CdmSessionId& session_id,
|
|
bool validate_key_id,
|
|
const CdmDecryptionParameters& parameters) {
|
|
// First find the CdmEngine that has the given session_id. If we are using
|
|
// key sharing, the shared session will still be in the same CdmEngine.
|
|
CdmEngine* cdm_engine = GetCdmForSessionId(session_id);
|
|
if (!cdm_engine) return SESSION_NOT_FOUND_FOR_DECRYPT;
|
|
|
|
CdmSessionId local_session_id = session_id;
|
|
if (validate_key_id &&
|
|
Properties::GetSessionSharingId(session_id) != 0) {
|
|
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 && parameters.is_encrypted) {
|
|
LOGE("WvContentDecryptionModule::Decrypt: unable to find session");
|
|
return KEY_NOT_FOUND_IN_SESSION;
|
|
}
|
|
}
|
|
CdmResponseType sts;
|
|
M_TIME(
|
|
sts = cdm_engine->Decrypt(
|
|
local_session_id,
|
|
parameters),
|
|
cdm_engine->GetMetrics(),
|
|
cdm_engine_decrypt_,
|
|
sts);
|
|
return sts;
|
|
}
|
|
|
|
void WvContentDecryptionModule::NotifyResolution(const CdmSessionId& session_id,
|
|
uint32_t width,
|
|
uint32_t height) {
|
|
CdmEngine* cdm_engine = GetCdmForSessionId(session_id);
|
|
if (!cdm_engine) return;
|
|
cdm_engine->NotifyResolution(session_id, width, height);
|
|
}
|
|
|
|
bool WvContentDecryptionModule::IsValidServiceCertificate(
|
|
const std::string& certificate) {
|
|
ServiceCertificate cert;
|
|
CdmResponseType status = cert.Init(certificate);
|
|
if (status != NO_ERROR) return false;
|
|
return cert.has_certificate();
|
|
}
|
|
|
|
void WvContentDecryptionModule::GetSerializedMetrics(
|
|
std::string* serialized_metrics) {
|
|
AutoLock auto_lock(cdms_lock_);
|
|
CloseCdmsWithoutSessions();
|
|
metrics_.SerializeToString(serialized_metrics);
|
|
metrics_.Clear();
|
|
}
|
|
|
|
WvContentDecryptionModule::CdmInfo::CdmInfo()
|
|
: cdm_engine(new CdmEngine(&file_system)) {}
|
|
|
|
CdmEngine* WvContentDecryptionModule::EnsureCdmForIdentifier(
|
|
const CdmIdentifier& identifier) {
|
|
AutoLock auto_lock(cdms_lock_);
|
|
if (cdms_.find(identifier) == cdms_.end()) {
|
|
// Accessing the map entry will create a new instance using the default
|
|
// constructor. We then need to provide it with two pieces of info: The
|
|
// origin provided by the app and an identifier that uniquely identifies
|
|
// this CDM. We concatenate all pieces of the CdmIdentifier in order to
|
|
// create an ID that is unique to that identifier.
|
|
cdms_[identifier].file_system.SetOrigin(identifier.origin);
|
|
cdms_[identifier].file_system.SetIdentifier(
|
|
identifier.spoid + identifier.origin);
|
|
}
|
|
|
|
return cdms_[identifier].cdm_engine.get();
|
|
}
|
|
|
|
CdmEngine* WvContentDecryptionModule::GetCdmForSessionId(
|
|
const std::string& session_id) {
|
|
// Use find to avoid creating empty entries when not found.
|
|
auto it = cdm_by_session_id_.find(session_id);
|
|
if (it == cdm_by_session_id_.end()) return NULL;
|
|
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())
|
|
policy_timer_.Start(this, kCdmPolicyTimerDurationSeconds);
|
|
}
|
|
|
|
void WvContentDecryptionModule::DisablePolicyTimer() {
|
|
bool cdms_is_empty = false;
|
|
{
|
|
AutoLock auto_lock(cdms_lock_);
|
|
CloseCdmsWithoutSessions();
|
|
cdms_is_empty = cdms_.empty();
|
|
}
|
|
|
|
AutoLock auto_lock(policy_timer_lock_);
|
|
if(cdms_is_empty) {
|
|
if (policy_timer_.IsRunning()) {
|
|
policy_timer_.Stop();
|
|
}
|
|
}
|
|
}
|
|
|
|
void WvContentDecryptionModule::ForceDisablePolicyTimer() {
|
|
{
|
|
AutoLock auto_lock(cdms_lock_);
|
|
CloseCdmsWithoutSessions();
|
|
}
|
|
|
|
AutoLock auto_lock(policy_timer_lock_);
|
|
if (policy_timer_.IsRunning()) {
|
|
policy_timer_.Stop();
|
|
}
|
|
}
|
|
|
|
void WvContentDecryptionModule::OnTimerEvent() {
|
|
AutoLock auto_lock(cdms_lock_);
|
|
for (auto it = cdms_.begin(); it != cdms_.end(); ++it) {
|
|
it->second.cdm_engine->OnTimerEvent();
|
|
}
|
|
}
|
|
|
|
uint32_t WvContentDecryptionModule::GenerateSessionSharingId() {
|
|
static int next_session_sharing_id = 0;
|
|
return ++next_session_sharing_id;
|
|
}
|
|
|
|
} // namespace wvcdm
|