• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 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/api/metrics_private/metrics_private_api.h"
6 
7 #include <algorithm>
8 
9 #include "base/metrics/field_trial.h"
10 #include "base/metrics/histogram.h"
11 #include "base/metrics/sparse_histogram.h"
12 #include "chrome/browser/metrics/chrome_metrics_service_accessor.h"
13 #include "chrome/common/extensions/api/metrics_private.h"
14 #include "components/variations/variations_associated_data.h"
15 #include "content/public/browser/user_metrics.h"
16 #include "extensions/common/extension.h"
17 
18 namespace extensions {
19 
20 namespace GetIsCrashReportingEnabled =
21     api::metrics_private::GetIsCrashReportingEnabled;
22 namespace GetVariationParams = api::metrics_private::GetVariationParams;
23 namespace GetFieldTrial = api::metrics_private::GetFieldTrial;
24 namespace RecordUserAction = api::metrics_private::RecordUserAction;
25 namespace RecordValue = api::metrics_private::RecordValue;
26 namespace RecordSparseValue = api::metrics_private::RecordSparseValue;
27 namespace RecordPercentage = api::metrics_private::RecordPercentage;
28 namespace RecordCount = api::metrics_private::RecordCount;
29 namespace RecordSmallCount = api::metrics_private::RecordSmallCount;
30 namespace RecordMediumCount = api::metrics_private::RecordMediumCount;
31 namespace RecordTime = api::metrics_private::RecordTime;
32 namespace RecordMediumTime = api::metrics_private::RecordMediumTime;
33 namespace RecordLongTime = api::metrics_private::RecordLongTime;
34 
35 namespace {
36 
37 const size_t kMaxBuckets = 10000; // We don't ever want more than these many
38                                   // buckets; there is no real need for them
39                                   // and would cause crazy memory usage
40 } // namespace
41 
RunSync()42 bool MetricsPrivateGetIsCrashReportingEnabledFunction::RunSync() {
43   SetResult(new base::FundamentalValue(
44       ChromeMetricsServiceAccessor::IsCrashReportingEnabled()));
45   return true;
46 }
47 
RunSync()48 bool MetricsPrivateGetFieldTrialFunction::RunSync() {
49   std::string name;
50   EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &name));
51 
52   SetResult(new base::StringValue(base::FieldTrialList::FindFullName(name)));
53   return true;
54 }
55 
RunSync()56 bool MetricsPrivateGetVariationParamsFunction::RunSync() {
57   scoped_ptr<GetVariationParams::Params> params(
58       GetVariationParams::Params::Create(*args_));
59   EXTENSION_FUNCTION_VALIDATE(params.get());
60 
61   GetVariationParams::Results::Params result;
62   if (chrome_variations::GetVariationParams(
63       params->name, &result.additional_properties)) {
64     SetResult(result.ToValue().release());
65   }
66   return true;
67 }
68 
RunSync()69 bool MetricsPrivateRecordUserActionFunction::RunSync() {
70   scoped_ptr<RecordUserAction::Params> params(
71       RecordUserAction::Params::Create(*args_));
72   EXTENSION_FUNCTION_VALIDATE(params.get());
73 
74   content::RecordComputedAction(params->name);
75   return true;
76 }
77 
RecordValue(const std::string & name,base::HistogramType type,int min,int max,size_t buckets,int sample)78 bool MetricsHistogramHelperFunction::RecordValue(
79     const std::string& name,
80     base::HistogramType type,
81     int min, int max, size_t buckets,
82     int sample) {
83   // Make sure toxic values don't get to internal code.
84   // Fix for maximums
85   min = std::min(min, INT_MAX - 3);
86   max = std::min(max, INT_MAX - 3);
87   buckets = std::min(buckets, kMaxBuckets);
88   // Fix for minimums.
89   min = std::max(min, 1);
90   max = std::max(max, min + 1);
91   buckets = std::max(buckets, static_cast<size_t>(3));
92   // Trim buckets down to a maximum of the given range + over/underflow buckets
93   if (buckets > static_cast<size_t>(max - min + 2))
94     buckets = max - min + 2;
95 
96   base::HistogramBase* counter;
97   if (type == base::LINEAR_HISTOGRAM) {
98     counter = base::LinearHistogram::FactoryGet(
99         name, min, max, buckets,
100         base::HistogramBase::kUmaTargetedHistogramFlag);
101   } else {
102     counter = base::Histogram::FactoryGet(
103         name, min, max, buckets,
104         base::HistogramBase::kUmaTargetedHistogramFlag);
105   }
106 
107   // The histogram can be NULL if it is constructed with bad arguments.  Ignore
108   // that data for this API.  An error message will be logged.
109   if (counter)
110     counter->Add(sample);
111   return true;
112 }
113 
RunSync()114 bool MetricsPrivateRecordValueFunction::RunSync() {
115   scoped_ptr<RecordValue::Params> params(RecordValue::Params::Create(*args_));
116   EXTENSION_FUNCTION_VALIDATE(params.get());
117 
118   // Get the histogram parameters from the metric type object.
119   std::string type = api::metrics_private::MetricType::ToString(
120       params->metric.type);
121 
122   base::HistogramType histogram_type(type == "histogram-linear" ?
123       base::LINEAR_HISTOGRAM : base::HISTOGRAM);
124   return RecordValue(params->metric.metric_name, histogram_type,
125                      params->metric.min, params->metric.max,
126                      params->metric.buckets, params->value);
127 }
128 
RunSync()129 bool MetricsPrivateRecordSparseValueFunction::RunSync() {
130   scoped_ptr<RecordSparseValue::Params> params(
131       RecordSparseValue::Params::Create(*args_));
132   EXTENSION_FUNCTION_VALIDATE(params.get());
133   // This particular UMA_HISTOGRAM_ macro is okay for
134   // non-runtime-constant strings.
135   UMA_HISTOGRAM_SPARSE_SLOWLY(params->metric_name, params->value);
136   return true;
137 }
138 
RunSync()139 bool MetricsPrivateRecordPercentageFunction::RunSync() {
140   scoped_ptr<RecordPercentage::Params> params(
141       RecordPercentage::Params::Create(*args_));
142   EXTENSION_FUNCTION_VALIDATE(params.get());
143   return RecordValue(params->metric_name, base::LINEAR_HISTOGRAM,
144                      1, 101, 102, params->value);
145 }
146 
RunSync()147 bool MetricsPrivateRecordCountFunction::RunSync() {
148   scoped_ptr<RecordCount::Params> params(RecordCount::Params::Create(*args_));
149   EXTENSION_FUNCTION_VALIDATE(params.get());
150   return RecordValue(params->metric_name, base::HISTOGRAM,
151                      1, 1000000, 50, params->value);
152 }
153 
RunSync()154 bool MetricsPrivateRecordSmallCountFunction::RunSync() {
155   scoped_ptr<RecordSmallCount::Params> params(
156       RecordSmallCount::Params::Create(*args_));
157   EXTENSION_FUNCTION_VALIDATE(params.get());
158   return RecordValue(params->metric_name, base::HISTOGRAM,
159                      1, 100, 50, params->value);
160 }
161 
RunSync()162 bool MetricsPrivateRecordMediumCountFunction::RunSync() {
163   scoped_ptr<RecordMediumCount::Params> params(
164       RecordMediumCount::Params::Create(*args_));
165   EXTENSION_FUNCTION_VALIDATE(params.get());
166   return RecordValue(params->metric_name, base::HISTOGRAM,
167                      1, 10000, 50, params->value);
168 }
169 
RunSync()170 bool MetricsPrivateRecordTimeFunction::RunSync() {
171   scoped_ptr<RecordTime::Params> params(RecordTime::Params::Create(*args_));
172   EXTENSION_FUNCTION_VALIDATE(params.get());
173   static const int kTenSecMs = 10 * 1000;
174   return RecordValue(params->metric_name, base::HISTOGRAM,
175                      1, kTenSecMs, 50, params->value);
176 }
177 
RunSync()178 bool MetricsPrivateRecordMediumTimeFunction::RunSync() {
179   scoped_ptr<RecordMediumTime::Params> params(
180       RecordMediumTime::Params::Create(*args_));
181   EXTENSION_FUNCTION_VALIDATE(params.get());
182   static const int kThreeMinMs = 3 * 60 * 1000;
183   return RecordValue(params->metric_name, base::HISTOGRAM,
184                      1, kThreeMinMs, 50, params->value);
185 }
186 
RunSync()187 bool MetricsPrivateRecordLongTimeFunction::RunSync() {
188   scoped_ptr<RecordLongTime::Params> params(
189       RecordLongTime::Params::Create(*args_));
190   EXTENSION_FUNCTION_VALIDATE(params.get());
191   static const int kOneHourMs = 60 * 60 * 1000;
192   return RecordValue(params->metric_name, base::HISTOGRAM,
193                      1, kOneHourMs, 50, params->value);
194 }
195 
196 } // namespace extensions
197