| Index: components/metrics/daily_interval.cc
|
| diff --git a/components/metrics/daily_interval.cc b/components/metrics/daily_interval.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..386a01592464215653b94784693f0b1fcdf6f12a
|
| --- /dev/null
|
| +++ b/components/metrics/daily_interval.cc
|
| @@ -0,0 +1,100 @@
|
| +// 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 "components/metrics/daily_interval.h"
|
| +
|
| +#include "base/i18n/time_formatting.h"
|
| +#include "base/metrics/histogram.h"
|
| +#include "base/prefs/pref_registry_simple.h"
|
| +#include "base/prefs/pref_service.h"
|
| +
|
| +namespace metrics {
|
| +
|
| +namespace {
|
| +
|
| +enum IntervalType {
|
| + FIRST_RUN,
|
| + DAY_ELAPSED,
|
| + CLOCK_CHANGED,
|
| + NUM_INTERVAL_TYPES
|
| +};
|
| +
|
| +void RecordIntervalTypeHistogram(const std::string& histogram_name,
|
| + IntervalType t) {
|
| + base::Histogram::FactoryGet(
|
| + histogram_name,
|
| + 1,
|
| + NUM_INTERVAL_TYPES,
|
| + NUM_INTERVAL_TYPES + 1,
|
| + base::HistogramBase::kUmaTargetedHistogramFlag)->Add(t);
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +DailyInterval::DailyInterval(PrefService* pref_service,
|
| + const char* pref_name,
|
| + const std::string& histogram_name)
|
| + : pref_service_(pref_service),
|
| + pref_name_(pref_name),
|
| + histogram_name_(histogram_name) {
|
| +}
|
| +
|
| +DailyInterval::~DailyInterval() {
|
| +}
|
| +
|
| +// static
|
| +void DailyInterval::RegisterPref(PrefRegistrySimple* registry,
|
| + const char* pref_name) {
|
| + registry->RegisterInt64Pref(pref_name, base::Time().ToInternalValue());
|
| +}
|
| +
|
| +void DailyInterval::AddObserver(DailyObserver* observer) {
|
| + DVLOG(2) << "DailyInterval observer added.";
|
| + DCHECK(last_fired_.is_null());
|
| + observers_.push_back(observer);
|
| +}
|
| +
|
| +void DailyInterval::CheckInterval() {
|
| + base::Time now = base::Time::Now();
|
| + if (last_fired_.is_null()) {
|
| + // The first time we call CheckInterval, we read the time stored in prefs.
|
| + last_fired_ = base::Time::FromInternalValue(
|
| + pref_service_->GetInt64(pref_name_));
|
| + DVLOG(1) << "DailyInterval time loaded: "
|
| + << base::TimeFormatShortDateAndTime(last_fired_);
|
| + if (last_fired_.is_null()) {
|
| + DVLOG(1) << "DailyInterval first run.";
|
| + RecordIntervalTypeHistogram(pref_name_, FIRST_RUN);
|
| + OnInterval(now);
|
| + return;
|
| + }
|
| + }
|
| + int days_elapsed = (now - last_fired_).InDays();
|
| + if (days_elapsed >= 1) {
|
| + DVLOG(1) << "DailyInterval day elapsed.";
|
| + RecordIntervalTypeHistogram(pref_name_, DAY_ELAPSED);
|
| + OnInterval(now);
|
| + } else if (days_elapsed <= -1) {
|
| + // The "last fired" time is more than a day in the future, so the clock
|
| + // must have been changed.
|
| + DVLOG(1) << "DailyInterval clock change detected.";
|
| + RecordIntervalTypeHistogram(pref_name_, CLOCK_CHANGED);
|
| + OnInterval(now);
|
| + }
|
| +}
|
| +
|
| +void DailyInterval::OnInterval(base::Time now) {
|
| + DCHECK(!now.is_null());
|
| + last_fired_ = now;
|
| + pref_service_->SetInt64(pref_name_, last_fired_.ToInternalValue());
|
| +
|
| + // Notify all observers
|
| + for (ScopedVector<DailyObserver>::iterator it = observers_.begin();
|
| + it != observers_.end();
|
| + ++it) {
|
| + (*it)->OnDailyInterval();
|
| + }
|
| +}
|
| +
|
| +} // namespace metrics
|
|
|