Commit 34afc93c authored by sandersd@chromium.org's avatar sandersd@chromium.org

Add UMA reporting to CdmPromise.

This allows all CdmPromise objects to report their result (success or
exception) if given the name of a histogram at construction.

As an example, a UMA for the unprefixed NewSession method is included.

BUG=351501

Review URL: https://codereview.chromium.org/452643002

Cr-Commit-Position: refs/heads/master@{#289453}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@289453 0039d316-1c4b-4281-b951-d872f2087c98
parent e5f5ed7b
......@@ -9,6 +9,7 @@
#include "base/memory/weak_ptr.h"
#include "base/stl_util.h"
#include "content/renderer/media/crypto/content_decryption_module_factory.h"
#include "content/renderer/media/crypto/key_systems.h"
#include "content/renderer/media/webcontentdecryptionmodulesession_impl.h"
#include "media/base/cdm_promise.h"
#include "media/base/media_keys.h"
......@@ -16,6 +17,9 @@
namespace content {
const char kMediaEME[] = "Media.EME.";
const char kDot[] = ".";
CdmSessionAdapter::CdmSessionAdapter() :
#if defined(ENABLE_BROWSER_CDMS)
cdm_id_(0),
......@@ -32,6 +36,7 @@ bool CdmSessionAdapter::Initialize(
#endif // defined(ENABLE_PEPPER_CDMS)
const std::string& key_system,
const GURL& security_origin) {
key_system_uma_prefix_ = kMediaEME + KeySystemNameForUMA(key_system) + kDot;
base::WeakPtr<CdmSessionAdapter> weak_this = weak_ptr_factory_.GetWeakPtr();
media_keys_ = ContentDecryptionModuleFactory::Create(
key_system,
......@@ -103,6 +108,10 @@ media::Decryptor* CdmSessionAdapter::GetDecryptor() {
return media_keys_->GetDecryptor();
}
const std::string& CdmSessionAdapter::GetKeySystemUMAPrefix() const {
return key_system_uma_prefix_;
}
#if defined(ENABLE_BROWSER_CDMS)
int CdmSessionAdapter::GetCdmId() const {
return cdm_id_;
......
......@@ -88,6 +88,9 @@ class CdmSessionAdapter : public base::RefCounted<CdmSessionAdapter> {
// after WebContentDecryptionModule is freed. http://crbug.com/330324
media::Decryptor* GetDecryptor();
// Returns a prefix to use for UMAs.
const std::string& GetKeySystemUMAPrefix() const;
#if defined(ENABLE_BROWSER_CDMS)
// Returns the CDM ID associated with the |media_keys_|. May be kInvalidCdmId
// if no CDM ID is associated.
......@@ -125,6 +128,8 @@ class CdmSessionAdapter : public base::RefCounted<CdmSessionAdapter> {
int cdm_id_;
#endif
std::string key_system_uma_prefix_;
// NOTE: Weak pointers must be invalidated before all other member variables.
base::WeakPtrFactory<CdmSessionAdapter> weak_ptr_factory_;
......
......@@ -15,6 +15,8 @@
namespace content {
const char kCreateSessionUMAName[] = "CreateSession";
// For backwards compatibility with blink not using
// WebContentDecryptionModuleResult, reserve an index for |outstanding_results_|
// that will not be used when adding a WebContentDecryptionModuleResult.
......@@ -107,7 +109,8 @@ void WebContentDecryptionModuleSessionImpl::initializeNewSession(
weak_ptr_factory_.GetWeakPtr(),
kReservedIndex),
base::Bind(&WebContentDecryptionModuleSessionImpl::OnSessionError,
weak_ptr_factory_.GetWeakPtr())));
weak_ptr_factory_.GetWeakPtr()),
adapter_->GetKeySystemUMAPrefix() + kCreateSessionUMAName));
adapter_->InitializeNewSession(init_data_type_as_ascii,
init_data,
init_data_length,
......@@ -168,7 +171,8 @@ void WebContentDecryptionModuleSessionImpl::initializeNewSession(
result_index),
base::Bind(&WebContentDecryptionModuleSessionImpl::SessionError,
weak_ptr_factory_.GetWeakPtr(),
result_index)));
result_index),
adapter_->GetKeySystemUMAPrefix() + kCreateSessionUMAName));
adapter_->InitializeNewSession(init_data_type_as_ascii,
init_data,
init_data_length,
......
......@@ -6,6 +6,7 @@
#include "base/bind.h"
#include "base/logging.h"
#include "base/metrics/histogram.h"
namespace media {
......@@ -17,15 +18,48 @@ CdmPromise::CdmPromise(PromiseRejectedCB reject_cb)
DCHECK(!reject_cb_.is_null());
}
CdmPromise::CdmPromise(PromiseRejectedCB reject_cb, const std::string& uma_name)
: reject_cb_(reject_cb), is_pending_(true), uma_name_(uma_name) {
DCHECK(!reject_cb_.is_null());
}
CdmPromise::~CdmPromise() {
DCHECK(!is_pending_);
}
static CdmPromise::ResultCodeForUMA ConvertExceptionToUMAResult(
MediaKeys::Exception exception_code) {
switch (exception_code) {
case MediaKeys::NOT_SUPPORTED_ERROR:
return CdmPromise::NOT_SUPPORTED_ERROR;
case MediaKeys::INVALID_STATE_ERROR:
return CdmPromise::INVALID_STATE_ERROR;
case MediaKeys::INVALID_ACCESS_ERROR:
return CdmPromise::INVALID_ACCESS_ERROR;
case MediaKeys::QUOTA_EXCEEDED_ERROR:
return CdmPromise::QUOTA_EXCEEDED_ERROR;
case MediaKeys::UNKNOWN_ERROR:
return CdmPromise::UNKNOWN_ERROR;
case MediaKeys::CLIENT_ERROR:
return CdmPromise::CLIENT_ERROR;
case MediaKeys::OUTPUT_ERROR:
return CdmPromise::OUTPUT_ERROR;
}
NOTREACHED();
return CdmPromise::UNKNOWN_ERROR;
}
void CdmPromise::reject(MediaKeys::Exception exception_code,
uint32 system_code,
const std::string& error_message) {
DCHECK(is_pending_);
is_pending_ = false;
if (!uma_name_.empty()) {
ResultCodeForUMA result_code = ConvertExceptionToUMAResult(exception_code);
base::LinearHistogram::FactoryGet(
uma_name_, 1, NUM_RESULT_CODES, NUM_RESULT_CODES + 1,
base::HistogramBase::kUmaTargetedHistogramFlag)->Add(result_code);
}
reject_cb_.Run(exception_code, system_code, error_message);
}
......@@ -37,6 +71,15 @@ CdmPromiseTemplate<T>::CdmPromiseTemplate(
DCHECK(!resolve_cb_.is_null());
}
template <typename T>
CdmPromiseTemplate<T>::CdmPromiseTemplate(
base::Callback<void(const T&)> resolve_cb,
PromiseRejectedCB reject_cb,
const std::string& uma_name)
: CdmPromise(reject_cb, uma_name), resolve_cb_(resolve_cb) {
DCHECK(!resolve_cb_.is_null());
}
template <typename T>
CdmPromiseTemplate<T>::~CdmPromiseTemplate() {
DCHECK(!is_pending_);
......@@ -46,6 +89,11 @@ template <typename T>
void CdmPromiseTemplate<T>::resolve(const T& result) {
DCHECK(is_pending_);
is_pending_ = false;
if (!uma_name_.empty()) {
base::LinearHistogram::FactoryGet(
uma_name_, 1, NUM_RESULT_CODES, NUM_RESULT_CODES + 1,
base::HistogramBase::kUmaTargetedHistogramFlag)->Add(SUCCESS);
}
resolve_cb_.Run(result);
}
......@@ -55,6 +103,14 @@ CdmPromiseTemplate<void>::CdmPromiseTemplate(base::Callback<void()> resolve_cb,
DCHECK(!resolve_cb_.is_null());
}
CdmPromiseTemplate<void>::CdmPromiseTemplate(base::Callback<void()> resolve_cb,
PromiseRejectedCB reject_cb,
const std::string& uma_name)
: CdmPromise(reject_cb, uma_name), resolve_cb_(resolve_cb) {
DCHECK(!resolve_cb_.is_null());
DCHECK(!uma_name_.empty());
}
CdmPromiseTemplate<void>::CdmPromiseTemplate() {
}
......@@ -65,6 +121,11 @@ CdmPromiseTemplate<void>::~CdmPromiseTemplate() {
void CdmPromiseTemplate<void>::resolve() {
DCHECK(is_pending_);
is_pending_ = false;
if (!uma_name_.empty()) {
base::LinearHistogram::FactoryGet(
uma_name_, 1, NUM_RESULT_CODES, NUM_RESULT_CODES + 1,
base::HistogramBase::kUmaTargetedHistogramFlag)->Add(SUCCESS);
}
resolve_cb_.Run();
}
......
......@@ -22,6 +22,19 @@ namespace media {
// This is only the base class, as parameter to resolve() varies.
class MEDIA_EXPORT CdmPromise {
public:
// A superset of media::MediaKeys::Exception for UMA reporting.
enum ResultCodeForUMA {
SUCCESS,
NOT_SUPPORTED_ERROR,
INVALID_STATE_ERROR,
INVALID_ACCESS_ERROR,
QUOTA_EXCEEDED_ERROR,
UNKNOWN_ERROR,
CLIENT_ERROR,
OUTPUT_ERROR,
NUM_RESULT_CODES
};
typedef base::Callback<void(MediaKeys::Exception exception_code,
uint32 system_code,
const std::string& error_message)>
......@@ -41,11 +54,19 @@ class MEDIA_EXPORT CdmPromise {
CdmPromise();
CdmPromise(PromiseRejectedCB reject_cb);
// If constructed with a |uma_name| (which must be the name of a
// CdmPromiseResult UMA), CdmPromise will report the promise result (success
// or rejection code).
CdmPromise(PromiseRejectedCB reject_cb, const std::string& uma_name);
PromiseRejectedCB reject_cb_;
// Keep track of whether the promise hasn't been resolved or rejected yet.
bool is_pending_;
// UMA to report result to.
std::string uma_name_;
DISALLOW_COPY_AND_ASSIGN(CdmPromise);
};
......@@ -54,6 +75,9 @@ class MEDIA_EXPORT CdmPromiseTemplate : public CdmPromise {
public:
CdmPromiseTemplate(base::Callback<void(const T&)> resolve_cb,
PromiseRejectedCB rejected_cb);
CdmPromiseTemplate(base::Callback<void(const T&)> resolve_cb,
PromiseRejectedCB rejected_cb,
const std::string& uma_name);
virtual ~CdmPromiseTemplate();
virtual void resolve(const T& result);
......@@ -69,6 +93,9 @@ class MEDIA_EXPORT CdmPromiseTemplate<void> : public CdmPromise {
public:
CdmPromiseTemplate(base::Callback<void(void)> resolve_cb,
PromiseRejectedCB rejected_cb);
CdmPromiseTemplate(base::Callback<void(void)> resolve_cb,
PromiseRejectedCB rejected_cb,
const std::string& uma_name);
virtual ~CdmPromiseTemplate();
virtual void resolve();
......
......@@ -10893,6 +10893,13 @@ Therefore, the affected-histogram name has to have at least one dot in it.
<summary>cancelKeyRequest result using the Clear Key key system.</summary>
</histogram>
<histogram name="Media.EME.ClearKey.CreateSession" enum="CdmPromiseResult">
<owner>sandersd@chromium.org</owner>
<summary>
Result of Clear Key createSession promises handled by Chromium code.
</summary>
</histogram>
<histogram name="Media.EME.ClearKey.DecryptError">
<owner>xhwang@chromium.org</owner>
<summary>
......@@ -10939,6 +10946,14 @@ Therefore, the affected-histogram name has to have at least one dot in it.
<summary>cancelKeyRequest result using an unknown key system.</summary>
</histogram>
<histogram name="Media.EME.Unknown.CreateSession" enum="CdmPromiseResult">
<owner>sandersd@chromium.org</owner>
<summary>
Result of createSession promises for unknown key systems promises that were
handled by Chromium code.
</summary>
</histogram>
<histogram name="Media.EME.Unknown.DecryptError">
<owner>xhwang@chromium.org</owner>
<summary>Decryption error event count using an unknown key system.</summary>
......@@ -10969,6 +10984,13 @@ Therefore, the affected-histogram name has to have at least one dot in it.
<summary>cancelKeyRequest result using the Widevine key system.</summary>
</histogram>
<histogram name="Media.EME.Widevine.CreateSession" enum="CdmPromiseResult">
<owner>sandersd@chromium.org</owner>
<summary>
Result of Widevine createSession promises handled by Chromium code.
</summary>
</histogram>
<histogram name="Media.EME.Widevine.DecryptError">
<owner>xhwang@chromium.org</owner>
<summary>Decryption error event count using the Widevine key system.</summary>
......@@ -37666,6 +37688,17 @@ Therefore, the affected-histogram name has to have at least one dot in it.
<int value="20" label="FutureCat (&gt;10.10), 8-bit (?)"/>
</enum>
<enum name="CdmPromiseResult" type="int">
<int value="0" label="Success"/>
<int value="1" label="NotSupportedError"/>
<int value="2" label="InvalidStateError"/>
<int value="3" label="InvalidAccessError"/>
<int value="4" label="QuotaExceededError"/>
<int value="5" label="UnknownError"/>
<int value="6" label="ClientError"/>
<int value="7" label="OutputError"/>
</enum>
<enum name="CertificateChainPosition" type="int">
<int value="0" label="Root Certificate"/>
</enum>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment