Chromium Code Reviews| 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"); | |
|
meacer
2016/11/08 19:39:41
minor nit: no need for parenthesis, here and blow.
estark
2016/11/08 19:46:34
Done.
| |
| 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 |