Roll src/third_party/WebKit 35143b2:56db356 (svn 201870:201871)
[chromium-blink-merge.git] / chromecast / base / system_time_change_notifier.cc
blob174a3853e350c4aba1da1ac9a7da00e726a3424e
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 {
12 namespace {
14 // Limits for periodic system time monitoring.
15 const int kLimitForMonitorPer1Sec = 60; // 1 minute
16 const int kLimitForMonitorPer10Sec = 600; // 10 minutes
18 } // namespace
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),
43 weak_factory_(this) {
44 DCHECK(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(
61 base::Time now) {
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(
72 base::Time now) {
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(
82 FROM_HERE,
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())
101 return fake_now_;
102 return base::Time::Now();
105 } // namespace chromecast