1// Copyright (c) 2011 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 "chrome/browser/extensions/extension_metrics_module.h"
6
7#include "base/metrics/histogram.h"
8#include "base/values.h"
9#include "chrome/common/extensions/extension.h"
10#include "chrome/browser/metrics/user_metrics.h"
11#include "chrome/browser/ui/options/options_util.h"
12#include "chrome/installer/util/google_update_settings.h"
13
14using base::Histogram;
15using base::LinearHistogram;
16
17namespace {
18
19// Build the full name of a metrics for the given extension.  Each metric
20// is made up of the unique name within the extension followed by the
21// extension's id.  This keeps the metrics from one extension unique from
22// other extensions, as well as those metrics from chrome itself.
23std::string BuildMetricName(const std::string& name,
24                            const Extension* extension) {
25  std::string full_name(name);
26  full_name += extension->id();
27  return full_name;
28}
29
30}  // anonymous namespace
31
32// These extension function classes are enabled only if the
33// enable-metrics-extension-api command line switch is used.  Refer to
34// extension_function_dispatcher.cc to see how they are enabled.
35
36bool MetricsSetEnabledFunction::RunImpl() {
37  bool enabled = false;
38  EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(0, &enabled));
39
40  // Using OptionsUtil is better because it actually ensures we reset all the
41  // necessary threads. This is the main way for starting / stopping UMA and
42  // crash reporting.
43  // This method will return the resulting enabled, which we send to JS.
44  bool result = OptionsUtil::ResolveMetricsReportingEnabled(enabled);
45  result_.reset(Value::CreateBooleanValue(result));
46  return true;
47}
48
49bool MetricsGetEnabledFunction::RunImpl() {
50  bool enabled = GoogleUpdateSettings::GetCollectStatsConsent();
51  result_.reset(Value::CreateBooleanValue(enabled));
52  return true;
53}
54
55bool MetricsRecordUserActionFunction::RunImpl() {
56  std::string name;
57  EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &name));
58
59  name = BuildMetricName(name, GetExtension());
60  UserMetrics::RecordComputedAction(name, profile());
61  return true;
62}
63
64bool MetricsHistogramHelperFunction::GetNameAndSample(std::string* name,
65                                                      int* sample) {
66  EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, name));
67  EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(1, sample));
68  return true;
69}
70
71bool MetricsHistogramHelperFunction::RecordValue(const std::string& name,
72                                                 Histogram::ClassType type,
73                                                 int min,
74                                                 int max,
75                                                 size_t buckets,
76                                                 int sample) {
77  std::string full_name = BuildMetricName(name, GetExtension());
78  Histogram* counter;
79  if (type == Histogram::LINEAR_HISTOGRAM) {
80    counter = LinearHistogram::FactoryGet(full_name,
81                                          min,
82                                          max,
83                                          buckets,
84                                          Histogram::kUmaTargetedHistogramFlag);
85  } else {
86    counter = Histogram::FactoryGet(full_name,
87                                    min,
88                                    max,
89                                    buckets,
90                                    Histogram::kUmaTargetedHistogramFlag);
91  }
92
93  counter->Add(sample);
94  return true;
95}
96
97bool MetricsRecordValueFunction::RunImpl() {
98  int sample;
99  EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(1, &sample));
100
101  // Get the histogram parameters from the metric type object.
102  DictionaryValue* metric_type;
103  EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &metric_type));
104
105  std::string name;
106  std::string type;
107  int min;
108  int max;
109  int buckets;
110  EXTENSION_FUNCTION_VALIDATE(metric_type->GetString("metricName", &name));
111  EXTENSION_FUNCTION_VALIDATE(metric_type->GetString("type", &type));
112  EXTENSION_FUNCTION_VALIDATE(metric_type->GetInteger("min", &min));
113  EXTENSION_FUNCTION_VALIDATE(metric_type->GetInteger("max", &max));
114  EXTENSION_FUNCTION_VALIDATE(metric_type->GetInteger("buckets", &buckets));
115
116  Histogram::ClassType histogram_type(type == "histogram-linear" ?
117      Histogram::LINEAR_HISTOGRAM : Histogram::HISTOGRAM);
118  return RecordValue(name, histogram_type, min, max, buckets, sample);
119}
120
121bool MetricsRecordPercentageFunction::RunImpl() {
122  std::string name;
123  int sample;
124  EXTENSION_FUNCTION_VALIDATE(GetNameAndSample(&name, &sample));
125  return RecordValue(name, Histogram::LINEAR_HISTOGRAM, 1, 101, 102, sample);
126}
127
128bool MetricsRecordCountFunction::RunImpl() {
129  std::string name;
130  int sample;
131  EXTENSION_FUNCTION_VALIDATE(GetNameAndSample(&name, &sample));
132  return RecordValue(name, Histogram::HISTOGRAM, 1, 1000000, 50, sample);
133}
134
135bool MetricsRecordSmallCountFunction::RunImpl() {
136  std::string name;
137  int sample;
138  EXTENSION_FUNCTION_VALIDATE(GetNameAndSample(&name, &sample));
139  return RecordValue(name, Histogram::HISTOGRAM, 1, 100, 50, sample);
140}
141
142bool MetricsRecordMediumCountFunction::RunImpl() {
143  std::string name;
144  int sample;
145  EXTENSION_FUNCTION_VALIDATE(GetNameAndSample(&name, &sample));
146  return RecordValue(name, Histogram::HISTOGRAM, 1, 10000, 50, sample);
147}
148
149bool MetricsRecordTimeFunction::RunImpl() {
150  std::string name;
151  int sample;
152  EXTENSION_FUNCTION_VALIDATE(GetNameAndSample(&name, &sample));
153  static const int kTenSecMs = 10 * 1000;
154  return RecordValue(name, Histogram::HISTOGRAM, 1, kTenSecMs, 50, sample);
155}
156
157bool MetricsRecordMediumTimeFunction::RunImpl() {
158  std::string name;
159  int sample;
160  EXTENSION_FUNCTION_VALIDATE(GetNameAndSample(&name, &sample));
161  static const int kThreeMinMs = 3 * 60 * 1000;
162  return RecordValue(name, Histogram::HISTOGRAM, 1, kThreeMinMs, 50, sample);
163}
164
165bool MetricsRecordLongTimeFunction::RunImpl() {
166  std::string name;
167  int sample;
168  EXTENSION_FUNCTION_VALIDATE(GetNameAndSample(&name, &sample));
169  static const int kOneHourMs = 60 * 60 * 1000;
170  return RecordValue(name, Histogram::HISTOGRAM, 1, kOneHourMs, 50, sample);
171}
172