Home | History | Annotate | Download | only in metrics_private
      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 
     42 bool MetricsPrivateGetIsCrashReportingEnabledFunction::RunSync() {
     43   SetResult(new base::FundamentalValue(
     44       ChromeMetricsServiceAccessor::IsCrashReportingEnabled()));
     45   return true;
     46 }
     47 
     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 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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