1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chromecast/base/system_time_change_notifier.h"
7 #include "base/location.h"
8 #include "base/sequenced_task_runner.h"
10 namespace chromecast
{
14 // Limits for periodic system time monitoring.
15 const int kLimitForMonitorPer1Sec
= 60; // 1 minute
16 const int kLimitForMonitorPer10Sec
= 600; // 10 minutes
20 SystemTimeChangeNotifier::SystemTimeChangeNotifier()
21 : observer_list_(new base::ObserverListThreadSafe
<Observer
>()) {
24 SystemTimeChangeNotifier::~SystemTimeChangeNotifier() {
27 void SystemTimeChangeNotifier::AddObserver(Observer
* observer
) {
28 observer_list_
->AddObserver(observer
);
31 void SystemTimeChangeNotifier::RemoveObserver(Observer
* observer
) {
32 observer_list_
->RemoveObserver(observer
);
35 void SystemTimeChangeNotifier::NotifySystemTimeChanged() {
36 observer_list_
->Notify(FROM_HERE
, &Observer::OnSystemTimeChanged
);
39 SystemTimeChangeNotifierPeriodicMonitor::
40 SystemTimeChangeNotifierPeriodicMonitor(
41 const scoped_refptr
<base::SequencedTaskRunner
>& task_runner
)
42 : task_runner_(task_runner
),
47 SystemTimeChangeNotifierPeriodicMonitor::
48 ~SystemTimeChangeNotifierPeriodicMonitor() {
51 void SystemTimeChangeNotifierPeriodicMonitor::Initialize() {
52 base::Time now
= Now();
53 ResetTimeAndLimits(now
);
54 ScheduleNextMonitor(now
);
57 void SystemTimeChangeNotifierPeriodicMonitor::Finalize() {
60 void SystemTimeChangeNotifierPeriodicMonitor::ResetTimeAndLimits(
62 // ScheduleNextMonitor() will adjust actual expected_system_time.
63 expected_system_time_
= now
;
64 monitoring_limit_time_1sec_
=
65 now
+ base::TimeDelta::FromSeconds(kLimitForMonitorPer1Sec
);
66 monitoring_limit_time_10sec_
=
67 monitoring_limit_time_1sec_
+
68 base::TimeDelta::FromSeconds(kLimitForMonitorPer10Sec
);
71 void SystemTimeChangeNotifierPeriodicMonitor::ScheduleNextMonitor(
73 base::TimeDelta next_checking_interval
=
74 now
<= monitoring_limit_time_1sec_
? base::TimeDelta::FromSeconds(1) :
75 now
<= monitoring_limit_time_10sec_
? base::TimeDelta::FromSeconds(10) :
76 base::TimeDelta::FromMinutes(10);
77 // Adjusting expected_system_time based on now cannot detect continuous system
78 // time drift (false negative), but tolerates task delay (false positive).
79 // Task delay is expected more than system time drift.
80 expected_system_time_
= now
+ next_checking_interval
;
81 task_runner_
->PostDelayedTask(
83 base::Bind(&SystemTimeChangeNotifierPeriodicMonitor::CheckSystemTime
,
84 weak_factory_
.GetWeakPtr()),
85 next_checking_interval
);
88 void SystemTimeChangeNotifierPeriodicMonitor::CheckSystemTime() {
89 base::Time now
= Now();
90 const base::TimeDelta
kInterval10Seconds(base::TimeDelta::FromSeconds(10));
91 if (now
< expected_system_time_
- kInterval10Seconds
||
92 now
> expected_system_time_
+ kInterval10Seconds
) { // Time changed!
93 ResetTimeAndLimits(now
);
94 NotifySystemTimeChanged();
96 ScheduleNextMonitor(now
);
99 base::Time
SystemTimeChangeNotifierPeriodicMonitor::Now() const {
100 if (!fake_now_
.is_null())
102 return base::Time::Now();
105 } // namespace chromecast