Chromium Code Reviews| Index: components/network_time/network_time_tracker.cc |
| diff --git a/components/network_time/network_time_tracker.cc b/components/network_time/network_time_tracker.cc |
| index d33de06568655a2f6a136e9a4ba7125385a8f8db..629016576a9fda82e8ea54ef43b7cc467c04740c 100644 |
| --- a/components/network_time/network_time_tracker.cc |
| +++ b/components/network_time/network_time_tracker.cc |
| @@ -100,6 +100,9 @@ const char kVariationsServiceCheckTimeIntervalSeconds[] = |
| "CheckTimeIntervalSeconds"; |
| const char kVariationsServiceRandomQueryProbability[] = |
| "RandomQueryProbability"; |
| +// This parameter must have the value "true" in order for |
| +// StartTimeFetch() to start time queries on demand. |
| +const char kVariationsServiceEnableFetchesOnDemand[] = "EnableFetchesOnDemand"; |
| // This is an ECDSA prime256v1 named-curve key. |
| const int kKeyVersion = 1; |
| @@ -295,9 +298,8 @@ bool NetworkTimeTracker::QueryTimeServiceForTesting() { |
| void NetworkTimeTracker::WaitForFetchForTesting(uint32_t nonce) { |
| query_signer_->OverrideNonceForTesting(kKeyVersion, nonce); |
| base::RunLoop run_loop; |
| - run_loop_for_testing_ = &run_loop; |
| + fetch_completion_callbacks_.push_back(run_loop.QuitClosure()); |
| run_loop.Run(); |
| - run_loop_for_testing_ = nullptr; |
| } |
| base::TimeDelta NetworkTimeTracker::GetTimerDelayForTesting() const { |
| @@ -316,18 +318,16 @@ NetworkTimeTracker::NetworkTimeResult NetworkTimeTracker::GetNetworkTime( |
| if (time_fetcher_) { |
| // A fetch (not the first attempt) is in progress. |
| return NETWORK_TIME_SUBSEQUENT_SYNC_PENDING; |
| - } else { |
| - return NETWORK_TIME_NO_SUCCESSFUL_SYNC; |
| - } |
| - } else { |
| - // No time queries have happened yet. |
| - if (time_fetcher_) { |
| - return NETWORK_TIME_FIRST_SYNC_PENDING; |
| - } else { |
| - return NETWORK_TIME_NO_SYNC_ATTEMPT; |
| } |
| + return NETWORK_TIME_NO_SUCCESSFUL_SYNC; |
|
estark
2016/10/25 20:14:00
unrelated cleanup, sorry. there was too much inden
|
| } |
| + // No time queries have happened yet. |
| + if (time_fetcher_) { |
| + return NETWORK_TIME_FIRST_SYNC_PENDING; |
| + } |
| + return NETWORK_TIME_NO_SYNC_ATTEMPT; |
| } |
| + |
| DCHECK(!ticks_at_last_measurement_.is_null()); |
| DCHECK(!time_at_last_measurement_.is_null()); |
| base::TimeDelta tick_delta = |
| @@ -372,6 +372,40 @@ NetworkTimeTracker::NetworkTimeResult NetworkTimeTracker::GetNetworkTime( |
| return NETWORK_TIME_AVAILABLE; |
| } |
| +bool NetworkTimeTracker::StartTimeFetch(const base::Closure& closure) { |
|
meacer
2016/10/26 19:19:22
Could you add a DCHECK(thread_checker_.CalledOnVal
estark
2016/10/26 20:35:13
Done.
|
| + // Check if the user is opted in to on-demand time fetches. |
| + const std::string param = variations::GetVariationParamValueByFeature( |
| + kNetworkTimeServiceQuerying, kVariationsServiceEnableFetchesOnDemand); |
| + if (param != "true") { |
| + return false; |
| + } |
| + |
| + // Enqueue the callback before calling CheckTime(), so that if |
| + // CheckTime() completes synchronously, the callback gets called. |
| + fetch_completion_callbacks_.push_back(closure); |
| + |
| + // If a time query is already in progress, do not start another one. |
| + if (time_fetcher_) { |
| + return true; |
| + } |
| + |
| + // Cancel any fetches that are scheduled for the future, and try to |
| + // start one now. |
|
meacer
2016/10/26 00:38:15
For my own education: If two clients call StartTim
meacer
2016/10/26 01:07:37
"If two clients call StartTimeFetch one of the oth
|
| + timer_.Stop(); |
| + CheckTime(); |
| + |
| + // CheckTime() does not necessarily start a fetch; for example, time |
| + // queries might be disabled or network time might already be |
| + // available. |
| + if (!time_fetcher_) { |
| + // If no query is in progress, there should be no callbacks waiting for it |
| + // to complete. |
|
meacer
2016/10/26 19:19:22
nit: I'm a bit confused by this comment, it sounds
estark
2016/10/26 20:35:13
Oh, yes, what I wrote was confusing. Done.
|
| + fetch_completion_callbacks_.clear(); |
| + return false; |
| + } |
| + return true; |
| +} |
| + |
| void NetworkTimeTracker::CheckTime() { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| @@ -490,8 +524,15 @@ void NetworkTimeTracker::OnURLFetchComplete(const net::URLFetcher* source) { |
| } |
| QueueCheckTime(backoff_); |
| time_fetcher_.reset(); |
| - if (run_loop_for_testing_ != nullptr) |
| - run_loop_for_testing_->QuitWhenIdle(); |
| + |
| + // Clear |fetch_completion_callbacks_| before running any of them, |
| + // because a callback could call StartTimeFetch() to enqueue another |
| + // callback. |
| + std::vector<base::Closure> callbacks = fetch_completion_callbacks_; |
| + fetch_completion_callbacks_.clear(); |
| + for (const auto& callback : callbacks) { |
| + callback.Run(); |
| + } |
| } |
| void NetworkTimeTracker::QueueCheckTime(base::TimeDelta delay) { |