// 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);
}