| Index: chromecast/browser/metrics/external_metrics.cc
|
| diff --git a/chromecast/browser/metrics/external_metrics.cc b/chromecast/browser/metrics/external_metrics.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..18e7ec0ff0f72899ce6f6289ae2e18e5f7e4aae1
|
| --- /dev/null
|
| +++ b/chromecast/browser/metrics/external_metrics.cc
|
| @@ -0,0 +1,152 @@
|
| +// Copyright 2014 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 "chromecast/browser/metrics/external_metrics.h"
|
| +
|
| +#include <string>
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/files/file_path.h"
|
| +#include "base/files/file_util.h"
|
| +#include "base/metrics/histogram.h"
|
| +#include "base/metrics/sparse_histogram.h"
|
| +#include "base/metrics/statistics_recorder.h"
|
| +#include "base/timer/elapsed_timer.h"
|
| +#include "chromecast/base/metrics/cast_histograms.h"
|
| +#include "chromecast/browser/metrics/cast_stability_metrics_provider.h"
|
| +#include "components/metrics/metrics_service.h"
|
| +#include "components/metrics/serialization/metric_sample.h"
|
| +#include "components/metrics/serialization/serialization_utils.h"
|
| +#include "content/public/browser/browser_thread.h"
|
| +#include "content/public/browser/user_metrics.h"
|
| +
|
| +namespace chromecast {
|
| +namespace metrics {
|
| +
|
| +namespace {
|
| +
|
| +bool CheckValues(const std::string& name,
|
| + int minimum,
|
| + int maximum,
|
| + size_t bucket_count) {
|
| + if (!base::Histogram::InspectConstructionArguments(
|
| + name, &minimum, &maximum, &bucket_count))
|
| + return false;
|
| + base::HistogramBase* histogram =
|
| + base::StatisticsRecorder::FindHistogram(name);
|
| + if (!histogram)
|
| + return true;
|
| + return histogram->HasConstructionArguments(minimum, maximum, bucket_count);
|
| +}
|
| +
|
| +bool CheckLinearValues(const std::string& name, int maximum) {
|
| + return CheckValues(name, 1, maximum, maximum + 1);
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +// The interval between external metrics collections in seconds
|
| +static const int kExternalMetricsCollectionIntervalSeconds = 30;
|
| +const char kEventsFilePath[] = "/data/share/chrome/metrics/uma-events";
|
| +
|
| +ExternalMetrics::ExternalMetrics(
|
| + CastStabilityMetricsProvider* stability_provider)
|
| + : stability_provider_(stability_provider),
|
| + uma_events_file_(kEventsFilePath),
|
| + weak_factory_(this) {
|
| + DCHECK(stability_provider);
|
| +}
|
| +
|
| +ExternalMetrics::~ExternalMetrics() {}
|
| +
|
| +void ExternalMetrics::Start() {
|
| + ScheduleCollector();
|
| +}
|
| +
|
| +void ExternalMetrics::RecordAction(const std::string& action) {
|
| + content::BrowserThread::PostTask(
|
| + content::BrowserThread::UI,
|
| + FROM_HERE,
|
| + base::Bind(&content::RecordComputedAction, action));
|
| +}
|
| +
|
| +void ExternalMetrics::RecordCrash(const std::string& crash_kind) {
|
| + content::BrowserThread::PostTask(
|
| + content::BrowserThread::UI, FROM_HERE,
|
| + base::Bind(&CastStabilityMetricsProvider::LogExternalCrash,
|
| + base::Unretained(stability_provider_),
|
| + crash_kind));
|
| +}
|
| +
|
| +void ExternalMetrics::RecordSparseHistogram(
|
| + const ::metrics::MetricSample& sample) {
|
| + CHECK_EQ(::metrics::MetricSample::SPARSE_HISTOGRAM, sample.type());
|
| + base::HistogramBase* counter = base::SparseHistogram::FactoryGet(
|
| + sample.name(), base::HistogramBase::kUmaTargetedHistogramFlag);
|
| + counter->Add(sample.sample());
|
| +}
|
| +
|
| +int ExternalMetrics::CollectEvents() {
|
| + ScopedVector< ::metrics::MetricSample> samples;
|
| + ::metrics::SerializationUtils::ReadAndTruncateMetricsFromFile(
|
| + uma_events_file_, &samples);
|
| +
|
| + for (ScopedVector< ::metrics::MetricSample>::iterator it = samples.begin();
|
| + it != samples.end();
|
| + ++it) {
|
| + const ::metrics::MetricSample& sample = **it;
|
| +
|
| + switch (sample.type()) {
|
| + case ::metrics::MetricSample::CRASH:
|
| + RecordCrash(sample.name());
|
| + break;
|
| + case ::metrics::MetricSample::USER_ACTION:
|
| + RecordAction(sample.name());
|
| + break;
|
| + case ::metrics::MetricSample::HISTOGRAM:
|
| + if (!CheckValues(sample.name(), sample.min(), sample.max(),
|
| + sample.bucket_count())) {
|
| + DLOG(ERROR) << "Invalid histogram: " << sample.name();
|
| + break;
|
| + }
|
| + UMA_HISTOGRAM_CUSTOM_COUNTS_NO_CACHE(
|
| + sample.name(), sample.sample(), sample.min(), sample.max(),
|
| + sample.bucket_count());
|
| + break;
|
| + case ::metrics::MetricSample::LINEAR_HISTOGRAM:
|
| + if (!CheckLinearValues(sample.name(), sample.max())) {
|
| + DLOG(ERROR) << "Invalid linear histogram: " << sample.name();
|
| + break;
|
| + }
|
| + UMA_HISTOGRAM_ENUMERATION_NO_CACHE(
|
| + sample.name(), sample.sample(), sample.max());
|
| + break;
|
| + case ::metrics::MetricSample::SPARSE_HISTOGRAM:
|
| + RecordSparseHistogram(sample);
|
| + break;
|
| + }
|
| + }
|
| +
|
| + return samples.size();
|
| +}
|
| +
|
| +void ExternalMetrics::CollectEventsAndReschedule() {
|
| + base::ElapsedTimer timer;
|
| + CollectEvents();
|
| + UMA_HISTOGRAM_TIMES("UMA.CollectExternalEventsTime", timer.Elapsed());
|
| + ScheduleCollector();
|
| +}
|
| +
|
| +void ExternalMetrics::ScheduleCollector() {
|
| + bool result = content::BrowserThread::PostDelayedTask(
|
| + content::BrowserThread::FILE,
|
| + FROM_HERE,
|
| + base::Bind(&ExternalMetrics::CollectEventsAndReschedule,
|
| + weak_factory_.GetWeakPtr()),
|
| + base::TimeDelta::FromSeconds(kExternalMetricsCollectionIntervalSeconds));
|
| + DCHECK(result);
|
| +}
|
| +
|
| +} // namespace metrics
|
| +} // namespace chromecast
|
|
|