1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "content/renderer/media/crypto/key_systems_support_uma.h"
6
7#include <string>
8
9#include "content/public/renderer/render_thread.h"
10#include "content/renderer/media/crypto/key_systems.h"
11
12namespace content {
13
14namespace {
15
16const char kKeySystemSupportActionPrefix[] = "KeySystemSupport.";
17
18// Reports an event only once.
19class OneTimeReporter {
20 public:
21  OneTimeReporter(const std::string& key_system,
22                  bool has_type,
23                  const std::string& event);
24  ~OneTimeReporter();
25
26  void Report();
27
28 private:
29  bool is_reported_;
30  std::string action_;
31};
32
33OneTimeReporter::OneTimeReporter(const std::string& key_system,
34                                 bool has_type,
35                                 const std::string& event)
36    : is_reported_(false) {
37  action_ = kKeySystemSupportActionPrefix + KeySystemNameForUMA(key_system);
38  if (has_type)
39    action_ += "WithType";
40  action_ += '.' + event;
41}
42
43OneTimeReporter::~OneTimeReporter() {}
44
45void OneTimeReporter::Report() {
46  if (is_reported_)
47    return;
48  RenderThread::Get()->RecordComputedAction(action_);
49  is_reported_ = true;
50}
51
52}  // namespace
53
54class KeySystemsSupportUMA::Reporter {
55 public:
56  explicit Reporter(const std::string& key_system);
57  ~Reporter();
58
59  void Report(bool has_type, bool is_supported);
60
61 private:
62  const std::string key_system_;
63
64  OneTimeReporter call_reporter_;
65  OneTimeReporter call_with_type_reporter_;
66  OneTimeReporter support_reporter_;
67  OneTimeReporter support_with_type_reporter_;
68};
69
70KeySystemsSupportUMA::Reporter::Reporter(const std::string& key_system)
71    : key_system_(key_system),
72      call_reporter_(key_system, false, "Queried"),
73      call_with_type_reporter_(key_system, true, "Queried"),
74      support_reporter_(key_system, false, "Supported"),
75      support_with_type_reporter_(key_system, true, "Supported") {}
76
77KeySystemsSupportUMA::Reporter::~Reporter() {}
78
79void KeySystemsSupportUMA::Reporter::Report(bool has_type, bool is_supported) {
80  call_reporter_.Report();
81  if (has_type)
82    call_with_type_reporter_.Report();
83
84  if (!is_supported)
85    return;
86
87  support_reporter_.Report();
88  if (has_type)
89    support_with_type_reporter_.Report();
90}
91
92KeySystemsSupportUMA::KeySystemsSupportUMA() {}
93
94KeySystemsSupportUMA::~KeySystemsSupportUMA() {}
95
96void KeySystemsSupportUMA::AddKeySystemToReport(const std::string& key_system) {
97  DCHECK(!GetReporter(key_system));
98  reporters_.set(key_system, scoped_ptr<Reporter>(new Reporter(key_system)));
99}
100
101void KeySystemsSupportUMA::ReportKeySystemQuery(const std::string& key_system,
102                                                bool has_type) {
103  Reporter* reporter = GetReporter(key_system);
104  if (!reporter)
105    return;
106  reporter->Report(has_type, false);
107}
108
109void KeySystemsSupportUMA::ReportKeySystemSupport(const std::string& key_system,
110                                                  bool has_type) {
111  Reporter* reporter = GetReporter(key_system);
112  if (!reporter)
113    return;
114  reporter->Report(has_type, true);
115}
116
117KeySystemsSupportUMA::Reporter* KeySystemsSupportUMA::GetReporter(
118    const std::string& key_system) {
119  Reporters::iterator reporter = reporters_.find(key_system);
120  if (reporter == reporters_.end())
121    return NULL;
122  return reporter->second;
123}
124
125}  // namespace content
126