xref: /aosp_15_r20/external/cronet/components/metrics/daily_event.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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