Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Side by Side Diff: chrome/browser/network_time/network_time_tracker.cc

Issue 271853004: Merge NetworkTimeNotifier to NetworkTimeTracker (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/network_time/network_time_tracker.h" 5 #include "chrome/browser/network_time/network_time_tracker.h"
6 6
7 #include "base/sequenced_task_runner.h" 7 #include "base/basictypes.h"
8 #include "chrome/browser/browser_process.h" 8 #include "base/i18n/time_formatting.h"
9 #include "chrome/browser/io_thread.h" 9 #include "base/logging.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "base/time/tick_clock.h"
10 12
11 namespace { 13 namespace {
12 14
13 // Helper functions for interacting with the NetworkTimeNotifier. 15 // Clock resolution is platform dependent.
14 // Registration happens as follows (assuming tracker lives on thread N): 16 #if defined(OS_WIN)
15 // | Thread N | | UI thread| | IO Thread | 17 const int64 kTicksResolutionMs = base::Time::kMinLowResolutionThresholdMs;
16 // Start 18 #else
17 // RegisterObserverOnUIThread 19 const int64 kTicksResolutionMs = 1; // Assume 1ms for non-windows platforms.
18 // RegisterObserverOnIOThread 20 #endif
19 // NetworkTimeNotifier::AddObserver
20 // after which updates to the notifier and the subsequent observer calls
21 // happen as follows (assuming the network time update comes from the same
22 // thread):
23 // | Thread N | | UI thread| | IO Thread |
24 // UpdateNetworkNotifier
25 // UpdateNetworkNotifierOnIOThread
26 // NetworkTimeNotifier::UpdateNetworkTime
27 // OnNetworkTimeUpdatedOnIOThread
28 // OnNetworkTimeUpdated
29 void RegisterObserverOnIOThread(
30 IOThread* io_thread,
31 const net::NetworkTimeNotifier::ObserverCallback& observer_callback) {
32 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
33 io_thread->globals()->network_time_notifier->AddObserver(observer_callback);
34 }
35 21
36 void RegisterObserverOnUIThread( 22 // Number of time measurements performed in a given network time calculation.
37 const net::NetworkTimeNotifier::ObserverCallback& observer_callback) { 23 const int kNumTimeMeasurements = 5;
38 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
39 content::BrowserThread::PostTask(
40 content::BrowserThread::IO, FROM_HERE,
41 base::Bind(&RegisterObserverOnIOThread,
42 g_browser_process->io_thread(),
43 observer_callback));
44 }
45
46 void UpdateNetworkNotifierOnIOThread(IOThread* io_thread,
47 const base::Time& network_time,
48 const base::TimeDelta& resolution,
49 const base::TimeDelta& latency,
50 const base::TimeTicks& post_time) {
51 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
52 io_thread->globals()->network_time_notifier->UpdateNetworkTime(
53 network_time, resolution, latency, post_time);
54 }
55
56 void UpdateNetworkNotifier(IOThread* io_thread,
57 const base::Time& network_time,
58 const base::TimeDelta& resolution,
59 const base::TimeDelta& latency) {
60 content::BrowserThread::PostTask(
61 content::BrowserThread::IO,
62 FROM_HERE,
63 base::Bind(&UpdateNetworkNotifierOnIOThread,
64 io_thread,
65 network_time,
66 resolution,
67 latency,
68 base::TimeTicks::Now()));
69 }
70
71 void OnNetworkTimeUpdatedOnIOThread(
72 const scoped_refptr<base::SequencedTaskRunner>& task_runner,
73 const net::NetworkTimeNotifier::ObserverCallback& observer_callback,
74 const base::Time& network_time,
75 const base::TimeTicks& network_time_ticks,
76 const base::TimeDelta& network_time_uncertainty) {
77 task_runner->PostTask(
78 FROM_HERE,
79 base::Bind(observer_callback,
80 network_time,
81 network_time_ticks,
82 network_time_uncertainty));
83 }
84 24
85 } // namespace 25 } // namespace
86 26
87 NetworkTimeTracker::TimeMapping::TimeMapping(base::Time local_time, 27 NetworkTimeTracker::TimeMapping::TimeMapping(base::Time local_time,
88 base::Time network_time) 28 base::Time network_time)
89 : local_time(local_time), 29 : local_time(local_time),
90 network_time(network_time) {} 30 network_time(network_time) {}
91 31
92 NetworkTimeTracker::NetworkTimeTracker() 32 NetworkTimeTracker::NetworkTimeTracker(scoped_ptr<base::TickClock> tick_clock)
93 : weak_ptr_factory_(this), 33 : tick_clock_(tick_clock.Pass()),
94 received_network_time_(false) { 34 received_network_time_(false) {
95 } 35 }
96 36
97 NetworkTimeTracker::~NetworkTimeTracker() { 37 NetworkTimeTracker::~NetworkTimeTracker() {
98 }
99
100 void NetworkTimeTracker::Start() {
101 DCHECK(thread_checker_.CalledOnValidThread()); 38 DCHECK(thread_checker_.CalledOnValidThread());
102 content::BrowserThread::PostTask(
103 content::BrowserThread::UI,
104 FROM_HERE,
105 base::Bind(&RegisterObserverOnUIThread,
106 BuildObserverCallback()));
107 } 39 }
108 40
109 void NetworkTimeTracker::InitFromSavedTime(const TimeMapping& saved) { 41 void NetworkTimeTracker::InitFromSavedTime(const TimeMapping& saved) {
110 DCHECK(thread_checker_.CalledOnValidThread()); 42 DCHECK(thread_checker_.CalledOnValidThread());
111 if (!network_time_.is_null() || saved.local_time.is_null() || 43 if (!network_time_.is_null() || saved.local_time.is_null() ||
112 saved.network_time.is_null()) 44 saved.network_time.is_null())
113 return; 45 return;
114 46
115 base::Time local_time_now = base::Time::Now(); 47 base::Time local_time_now = base::Time::Now();
116 if (local_time_now < saved.local_time) { 48 if (local_time_now < saved.local_time) {
117 DLOG(WARNING) << "Can't initialize because clock skew has changed."; 49 DLOG(WARNING) << "Can't initialize because clock skew has changed.";
118 return; 50 return;
119 } 51 }
120 52
121 network_time_ = saved.network_time + (local_time_now - saved.local_time); 53 network_time_ = saved.network_time + (local_time_now - saved.local_time);
122 network_time_ticks_ = base::TimeTicks::Now(); 54 network_time_ticks_ = base::TimeTicks::Now();
123 } 55 }
124 56
125 bool NetworkTimeTracker::GetNetworkTime(const base::TimeTicks& time_ticks, 57 void NetworkTimeTracker::UpdateNetworkTime(base::Time network_time,
58 base::TimeDelta resolution,
59 base::TimeDelta latency,
60 base::TimeTicks post_time) {
61 DCHECK(thread_checker_.CalledOnValidThread());
62 DVLOG(1) << "Network time updating to "
63 << base::UTF16ToUTF8(
64 base::TimeFormatFriendlyDateAndTime(network_time));
65 // Update network time on every request to limit dependency on ticks lag.
66 // TODO(mad): Find a heuristic to avoid augmenting the
67 // network_time_uncertainty_ too much by a particularly long latency.
68 // Maybe only update when the the new time either improves in accuracy or
69 // drifts too far from |network_time_|.
70 network_time_ = network_time;
71
72 // Calculate the delay since the network time was received.
73 base::TimeTicks now = tick_clock_->NowTicks();
74 base::TimeDelta task_delay = now - post_time;
75 // Estimate that the time was set midway through the latency time.
76 network_time_ticks_ = now - task_delay - latency / 2;
77
78 // Can't assume a better time than the resolution of the given time
79 // and 5 ticks measurements are involved, each with their own uncertainty.
80 // 1 & 2 are the ones used to compute the latency, 3 is the Now() from when
81 // this task was posted, 4 is the Now() above and 5 will be the Now() used in
82 // GetNetworkTime().
83 network_time_uncertainty_ =
84 resolution + latency + kNumTimeMeasurements *
85 base::TimeDelta::FromMilliseconds(kTicksResolutionMs);
86
87 received_network_time_ = true;
88 }
89
90 bool NetworkTimeTracker::GetNetworkTime(base::TimeTicks time_ticks,
126 base::Time* network_time, 91 base::Time* network_time,
127 base::TimeDelta* uncertainty) const { 92 base::TimeDelta* uncertainty) const {
128 DCHECK(thread_checker_.CalledOnValidThread()); 93 DCHECK(thread_checker_.CalledOnValidThread());
129 DCHECK(network_time); 94 DCHECK(network_time);
130 if (network_time_.is_null()) 95 if (network_time_.is_null())
131 return false; 96 return false;
132 DCHECK(!network_time_ticks_.is_null()); 97 DCHECK(!network_time_ticks_.is_null());
133 *network_time = network_time_ + (time_ticks - network_time_ticks_); 98 *network_time = network_time_ + (time_ticks - network_time_ticks_);
134 if (uncertainty) 99 if (uncertainty)
135 *uncertainty = network_time_uncertainty_; 100 *uncertainty = network_time_uncertainty_;
136 return true; 101 return true;
137 } 102 }
138
139 // static
140 // Note: UpdateNetworkNotifier is exposed via callback because getting the IO
141 // thread pointer must be done on the UI thread, while components that provide
142 // network time updates may live on other threads.
143 NetworkTimeTracker::UpdateCallback
144 NetworkTimeTracker::BuildNotifierUpdateCallback() {
145 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
146 return base::Bind(&UpdateNetworkNotifier,
147 g_browser_process->io_thread());
148 }
149
150 net::NetworkTimeNotifier::ObserverCallback
151 NetworkTimeTracker::BuildObserverCallback() {
152 return base::Bind(&OnNetworkTimeUpdatedOnIOThread,
153 base::MessageLoop::current()->message_loop_proxy(),
154 base::Bind(&NetworkTimeTracker::OnNetworkTimeUpdate,
155 weak_ptr_factory_.GetWeakPtr()));
156 }
157
158 void NetworkTimeTracker::OnNetworkTimeUpdate(
159 const base::Time& network_time,
160 const base::TimeTicks& network_time_ticks,
161 const base::TimeDelta& network_time_uncertainty) {
162 DCHECK(thread_checker_.CalledOnValidThread());
163 network_time_ = network_time;
164 network_time_ticks_ = network_time_ticks;
165 network_time_uncertainty_ = network_time_uncertainty;
166 received_network_time_ = true;
167 }
168
OLDNEW
« no previous file with comments | « chrome/browser/network_time/network_time_tracker.h ('k') | chrome/browser/network_time/network_time_tracker_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698