1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_metrics_module.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/metrics/histogram.h"
83345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/values.h"
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/extensions/extension.h"
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/metrics/user_metrics.h"
1172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/options/options_util.h"
1272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/installer/util/google_update_settings.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
14731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickusing base::Histogram;
15731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickusing base::LinearHistogram;
16731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Build the full name of a metrics for the given extension.  Each metric
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// is made up of the unique name within the extension followed by the
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// extension's id.  This keeps the metrics from one extension unique from
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// other extensions, as well as those metrics from chrome itself.
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string BuildMetricName(const std::string& name,
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            const Extension* extension) {
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string full_name(name);
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  full_name += extension->id();
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return full_name;
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // anonymous namespace
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// These extension function classes are enabled only if the
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// enable-metrics-extension-api command line switch is used.  Refer to
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// extension_function_dispatcher.cc to see how they are enabled.
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool MetricsSetEnabledFunction::RunImpl() {
3772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  bool enabled = false;
3872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(0, &enabled));
3972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
4072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Using OptionsUtil is better because it actually ensures we reset all the
4172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // necessary threads. This is the main way for starting / stopping UMA and
4272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // crash reporting.
4372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // This method will return the resulting enabled, which we send to JS.
4472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  bool result = OptionsUtil::ResolveMetricsReportingEnabled(enabled);
4572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  result_.reset(Value::CreateBooleanValue(result));
4672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return true;
4772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
4872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
4972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool MetricsGetEnabledFunction::RunImpl() {
5072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  bool enabled = GoogleUpdateSettings::GetCollectStatsConsent();
5172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  result_.reset(Value::CreateBooleanValue(enabled));
5272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return true;
5372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
5472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool MetricsRecordUserActionFunction::RunImpl() {
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string name;
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &name));
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  name = BuildMetricName(name, GetExtension());
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordComputedAction(name, profile());
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool MetricsHistogramHelperFunction::GetNameAndSample(std::string* name,
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                      int* sample) {
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, name));
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(1, sample));
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool MetricsHistogramHelperFunction::RecordValue(const std::string& name,
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                 Histogram::ClassType type,
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                 int min,
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                 int max,
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                 size_t buckets,
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                 int sample) {
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string full_name = BuildMetricName(name, GetExtension());
78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Histogram* counter;
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (type == Histogram::LINEAR_HISTOGRAM) {
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    counter = LinearHistogram::FactoryGet(full_name,
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          min,
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          max,
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          buckets,
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          Histogram::kUmaTargetedHistogramFlag);
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    counter = Histogram::FactoryGet(full_name,
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    min,
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    max,
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    buckets,
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    Histogram::kUmaTargetedHistogramFlag);
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  counter->Add(sample);
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool MetricsRecordValueFunction::RunImpl() {
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int sample;
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(1, &sample));
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Get the histogram parameters from the metric type object.
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DictionaryValue* metric_type;
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &metric_type));
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string name;
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string type;
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int min;
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int max;
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int buckets;
1103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXTENSION_FUNCTION_VALIDATE(metric_type->GetString("metricName", &name));
1113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXTENSION_FUNCTION_VALIDATE(metric_type->GetString("type", &type));
1123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXTENSION_FUNCTION_VALIDATE(metric_type->GetInteger("min", &min));
1133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXTENSION_FUNCTION_VALIDATE(metric_type->GetInteger("max", &max));
1143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXTENSION_FUNCTION_VALIDATE(metric_type->GetInteger("buckets", &buckets));
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Histogram::ClassType histogram_type(type == "histogram-linear" ?
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      Histogram::LINEAR_HISTOGRAM : Histogram::HISTOGRAM);
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return RecordValue(name, histogram_type, min, max, buckets, sample);
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool MetricsRecordPercentageFunction::RunImpl() {
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string name;
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int sample;
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXTENSION_FUNCTION_VALIDATE(GetNameAndSample(&name, &sample));
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return RecordValue(name, Histogram::LINEAR_HISTOGRAM, 1, 101, 102, sample);
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool MetricsRecordCountFunction::RunImpl() {
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string name;
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int sample;
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXTENSION_FUNCTION_VALIDATE(GetNameAndSample(&name, &sample));
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return RecordValue(name, Histogram::HISTOGRAM, 1, 1000000, 50, sample);
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool MetricsRecordSmallCountFunction::RunImpl() {
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string name;
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int sample;
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXTENSION_FUNCTION_VALIDATE(GetNameAndSample(&name, &sample));
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return RecordValue(name, Histogram::HISTOGRAM, 1, 100, 50, sample);
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool MetricsRecordMediumCountFunction::RunImpl() {
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string name;
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int sample;
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXTENSION_FUNCTION_VALIDATE(GetNameAndSample(&name, &sample));
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return RecordValue(name, Histogram::HISTOGRAM, 1, 10000, 50, sample);
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool MetricsRecordTimeFunction::RunImpl() {
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string name;
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int sample;
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXTENSION_FUNCTION_VALIDATE(GetNameAndSample(&name, &sample));
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const int kTenSecMs = 10 * 1000;
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return RecordValue(name, Histogram::HISTOGRAM, 1, kTenSecMs, 50, sample);
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool MetricsRecordMediumTimeFunction::RunImpl() {
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string name;
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int sample;
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXTENSION_FUNCTION_VALIDATE(GetNameAndSample(&name, &sample));
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const int kThreeMinMs = 3 * 60 * 1000;
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return RecordValue(name, Histogram::HISTOGRAM, 1, kThreeMinMs, 50, sample);
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool MetricsRecordLongTimeFunction::RunImpl() {
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string name;
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int sample;
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXTENSION_FUNCTION_VALIDATE(GetNameAndSample(&name, &sample));
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const int kOneHourMs = 60 * 60 * 1000;
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return RecordValue(name, Histogram::HISTOGRAM, 1, kOneHourMs, 50, sample);
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
172