OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/network_time/network_time_tracker.h" | 5 #include "components/network_time/network_time_tracker.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 #include <string> | 8 #include <string> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 // be that badly wrong, but all the same it's included here to document the very | 93 // be that badly wrong, but all the same it's included here to document the very |
94 // rough nature of the time service provided by this class.) | 94 // rough nature of the time service provided by this class.) |
95 const uint32_t kTimeServerMaxSkewSeconds = 10; | 95 const uint32_t kTimeServerMaxSkewSeconds = 10; |
96 | 96 |
97 const char kTimeServiceURL[] = "http://clients2.google.com/time/1/current"; | 97 const char kTimeServiceURL[] = "http://clients2.google.com/time/1/current"; |
98 | 98 |
99 const char kVariationsServiceCheckTimeIntervalSeconds[] = | 99 const char kVariationsServiceCheckTimeIntervalSeconds[] = |
100 "CheckTimeIntervalSeconds"; | 100 "CheckTimeIntervalSeconds"; |
101 const char kVariationsServiceRandomQueryProbability[] = | 101 const char kVariationsServiceRandomQueryProbability[] = |
102 "RandomQueryProbability"; | 102 "RandomQueryProbability"; |
103 // This parameter must have the value "true" in order for | 103 |
104 // StartTimeFetch() to start time queries on demand. | 104 // This parameter can have three values: |
105 const char kVariationsServiceEnableFetchesOnDemand[] = "EnableFetchesOnDemand"; | 105 // |
| 106 // - "background-only": Time queries will be issued in the background as |
| 107 // needed (when the clock loses sync), but on-demand time queries will |
| 108 // not be issued (i.e. StartTimeFetch() will not start time queries.) |
| 109 // |
| 110 // - "on-demand-only": Time queries will not be issued except when |
| 111 // StartTimeFetch() is called. |
| 112 // |
| 113 // - "background-and-on-demand": Time queries will be issued both in the |
| 114 // background as needed and also on-demand. |
| 115 const char kVariationsServiceFetchBehavior[] = "FetchBehavior"; |
106 | 116 |
107 // This is an ECDSA prime256v1 named-curve key. | 117 // This is an ECDSA prime256v1 named-curve key. |
108 const int kKeyVersion = 1; | 118 const int kKeyVersion = 1; |
109 const uint8_t kKeyPubBytes[] = { | 119 const uint8_t kKeyPubBytes[] = { |
110 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, | 120 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, |
111 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, | 121 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, |
112 0x42, 0x00, 0x04, 0xeb, 0xd8, 0xad, 0x0b, 0x8f, 0x75, 0xe8, 0x84, 0x36, | 122 0x42, 0x00, 0x04, 0xeb, 0xd8, 0xad, 0x0b, 0x8f, 0x75, 0xe8, 0x84, 0x36, |
113 0x23, 0x48, 0x14, 0x24, 0xd3, 0x93, 0x42, 0x25, 0x43, 0xc1, 0xde, 0x36, | 123 0x23, 0x48, 0x14, 0x24, 0xd3, 0x93, 0x42, 0x25, 0x43, 0xc1, 0xde, 0x36, |
114 0x29, 0xc6, 0x95, 0xca, 0xeb, 0x28, 0x85, 0xff, 0x09, 0xdc, 0x08, 0xec, | 124 0x29, 0xc6, 0x95, 0xca, 0xeb, 0x28, 0x85, 0xff, 0x09, 0xdc, 0x08, 0xec, |
115 0x45, 0x74, 0x6e, 0x4b, 0xc3, 0xa5, 0xfd, 0x8a, 0x2f, 0x02, 0xa0, 0x4b, | 125 0x45, 0x74, 0x6e, 0x4b, 0xc3, 0xa5, 0xfd, 0x8a, 0x2f, 0x02, 0xa0, 0x4b, |
(...skipping 24 matching lines...) Expand all Loading... |
140 if (data().length() + num_bytes > limit_) { | 150 if (data().length() + num_bytes > limit_) { |
141 return net::ERR_FILE_TOO_BIG; | 151 return net::ERR_FILE_TOO_BIG; |
142 } | 152 } |
143 return net::URLFetcherStringWriter::Write(buffer, num_bytes, callback); | 153 return net::URLFetcherStringWriter::Write(buffer, num_bytes, callback); |
144 } | 154 } |
145 | 155 |
146 private: | 156 private: |
147 size_t limit_; | 157 size_t limit_; |
148 }; | 158 }; |
149 | 159 |
| 160 bool BackgroundQueriesEnabled() { |
| 161 if (!base::FeatureList::IsEnabled(kNetworkTimeServiceQuerying)) { |
| 162 return false; |
| 163 } |
| 164 |
| 165 const std::string param = variations::GetVariationParamValueByFeature( |
| 166 kNetworkTimeServiceQuerying, kVariationsServiceFetchBehavior); |
| 167 return param == "background-only" || param == "background-and-on-demand"; |
| 168 } |
| 169 |
| 170 bool OnDemandQueriesEnabled() { |
| 171 if (!base::FeatureList::IsEnabled(kNetworkTimeServiceQuerying)) { |
| 172 return false; |
| 173 } |
| 174 |
| 175 const std::string param = variations::GetVariationParamValueByFeature( |
| 176 kNetworkTimeServiceQuerying, kVariationsServiceFetchBehavior); |
| 177 return param == "on-demand-only" || param == "background-and-on-demand"; |
| 178 } |
| 179 |
150 base::TimeDelta CheckTimeInterval() { | 180 base::TimeDelta CheckTimeInterval() { |
151 int64_t seconds; | 181 int64_t seconds; |
152 const std::string param = variations::GetVariationParamValueByFeature( | 182 const std::string param = variations::GetVariationParamValueByFeature( |
153 kNetworkTimeServiceQuerying, kVariationsServiceCheckTimeIntervalSeconds); | 183 kNetworkTimeServiceQuerying, kVariationsServiceCheckTimeIntervalSeconds); |
154 if (!param.empty() && base::StringToInt64(param, &seconds) && seconds > 0) { | 184 if (!param.empty() && base::StringToInt64(param, &seconds) && seconds > 0) { |
155 return base::TimeDelta::FromSeconds(seconds); | 185 return base::TimeDelta::FromSeconds(seconds); |
156 } | 186 } |
157 return base::TimeDelta::FromSeconds(kCheckTimeIntervalSeconds); | 187 return base::TimeDelta::FromSeconds(kCheckTimeIntervalSeconds); |
158 } | 188 } |
159 | 189 |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 network_time_uncertainty_.ToInternalValue())); | 305 network_time_uncertainty_.ToInternalValue())); |
276 time_mapping.SetDouble(kPrefNetworkTime, | 306 time_mapping.SetDouble(kPrefNetworkTime, |
277 network_time_at_last_measurement_.ToJsTime()); | 307 network_time_at_last_measurement_.ToJsTime()); |
278 pref_service_->Set(prefs::kNetworkTimeMapping, time_mapping); | 308 pref_service_->Set(prefs::kNetworkTimeMapping, time_mapping); |
279 } | 309 } |
280 | 310 |
281 void NetworkTimeTracker::SetTimeServerURLForTesting(const GURL& url) { | 311 void NetworkTimeTracker::SetTimeServerURLForTesting(const GURL& url) { |
282 server_url_ = url; | 312 server_url_ = url; |
283 } | 313 } |
284 | 314 |
| 315 GURL NetworkTimeTracker::GetTimeServerURLForTesting() const { |
| 316 return server_url_; |
| 317 } |
| 318 |
285 void NetworkTimeTracker::SetMaxResponseSizeForTesting(size_t limit) { | 319 void NetworkTimeTracker::SetMaxResponseSizeForTesting(size_t limit) { |
286 max_response_size_ = limit; | 320 max_response_size_ = limit; |
287 } | 321 } |
288 | 322 |
289 void NetworkTimeTracker::SetPublicKeyForTesting(const base::StringPiece& key) { | 323 void NetworkTimeTracker::SetPublicKeyForTesting(const base::StringPiece& key) { |
290 query_signer_ = client_update_protocol::Ecdsa::Create(kKeyVersion, key); | 324 query_signer_ = client_update_protocol::Ecdsa::Create(kKeyVersion, key); |
291 } | 325 } |
292 | 326 |
293 bool NetworkTimeTracker::QueryTimeServiceForTesting() { | 327 bool NetworkTimeTracker::QueryTimeServiceForTesting() { |
294 CheckTime(); | 328 CheckTime(); |
295 return time_fetcher_ != nullptr; | 329 return time_fetcher_ != nullptr; |
296 } | 330 } |
297 | 331 |
298 void NetworkTimeTracker::WaitForFetchForTesting(uint32_t nonce) { | 332 void NetworkTimeTracker::WaitForFetchForTesting(uint32_t nonce) { |
299 query_signer_->OverrideNonceForTesting(kKeyVersion, nonce); | 333 query_signer_->OverrideNonceForTesting(kKeyVersion, nonce); |
300 base::RunLoop run_loop; | 334 base::RunLoop run_loop; |
301 fetch_completion_callbacks_.push_back(run_loop.QuitClosure()); | 335 fetch_completion_callbacks_.push_back(run_loop.QuitClosure()); |
302 run_loop.Run(); | 336 run_loop.Run(); |
303 } | 337 } |
304 | 338 |
| 339 void NetworkTimeTracker::OverrideNonceForTesting(uint32_t nonce) { |
| 340 query_signer_->OverrideNonceForTesting(kKeyVersion, nonce); |
| 341 } |
| 342 |
305 base::TimeDelta NetworkTimeTracker::GetTimerDelayForTesting() const { | 343 base::TimeDelta NetworkTimeTracker::GetTimerDelayForTesting() const { |
306 DCHECK(timer_.IsRunning()); | 344 DCHECK(timer_.IsRunning()); |
307 return timer_.GetCurrentDelay(); | 345 return timer_.GetCurrentDelay(); |
308 } | 346 } |
309 | 347 |
310 NetworkTimeTracker::NetworkTimeResult NetworkTimeTracker::GetNetworkTime( | 348 NetworkTimeTracker::NetworkTimeResult NetworkTimeTracker::GetNetworkTime( |
311 base::Time* network_time, | 349 base::Time* network_time, |
312 base::TimeDelta* uncertainty) const { | 350 base::TimeDelta* uncertainty) const { |
313 DCHECK(thread_checker_.CalledOnValidThread()); | 351 DCHECK(thread_checker_.CalledOnValidThread()); |
314 DCHECK(network_time); | 352 DCHECK(network_time); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 } | 405 } |
368 *network_time = network_time_at_last_measurement_ + tick_delta; | 406 *network_time = network_time_at_last_measurement_ + tick_delta; |
369 if (uncertainty) { | 407 if (uncertainty) { |
370 *uncertainty = network_time_uncertainty_ + divergence; | 408 *uncertainty = network_time_uncertainty_ + divergence; |
371 } | 409 } |
372 return NETWORK_TIME_AVAILABLE; | 410 return NETWORK_TIME_AVAILABLE; |
373 } | 411 } |
374 | 412 |
375 bool NetworkTimeTracker::StartTimeFetch(const base::Closure& closure) { | 413 bool NetworkTimeTracker::StartTimeFetch(const base::Closure& closure) { |
376 DCHECK(thread_checker_.CalledOnValidThread()); | 414 DCHECK(thread_checker_.CalledOnValidThread()); |
377 // Check if the user is opted in to on-demand time fetches. | 415 if (!OnDemandQueriesEnabled()) { |
378 const std::string param = variations::GetVariationParamValueByFeature( | |
379 kNetworkTimeServiceQuerying, kVariationsServiceEnableFetchesOnDemand); | |
380 if (param != "true") { | |
381 return false; | 416 return false; |
382 } | 417 } |
383 | 418 |
384 // Enqueue the callback before calling CheckTime(), so that if | 419 // Enqueue the callback before calling CheckTime(), so that if |
385 // CheckTime() completes synchronously, the callback gets called. | 420 // CheckTime() completes synchronously, the callback gets called. |
386 fetch_completion_callbacks_.push_back(closure); | 421 fetch_completion_callbacks_.push_back(closure); |
387 | 422 |
388 // If a time query is already in progress, do not start another one. | 423 // If a time query is already in progress, do not start another one. |
389 if (time_fetcher_) { | 424 if (time_fetcher_) { |
390 return true; | 425 return true; |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
529 // because a callback could call StartTimeFetch() to enqueue another | 564 // because a callback could call StartTimeFetch() to enqueue another |
530 // callback. | 565 // callback. |
531 std::vector<base::Closure> callbacks = fetch_completion_callbacks_; | 566 std::vector<base::Closure> callbacks = fetch_completion_callbacks_; |
532 fetch_completion_callbacks_.clear(); | 567 fetch_completion_callbacks_.clear(); |
533 for (const auto& callback : callbacks) { | 568 for (const auto& callback : callbacks) { |
534 callback.Run(); | 569 callback.Run(); |
535 } | 570 } |
536 } | 571 } |
537 | 572 |
538 void NetworkTimeTracker::QueueCheckTime(base::TimeDelta delay) { | 573 void NetworkTimeTracker::QueueCheckTime(base::TimeDelta delay) { |
539 timer_.Start(FROM_HERE, delay, this, &NetworkTimeTracker::CheckTime); | 574 // Check if the user is opted in to background time fetches. |
| 575 if (BackgroundQueriesEnabled()) { |
| 576 timer_.Start(FROM_HERE, delay, this, &NetworkTimeTracker::CheckTime); |
| 577 } |
540 } | 578 } |
541 | 579 |
542 bool NetworkTimeTracker::ShouldIssueTimeQuery() { | 580 bool NetworkTimeTracker::ShouldIssueTimeQuery() { |
543 // Do not query the time service if not enabled via Variations Service. | 581 // Do not query the time service if not enabled via Variations Service. |
544 if (!base::FeatureList::IsEnabled(kNetworkTimeServiceQuerying)) { | 582 if (!base::FeatureList::IsEnabled(kNetworkTimeServiceQuerying)) { |
545 return false; | 583 return false; |
546 } | 584 } |
547 | 585 |
548 // If GetNetworkTime() does not return NETWORK_TIME_AVAILABLE, | 586 // If GetNetworkTime() does not return NETWORK_TIME_AVAILABLE, |
549 // synchronization has been lost and a query is needed. | 587 // synchronization has been lost and a query is needed. |
550 base::Time network_time; | 588 base::Time network_time; |
551 if (GetNetworkTime(&network_time, nullptr) != NETWORK_TIME_AVAILABLE) { | 589 if (GetNetworkTime(&network_time, nullptr) != NETWORK_TIME_AVAILABLE) { |
552 return true; | 590 return true; |
553 } | 591 } |
554 | 592 |
555 // Otherwise, make the decision at random. | 593 // Otherwise, make the decision at random. |
556 return base::RandDouble() < RandomQueryProbability(); | 594 return base::RandDouble() < RandomQueryProbability(); |
557 } | 595 } |
558 | 596 |
559 } // namespace network_time | 597 } // namespace network_time |
OLD | NEW |