Add a metric decorator around cdm engine

[ Merge from http://go/wvgerrit/69105 ]

This adds a metric collecting decorator class around cdm engine. This
implementation uses a templated decorator. The decorator enables:

1) Wrapping the CDM Engine methods to capture timing and error
information.
2) Allows use of a mock CDM Engine for testing.

Test: Unit tests. GPlay manual testing and GTS tests.
BUG: http://b/64724336
Change-Id: I5e4a0f552974fab1939bc7ab02719a1f5849cf3f
This commit is contained in:
Adam Stone
2019-01-15 17:25:43 -08:00
parent 1cc4f71975
commit 46eecb6b80
14 changed files with 954 additions and 110 deletions

View File

@@ -6,6 +6,7 @@
#include "cdm_client_property_set.h"
#include "cdm_engine.h"
#include "cdm_engine_factory.h"
#include "initialization_data.h"
#include "license.h"
#include "log.h"
@@ -64,7 +65,6 @@ 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);
if (sts == NO_ERROR) {
cdm_by_session_id_[*session_id] = cdm_engine;
}
@@ -79,7 +79,6 @@ CdmResponseType WvContentDecryptionModule::CloseSession(
if (!cdm_engine) return SESSION_NOT_FOUND_1;
std::unique_lock<std::mutex> auto_lock(cdms_lock_);
CdmResponseType sts = cdm_engine->CloseSession(session_id);
cdm_engine->GetMetrics()->cdm_engine_close_session_.Increment(sts);
if (sts == NO_ERROR) {
cdm_by_session_id_.erase(session_id);
}
@@ -102,7 +101,6 @@ CdmResponseType WvContentDecryptionModule::GenerateKeyRequest(
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);
if (sts != NO_ERROR) return sts;
cdm_by_session_id_[key_set_id] = cdm_engine;
}
@@ -124,11 +122,9 @@ CdmResponseType WvContentDecryptionModule::GenerateKeyRequest(
InitializationData initialization_data(init_data_type, init_data,
oec_version);
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, license_type);
sts = cdm_engine->GenerateKeyRequest(session_id, key_set_id,
initialization_data, license_type,
app_parameters, key_request);
switch (license_type) {
case kLicenseTypeRelease:
if (sts != KEY_MESSAGE) {
@@ -156,9 +152,7 @@ CdmResponseType WvContentDecryptionModule::AddKey(
}
CdmResponseType sts;
CdmLicenseType license_type;
M_TIME(sts = cdm_engine->AddKey(session_id, key_data,
&license_type, key_set_id),
cdm_engine->GetMetrics(), cdm_engine_add_key_, sts, license_type);
sts = cdm_engine->AddKey(session_id, key_data, &license_type, key_set_id);
// Empty session id indicates license type release.
if (sts == KEY_ADDED && session_id.empty()) {
cdm_engine->CloseKeySetSession(release_key_set_id);
@@ -172,8 +166,7 @@ CdmResponseType WvContentDecryptionModule::RestoreKey(
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);
sts = cdm_engine->RestoreKey(session_id, key_set_id);
if (sts == KEY_ADDED) EnablePolicyTimer();
return sts;
}
@@ -183,7 +176,6 @@ CdmResponseType WvContentDecryptionModule::RemoveKeys(
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);
return sts;
}
@@ -205,8 +197,7 @@ CdmResponseType WvContentDecryptionModule::QueryKeyStatus(
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);
sts = cdm_engine->QueryKeyStatus(session_id, key_info);
return sts;
}
@@ -227,59 +218,41 @@ CdmResponseType WvContentDecryptionModule::GetProvisioningRequest(
const CdmIdentifier& identifier, const std::string& service_certificate,
CdmProvisioningRequest* request, std::string* default_url) {
CdmEngine* cdm_engine = EnsureCdmForIdentifier(identifier);
CdmResponseType sts;
M_TIME(sts = cdm_engine->GetProvisioningRequest(cert_type, cert_authority,
service_certificate,
request, default_url),
cdm_engine->GetMetrics(), cdm_engine_get_provisioning_request_, sts);
return sts;
return cdm_engine->GetProvisioningRequest(
cert_type, cert_authority, service_certificate, request, default_url);
}
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;
return cdm_engine->HandleProvisioningResponse(response, cert, wrapped_key);
}
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);
return sts;
return cdm_engine->Unprovision(level);
}
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;
return cdm_engine->GetUsageInfo(app_id, usage_info);
}
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;
return cdm_engine->GetUsageInfo(app_id, ssid, usage_info);
}
CdmResponseType WvContentDecryptionModule::RemoveAllUsageInfo(
const std::string& app_id, const CdmIdentifier& identifier) {
CdmEngine* cdm_engine = EnsureCdmForIdentifier(identifier);
CdmResponseType sts = cdm_engine->RemoveAllUsageInfo(app_id);
cdm_engine->GetMetrics()->cdm_engine_remove_all_usage_info_.Increment(sts);
return sts;
return cdm_engine->RemoveAllUsageInfo(app_id);
}
CdmResponseType WvContentDecryptionModule::RemoveUsageInfo(
@@ -287,18 +260,14 @@ CdmResponseType WvContentDecryptionModule::RemoveUsageInfo(
const CdmIdentifier& identifier,
const CdmSecureStopId& secure_stop_id) {
CdmEngine* cdm_engine = EnsureCdmForIdentifier(identifier);
CdmResponseType sts = cdm_engine->RemoveUsageInfo(app_id, secure_stop_id);
cdm_engine->GetMetrics()->cdm_engine_remove_usage_info_.Increment(sts);
return sts;
return cdm_engine->RemoveUsageInfo(app_id, secure_stop_id);
}
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);
return sts;
return cdm_engine->ReleaseUsageInfo(message);
}
CdmResponseType WvContentDecryptionModule::GetSecureStopIds(
@@ -318,9 +287,7 @@ CdmResponseType WvContentDecryptionModule::GetSecureStopIds(
CdmResponseType sts_l3 = cdm_engine->ListUsageIds(app_id, kSecurityLevelL3,
NULL, &secure_stop_ids);
ssids->insert(ssids->end(), secure_stop_ids.begin(), secure_stop_ids.end());
if (sts_l3 != NO_ERROR) sts = sts_l3;
cdm_engine->GetMetrics()->cdm_engine_get_secure_stop_ids_.Increment(sts);
return sts;
return sts_l3 != NO_ERROR ? sts_l3 : sts;
}
CdmResponseType WvContentDecryptionModule::Decrypt(
@@ -339,8 +306,6 @@ CdmResponseType WvContentDecryptionModule::Decrypt(
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) {
// key does not need to be loaded if clear lead/frame has a
// single subsample. It does in all other cases.
@@ -351,11 +316,7 @@ CdmResponseType WvContentDecryptionModule::Decrypt(
}
}
}
CdmResponseType sts;
M_TIME(sts = cdm_engine->Decrypt(local_session_id, parameters),
cdm_engine->GetMetrics(), cdm_engine_decrypt_, sts,
metrics::Pow2Bucket(parameters.encrypt_length));
return sts;
return cdm_engine->Decrypt(local_session_id, parameters);
}
void WvContentDecryptionModule::NotifyResolution(const CdmSessionId& session_id,
@@ -387,12 +348,12 @@ CdmResponseType WvContentDecryptionModule::GetMetrics(
// TODO(blueeyes): Add a better error.
return UNKNOWN_ERROR;
}
it->second.cdm_engine->GetMetrics()->Serialize(metrics);
return NO_ERROR;
return it->second.cdm_engine->GetMetricsSnapshot(metrics) ?
NO_ERROR : UNKNOWN_ERROR;
}
WvContentDecryptionModule::CdmInfo::CdmInfo()
: cdm_engine(new CdmEngine(&file_system)) {}
: cdm_engine(CdmEngineFactory::CreateCdmEngine(&file_system)) {}
CdmEngine* WvContentDecryptionModule::EnsureCdmForIdentifier(
const CdmIdentifier& identifier) {
@@ -406,9 +367,7 @@ CdmEngine* WvContentDecryptionModule::EnsureCdmForIdentifier(
cdms_[identifier].file_system.set_origin(identifier.origin);
cdms_[identifier].file_system.set_identifier(identifier.spoid +
identifier.origin);
// Set the app package name for use by metrics.
cdms_[identifier].cdm_engine->GetMetrics()->SetAppPackageName(
cdms_[identifier].cdm_engine->SetAppPackageName(
identifier.app_package_name);
}
CdmEngine* cdm_engine = cdms_[identifier].cdm_engine.get();