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 <math.h> |
| 8 |
| 9 #include "base/logging.h" |
| 10 |
| 11 namespace { |
| 12 |
| 13 // base::TimeTicks::Now() is documented to have a resolution of ~1-15ms. |
| 14 const int64 kTicksResolutionMs = 15; |
| 15 |
| 16 } // namespace |
| 17 |
| 18 NetworkTimeTracker::NetworkTimeTracker() { |
| 19 } |
| 20 |
| 21 NetworkTimeTracker::~NetworkTimeTracker() { |
| 22 } |
| 23 |
| 24 bool NetworkTimeTracker::GetNetworkTime(base::Time* network_time, |
| 25 base::TimeDelta* uncertainty) const { |
| 26 if (network_time_.is_null()) |
| 27 return false; |
| 28 DCHECK(!network_time_ticks_.is_null()); |
| 29 DCHECK(network_time); |
| 30 *network_time = network_time_ + (GetTicksNow() - network_time_ticks_); |
| 31 if (uncertainty) |
| 32 *uncertainty = network_time_uncertainty_; |
| 33 return true; |
| 34 } |
| 35 |
| 36 void NetworkTimeTracker::UpdateNetworkTime(const base::Time& network_time, |
| 37 const base::TimeDelta& resolution, |
| 38 const base::TimeDelta& latency) { |
| 39 DCHECK(ValidateTimeTracking(network_time, resolution, latency)); |
| 40 |
| 41 // Update network time on every request to limit dependency on ticks lag. |
| 42 // TODO(mad): Find a heuristic to avoid augmenting the |
| 43 // network_time_uncertainty_ too much by a particularly long latency. |
| 44 // Maybe only update when we either improve accuracy or drifted too far |
| 45 // from |network_time|. |
| 46 network_time_ = network_time; |
| 47 // Estimate that the time was set midway through the latency time. |
| 48 network_time_ticks_ = GetTicksNow() - latency / 2; |
| 49 |
| 50 // We can't assume a better time than the resolution of the given time |
| 51 // and we involve 4 ticks value, each with their own uncertainty, 1 & 2 |
| 52 // are the ones used to compute the latency, 3 is the Now() above and 4 |
| 53 // will be the Now() used in GetNetworkTime(). |
| 54 network_time_uncertainty_ = |
| 55 resolution + latency + |
| 56 4 * base::TimeDelta::FromMilliseconds(kTicksResolutionMs); |
| 57 } |
| 58 |
| 59 base::TimeTicks NetworkTimeTracker::GetTicksNow() const { |
| 60 return base::TimeTicks::Now(); |
| 61 } |
| 62 |
| 63 bool NetworkTimeTracker::ValidateTimeTracking( |
| 64 const base::Time& new_network_time, |
| 65 const base::TimeDelta& resolution, |
| 66 const base::TimeDelta& latency) { |
| 67 #ifndef NDEBUG |
| 68 base::Time current_network_time; |
| 69 base::TimeDelta uncertainty; |
| 70 if (GetNetworkTime(¤t_network_time, &uncertainty)) { |
| 71 // Account for new_network_time's own innaccuracy. |
| 72 uncertainty += |
| 73 resolution + latency + |
| 74 2 * base::TimeDelta::FromMilliseconds(kTicksResolutionMs); |
| 75 DVLOG(1) << current_network_time.ToInternalValue() << " VS " |
| 76 << new_network_time.ToInternalValue() << ", should be within: " |
| 77 << uncertainty.ToInternalValue(); |
| 78 return fabs(static_cast<double>(current_network_time.ToInternalValue() - |
| 79 new_network_time.ToInternalValue())) <= |
| 80 static_cast<double>(uncertainty.ToInternalValue()); |
| 81 } |
| 82 #endif // ifndef NDEBUG |
| 83 return true; // No time to track so no tracking drift, or in an NDEBUG build. |
| 84 } |
OLD | NEW |