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/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 |