system_time_change_notifier.cc 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  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.
  4. #include "chromecast/base/system_time_change_notifier.h"
  5. #include "base/bind.h"
  6. #include "base/location.h"
  7. #include "base/task/sequenced_task_runner.h"
  8. namespace chromecast {
  9. namespace {
  10. // Limits for periodic system time monitoring.
  11. const int kLimitForMonitorPer1Sec = 60; // 1 minute
  12. const int kLimitForMonitorPer10Sec = 600; // 10 minutes
  13. } // namespace
  14. SystemTimeChangeNotifier::SystemTimeChangeNotifier()
  15. : observer_list_(new base::ObserverListThreadSafe<Observer>()) {}
  16. SystemTimeChangeNotifier::~SystemTimeChangeNotifier() = default;
  17. void SystemTimeChangeNotifier::AddObserver(Observer* observer) {
  18. observer_list_->AddObserver(observer);
  19. }
  20. void SystemTimeChangeNotifier::RemoveObserver(Observer* observer) {
  21. observer_list_->RemoveObserver(observer);
  22. }
  23. void SystemTimeChangeNotifier::NotifySystemTimeChanged() {
  24. observer_list_->Notify(FROM_HERE, &Observer::OnSystemTimeChanged);
  25. }
  26. SystemTimeChangeNotifierPeriodicMonitor::
  27. SystemTimeChangeNotifierPeriodicMonitor(
  28. const scoped_refptr<base::SequencedTaskRunner>& task_runner)
  29. : task_runner_(task_runner),
  30. weak_factory_(this) {
  31. DCHECK(task_runner_);
  32. base::Time now = Now();
  33. ResetTimeAndLimits(now);
  34. ScheduleNextMonitor(now);
  35. }
  36. SystemTimeChangeNotifierPeriodicMonitor::
  37. ~SystemTimeChangeNotifierPeriodicMonitor() = default;
  38. void SystemTimeChangeNotifierPeriodicMonitor::ResetTimeAndLimits(
  39. base::Time now) {
  40. // ScheduleNextMonitor() will adjust actual expected_system_time.
  41. expected_system_time_ = now;
  42. monitoring_limit_time_1sec_ = now + base::Seconds(kLimitForMonitorPer1Sec);
  43. monitoring_limit_time_10sec_ =
  44. monitoring_limit_time_1sec_ + base::Seconds(kLimitForMonitorPer10Sec);
  45. }
  46. void SystemTimeChangeNotifierPeriodicMonitor::ScheduleNextMonitor(
  47. base::Time now) {
  48. base::TimeDelta next_checking_interval =
  49. now <= monitoring_limit_time_1sec_
  50. ? base::Seconds(1)
  51. : now <= monitoring_limit_time_10sec_ ? base::Seconds(10)
  52. : base::Minutes(10);
  53. // Adjusting expected_system_time based on now cannot detect continuous system
  54. // time drift (false negative), but tolerates task delay (false positive).
  55. // Task delay is expected more than system time drift.
  56. expected_system_time_ = now + next_checking_interval;
  57. task_runner_->PostDelayedTask(
  58. FROM_HERE,
  59. base::BindOnce(&SystemTimeChangeNotifierPeriodicMonitor::CheckSystemTime,
  60. weak_factory_.GetWeakPtr()),
  61. next_checking_interval);
  62. }
  63. void SystemTimeChangeNotifierPeriodicMonitor::CheckSystemTime() {
  64. base::Time now = Now();
  65. const base::TimeDelta kInterval10Seconds(base::Seconds(10));
  66. if (now < expected_system_time_ - kInterval10Seconds ||
  67. now > expected_system_time_ + kInterval10Seconds) { // Time changed!
  68. ResetTimeAndLimits(now);
  69. NotifySystemTimeChanged();
  70. }
  71. ScheduleNextMonitor(now);
  72. }
  73. base::Time SystemTimeChangeNotifierPeriodicMonitor::Now() const {
  74. if (!fake_now_.is_null())
  75. return fake_now_;
  76. return base::Time::Now();
  77. }
  78. } // namespace chromecast