// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/browser/extensions/extension_metrics_module.h" #include "base/metrics/histogram.h" #include "base/values.h" #include "chrome/common/extensions/extension.h" #include "chrome/browser/metrics/user_metrics.h" #include "chrome/browser/ui/options/options_util.h" #include "chrome/installer/util/google_update_settings.h" using base::Histogram; using base::LinearHistogram; namespace { // Build the full name of a metrics for the given extension. Each metric // is made up of the unique name within the extension followed by the // extension's id. This keeps the metrics from one extension unique from // other extensions, as well as those metrics from chrome itself. std::string BuildMetricName(const std::string& name, const Extension* extension) { std::string full_name(name); full_name += extension->id(); return full_name; } } // anonymous namespace // These extension function classes are enabled only if the // enable-metrics-extension-api command line switch is used. Refer to // extension_function_dispatcher.cc to see how they are enabled. bool MetricsSetEnabledFunction::RunImpl() { bool enabled = false; EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(0, &enabled)); // Using OptionsUtil is better because it actually ensures we reset all the // necessary threads. This is the main way for starting / stopping UMA and // crash reporting. // This method will return the resulting enabled, which we send to JS. bool result = OptionsUtil::ResolveMetricsReportingEnabled(enabled); result_.reset(Value::CreateBooleanValue(result)); return true; } bool MetricsGetEnabledFunction::RunImpl() { bool enabled = GoogleUpdateSettings::GetCollectStatsConsent(); result_.reset(Value::CreateBooleanValue(enabled)); return true; } bool MetricsRecordUserActionFunction::RunImpl() { std::string name; EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &name)); name = BuildMetricName(name, GetExtension()); UserMetrics::RecordComputedAction(name, profile()); return true; } bool MetricsHistogramHelperFunction::GetNameAndSample(std::string* name, int* sample) { EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, name)); EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(1, sample)); return true; } bool MetricsHistogramHelperFunction::RecordValue(const std::string& name, Histogram::ClassType type, int min, int max, size_t buckets, int sample) { std::string full_name = BuildMetricName(name, GetExtension()); Histogram* counter; if (type == Histogram::LINEAR_HISTOGRAM) { counter = LinearHistogram::FactoryGet(full_name, min, max, buckets, Histogram::kUmaTargetedHistogramFlag); } else { counter = Histogram::FactoryGet(full_name, min, max, buckets, Histogram::kUmaTargetedHistogramFlag); } counter->Add(sample); return true; } bool MetricsRecordValueFunction::RunImpl() { int sample; EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(1, &sample)); // Get the histogram parameters from the metric type object. DictionaryValue* metric_type; EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &metric_type)); std::string name; std::string type; int min; int max; int buckets; EXTENSION_FUNCTION_VALIDATE(metric_type->GetString("metricName", &name)); EXTENSION_FUNCTION_VALIDATE(metric_type->GetString("type", &type)); EXTENSION_FUNCTION_VALIDATE(metric_type->GetInteger("min", &min)); EXTENSION_FUNCTION_VALIDATE(metric_type->GetInteger("max", &max)); EXTENSION_FUNCTION_VALIDATE(metric_type->GetInteger("buckets", &buckets)); Histogram::ClassType histogram_type(type == "histogram-linear" ? Histogram::LINEAR_HISTOGRAM : Histogram::HISTOGRAM); return RecordValue(name, histogram_type, min, max, buckets, sample); } bool MetricsRecordPercentageFunction::RunImpl() { std::string name; int sample; EXTENSION_FUNCTION_VALIDATE(GetNameAndSample(&name, &sample)); return RecordValue(name, Histogram::LINEAR_HISTOGRAM, 1, 101, 102, sample); } bool MetricsRecordCountFunction::RunImpl() { std::string name; int sample; EXTENSION_FUNCTION_VALIDATE(GetNameAndSample(&name, &sample)); return RecordValue(name, Histogram::HISTOGRAM, 1, 1000000, 50, sample); } bool MetricsRecordSmallCountFunction::RunImpl() { std::string name; int sample; EXTENSION_FUNCTION_VALIDATE(GetNameAndSample(&name, &sample)); return RecordValue(name, Histogram::HISTOGRAM, 1, 100, 50, sample); } bool MetricsRecordMediumCountFunction::RunImpl() { std::string name; int sample; EXTENSION_FUNCTION_VALIDATE(GetNameAndSample(&name, &sample)); return RecordValue(name, Histogram::HISTOGRAM, 1, 10000, 50, sample); } bool MetricsRecordTimeFunction::RunImpl() { std::string name; int sample; EXTENSION_FUNCTION_VALIDATE(GetNameAndSample(&name, &sample)); static const int kTenSecMs = 10 * 1000; return RecordValue(name, Histogram::HISTOGRAM, 1, kTenSecMs, 50, sample); } bool MetricsRecordMediumTimeFunction::RunImpl() { std::string name; int sample; EXTENSION_FUNCTION_VALIDATE(GetNameAndSample(&name, &sample)); static const int kThreeMinMs = 3 * 60 * 1000; return RecordValue(name, Histogram::HISTOGRAM, 1, kThreeMinMs, 50, sample); } bool MetricsRecordLongTimeFunction::RunImpl() { std::string name; int sample; EXTENSION_FUNCTION_VALIDATE(GetNameAndSample(&name, &sample)); static const int kOneHourMs = 60 * 60 * 1000; return RecordValue(name, Histogram::HISTOGRAM, 1, kOneHourMs, 50, sample); }