1*6777b538SAndroid Build Coastguard Worker // Copyright 2014 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "components/metrics/daily_event.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <utility>
8*6777b538SAndroid Build Coastguard Worker
9*6777b538SAndroid Build Coastguard Worker #include "base/logging.h"
10*6777b538SAndroid Build Coastguard Worker #include "base/metrics/histogram_functions.h"
11*6777b538SAndroid Build Coastguard Worker #include "components/prefs/pref_registry_simple.h"
12*6777b538SAndroid Build Coastguard Worker #include "components/prefs/pref_service.h"
13*6777b538SAndroid Build Coastguard Worker
14*6777b538SAndroid Build Coastguard Worker namespace metrics {
15*6777b538SAndroid Build Coastguard Worker
16*6777b538SAndroid Build Coastguard Worker namespace {
17*6777b538SAndroid Build Coastguard Worker
RecordIntervalTypeHistogram(const std::string & histogram_name,DailyEvent::IntervalType type)18*6777b538SAndroid Build Coastguard Worker void RecordIntervalTypeHistogram(const std::string& histogram_name,
19*6777b538SAndroid Build Coastguard Worker DailyEvent::IntervalType type) {
20*6777b538SAndroid Build Coastguard Worker if (histogram_name.empty())
21*6777b538SAndroid Build Coastguard Worker return;
22*6777b538SAndroid Build Coastguard Worker base::UmaHistogramEnumeration(histogram_name, type);
23*6777b538SAndroid Build Coastguard Worker }
24*6777b538SAndroid Build Coastguard Worker
25*6777b538SAndroid Build Coastguard Worker } // namespace
26*6777b538SAndroid Build Coastguard Worker
Observer()27*6777b538SAndroid Build Coastguard Worker DailyEvent::Observer::Observer() {
28*6777b538SAndroid Build Coastguard Worker }
29*6777b538SAndroid Build Coastguard Worker
~Observer()30*6777b538SAndroid Build Coastguard Worker DailyEvent::Observer::~Observer() {
31*6777b538SAndroid Build Coastguard Worker }
32*6777b538SAndroid Build Coastguard Worker
DailyEvent(PrefService * pref_service,const char * pref_name,const std::string & histogram_name)33*6777b538SAndroid Build Coastguard Worker DailyEvent::DailyEvent(PrefService* pref_service,
34*6777b538SAndroid Build Coastguard Worker const char* pref_name,
35*6777b538SAndroid Build Coastguard Worker const std::string& histogram_name)
36*6777b538SAndroid Build Coastguard Worker : pref_service_(pref_service),
37*6777b538SAndroid Build Coastguard Worker pref_name_(pref_name),
38*6777b538SAndroid Build Coastguard Worker histogram_name_(histogram_name) {
39*6777b538SAndroid Build Coastguard Worker }
40*6777b538SAndroid Build Coastguard Worker
~DailyEvent()41*6777b538SAndroid Build Coastguard Worker DailyEvent::~DailyEvent() {
42*6777b538SAndroid Build Coastguard Worker }
43*6777b538SAndroid Build Coastguard Worker
44*6777b538SAndroid Build Coastguard Worker // static
RegisterPref(PrefRegistrySimple * registry,const std::string & pref_name)45*6777b538SAndroid Build Coastguard Worker void DailyEvent::RegisterPref(PrefRegistrySimple* registry,
46*6777b538SAndroid Build Coastguard Worker const std::string& pref_name) {
47*6777b538SAndroid Build Coastguard Worker registry->RegisterInt64Pref(pref_name, 0);
48*6777b538SAndroid Build Coastguard Worker }
49*6777b538SAndroid Build Coastguard Worker
AddObserver(std::unique_ptr<DailyEvent::Observer> observer)50*6777b538SAndroid Build Coastguard Worker void DailyEvent::AddObserver(std::unique_ptr<DailyEvent::Observer> observer) {
51*6777b538SAndroid Build Coastguard Worker DVLOG(2) << "DailyEvent observer added.";
52*6777b538SAndroid Build Coastguard Worker DCHECK(last_fired_.is_null());
53*6777b538SAndroid Build Coastguard Worker observers_.push_back(std::move(observer));
54*6777b538SAndroid Build Coastguard Worker }
55*6777b538SAndroid Build Coastguard Worker
CheckInterval()56*6777b538SAndroid Build Coastguard Worker void DailyEvent::CheckInterval() {
57*6777b538SAndroid Build Coastguard Worker base::Time now = base::Time::Now();
58*6777b538SAndroid Build Coastguard Worker if (last_fired_.is_null()) {
59*6777b538SAndroid Build Coastguard Worker // The first time we call CheckInterval, we read the time stored in prefs.
60*6777b538SAndroid Build Coastguard Worker last_fired_ =
61*6777b538SAndroid Build Coastguard Worker base::Time() + base::Microseconds(pref_service_->GetInt64(pref_name_));
62*6777b538SAndroid Build Coastguard Worker
63*6777b538SAndroid Build Coastguard Worker DVLOG(1) << "DailyEvent time loaded: " << last_fired_;
64*6777b538SAndroid Build Coastguard Worker if (last_fired_.is_null()) {
65*6777b538SAndroid Build Coastguard Worker DVLOG(1) << "DailyEvent first run.";
66*6777b538SAndroid Build Coastguard Worker RecordIntervalTypeHistogram(histogram_name_, IntervalType::FIRST_RUN);
67*6777b538SAndroid Build Coastguard Worker OnInterval(now, IntervalType::FIRST_RUN);
68*6777b538SAndroid Build Coastguard Worker return;
69*6777b538SAndroid Build Coastguard Worker }
70*6777b538SAndroid Build Coastguard Worker }
71*6777b538SAndroid Build Coastguard Worker int days_elapsed = (now - last_fired_).InDays();
72*6777b538SAndroid Build Coastguard Worker if (days_elapsed >= 1) {
73*6777b538SAndroid Build Coastguard Worker DVLOG(1) << "DailyEvent day elapsed.";
74*6777b538SAndroid Build Coastguard Worker RecordIntervalTypeHistogram(histogram_name_, IntervalType::DAY_ELAPSED);
75*6777b538SAndroid Build Coastguard Worker OnInterval(now, IntervalType::DAY_ELAPSED);
76*6777b538SAndroid Build Coastguard Worker } else if (days_elapsed <= -1) {
77*6777b538SAndroid Build Coastguard Worker // The "last fired" time is more than a day in the future, so the clock
78*6777b538SAndroid Build Coastguard Worker // must have been changed.
79*6777b538SAndroid Build Coastguard Worker DVLOG(1) << "DailyEvent clock change detected.";
80*6777b538SAndroid Build Coastguard Worker RecordIntervalTypeHistogram(histogram_name_, IntervalType::CLOCK_CHANGED);
81*6777b538SAndroid Build Coastguard Worker OnInterval(now, IntervalType::CLOCK_CHANGED);
82*6777b538SAndroid Build Coastguard Worker }
83*6777b538SAndroid Build Coastguard Worker }
84*6777b538SAndroid Build Coastguard Worker
OnInterval(base::Time now,IntervalType type)85*6777b538SAndroid Build Coastguard Worker void DailyEvent::OnInterval(base::Time now, IntervalType type) {
86*6777b538SAndroid Build Coastguard Worker DCHECK(!now.is_null());
87*6777b538SAndroid Build Coastguard Worker last_fired_ = now;
88*6777b538SAndroid Build Coastguard Worker pref_service_->SetInt64(pref_name_,
89*6777b538SAndroid Build Coastguard Worker last_fired_.since_origin().InMicroseconds());
90*6777b538SAndroid Build Coastguard Worker
91*6777b538SAndroid Build Coastguard Worker for (auto it = observers_.begin(); it != observers_.end(); ++it) {
92*6777b538SAndroid Build Coastguard Worker (*it)->OnDailyEvent(type);
93*6777b538SAndroid Build Coastguard Worker }
94*6777b538SAndroid Build Coastguard Worker }
95*6777b538SAndroid Build Coastguard Worker
96*6777b538SAndroid Build Coastguard Worker } // namespace metrics
97