OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2013 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 | |
5 #include "chrome/browser/metrics/variations/network_time_tracker.h" | |
6 | |
7 #include "base/logging.h" | |
8 | |
9 namespace { | |
10 | |
11 // base::TimeTicks::Now() is documented to have a resolution of ~1-15ms. | |
12 const int64 kTicksResolutionMs = 15; | |
13 | |
14 #ifndef NDEBUG | |
15 // Checks that time is tracked correctly. | |
16 bool ValidateTimeTracking(const NetworkTimeTracker& network_time_tracker, | |
Alexei Svitkine (slow)
2013/02/04 21:23:18
If you're passing in the NetworkTimeTracker object
MAD
2013/02/05 01:05:55
D'Ho! This evolved from something else... Makes se
| |
17 const base::Time& new_network_time, | |
18 const base::TimeDelta& resolution, | |
19 const base::TimeDelta& latency) { | |
20 base::Time current_network_time; | |
21 base::TimeDelta uncertainty; | |
22 if (network_time_tracker.GetNetworkTime(¤t_network_time, | |
23 &uncertainty)) { | |
24 // Account for new_network_time's own innaccuracy. | |
25 uncertainty += | |
26 resolution + latency + | |
27 2 * base::TimeDelta::FromMilliseconds(kTicksResolutionMs); | |
28 DVLOG(1) << current_network_time.ToInternalValue() << " VS " | |
29 << new_network_time.ToInternalValue() << ", should be within: " | |
30 << uncertainty.ToInternalValue(); | |
31 return abs(current_network_time.ToInternalValue() - | |
32 new_network_time.ToInternalValue()) <= | |
33 uncertainty.ToInternalValue(); | |
34 } | |
35 return true; // No time to track, so no tracking drift. | |
36 } | |
37 #endif // ifndef NDEBUG | |
38 | |
39 } // namespace | |
40 | |
41 NetworkTimeTracker::NetworkTimeTracker() { | |
42 } | |
43 | |
44 NetworkTimeTracker::~NetworkTimeTracker() { | |
45 } | |
46 | |
47 bool NetworkTimeTracker::GetNetworkTime(base::Time* network_time, | |
48 base::TimeDelta* uncertainty) const { | |
49 if (network_time_.is_null()) | |
50 return false; | |
51 DCHECK(!network_time_ticks_.is_null()); | |
52 DCHECK(network_time); | |
53 *network_time = network_time_ + (base::TimeTicks::Now() - | |
54 network_time_ticks_); | |
55 if (uncertainty) | |
56 *uncertainty = network_time_uncertainty_; | |
57 return true; | |
58 } | |
59 | |
60 void NetworkTimeTracker::UpdateNetworkTime(const base::Time& network_time, | |
61 const base::TimeDelta& resolution, | |
62 const base::TimeDelta& latency) { | |
63 DCHECK(ValidateTimeTracking(*this, network_time, resolution, latency)); | |
64 // Update network time on every request to limit dependency on ticks lag. | |
Alexei Svitkine (slow)
2013/02/04 21:23:18
Nit: add a blank line before this to make it more
MAD
2013/02/05 01:05:55
Done.
| |
65 // TODO(mad): Find a heuristic to avoid augmenting the | |
66 // network_time_uncertainty_ too much by a particularly long latency. | |
67 // Maybe only update when we either improve accuracy or drifted too far | |
68 // from |network_time|. | |
69 network_time_ = network_time; | |
70 // Estimate that the time was set midway through the latency time. | |
71 network_time_ticks_ = base::TimeTicks::Now() - latency / 2; | |
72 // We can't assume a better time than the resolution of the given time | |
Alexei Svitkine (slow)
2013/02/04 21:23:18
Nit: add a blank line before this to make it more
MAD
2013/02/05 01:05:55
Done.
| |
73 // and we involve 4 ticks value, each with their own uncertainty, 1 & 2 | |
74 // are the ones used to compute the latency, 3 is the Now() above and 4 | |
75 // will be the Now() used in GetNetworkTime(). | |
76 network_time_uncertainty_ = | |
77 resolution + latency + | |
78 4 * base::TimeDelta::FromMilliseconds(kTicksResolutionMs); | |
79 } | |
OLD | NEW |