diff options
author | zea@chromium.org <zea@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-30 03:45:14 +0000 |
---|---|---|
committer | zea@chromium.org <zea@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-30 03:45:14 +0000 |
commit | daae3462e123480220b6545b94d44659ab20dac1 (patch) | |
tree | e9ea57a0f513c5b4866cae24db93b03fa3b702fd /net/base | |
parent | ed7c6617764efaf49a091ecd69ef898653435cca (diff) | |
download | chromium_src-daae3462e123480220b6545b94d44659ab20dac1.zip chromium_src-daae3462e123480220b6545b94d44659ab20dac1.tar.gz chromium_src-daae3462e123480220b6545b94d44659ab20dac1.tar.bz2 |
Split NetworkTimeTracker into service part and observer part.
The service will now get time updates from sync's http bridge (with
time data from the sync server).
Original codereview by haitaol@chromium.org at
https://codereview.chromium.org/12211117/
BUG=177072
TBR=akalin@chromium.org
Review URL: https://chromiumcodereview.appspot.com/12833011
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@197258 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/base')
-rw-r--r-- | net/base/network_time_notifier.cc | 91 | ||||
-rw-r--r-- | net/base/network_time_notifier.h | 84 |
2 files changed, 175 insertions, 0 deletions
diff --git a/net/base/network_time_notifier.cc b/net/base/network_time_notifier.cc new file mode 100644 index 0000000..fedd052 --- /dev/null +++ b/net/base/network_time_notifier.cc @@ -0,0 +1,91 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/base/network_time_notifier.h" + +#include "base/basictypes.h" +#include "base/bind.h" +#include "base/i18n/time_formatting.h" +#include "base/location.h" +#include "base/message_loop.h" +#include "base/stl_util.h" +#include "base/utf_string_conversions.h" + +namespace { + +// Clock resolution is platform dependent. +#if defined(OS_WIN) +const int64 kTicksResolutionMs = base::Time::kMinLowResolutionThresholdMs; +#else +const int64 kTicksResolutionMs = 1; // Assume 1ms for non-windows platforms. +#endif + +// Number of time measurements performed in a given network time calculation. +const int kNumTimeMeasurements = 5; + +} // namespace + +namespace net { + +NetworkTimeNotifier::NetworkTimeNotifier( + scoped_ptr<base::TickClock> tick_clock) { + tick_clock_ = tick_clock.Pass(); +} + +NetworkTimeNotifier::~NetworkTimeNotifier() {} + +void NetworkTimeNotifier::UpdateNetworkTime(const base::Time& network_time, + const base::TimeDelta& resolution, + const base::TimeDelta& latency, + const base::TimeTicks& post_time) { + DCHECK(thread_checker_.CalledOnValidThread()); + DVLOG(1) << "Network time updating to " + << UTF16ToUTF8(base::TimeFormatFriendlyDateAndTime(network_time)); + // Update network time on every request to limit dependency on ticks lag. + // TODO(mad): Find a heuristic to avoid augmenting the + // network_time_uncertainty_ too much by a particularly long latency. + // Maybe only update when the the new time either improves in accuracy or + // drifts too far from |network_time_|. + network_time_ = network_time; + + // Calculate the delay since the network time was received. + base::TimeTicks now = tick_clock_->NowTicks(); + base::TimeDelta task_delay = now - post_time; + // Estimate that the time was set midway through the latency time. + network_time_ticks_ = now - task_delay - latency / 2; + + // Can't assume a better time than the resolution of the given time + // and 5 ticks measurements are involved, each with their own uncertainty. + // 1 & 2 are the ones used to compute the latency, 3 is the Now() from when + // this task was posted, 4 is the Now() above and 5 will be the Now() used in + // GetNetworkTime(). + network_time_uncertainty_ = + resolution + latency + kNumTimeMeasurements * + base::TimeDelta::FromMilliseconds(kTicksResolutionMs); + + for (size_t i = 0; i < observers_.size(); ++i) { + MessageLoop::current()->PostTask( + FROM_HERE, + base::Bind(observers_[i], + network_time_, + network_time_ticks_, + network_time_uncertainty_)); + } +} + +void NetworkTimeNotifier::AddObserver( + const ObserverCallback& observer_callback) { + DCHECK(thread_checker_.CalledOnValidThread()); + observers_.push_back(observer_callback); + if (!network_time_.is_null()) { + MessageLoop::current()->PostTask( + FROM_HERE, + base::Bind(observer_callback, + network_time_, + network_time_ticks_, + network_time_uncertainty_)); + } +} + +} // namespace net diff --git a/net/base/network_time_notifier.h b/net/base/network_time_notifier.h new file mode 100644 index 0000000..06fb803 --- /dev/null +++ b/net/base/network_time_notifier.h @@ -0,0 +1,84 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_BASE_NETWORK_TIME_NOTIFIER_H_ +#define NET_BASE_NETWORK_TIME_NOTIFIER_H_ + +#include <vector> + +#include "base/callback.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" +#include "base/threading/thread_checker.h" +#include "base/time.h" +#include "base/time/tick_clock.h" +#include "net/base/net_export.h" + +namespace net { + +// A class that receives updates for and maintains network time. Network time +// sources can pass updates through UpdateNetworkTime, and network time +// consumers can register as observers. This class is not thread-safe. +class NET_EXPORT NetworkTimeNotifier { + public: + // Callback for observers to receive network time updates. + // The parameters are: + // const base::Time& network_time - the new network time. + // const base::TimeTicks& network_time_ticks - the ticks time that corresponds + // with |network_time|. + // const base::TimeDelta& network_time_uncertainty - the uncertainty + // associated with the new network time. + typedef base::Callback<void(const base::Time&, + const base::TimeTicks&, + const base::TimeDelta&)> ObserverCallback; + + // Takes ownership of |tick_clock|. + explicit NetworkTimeNotifier(scoped_ptr<base::TickClock> tick_clock); + ~NetworkTimeNotifier(); + + // Calculates corresponding time ticks according to the given parameters and + // notifies observers. The provided |network_time| is precise at the given + // |resolution| and represent the time between now and up to |latency| + + // (now - |post_time|) ago. + void UpdateNetworkTime(const base::Time& network_time, + const base::TimeDelta& resolution, + const base::TimeDelta& latency, + const base::TimeTicks& post_time); + + // |observer_callback| will invoked every time the network time is updated, or + // if a network time is already available when AddObserver is called. + void AddObserver(const ObserverCallback& observer_callback); + + private: + base::ThreadChecker thread_checker_; + + // For querying current time ticks. + scoped_ptr<base::TickClock> tick_clock_; + + // The network time based on last call to UpdateNetworkTime(). + base::Time network_time_; + + // The estimated local time from |tick_clock| that corresponds with + // |network_time|. Assumes the actual network time measurement was performed + // midway through the latency time, and does not account for suspect/resume + // events since the network time was measured. + // See UpdateNetworkTime(..) implementation for details. + base::TimeTicks network_time_ticks_; + + // Uncertainty of |network_time_| based on added inaccuracies/resolution. + // See UpdateNetworkTime(..) implementation for details. + base::TimeDelta network_time_uncertainty_; + + // List of network time update observers. + // A vector of callbacks is used, rather than an ObserverList, so that the + // lifetime of the observer can be bound to the callback. + std::vector<ObserverCallback> observers_; + + DISALLOW_COPY_AND_ASSIGN(NetworkTimeNotifier); +}; + +} // namespace net + +#endif // NET_BASE_NETWORK_TIME_NOTIFIER_H_ |