diff options
author | haitaol@chromium.org <haitaol@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-27 22:05:03 +0000 |
---|---|---|
committer | haitaol@chromium.org <haitaol@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-27 22:05:03 +0000 |
commit | 55a79dc5b18c6de77a17068254dce94aec4e138b (patch) | |
tree | b7c98c20f7b431dff620cd400b34ae32599f3d8e | |
parent | ede9c721711601ca16cbee0c85b52ae27b791657 (diff) | |
download | chromium_src-55a79dc5b18c6de77a17068254dce94aec4e138b.zip chromium_src-55a79dc5b18c6de77a17068254dce94aec4e138b.tar.gz chromium_src-55a79dc5b18c6de77a17068254dce94aec4e138b.tar.bz2 |
Add NetworkTimeService for converting local time to network time.
Guarded by command switch. When enabled, NetworkTimeService converts local navigation time to network time, which is used to timestamp history entry and session sync entry.
BUG=265523
NOTRY=true
TBR=asvitkine@chromium.org
Review URL: https://codereview.chromium.org/23876007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@225796 0039d316-1c4b-4281-b951-d872f2087c98
18 files changed, 283 insertions, 17 deletions
diff --git a/chrome/browser/metrics/variations/variations_service.cc b/chrome/browser/metrics/variations/variations_service.cc index ce3e059..ce39915 100644 --- a/chrome/browser/metrics/variations/variations_service.cc +++ b/chrome/browser/metrics/variations/variations_service.cc @@ -18,7 +18,7 @@ #include "base/strings/string_number_conversions.h" #include "base/version.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/net/network_time_tracker.h" +#include "chrome/browser/network_time/network_time_tracker.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/metrics/variations/variations_util.h" #include "chrome/common/pref_names.h" diff --git a/chrome/browser/network_time/navigation_time_helper.cc b/chrome/browser/network_time/navigation_time_helper.cc index fd3fafd..704a310 100644 --- a/chrome/browser/network_time/navigation_time_helper.cc +++ b/chrome/browser/network_time/navigation_time_helper.cc @@ -4,6 +4,8 @@ #include "chrome/browser/network_time/navigation_time_helper.h" +#include "chrome/browser/network_time/network_time_service.h" +#include "chrome/browser/network_time/network_time_service_factory.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_types.h" @@ -68,6 +70,8 @@ void NavigationTimeHelper::Observe( } base::Time NavigationTimeHelper::GetNetworkTime(base::Time local_time) { - // TODO(haitaol): calculate network time based on local_time. - return local_time; + Profile* profile = + Profile::FromBrowserContext(web_contents_->GetBrowserContext()); + return NetworkTimeServiceFactory::GetForProfile(profile)-> + GetNetworkTime(local_time); } diff --git a/chrome/browser/network_time/network_time_service.cc b/chrome/browser/network_time/network_time_service.cc new file mode 100644 index 0000000..9a94a90 --- /dev/null +++ b/chrome/browser/network_time/network_time_service.cc @@ -0,0 +1,87 @@ +// Copyright 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 "chrome/browser/network_time/network_time_service.h" + +#include "base/command_line.h" +#include "base/prefs/pref_service.h" +#include "chrome/browser/network_time/network_time_tracker.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/common/pref_names.h" +#include "components/user_prefs/pref_registry_syncable.h" + +// static +void NetworkTimeService::RegisterProfilePrefs( + user_prefs::PrefRegistrySyncable* registry) { + registry->RegisterDictionaryPref( + prefs::kNetworkTimeMapping, + new base::DictionaryValue(), + user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); +} + +NetworkTimeService::NetworkTimeService(Profile* profile) + : profile_(profile) { + if (!CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableNetworkTime)) { + return; + } + + network_time_tracker_.reset(new NetworkTimeTracker); + network_time_tracker_->Start(); + + const base::DictionaryValue* time_mapping = + profile_->GetPrefs()->GetDictionary(prefs::kNetworkTimeMapping); + double local_time_js; + double network_time_js; + if (time_mapping->GetDouble("local", &local_time_js) && + time_mapping->GetDouble("network", &network_time_js)) { + base::Time local_time_saved = base::Time::FromJsTime(local_time_js); + if (local_time_saved > base::Time::Now() || + base::Time::Now() - local_time_saved > base::TimeDelta::FromDays(7)) { + // Drop saved mapping if clock skew has changed or the data is too old. + profile_->GetPrefs()->ClearPref(prefs::kNetworkTimeMapping); + } else { + network_time_tracker_->InitFromSavedTime( + NetworkTimeTracker::TimeMapping( + local_time_saved, base::Time::FromJsTime(network_time_js))); + } + } +} + +NetworkTimeService::~NetworkTimeService() {} + +void NetworkTimeService::Shutdown() { + if (!network_time_tracker_) + return; + + if (network_time_tracker_->received_network_time()) { + // Update time mapping if tracker received time update from server, i.e. + // mapping is accurate. + base::Time local_now = base::Time::Now(); + base::Time network_now = GetNetworkTime(local_now); + DictionaryValue time_mapping; + time_mapping.SetDouble("local", local_now.ToJsTime()); + time_mapping.SetDouble("network", network_now.ToJsTime()); + profile_->GetPrefs()->Set(prefs::kNetworkTimeMapping, time_mapping); + } +} + +base::Time NetworkTimeService::GetNetworkTime( + const base::Time& local_time) { + if (!network_time_tracker_.get() || local_time.is_null() || + local_time.is_max()) + return local_time; + + base::Time network_time_now; + if (!network_time_tracker_->GetNetworkTime(base::TimeTicks::Now(), + &network_time_now, NULL)) { + return local_time; + } + return local_time + (network_time_now - base::Time::Now()); +} + +base::Time NetworkTimeService::GetNetworkNow() { + return GetNetworkTime(base::Time::Now()); +} diff --git a/chrome/browser/network_time/network_time_service.h b/chrome/browser/network_time/network_time_service.h new file mode 100644 index 0000000..e1fde3a --- /dev/null +++ b/chrome/browser/network_time/network_time_service.h @@ -0,0 +1,41 @@ +// Copyright 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 CHROME_BROWSER_NETWORK_TIME_NETWORK_TIME_SERVICE_H_ +#define CHROME_BROWSER_NETWORK_TIME_NETWORK_TIME_SERVICE_H_ + +#include "base/memory/scoped_ptr.h" +#include "base/time/time.h" +#include "components/browser_context_keyed_service/browser_context_keyed_service.h" + +class NetworkTimeTracker; +class Profile; + +namespace user_prefs { +class PrefRegistrySyncable; +} + +// NetworkTimeService can convert local time to network time. +class NetworkTimeService : public BrowserContextKeyedService { + public: + explicit NetworkTimeService(Profile* profile); + virtual ~NetworkTimeService(); + + static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); + + // Return network time corresponding to |local_time| if possible. Return + // |local_time| otherwise. + base::Time GetNetworkTime(const base::Time& local_time); + + // Shortcut to get current time. + base::Time GetNetworkNow(); + + virtual void Shutdown() OVERRIDE; + + private: + Profile* profile_; + scoped_ptr<NetworkTimeTracker> network_time_tracker_; +}; + +#endif // CHROME_BROWSER_NETWORK_TIME_NETWORK_TIME_SERVICE_H_ diff --git a/chrome/browser/network_time/network_time_service_factory.cc b/chrome/browser/network_time/network_time_service_factory.cc new file mode 100644 index 0000000..a6132dc --- /dev/null +++ b/chrome/browser/network_time/network_time_service_factory.cc @@ -0,0 +1,41 @@ +// Copyright 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 "chrome/browser/network_time/network_time_service_factory.h" + +#include "chrome/browser/network_time/network_time_service.h" +#include "chrome/browser/profiles/incognito_helpers.h" +#include "components/browser_context_keyed_service/browser_context_dependency_manager.h" + +NetworkTimeServiceFactory::NetworkTimeServiceFactory() + : BrowserContextKeyedServiceFactory( + "NetworkTimeService", + BrowserContextDependencyManager::GetInstance()) { +} + +NetworkTimeServiceFactory::~NetworkTimeServiceFactory() { +} + +// static +NetworkTimeServiceFactory* NetworkTimeServiceFactory::GetInstance() { + return Singleton<NetworkTimeServiceFactory>::get(); +} + +// static +NetworkTimeService* NetworkTimeServiceFactory::GetForProfile( + Profile* profile) { + return static_cast<NetworkTimeService*>( + GetInstance()->GetServiceForBrowserContext(profile, true)); +} + +content::BrowserContext* NetworkTimeServiceFactory::GetBrowserContextToUse( + content::BrowserContext* context) const { + return chrome::GetBrowserContextRedirectedInIncognito(context); +} + +BrowserContextKeyedService* +NetworkTimeServiceFactory::BuildServiceInstanceFor( + content::BrowserContext* context) const { + return new NetworkTimeService(static_cast<Profile*>(context)); +} diff --git a/chrome/browser/network_time/network_time_service_factory.h b/chrome/browser/network_time/network_time_service_factory.h new file mode 100644 index 0000000..86acfef --- /dev/null +++ b/chrome/browser/network_time/network_time_service_factory.h @@ -0,0 +1,37 @@ +// Copyright 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 CHROME_BROWSER_NETWORK_TIME_NETWORK_TIME_SERVICE_FACTORY_H_ +#define CHROME_BROWSER_NETWORK_TIME_NETWORK_TIME_SERVICE_FACTORY_H_ + +#include "base/memory/singleton.h" +#include "chrome/browser/profiles/profile.h" +#include "components/browser_context_keyed_service/browser_context_keyed_service_factory.h" + +class BrowserContextKeyedService; +class NetworkTimeService; + +// Singleton that owns all NetworkTimeService and associates them with +// Profiles. +class NetworkTimeServiceFactory : public BrowserContextKeyedServiceFactory { + public: + static NetworkTimeServiceFactory* GetInstance(); + static NetworkTimeService* GetForProfile(Profile* profile); + + private: + friend struct DefaultSingletonTraits<NetworkTimeServiceFactory>; + + NetworkTimeServiceFactory(); + virtual ~NetworkTimeServiceFactory(); + + // BrowserContextKeyedServiceFactory: + virtual content::BrowserContext* GetBrowserContextToUse( + content::BrowserContext* context) const OVERRIDE; + virtual BrowserContextKeyedService* BuildServiceInstanceFor( + content::BrowserContext* context) const OVERRIDE; + + DISALLOW_COPY_AND_ASSIGN(NetworkTimeServiceFactory); +}; + +#endif // CHROME_BROWSER_NETWORK_TIME_NETWORK_TIME_SERVICE_FACTORY_H_ diff --git a/chrome/browser/net/network_time_tracker.cc b/chrome/browser/network_time/network_time_tracker.cc index ff4dae5..b97005a 100644 --- a/chrome/browser/net/network_time_tracker.cc +++ b/chrome/browser/network_time/network_time_tracker.cc @@ -1,8 +1,8 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Copyright 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 "chrome/browser/net/network_time_tracker.h" +#include "chrome/browser/network_time/network_time_tracker.h" #include "base/sequenced_task_runner.h" #include "chrome/browser/browser_process.h" @@ -84,8 +84,14 @@ void OnNetworkTimeUpdatedOnIOThread( } // namespace +NetworkTimeTracker::TimeMapping::TimeMapping(base::Time local_time, + base::Time network_time) + : local_time(local_time), + network_time(network_time) {} + NetworkTimeTracker::NetworkTimeTracker() - : weak_ptr_factory_(this) { + : weak_ptr_factory_(this), + received_network_time_(false) { } NetworkTimeTracker::~NetworkTimeTracker() { @@ -100,6 +106,22 @@ void NetworkTimeTracker::Start() { BuildObserverCallback())); } +void NetworkTimeTracker::InitFromSavedTime(const TimeMapping& saved) { + DCHECK(thread_checker_.CalledOnValidThread()); + if (!network_time_.is_null() || saved.local_time.is_null() || + saved.network_time.is_null()) + return; + + base::Time local_time_now = base::Time::Now(); + if (local_time_now < saved.local_time) { + DLOG(WARNING) << "Can't initialize because clock skew has changed."; + return; + } + + network_time_ = saved.network_time + (local_time_now - saved.local_time); + network_time_ticks_ = base::TimeTicks::Now(); +} + bool NetworkTimeTracker::GetNetworkTime(const base::TimeTicks& time_ticks, base::Time* network_time, base::TimeDelta* uncertainty) const { @@ -141,5 +163,6 @@ void NetworkTimeTracker::OnNetworkTimeUpdate( network_time_ = network_time; network_time_ticks_ = network_time_ticks; network_time_uncertainty_ = network_time_uncertainty; + received_network_time_ = true; } diff --git a/chrome/browser/net/network_time_tracker.h b/chrome/browser/network_time/network_time_tracker.h index 5eaf97a..f760351 100644 --- a/chrome/browser/net/network_time_tracker.h +++ b/chrome/browser/network_time/network_time_tracker.h @@ -1,9 +1,9 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Copyright 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 CHROME_BROWSER_NET_NETWORK_TIME_TRACKER_H_ -#define CHROME_BROWSER_NET_NETWORK_TIME_TRACKER_H_ +#ifndef CHROME_BROWSER_NETWORK_TIME_NETWORK_TIME_TRACKER_H_ +#define CHROME_BROWSER_NETWORK_TIME_NETWORK_TIME_TRACKER_H_ #include "base/callback.h" #include "base/memory/weak_ptr.h" @@ -39,6 +39,16 @@ class NetworkTimeTracker { // Starts tracking network time. void Start(); + struct TimeMapping { + TimeMapping(base::Time local_time, base::Time network_time); + base::Time local_time; + base::Time network_time; + }; + + // Initializes from saved times to be able to compute network time before + // receiving accurate time from HTTP response. + void InitFromSavedTime(const TimeMapping& saved); + // Returns the network time corresponding to |time_ticks| if network time // is available. Returns false if no network time is available yet. Can also // return the error range if |uncertainty| isn't NULL. @@ -51,6 +61,10 @@ class NetworkTimeTracker { // called from any thread. static UpdateCallback BuildNotifierUpdateCallback(); + bool received_network_time() const { + return received_network_time_; + } + private: friend class NetworkTimeTrackerTest; @@ -78,7 +92,9 @@ class NetworkTimeTracker { base::ThreadChecker thread_checker_; + bool received_network_time_; + DISALLOW_COPY_AND_ASSIGN(NetworkTimeTracker); }; -#endif // CHROME_BROWSER_NET_NETWORK_TIME_TRACKER_H_ +#endif // CHROME_BROWSER_NETWORK_TIME_NETWORK_TIME_TRACKER_H_ diff --git a/chrome/browser/net/network_time_tracker_unittest.cc b/chrome/browser/network_time/network_time_tracker_unittest.cc index 70b6909..e30cc79 100644 --- a/chrome/browser/net/network_time_tracker_unittest.cc +++ b/chrome/browser/network_time/network_time_tracker_unittest.cc @@ -1,14 +1,15 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Copyright 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 "chrome/browser/network_time/network_time_tracker.h" + #include <math.h> #include "base/bind.h" #include "base/bind_helpers.h" #include "base/compiler_specific.h" #include "base/message_loop/message_loop.h" -#include "chrome/browser/net/network_time_tracker.h" #include "content/public/test/test_browser_thread.h" #include "net/base/network_time_notifier.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index 744f414..bd2970b 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc @@ -45,6 +45,7 @@ #include "chrome/browser/net/predictor.h" #include "chrome/browser/net/pref_proxy_config_tracker_impl.h" #include "chrome/browser/net/ssl_config_service_manager.h" +#include "chrome/browser/network_time/network_time_service.h" #include "chrome/browser/notifications/desktop_notification_service.h" #include "chrome/browser/notifications/notification_prefs_manager.h" #if !defined(OS_ANDROID) @@ -331,6 +332,7 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) { MediaCaptureDevicesDispatcher::RegisterProfilePrefs(registry); MediaStreamDevicesController::RegisterProfilePrefs(registry); NetPrefObserver::RegisterProfilePrefs(registry); + NetworkTimeService::RegisterProfilePrefs(registry); NewTabUI::RegisterProfilePrefs(registry); #if !defined(OS_ANDROID) notifier::ChromeNotifierService::RegisterProfilePrefs(registry); diff --git a/chrome/browser/sync/glue/sync_backend_host.cc b/chrome/browser/sync/glue/sync_backend_host.cc index cf765bd..84c0b16 100644 --- a/chrome/browser/sync/glue/sync_backend_host.cc +++ b/chrome/browser/sync/glue/sync_backend_host.cc @@ -22,7 +22,7 @@ #include "chrome/browser/invalidation/invalidation_service.h" #include "chrome/browser/invalidation/invalidation_service_factory.h" #include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/net/network_time_tracker.h" +#include "chrome/browser/network_time/network_time_tracker.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/token_service.h" #include "chrome/browser/signin/token_service_factory.h" diff --git a/chrome/browser/upgrade_detector_impl.h b/chrome/browser/upgrade_detector_impl.h index e8a1d82..d0eef53 100644 --- a/chrome/browser/upgrade_detector_impl.h +++ b/chrome/browser/upgrade_detector_impl.h @@ -7,7 +7,7 @@ #include "base/memory/weak_ptr.h" #include "base/timer/timer.h" -#include "chrome/browser/net/network_time_tracker.h" +#include "chrome/browser/network_time/network_time_tracker.h" #include "chrome/browser/upgrade_detector.h" template <typename T> struct DefaultSingletonTraits; diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 53fdf01..f08154f 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1217,8 +1217,6 @@ 'browser/net/net_pref_observer.h', 'browser/net/network_stats.cc', 'browser/net/network_stats.h', - 'browser/net/network_time_tracker.cc', - 'browser/net/network_time_tracker.h', 'browser/net/preconnect.cc', 'browser/net/preconnect.h', 'browser/net/predictor.cc', @@ -1255,6 +1253,12 @@ 'browser/net/url_info.h', 'browser/network_time/navigation_time_helper.cc', 'browser/network_time/navigation_time_helper.h', + 'browser/network_time/network_time_service.cc', + 'browser/network_time/network_time_service.h', + 'browser/network_time/network_time_service_factory.cc', + 'browser/network_time/network_time_service_factory.h', + 'browser/network_time/network_time_tracker.cc', + 'browser/network_time/network_time_tracker.h', 'browser/notifications/balloon.cc', 'browser/notifications/balloon.h', 'browser/notifications/balloon_collection.cc', diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index 5bae30f..289c87c 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi @@ -1011,7 +1011,6 @@ 'browser/net/net_error_tab_helper_unittest.cc', 'browser/net/net_log_temp_file_unittest.cc', 'browser/net/network_stats_unittest.cc', - 'browser/net/network_time_tracker_unittest.cc', 'browser/net/predictor_unittest.cc', 'browser/net/pref_proxy_config_tracker_impl_unittest.cc', 'browser/net/probe_message_unittest.cc', @@ -1021,6 +1020,7 @@ 'browser/net/transport_security_persister_unittest.cc', 'browser/net/url_info_unittest.cc', 'browser/network_time/navigation_time_helper_unittest.cc', + 'browser/network_time/network_time_tracker_unittest.cc', 'browser/notifications/desktop_notification_service_unittest.cc', 'browser/notifications/message_center_notifications_unittest_win.cc', 'browser/notifications/message_center_settings_controller_unittest.cc', diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 95b5a66..a5ec65e 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc @@ -662,6 +662,9 @@ const char kEnableNaCl[] = "enable-nacl"; // Enables the network-related benchmarking extensions. const char kEnableNetBenchmarking[] = "enable-net-benchmarking"; +// Enables |NetworkTimeService| to convert local time to network time. +const char kEnableNetworkTime[] = "enable-network-time"; + // Enables NPN and SPDY. In case server supports SPDY, browser will use SPDY. const char kEnableNpn[] = "enable-npn"; diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index c36c9f7..46abc725 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h @@ -191,6 +191,7 @@ extern const char kEnableMemoryInfo[]; extern const char kEnableMetricsReportingForTesting[]; extern const char kEnableNaCl[]; extern const char kEnableNetBenchmarking[]; +extern const char kEnableNetworkTime[]; extern const char kEnableNpn[]; extern const char kEnableNpnHttpOnly[]; extern const char kEnableOmniboxAutoCompletionForIme[]; diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index 96db122..881b0b4 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc @@ -2513,4 +2513,8 @@ const char kWatchdogExtensionActive[] = // of Chrome. const char kProfilePreferenceHashes[] = "profile.preference_hashes"; +// Stores a pair of local time and corresponding network time to bootstrap +// network time tracker when browser starts. +const char kNetworkTimeMapping[] = "profile.network_time_mapping"; + } // namespace prefs diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 17819984..00ade93 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h @@ -920,6 +920,8 @@ extern const char kWatchdogExtensionActive[]; extern const char kProfilePreferenceHashes[]; +extern const char kNetworkTimeMapping[]; + } // namespace prefs #endif // CHROME_COMMON_PREF_NAMES_H_ |