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/prefs/pref_service.h"
     12 #include "chrome/browser/browser_process.h"
     13 #include "chrome/common/extensions/api/metrics_private.h"
     14 #include "chrome/common/extensions/extension.h"
     15 #include "chrome/common/metrics/variations/variations_associated_data.h"
     16 #include "chrome/common/pref_names.h"
     17 #include "content/public/browser/user_metrics.h"
     18 
     19 #if defined(OS_CHROMEOS)
     20 #include "chrome/browser/chromeos/settings/cros_settings.h"
     21 #endif  // OS_CHROMEOS
     22 
     23 namespace extensions {
     24 
     25 namespace GetIsCrashReportingEnabled =
     26     api::metrics_private::GetIsCrashReportingEnabled;
     27 namespace GetVariationParams = api::metrics_private::GetVariationParams;
     28 namespace GetFieldTrial = api::metrics_private::GetFieldTrial;
     29 namespace RecordUserAction = api::metrics_private::RecordUserAction;
     30 namespace RecordValue = api::metrics_private::RecordValue;
     31 namespace RecordPercentage = api::metrics_private::RecordPercentage;
     32 namespace RecordCount = api::metrics_private::RecordCount;
     33 namespace RecordSmallCount = api::metrics_private::RecordSmallCount;
     34 namespace RecordMediumCount = api::metrics_private::RecordMediumCount;
     35 namespace RecordTime = api::metrics_private::RecordTime;
     36 namespace RecordMediumTime = api::metrics_private::RecordMediumTime;
     37 namespace RecordLongTime = api::metrics_private::RecordLongTime;
     38 
     39 namespace {
     40 
     41 const size_t kMaxBuckets = 10000; // We don't ever want more than these many
     42                                   // buckets; there is no real need for them
     43                                   // and would cause crazy memory usage
     44 } // namespace
     45 
     46 // Returns true if the user opted in to sending crash reports.
     47 // TODO(vadimt): Unify with CrashesUI::CrashReportingUIEnabled
     48 static bool IsCrashReportingEnabled() {
     49 #if defined(GOOGLE_CHROME_BUILD)
     50 #if defined(OS_CHROMEOS)
     51   bool reporting_enabled = false;
     52   chromeos::CrosSettings::Get()->GetBoolean(chromeos::kStatsReportingPref,
     53                                             &reporting_enabled);
     54   return reporting_enabled;
     55 #elif defined(OS_ANDROID)
     56   // Android has its own settings for metrics / crash uploading.
     57   PrefService* prefs = g_browser_process->local_state();
     58   return prefs->GetBoolean(prefs::kCrashReportingEnabled);
     59 #else
     60   PrefService* prefs = g_browser_process->local_state();
     61   return prefs->GetBoolean(prefs::kMetricsReportingEnabled);
     62 #endif
     63 #else
     64   return false;
     65 #endif
     66 }
     67 
     68 bool MetricsPrivateGetIsCrashReportingEnabledFunction::RunImpl() {
     69   SetResult(new base::FundamentalValue(IsCrashReportingEnabled()));
     70   return true;
     71 }
     72 
     73 bool MetricsPrivateGetFieldTrialFunction::RunImpl() {
     74   std::string name;
     75   EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &name));
     76 
     77   SetResult(new base::StringValue(base::FieldTrialList::FindFullName(name)));
     78   return true;
     79 }
     80 
     81 bool MetricsPrivateGetVariationParamsFunction::RunImpl() {
     82   scoped_ptr<GetVariationParams::Params> params(
     83       GetVariationParams::Params::Create(*args_));
     84   EXTENSION_FUNCTION_VALIDATE(params.get());
     85 
     86   GetVariationParams::Results::Params result;
     87   if (!chrome_variations::GetVariationParams(
     88       params->name, &result.additional_properties)) {
     89     SetError("Variation parameters are unavailable.");
     90     return false;
     91   }
     92 
     93   SetResult(result.ToValue().release());
     94   return true;
     95 }
     96 
     97 bool MetricsPrivateRecordUserActionFunction::RunImpl() {
     98   scoped_ptr<RecordUserAction::Params> params(
     99       RecordUserAction::Params::Create(*args_));
    100   EXTENSION_FUNCTION_VALIDATE(params.get());
    101 
    102   content::RecordComputedAction(params->name);
    103   return true;
    104 }
    105 
    106 bool MetricsHistogramHelperFunction::GetNameAndSample(std::string* name,
    107                                                       int* sample) {
    108   EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, name));
    109   EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(1, sample));
    110   return true;
    111 }
    112 
    113 bool MetricsHistogramHelperFunction::RecordValue(
    114     const std::string& name,
    115     base::HistogramType type,
    116     int min, int max, size_t buckets,
    117     int sample) {
    118   // Make sure toxic values don't get to internal code.
    119   // Fix for maximums
    120   min = std::min(min, INT_MAX - 3);
    121   max = std::min(max, INT_MAX - 3);
    122   buckets = std::min(buckets, kMaxBuckets);
    123   // Fix for minimums.
    124   min = std::max(min, 1);
    125   max = std::max(max, min + 1);
    126   buckets = std::max(buckets, static_cast<size_t>(3));
    127   // Trim buckets down to a maximum of the given range + over/underflow buckets
    128   if (buckets > static_cast<size_t>(max - min + 2))
    129     buckets = max - min + 2;
    130 
    131   base::HistogramBase* counter;
    132   if (type == base::LINEAR_HISTOGRAM) {
    133     counter = base::LinearHistogram::FactoryGet(
    134         name, min, max, buckets,
    135         base::HistogramBase::kUmaTargetedHistogramFlag);
    136   } else {
    137     counter = base::Histogram::FactoryGet(
    138         name, min, max, buckets,
    139         base::HistogramBase::kUmaTargetedHistogramFlag);
    140   }
    141 
    142   counter->Add(sample);
    143   return true;
    144 }
    145 
    146 bool MetricsPrivateRecordValueFunction::RunImpl() {
    147   scoped_ptr<RecordValue::Params> params(RecordValue::Params::Create(*args_));
    148   EXTENSION_FUNCTION_VALIDATE(params.get());
    149 
    150   // Get the histogram parameters from the metric type object.
    151   std::string type = api::metrics_private::MetricType::ToString(
    152       params->metric.type);
    153 
    154   base::HistogramType histogram_type(type == "histogram-linear" ?
    155       base::LINEAR_HISTOGRAM : base::HISTOGRAM);
    156   return RecordValue(params->metric.metric_name, histogram_type,
    157                      params->metric.min, params->metric.max,
    158                      params->metric.buckets, params->value);
    159 }
    160 
    161 bool MetricsPrivateRecordPercentageFunction::RunImpl() {
    162   scoped_ptr<RecordPercentage::Params> params(
    163       RecordPercentage::Params::Create(*args_));
    164   EXTENSION_FUNCTION_VALIDATE(params.get());
    165   return RecordValue(params->metric_name, base::LINEAR_HISTOGRAM,
    166                      1, 101, 102, params->value);
    167 }
    168 
    169 bool MetricsPrivateRecordCountFunction::RunImpl() {
    170   scoped_ptr<RecordCount::Params> params(RecordCount::Params::Create(*args_));
    171   EXTENSION_FUNCTION_VALIDATE(params.get());
    172   return RecordValue(params->metric_name, base::HISTOGRAM,
    173                      1, 1000000, 50, params->value);
    174 }
    175 
    176 bool MetricsPrivateRecordSmallCountFunction::RunImpl() {
    177   scoped_ptr<RecordSmallCount::Params> params(
    178       RecordSmallCount::Params::Create(*args_));
    179   EXTENSION_FUNCTION_VALIDATE(params.get());
    180   return RecordValue(params->metric_name, base::HISTOGRAM,
    181                      1, 100, 50, params->value);
    182 }
    183 
    184 bool MetricsPrivateRecordMediumCountFunction::RunImpl() {
    185   scoped_ptr<RecordMediumCount::Params> params(
    186       RecordMediumCount::Params::Create(*args_));
    187   EXTENSION_FUNCTION_VALIDATE(params.get());
    188   return RecordValue(params->metric_name, base::HISTOGRAM,
    189                      1, 10000, 50, params->value);
    190 }
    191 
    192 bool MetricsPrivateRecordTimeFunction::RunImpl() {
    193   scoped_ptr<RecordTime::Params> params(RecordTime::Params::Create(*args_));
    194   EXTENSION_FUNCTION_VALIDATE(params.get());
    195   static const int kTenSecMs = 10 * 1000;
    196   return RecordValue(params->metric_name, base::HISTOGRAM,
    197                      1, kTenSecMs, 50, params->value);
    198 }
    199 
    200 bool MetricsPrivateRecordMediumTimeFunction::RunImpl() {
    201   scoped_ptr<RecordMediumTime::Params> params(
    202       RecordMediumTime::Params::Create(*args_));
    203   EXTENSION_FUNCTION_VALIDATE(params.get());
    204   static const int kThreeMinMs = 3 * 60 * 1000;
    205   return RecordValue(params->metric_name, base::HISTOGRAM,
    206                      1, kThreeMinMs, 50, params->value);
    207 }
    208 
    209 bool MetricsPrivateRecordLongTimeFunction::RunImpl() {
    210   scoped_ptr<RecordLongTime::Params> params(
    211       RecordLongTime::Params::Create(*args_));
    212   EXTENSION_FUNCTION_VALIDATE(params.get());
    213   static const int kOneHourMs = 60 * 60 * 1000;
    214   return RecordValue(params->metric_name, base::HISTOGRAM,
    215                      1, kOneHourMs, 50, params->value);
    216 }
    217 
    218 } // namespace extensions
    219