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/suggestions/suggestions_service.h" | 5 #include "components/suggestions/suggestions_service.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/feature_list.h" | 9 #include "base/feature_list.h" |
10 #include "base/location.h" | 10 #include "base/location.h" |
11 #include "base/metrics/histogram_macros.h" | 11 #include "base/metrics/histogram_macros.h" |
12 #include "base/metrics/sparse_histogram.h" | 12 #include "base/metrics/sparse_histogram.h" |
13 #include "base/strings/string_number_conversions.h" | 13 #include "base/strings/string_number_conversions.h" |
14 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
15 #include "base/strings/stringprintf.h" | 15 #include "base/strings/stringprintf.h" |
16 #include "base/thread_task_runner_handle.h" | 16 #include "base/thread_task_runner_handle.h" |
17 #include "build/build_config.h" | 17 #include "build/build_config.h" |
18 #include "components/data_use_measurement/core/data_use_user_data.h" | 18 #include "components/data_use_measurement/core/data_use_user_data.h" |
19 #include "components/google/core/browser/google_util.h" | 19 #include "components/google/core/browser/google_util.h" |
20 #include "components/pref_registry/pref_registry_syncable.h" | 20 #include "components/pref_registry/pref_registry_syncable.h" |
21 #include "components/signin/core/browser/signin_manager_base.h" | 21 #include "components/signin/core/browser/signin_manager_base.h" |
22 #include "components/suggestions/blacklist_store.h" | 22 #include "components/suggestions/blacklist_store.h" |
23 #include "components/suggestions/image_manager.h" | 23 #include "components/suggestions/image_manager.h" |
24 #include "components/suggestions/suggestions_store.h" | 24 #include "components/suggestions/suggestions_store.h" |
25 #include "components/sync_driver/sync_service.h" | |
25 #include "components/variations/net/variations_http_headers.h" | 26 #include "components/variations/net/variations_http_headers.h" |
26 #include "google_apis/gaia/gaia_constants.h" | 27 #include "google_apis/gaia/gaia_constants.h" |
27 #include "google_apis/gaia/oauth2_token_service.h" | 28 #include "google_apis/gaia/oauth2_token_service.h" |
28 #include "net/base/escape.h" | 29 #include "net/base/escape.h" |
29 #include "net/base/load_flags.h" | 30 #include "net/base/load_flags.h" |
30 #include "net/base/net_errors.h" | 31 #include "net/base/net_errors.h" |
31 #include "net/base/url_util.h" | 32 #include "net/base/url_util.h" |
32 #include "net/http/http_response_headers.h" | 33 #include "net/http/http_response_headers.h" |
33 #include "net/http/http_status_code.h" | 34 #include "net/http/http_status_code.h" |
34 #include "net/http/http_util.h" | 35 #include "net/http/http_util.h" |
35 #include "net/url_request/url_fetcher.h" | 36 #include "net/url_request/url_fetcher.h" |
36 #include "net/url_request/url_request_status.h" | 37 #include "net/url_request/url_request_status.h" |
37 | 38 |
38 using base::TimeDelta; | 39 using base::TimeDelta; |
39 using base::TimeTicks; | 40 using base::TimeTicks; |
40 | 41 |
41 namespace suggestions { | 42 namespace suggestions { |
42 | 43 |
43 namespace { | 44 namespace { |
44 | 45 |
46 // Establishes the different sync states that matter to SuggestionsService. | |
47 // There are three different concepts in the sync service: initialized, sync | |
48 // enabled and history sync enabled. | |
49 enum SyncState { | |
50 // State: Sync service is not initialized, yet not disabled. History sync | |
51 // state is unknown (since not initialized). | |
52 // Behavior: Does not issue a server request, but serves from cache if | |
53 // available. | |
54 NOT_INITIALIZED_ENABLED, | |
55 | |
56 // State: Sync service is initialized, sync is enabled and history sync is | |
57 // enabled. | |
58 // Behavior: Update suggestions from the server. Serve from cache on timeout. | |
59 INITIALIZED_ENABLED_HISTORY, | |
60 | |
61 // State: Sync service is disabled or history sync is disabled. | |
62 // Behavior: Do not issue a server request. Clear the cache. Serve empty | |
63 // suggestions. | |
64 SYNC_OR_HISTORY_SYNC_DISABLED, | |
65 }; | |
66 | |
67 SyncState GetSyncState(sync_driver::SyncService* sync) { | |
68 if (!sync || !sync->CanSyncStart()) | |
69 return SYNC_OR_HISTORY_SYNC_DISABLED; | |
70 if (!sync->IsSyncActive() || !sync->ConfigurationDone()) | |
71 return NOT_INITIALIZED_ENABLED; | |
72 return sync->GetActiveDataTypes().Has(syncer::HISTORY_DELETE_DIRECTIVES) | |
73 ? INITIALIZED_ENABLED_HISTORY | |
74 : SYNC_OR_HISTORY_SYNC_DISABLED; | |
75 } | |
76 | |
45 // Used to UMA log the state of the last response from the server. | 77 // Used to UMA log the state of the last response from the server. |
46 enum SuggestionsResponseState { | 78 enum SuggestionsResponseState { |
47 RESPONSE_EMPTY, | 79 RESPONSE_EMPTY, |
48 RESPONSE_INVALID, | 80 RESPONSE_INVALID, |
49 RESPONSE_VALID, | 81 RESPONSE_VALID, |
50 RESPONSE_STATE_SIZE | 82 RESPONSE_STATE_SIZE |
51 }; | 83 }; |
52 | 84 |
53 // Will log the supplied response |state|. | 85 // Will log the supplied response |state|. |
54 void LogResponseState(SuggestionsResponseState state) { | 86 void LogResponseState(SuggestionsResponseState state) { |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
160 const SigninManagerBase* signin_manager_; | 192 const SigninManagerBase* signin_manager_; |
161 OAuth2TokenService* token_service_; | 193 OAuth2TokenService* token_service_; |
162 | 194 |
163 TokenCallback callback_; | 195 TokenCallback callback_; |
164 scoped_ptr<OAuth2TokenService::Request> token_request_; | 196 scoped_ptr<OAuth2TokenService::Request> token_request_; |
165 }; | 197 }; |
166 | 198 |
167 SuggestionsService::SuggestionsService( | 199 SuggestionsService::SuggestionsService( |
168 const SigninManagerBase* signin_manager, | 200 const SigninManagerBase* signin_manager, |
169 OAuth2TokenService* token_service, | 201 OAuth2TokenService* token_service, |
202 sync_driver::SyncService* sync_service, | |
170 net::URLRequestContextGetter* url_request_context, | 203 net::URLRequestContextGetter* url_request_context, |
171 scoped_ptr<SuggestionsStore> suggestions_store, | 204 scoped_ptr<SuggestionsStore> suggestions_store, |
172 scoped_ptr<ImageManager> thumbnail_manager, | 205 scoped_ptr<ImageManager> thumbnail_manager, |
173 scoped_ptr<BlacklistStore> blacklist_store) | 206 scoped_ptr<BlacklistStore> blacklist_store) |
174 : url_request_context_(url_request_context), | 207 : sync_service_(sync_service), |
208 sync_service_observer_(this), | |
209 url_request_context_(url_request_context), | |
175 suggestions_store_(std::move(suggestions_store)), | 210 suggestions_store_(std::move(suggestions_store)), |
176 thumbnail_manager_(std::move(thumbnail_manager)), | 211 thumbnail_manager_(std::move(thumbnail_manager)), |
177 blacklist_store_(std::move(blacklist_store)), | 212 blacklist_store_(std::move(blacklist_store)), |
178 scheduling_delay_(TimeDelta::FromSeconds(kDefaultSchedulingDelaySec)), | 213 scheduling_delay_(TimeDelta::FromSeconds(kDefaultSchedulingDelaySec)), |
179 token_fetcher_(new AccessTokenFetcher(signin_manager, token_service)), | 214 token_fetcher_(new AccessTokenFetcher(signin_manager, token_service)), |
180 weak_ptr_factory_(this) {} | 215 weak_ptr_factory_(this) { |
216 // |sync_service_| is null if switches::kDisableSync is set (tests use that). | |
217 if (sync_service_) | |
218 sync_service_observer_.Add(sync_service_); | |
219 // Immediately get the current sync state, so we'll flush the cache if | |
220 // necessary. | |
221 OnStateChanged(); | |
222 } | |
181 | 223 |
182 SuggestionsService::~SuggestionsService() {} | 224 SuggestionsService::~SuggestionsService() {} |
183 | 225 |
184 void SuggestionsService::FetchSuggestionsData( | 226 bool SuggestionsService::FetchSuggestionsData() { |
185 SyncState sync_state, | |
186 const ResponseCallback& callback) { | |
187 DCHECK(thread_checker_.CalledOnValidThread()); | 227 DCHECK(thread_checker_.CalledOnValidThread()); |
188 switch (sync_state) { | 228 // If sync state allows, issue a network request to refresh the suggestions. |
189 case SYNC_OR_HISTORY_SYNC_DISABLED: | 229 if (GetSyncState(sync_service_) != INITIALIZED_ENABLED_HISTORY) |
190 // Cancel any ongoing request, to stop interacting with the server. | 230 return false; |
191 pending_request_.reset(nullptr); | 231 IssueRequestIfNoneOngoing(BuildSuggestionsURL()); |
192 suggestions_store_->ClearSuggestions(); | 232 return true; |
193 if (!callback.is_null()) | 233 } |
194 callback.Run(SuggestionsProfile()); | |
195 break; | |
196 case INITIALIZED_ENABLED_HISTORY: | |
197 case NOT_INITIALIZED_ENABLED: | |
198 // TODO(treib): For NOT_INITIALIZED_ENABLED, we shouldn't issue a network | |
199 // request. Verify that that won't break anything. | |
200 // Sync is enabled. Serve previously cached suggestions if available, else | |
201 // an empty set of suggestions. | |
202 ServeFromCache(callback); | |
203 | 234 |
204 // Issue a network request to refresh the suggestions in the cache. | 235 SuggestionsProfile SuggestionsService::GetSuggestionsDataFromCache() const { |
205 IssueRequestIfNoneOngoing(BuildSuggestionsURL()); | 236 SuggestionsProfile suggestions; |
206 break; | 237 // In case of empty cache or error, |suggestions| stays empty. |
207 } | 238 suggestions_store_->LoadSuggestions(&suggestions); |
239 thumbnail_manager_->Initialize(suggestions); | |
240 blacklist_store_->FilterSuggestions(&suggestions); | |
241 return suggestions; | |
242 } | |
243 | |
244 scoped_ptr<SuggestionsService::ResponseCallbackList::Subscription> | |
245 SuggestionsService::AddCallback(const ResponseCallback& callback) { | |
246 return callback_list_.Add(callback); | |
208 } | 247 } |
209 | 248 |
210 void SuggestionsService::GetPageThumbnail(const GURL& url, | 249 void SuggestionsService::GetPageThumbnail(const GURL& url, |
211 const BitmapCallback& callback) { | 250 const BitmapCallback& callback) { |
212 thumbnail_manager_->GetImageForURL(url, callback); | 251 thumbnail_manager_->GetImageForURL(url, callback); |
213 } | 252 } |
214 | 253 |
215 void SuggestionsService::GetPageThumbnailWithURL( | 254 void SuggestionsService::GetPageThumbnailWithURL( |
216 const GURL& url, | 255 const GURL& url, |
217 const GURL& thumbnail_url, | 256 const GURL& thumbnail_url, |
218 const BitmapCallback& callback) { | 257 const BitmapCallback& callback) { |
219 thumbnail_manager_->AddImageURL(url, thumbnail_url); | 258 thumbnail_manager_->AddImageURL(url, thumbnail_url); |
220 GetPageThumbnail(url, callback); | 259 GetPageThumbnail(url, callback); |
221 } | 260 } |
222 | 261 |
223 void SuggestionsService::BlacklistURL(const GURL& candidate_url, | 262 bool SuggestionsService::BlacklistURL(const GURL& candidate_url) { |
224 const ResponseCallback& callback, | |
225 const base::Closure& fail_callback) { | |
226 DCHECK(thread_checker_.CalledOnValidThread()); | 263 DCHECK(thread_checker_.CalledOnValidThread()); |
227 | 264 |
228 if (!blacklist_store_->BlacklistUrl(candidate_url)) { | 265 if (!blacklist_store_->BlacklistUrl(candidate_url)) |
229 if (!fail_callback.is_null()) | 266 return false; |
230 fail_callback.Run(); | |
231 return; | |
232 } | |
233 | 267 |
234 ServeFromCache(callback); | 268 callback_list_.Notify(GetSuggestionsDataFromCache()); |
269 | |
235 // Blacklist uploads are scheduled on any request completion, so only schedule | 270 // Blacklist uploads are scheduled on any request completion, so only schedule |
236 // an upload if there is no ongoing request. | 271 // an upload if there is no ongoing request. |
237 if (!pending_request_.get()) | 272 if (!pending_request_.get()) |
238 ScheduleBlacklistUpload(); | 273 ScheduleBlacklistUpload(); |
274 | |
275 return true; | |
239 } | 276 } |
240 | 277 |
241 void SuggestionsService::UndoBlacklistURL(const GURL& url, | 278 bool SuggestionsService::UndoBlacklistURL(const GURL& url) { |
242 const ResponseCallback& callback, | |
243 const base::Closure& fail_callback) { | |
244 DCHECK(thread_checker_.CalledOnValidThread()); | 279 DCHECK(thread_checker_.CalledOnValidThread()); |
245 TimeDelta time_delta; | 280 TimeDelta time_delta; |
246 if (blacklist_store_->GetTimeUntilURLReadyForUpload(url, &time_delta) && | 281 if (blacklist_store_->GetTimeUntilURLReadyForUpload(url, &time_delta) && |
247 time_delta > TimeDelta::FromSeconds(0) && | 282 time_delta > TimeDelta::FromSeconds(0) && |
248 blacklist_store_->RemoveUrl(url)) { | 283 blacklist_store_->RemoveUrl(url)) { |
249 // The URL was not yet candidate for upload to the server and could be | 284 // The URL was not yet candidate for upload to the server and could be |
250 // removed from the blacklist. | 285 // removed from the blacklist. |
251 ServeFromCache(callback); | 286 callback_list_.Notify(GetSuggestionsDataFromCache()); |
252 return; | 287 return true; |
253 } | 288 } |
254 if (!fail_callback.is_null()) | 289 return false; |
255 fail_callback.Run(); | |
256 } | 290 } |
257 | 291 |
258 void SuggestionsService::ClearBlacklist(const ResponseCallback& callback) { | 292 void SuggestionsService::ClearBlacklist() { |
259 DCHECK(thread_checker_.CalledOnValidThread()); | 293 DCHECK(thread_checker_.CalledOnValidThread()); |
260 blacklist_store_->ClearBlacklist(); | 294 blacklist_store_->ClearBlacklist(); |
295 callback_list_.Notify(GetSuggestionsDataFromCache()); | |
261 IssueRequestIfNoneOngoing(BuildSuggestionsBlacklistClearURL()); | 296 IssueRequestIfNoneOngoing(BuildSuggestionsBlacklistClearURL()); |
262 ServeFromCache(callback); | |
263 } | 297 } |
264 | 298 |
265 // static | 299 // static |
266 bool SuggestionsService::GetBlacklistedUrl(const net::URLFetcher& request, | 300 bool SuggestionsService::GetBlacklistedUrl(const net::URLFetcher& request, |
267 GURL* url) { | 301 GURL* url) { |
268 bool is_blacklist_request = base::StartsWith( | 302 bool is_blacklist_request = base::StartsWith( |
269 request.GetOriginalURL().spec(), BuildSuggestionsBlacklistURLPrefix(), | 303 request.GetOriginalURL().spec(), BuildSuggestionsBlacklistURLPrefix(), |
270 base::CompareCase::SENSITIVE); | 304 base::CompareCase::SENSITIVE); |
271 if (!is_blacklist_request) return false; | 305 if (!is_blacklist_request) return false; |
272 | 306 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
316 net::EscapeQueryParamValue(candidate_url.spec(), true)); | 350 net::EscapeQueryParamValue(candidate_url.spec(), true)); |
317 } | 351 } |
318 | 352 |
319 // static | 353 // static |
320 GURL SuggestionsService::BuildSuggestionsBlacklistClearURL() { | 354 GURL SuggestionsService::BuildSuggestionsBlacklistClearURL() { |
321 return GURL(base::StringPrintf(kSuggestionsBlacklistClearURLFormat, | 355 return GURL(base::StringPrintf(kSuggestionsBlacklistClearURLFormat, |
322 GetGoogleBaseURL().spec().c_str(), | 356 GetGoogleBaseURL().spec().c_str(), |
323 kDeviceType)); | 357 kDeviceType)); |
324 } | 358 } |
325 | 359 |
360 void SuggestionsService::OnStateChanged() { | |
361 switch (GetSyncState(sync_service_)) { | |
362 case SYNC_OR_HISTORY_SYNC_DISABLED: | |
363 // Cancel any ongoing request, to stop interacting with the server. | |
364 pending_request_.reset(nullptr); | |
365 suggestions_store_->ClearSuggestions(); | |
366 callback_list_.Notify(SuggestionsProfile()); | |
367 break; | |
368 case NOT_INITIALIZED_ENABLED: | |
369 // Keep the cache (if any), but don't refresh. | |
370 break; | |
371 case INITIALIZED_ENABLED_HISTORY: | |
372 // If we have any observers, issue a network request to refresh the | |
373 // suggestions in the cache. | |
374 if (!callback_list_.empty()) | |
375 IssueRequestIfNoneOngoing(BuildSuggestionsURL()); | |
Mathieu
2016/03/08 14:52:34
So the first OnStateChanged that is called in the
Marc Treib
2016/03/08 15:31:17
The main reason I put this in was to avoid lots of
| |
376 break; | |
377 } | |
378 } | |
379 | |
326 void SuggestionsService::SetDefaultExpiryTimestamp( | 380 void SuggestionsService::SetDefaultExpiryTimestamp( |
327 SuggestionsProfile* suggestions, | 381 SuggestionsProfile* suggestions, |
328 int64_t default_timestamp_usec) { | 382 int64_t default_timestamp_usec) { |
329 for (int i = 0; i < suggestions->suggestions_size(); ++i) { | 383 for (int i = 0; i < suggestions->suggestions_size(); ++i) { |
330 ChromeSuggestion* suggestion = suggestions->mutable_suggestions(i); | 384 ChromeSuggestion* suggestion = suggestions->mutable_suggestions(i); |
331 // Do not set expiry if the server has already provided a more specific | 385 // Do not set expiry if the server has already provided a more specific |
332 // expiry time for this suggestion. | 386 // expiry time for this suggestion. |
333 if (!suggestion->has_expiry_ts()) { | 387 if (!suggestion->has_expiry_ts()) { |
334 suggestion->set_expiry_ts(default_timestamp_usec); | 388 suggestion->set_expiry_ts(default_timestamp_usec); |
335 } | 389 } |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
448 int64_t now_usec = | 502 int64_t now_usec = |
449 (base::Time::NowFromSystemTime() - base::Time::UnixEpoch()) | 503 (base::Time::NowFromSystemTime() - base::Time::UnixEpoch()) |
450 .ToInternalValue(); | 504 .ToInternalValue(); |
451 SetDefaultExpiryTimestamp(&suggestions, now_usec + kDefaultExpiryUsec); | 505 SetDefaultExpiryTimestamp(&suggestions, now_usec + kDefaultExpiryUsec); |
452 PopulateExtraData(&suggestions); | 506 PopulateExtraData(&suggestions); |
453 suggestions_store_->StoreSuggestions(suggestions); | 507 suggestions_store_->StoreSuggestions(suggestions); |
454 } else { | 508 } else { |
455 LogResponseState(RESPONSE_INVALID); | 509 LogResponseState(RESPONSE_INVALID); |
456 } | 510 } |
457 | 511 |
512 callback_list_.Notify(GetSuggestionsDataFromCache()); | |
513 | |
458 UpdateBlacklistDelay(true); | 514 UpdateBlacklistDelay(true); |
459 ScheduleBlacklistUpload(); | 515 ScheduleBlacklistUpload(); |
460 } | 516 } |
461 | 517 |
462 void SuggestionsService::PopulateExtraData(SuggestionsProfile* suggestions) { | 518 void SuggestionsService::PopulateExtraData(SuggestionsProfile* suggestions) { |
463 for (int i = 0; i < suggestions->suggestions_size(); ++i) { | 519 for (int i = 0; i < suggestions->suggestions_size(); ++i) { |
464 suggestions::ChromeSuggestion* s = suggestions->mutable_suggestions(i); | 520 suggestions::ChromeSuggestion* s = suggestions->mutable_suggestions(i); |
465 if (!s->has_favicon_url() || s->favicon_url().empty()) { | 521 if (!s->has_favicon_url() || s->favicon_url().empty()) { |
466 s->set_favicon_url(base::StringPrintf(kFaviconURL, s->url().c_str())); | 522 s->set_favicon_url(base::StringPrintf(kFaviconURL, s->url().c_str())); |
467 } | 523 } |
468 if (!s->has_impression_url() || s->impression_url().empty()) { | 524 if (!s->has_impression_url() || s->impression_url().empty()) { |
469 s->set_impression_url( | 525 s->set_impression_url( |
470 base::StringPrintf( | 526 base::StringPrintf( |
471 kPingURL, static_cast<long long>(suggestions->timestamp()), -1)); | 527 kPingURL, static_cast<long long>(suggestions->timestamp()), -1)); |
472 } | 528 } |
473 | 529 |
474 if (!s->has_click_url() || s->click_url().empty()) { | 530 if (!s->has_click_url() || s->click_url().empty()) { |
475 s->set_click_url(base::StringPrintf( | 531 s->set_click_url(base::StringPrintf( |
476 kPingURL, static_cast<long long>(suggestions->timestamp()), i)); | 532 kPingURL, static_cast<long long>(suggestions->timestamp()), i)); |
477 } | 533 } |
478 } | 534 } |
479 } | 535 } |
480 | 536 |
481 void SuggestionsService::Shutdown() { | 537 void SuggestionsService::Shutdown() { |
482 // Cancel pending request. | 538 // Cancel pending request. |
483 pending_request_.reset(nullptr); | 539 pending_request_.reset(nullptr); |
484 } | 540 } |
485 | 541 |
486 void SuggestionsService::ServeFromCache(const ResponseCallback& callback) { | |
487 SuggestionsProfile suggestions; | |
488 // In case of empty cache or error, |suggestions| stays empty. | |
489 suggestions_store_->LoadSuggestions(&suggestions); | |
490 thumbnail_manager_->Initialize(suggestions); | |
491 blacklist_store_->FilterSuggestions(&suggestions); | |
492 if (!callback.is_null()) | |
493 callback.Run(suggestions); | |
494 } | |
495 | |
496 void SuggestionsService::ScheduleBlacklistUpload() { | 542 void SuggestionsService::ScheduleBlacklistUpload() { |
497 DCHECK(thread_checker_.CalledOnValidThread()); | 543 DCHECK(thread_checker_.CalledOnValidThread()); |
498 TimeDelta time_delta; | 544 TimeDelta time_delta; |
499 if (blacklist_store_->GetTimeUntilReadyForUpload(&time_delta)) { | 545 if (blacklist_store_->GetTimeUntilReadyForUpload(&time_delta)) { |
500 // Blacklist cache is not empty: schedule. | 546 // Blacklist cache is not empty: schedule. |
501 base::Closure blacklist_cb = | 547 base::Closure blacklist_cb = |
502 base::Bind(&SuggestionsService::UploadOneFromBlacklist, | 548 base::Bind(&SuggestionsService::UploadOneFromBlacklist, |
503 weak_ptr_factory_.GetWeakPtr()); | 549 weak_ptr_factory_.GetWeakPtr()); |
504 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 550 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
505 FROM_HERE, blacklist_cb, time_delta + scheduling_delay_); | 551 FROM_HERE, blacklist_cb, time_delta + scheduling_delay_); |
(...skipping 23 matching lines...) Expand all Loading... | |
529 scheduling_delay_ = TimeDelta::FromSeconds(kDefaultSchedulingDelaySec); | 575 scheduling_delay_ = TimeDelta::FromSeconds(kDefaultSchedulingDelaySec); |
530 } else { | 576 } else { |
531 TimeDelta candidate_delay = | 577 TimeDelta candidate_delay = |
532 scheduling_delay_ * kSchedulingBackoffMultiplier; | 578 scheduling_delay_ * kSchedulingBackoffMultiplier; |
533 if (candidate_delay < TimeDelta::FromSeconds(kSchedulingMaxDelaySec)) | 579 if (candidate_delay < TimeDelta::FromSeconds(kSchedulingMaxDelaySec)) |
534 scheduling_delay_ = candidate_delay; | 580 scheduling_delay_ = candidate_delay; |
535 } | 581 } |
536 } | 582 } |
537 | 583 |
538 } // namespace suggestions | 584 } // namespace suggestions |
OLD | NEW |