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