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:
@@ -26,6 +26,7 @@
|
||||
namespace wvcdm {
|
||||
|
||||
class CdmClientPropertySet;
|
||||
class CdmEngineFactory;
|
||||
class CdmSession;
|
||||
class CryptoEngine;
|
||||
class UsagePropertySet;
|
||||
@@ -37,7 +38,6 @@ typedef std::map<CdmKeySetId,
|
||||
|
||||
class CdmEngine {
|
||||
public:
|
||||
CdmEngine(FileSystem* file_system, const std::string& spoid = EMPTY_SPOID);
|
||||
virtual ~CdmEngine();
|
||||
|
||||
// Session related methods
|
||||
@@ -316,10 +316,37 @@ class CdmEngine {
|
||||
// dead lock.
|
||||
virtual void OnTimerEvent();
|
||||
|
||||
virtual metrics::EngineMetrics* GetMetrics() { return &metrics_; }
|
||||
// Fills the |engine_metrics| parameter with the current snapshot of metrics
|
||||
// data. Returns true if the metrics data is populated, false otherwise.
|
||||
// |engine_metrics| is owned by the caller and must not be null.
|
||||
// The CdmEngine implementation is a placeholder. Just return false.
|
||||
virtual bool GetMetricsSnapshot(
|
||||
__attribute__((unused)) drm_metrics::WvCdmMetrics *metrics) {
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual CdmResponseType ValidateServiceCertificate(const std::string& cert);
|
||||
|
||||
// Setter and getter for the |app_package_name| identifier for this instance
|
||||
// of the CdmEngine. This is used to identify the package name.
|
||||
virtual void SetAppPackageName(const std::string& app_package_name) {
|
||||
app_package_name_ = app_package_name;
|
||||
}
|
||||
virtual const std::string& GetAppPackageName() {
|
||||
return app_package_name_;
|
||||
}
|
||||
|
||||
protected:
|
||||
friend class CdmEngineFactory;
|
||||
friend class WvCdmEnginePreProvTest;
|
||||
friend class WvCdmTestBase;
|
||||
friend class WvGenericOperationsTest;
|
||||
friend class TestLicenseHolder;
|
||||
|
||||
CdmEngine(FileSystem* file_system,
|
||||
std::shared_ptr<metrics::EngineMetrics> metrics,
|
||||
const std::string& spoid = EMPTY_SPOID);
|
||||
|
||||
private:
|
||||
// private methods
|
||||
CdmResponseType OpenSession(
|
||||
@@ -348,7 +375,8 @@ class CdmEngine {
|
||||
* ensure that all data has been properly recorded in the group before
|
||||
* it is published.
|
||||
*/
|
||||
metrics::EngineMetrics metrics_;
|
||||
std::shared_ptr<metrics::EngineMetrics> metrics_;
|
||||
std::string app_package_name_;
|
||||
|
||||
CdmSessionMap session_map_;
|
||||
CdmReleaseKeySetMap release_key_sets_;
|
||||
|
||||
28
libwvdrmengine/cdm/core/include/cdm_engine_factory.h
Normal file
28
libwvdrmengine/cdm/core/include/cdm_engine_factory.h
Normal file
@@ -0,0 +1,28 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
|
||||
#ifndef WVCDM_CORE_CDM_ENGINE_FACTORY_H_
|
||||
#define WVCDM_CORE_CDM_ENGINE_FACTORY_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "cdm_engine.h"
|
||||
#include "file_store.h"
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
// This factory is used to create an instance of the CdmEngine.
|
||||
class CdmEngineFactory {
|
||||
public:
|
||||
// Creates a new instance of a CdmEngine. Caller retains ownership of the
|
||||
// |files_system| which cannot be null.
|
||||
static CdmEngine* CreateCdmEngine(FileSystem* file_system);
|
||||
|
||||
private:
|
||||
CORE_DISALLOW_COPY_AND_ASSIGN(CdmEngineFactory);
|
||||
};
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
#endif // WVCDM_CORE_CDM_ENGINE_FACTORY_H_
|
||||
263
libwvdrmengine/cdm/core/include/cdm_engine_metrics_decorator.h
Normal file
263
libwvdrmengine/cdm/core/include/cdm_engine_metrics_decorator.h
Normal file
@@ -0,0 +1,263 @@
|
||||
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
#ifndef WVCDM_CORE_CDM_ENGINE_METRICS_DECORATOR_H_
|
||||
#define WVCDM_CORE_CDM_ENGINE_METRICS_DECORATOR_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "cdm_engine.h"
|
||||
#include "cdm_session_map.h"
|
||||
#include "certificate_provisioning.h"
|
||||
#include "clock.h"
|
||||
#include "crypto_session.h"
|
||||
#include "disallow_copy_and_assign.h"
|
||||
#include "file_store.h"
|
||||
#include "initialization_data.h"
|
||||
#include "metrics_collections.h"
|
||||
#include "oemcrypto_adapter.h"
|
||||
#include "properties.h"
|
||||
#include "service_certificate.h"
|
||||
#include "wv_cdm_constants.h"
|
||||
#include "wv_cdm_types.h"
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
class CdmClientPropertySet;
|
||||
class CdmEngineFactory;
|
||||
class CdmSession;
|
||||
class CryptoEngine;
|
||||
class UsagePropertySet;
|
||||
class WvCdmEventListener;
|
||||
|
||||
// This is a templated decorator class implementation of the CdmEngine.
|
||||
// It captures metric information related to the inner CdmEngine class.
|
||||
// Usage:
|
||||
// FileSystem* file_system; // Construction of FileSystem object not shown.
|
||||
// std::shared_ptr<metrics::EngineMetrics> metrics(new EngineMetrics);
|
||||
// CdmEngine* e = new CdmEngineMetricsImpl<CdmEngine>(file_system, metrics);
|
||||
template<class T>
|
||||
class CdmEngineMetricsImpl : public T {
|
||||
public:
|
||||
// This constructor initializes the instance and takes ownership of |metrics|.
|
||||
// |file_system| and |metrics| must not be null.
|
||||
// |metrics| is used within the base class constructor. So, it must be
|
||||
// passed in as a dependency and provided to the base constructor.
|
||||
CdmEngineMetricsImpl(FileSystem* file_system,
|
||||
std::shared_ptr<metrics::EngineMetrics> metrics,
|
||||
const std::string& spoid = EMPTY_SPOID)
|
||||
: T(file_system, metrics, spoid), metrics_(metrics) {
|
||||
metrics_->cdm_engine_creation_time_millis_.Record(clock_.GetCurrentTime());
|
||||
std::string cdm_version;
|
||||
if(Properties::GetWVCdmVersion(&cdm_version)) {
|
||||
metrics_->cdm_engine_cdm_version_.Record(cdm_version);
|
||||
} else {
|
||||
metrics_->cdm_engine_cdm_version_.SetError(false);
|
||||
}
|
||||
}
|
||||
|
||||
~CdmEngineMetricsImpl() override {};
|
||||
|
||||
bool GetMetricsSnapshot(drm_metrics::WvCdmMetrics *metrics) override {
|
||||
if (metrics == nullptr) return false;
|
||||
metrics_->Serialize(metrics);
|
||||
return true;
|
||||
}
|
||||
|
||||
CdmResponseType OpenSession(
|
||||
const CdmKeySystem& key_system, CdmClientPropertySet* property_set,
|
||||
const CdmSessionId& forced_session_id, WvCdmEventListener* event_listener)
|
||||
override {
|
||||
CdmResponseType sts = T::OpenSession(
|
||||
key_system, property_set, forced_session_id, event_listener);
|
||||
metrics_->cdm_engine_open_session_.Increment(sts);
|
||||
return sts;
|
||||
}
|
||||
|
||||
CdmResponseType OpenSession(
|
||||
const CdmKeySystem& key_system, CdmClientPropertySet* property_set,
|
||||
WvCdmEventListener* event_listener, CdmSessionId* session_id)
|
||||
override {
|
||||
CdmResponseType sts = T::OpenSession(
|
||||
key_system, property_set, event_listener, session_id);
|
||||
metrics_->cdm_engine_open_session_.Increment(sts);
|
||||
return sts;
|
||||
}
|
||||
|
||||
CdmResponseType CloseSession(const CdmSessionId& session_id) override {
|
||||
CdmResponseType sts = T::CloseSession(session_id);
|
||||
metrics_->cdm_engine_close_session_.Increment(sts);
|
||||
return sts;
|
||||
}
|
||||
|
||||
CdmResponseType OpenKeySetSession(
|
||||
const CdmKeySetId& key_set_id, CdmClientPropertySet* property_set,
|
||||
WvCdmEventListener* event_listener) override {
|
||||
CdmResponseType sts = T::OpenKeySetSession(key_set_id, property_set,
|
||||
event_listener);
|
||||
metrics_->cdm_engine_open_key_set_session_.Increment(sts);
|
||||
return sts;
|
||||
}
|
||||
|
||||
CdmResponseType GenerateKeyRequest(
|
||||
const CdmSessionId& session_id, const CdmKeySetId& key_set_id,
|
||||
const InitializationData& init_data, const CdmLicenseType license_type,
|
||||
CdmAppParameterMap& app_parameters, CdmKeyRequest* key_request) override {
|
||||
CdmResponseType sts;
|
||||
M_TIME(sts = T::GenerateKeyRequest(session_id, key_set_id, init_data,
|
||||
license_type, app_parameters,
|
||||
key_request),
|
||||
metrics_, cdm_engine_generate_key_request_, sts, license_type);
|
||||
return sts;
|
||||
}
|
||||
|
||||
CdmResponseType AddKey(
|
||||
const CdmSessionId& session_id, const CdmKeyResponse& key_data,
|
||||
CdmLicenseType* license_type, CdmKeySetId* key_set_id) override {
|
||||
if (license_type == nullptr) {
|
||||
LOGE("CdmEngine::AddKey: license_type cannot be null.");
|
||||
return PARAMETER_NULL;
|
||||
}
|
||||
|
||||
CdmResponseType sts;
|
||||
M_TIME(sts = T::AddKey(session_id, key_data, license_type, key_set_id),
|
||||
metrics_, cdm_engine_add_key_, sts, *license_type);
|
||||
return sts;
|
||||
}
|
||||
|
||||
|
||||
CdmResponseType RestoreKey(const CdmSessionId& session_id,
|
||||
const CdmKeySetId& key_set_id) override {
|
||||
CdmResponseType sts;
|
||||
M_TIME(sts = T::RestoreKey(session_id, key_set_id),
|
||||
metrics_, cdm_engine_restore_key_, sts);
|
||||
return sts;
|
||||
}
|
||||
|
||||
CdmResponseType RemoveKeys(const CdmSessionId& session_id) override {
|
||||
CdmResponseType sts = T::RemoveKeys(session_id);
|
||||
metrics_->cdm_engine_remove_keys_.Increment(sts);
|
||||
return sts;
|
||||
}
|
||||
|
||||
CdmResponseType QueryKeyStatus(const CdmSessionId& session_id,
|
||||
CdmQueryMap* query_response) override {
|
||||
CdmResponseType sts;
|
||||
M_TIME(sts = T::QueryKeyStatus(session_id, query_response),
|
||||
metrics_, cdm_engine_query_key_status_, sts);
|
||||
return sts;
|
||||
}
|
||||
|
||||
CdmResponseType GetProvisioningRequest(
|
||||
CdmCertificateType cert_type, const std::string& cert_authority,
|
||||
const std::string& service_certificate,
|
||||
CdmProvisioningRequest* request, std::string* default_url) override {
|
||||
CdmResponseType sts;
|
||||
M_TIME(sts = T::GetProvisioningRequest(cert_type, cert_authority,
|
||||
service_certificate,
|
||||
request, default_url),
|
||||
metrics_, cdm_engine_get_provisioning_request_, sts);
|
||||
return sts;
|
||||
}
|
||||
|
||||
CdmResponseType HandleProvisioningResponse(
|
||||
const CdmProvisioningResponse& response, std::string* cert,
|
||||
std::string* wrapped_key) override {
|
||||
CdmResponseType sts;
|
||||
M_TIME(
|
||||
sts = T::HandleProvisioningResponse(response, cert, wrapped_key),
|
||||
metrics_, cdm_engine_handle_provisioning_response_, sts);
|
||||
return sts;
|
||||
}
|
||||
|
||||
|
||||
CdmResponseType Unprovision(CdmSecurityLevel security_level) override {
|
||||
CdmResponseType sts = T::Unprovision(security_level);
|
||||
metrics_->cdm_engine_unprovision_.Increment(sts, security_level);
|
||||
return sts;
|
||||
}
|
||||
|
||||
CdmResponseType GetUsageInfo(const std::string& app_id,
|
||||
CdmUsageInfo* usage_info) override {
|
||||
CdmResponseType sts;
|
||||
M_TIME(sts = T::GetUsageInfo(app_id, usage_info),
|
||||
metrics_, cdm_engine_get_usage_info_, sts);
|
||||
return sts;
|
||||
}
|
||||
|
||||
|
||||
CdmResponseType GetUsageInfo(const std::string& app_id,
|
||||
const CdmSecureStopId& ssid,
|
||||
CdmUsageInfo* usage_info) override {
|
||||
CdmResponseType sts;
|
||||
M_TIME(sts = T::GetUsageInfo(app_id, ssid, usage_info),
|
||||
metrics_, cdm_engine_get_usage_info_, sts);
|
||||
return sts;
|
||||
}
|
||||
|
||||
CdmResponseType RemoveAllUsageInfo(const std::string& app_id) override {
|
||||
CdmResponseType sts = T::RemoveAllUsageInfo(app_id);
|
||||
metrics_->cdm_engine_remove_all_usage_info_.Increment(sts);
|
||||
return sts;
|
||||
}
|
||||
|
||||
CdmResponseType RemoveAllUsageInfo(const std::string& app_id,
|
||||
CdmSecurityLevel security_level) override {
|
||||
CdmResponseType sts = T::RemoveAllUsageInfo(app_id, security_level);
|
||||
metrics_->cdm_engine_remove_all_usage_info_.Increment(sts);
|
||||
return sts;
|
||||
}
|
||||
|
||||
CdmResponseType RemoveUsageInfo(
|
||||
const std::string& app_id, const CdmSecureStopId& secure_stop_id)
|
||||
override {
|
||||
CdmResponseType sts = T::RemoveUsageInfo(app_id, secure_stop_id);
|
||||
metrics_->cdm_engine_remove_usage_info_.Increment(sts);
|
||||
return sts;
|
||||
}
|
||||
|
||||
CdmResponseType ReleaseUsageInfo(const CdmUsageInfoReleaseMessage& message)
|
||||
override {
|
||||
CdmResponseType sts = T::ReleaseUsageInfo(message);
|
||||
metrics_->cdm_engine_release_usage_info_.Increment(sts);
|
||||
return sts;
|
||||
}
|
||||
|
||||
CdmResponseType ListUsageIds(
|
||||
const std::string& app_id, CdmSecurityLevel security_level,
|
||||
std::vector<std::string>* ksids,
|
||||
std::vector<std::string>* provider_session_tokens) override {
|
||||
CdmResponseType sts = T::ListUsageIds(app_id, security_level,
|
||||
ksids, provider_session_tokens);
|
||||
metrics_->cdm_engine_get_secure_stop_ids_.Increment(sts);
|
||||
return sts;
|
||||
}
|
||||
|
||||
|
||||
bool FindSessionForKey(const KeyId& key_id, CdmSessionId* session_id)
|
||||
override {
|
||||
bool status =
|
||||
T::FindSessionForKey(key_id, session_id);
|
||||
metrics_->cdm_engine_find_session_for_key_.Increment(status);
|
||||
return status;
|
||||
}
|
||||
|
||||
CdmResponseType Decrypt(const CdmSessionId& session_id,
|
||||
const CdmDecryptionParameters& parameters) override {
|
||||
CdmResponseType sts;
|
||||
M_TIME(sts = T::Decrypt(session_id, parameters),
|
||||
metrics_, cdm_engine_decrypt_, sts,
|
||||
metrics::Pow2Bucket(parameters.encrypt_length));
|
||||
return sts;
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<metrics::EngineMetrics> metrics_;
|
||||
Clock clock_;
|
||||
};
|
||||
|
||||
} // wvcdm namespace
|
||||
#endif // WVCDM_CORE_CDM_ENGINE_METRICS_DECORATOR_H_
|
||||
Reference in New Issue
Block a user