summaryrefslogtreecommitdiffstats
path: root/net/base
diff options
context:
space:
mode:
authorzea@chromium.org <zea@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-30 03:45:14 +0000
committerzea@chromium.org <zea@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-30 03:45:14 +0000
commitdaae3462e123480220b6545b94d44659ab20dac1 (patch)
treee9ea57a0f513c5b4866cae24db93b03fa3b702fd /net/base
parented7c6617764efaf49a091ecd69ef898653435cca (diff)
downloadchromium_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.cc91
-rw-r--r--net/base/network_time_notifier.h84
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_