| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/ntp_snippets/remote/remote_suggestions_provider.h" | 5 #include "components/ntp_snippets/remote/remote_suggestions_provider.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <iterator> | 8 #include <iterator> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 #include "base/time/default_tick_clock.h" | 22 #include "base/time/default_tick_clock.h" |
| 23 #include "base/time/time.h" | 23 #include "base/time/time.h" |
| 24 #include "base/values.h" | 24 #include "base/values.h" |
| 25 #include "components/data_use_measurement/core/data_use_user_data.h" | 25 #include "components/data_use_measurement/core/data_use_user_data.h" |
| 26 #include "components/history/core/browser/history_service.h" | 26 #include "components/history/core/browser/history_service.h" |
| 27 #include "components/image_fetcher/image_decoder.h" | 27 #include "components/image_fetcher/image_decoder.h" |
| 28 #include "components/image_fetcher/image_fetcher.h" | 28 #include "components/image_fetcher/image_fetcher.h" |
| 29 #include "components/ntp_snippets/features.h" | 29 #include "components/ntp_snippets/features.h" |
| 30 #include "components/ntp_snippets/pref_names.h" | 30 #include "components/ntp_snippets/pref_names.h" |
| 31 #include "components/ntp_snippets/remote/remote_suggestions_database.h" | 31 #include "components/ntp_snippets/remote/remote_suggestions_database.h" |
| 32 #include "components/ntp_snippets/remote/remote_suggestions_scheduler.h" |
| 32 #include "components/ntp_snippets/switches.h" | 33 #include "components/ntp_snippets/switches.h" |
| 33 #include "components/ntp_snippets/user_classifier.h" | 34 #include "components/ntp_snippets/user_classifier.h" |
| 34 #include "components/prefs/pref_registry_simple.h" | 35 #include "components/prefs/pref_registry_simple.h" |
| 35 #include "components/prefs/pref_service.h" | 36 #include "components/prefs/pref_service.h" |
| 36 #include "components/variations/variations_associated_data.h" | 37 #include "components/variations/variations_associated_data.h" |
| 37 #include "grit/components_strings.h" | 38 #include "grit/components_strings.h" |
| 38 #include "ui/base/l10n/l10n_util.h" | 39 #include "ui/base/l10n/l10n_util.h" |
| 39 #include "ui/gfx/image/image.h" | 40 #include "ui/gfx/image/image.h" |
| 40 | 41 |
| 41 namespace ntp_snippets { | 42 namespace ntp_snippets { |
| 42 | 43 |
| 43 namespace { | 44 namespace { |
| 44 | 45 |
| 45 // Number of snippets requested to the server. Consider replacing sparse UMA | 46 // Number of snippets requested to the server. Consider replacing sparse UMA |
| 46 // histograms with COUNTS() if this number increases beyond 50. | 47 // histograms with COUNTS() if this number increases beyond 50. |
| 47 const int kMaxSnippetCount = 10; | 48 const int kMaxSnippetCount = 10; |
| 48 | 49 |
| 49 // Number of archived snippets we keep around in memory. | 50 // Number of archived snippets we keep around in memory. |
| 50 const int kMaxArchivedSnippetCount = 200; | 51 const int kMaxArchivedSnippetCount = 200; |
| 51 | 52 |
| 52 // Default values for fetching intervals, fallback and wifi. | |
| 53 const double kDefaultFetchingIntervalRareNtpUser[] = {48.0, 24.0}; | |
| 54 const double kDefaultFetchingIntervalActiveNtpUser[] = {24.0, 6.0}; | |
| 55 const double kDefaultFetchingIntervalActiveSuggestionsConsumer[] = {24.0, 6.0}; | |
| 56 | |
| 57 // Variation parameters than can override the default fetching intervals. | |
| 58 const char* kFetchingIntervalParamNameRareNtpUser[] = { | |
| 59 "fetching_interval_hours-fallback-rare_ntp_user", | |
| 60 "fetching_interval_hours-wifi-rare_ntp_user"}; | |
| 61 const char* kFetchingIntervalParamNameActiveNtpUser[] = { | |
| 62 "fetching_interval_hours-fallback-active_ntp_user", | |
| 63 "fetching_interval_hours-wifi-active_ntp_user"}; | |
| 64 const char* kFetchingIntervalParamNameActiveSuggestionsConsumer[] = { | |
| 65 "fetching_interval_hours-fallback-active_suggestions_consumer", | |
| 66 "fetching_interval_hours-wifi-active_suggestions_consumer"}; | |
| 67 | |
| 68 // Keys for storing CategoryContent info in prefs. | 53 // Keys for storing CategoryContent info in prefs. |
| 69 const char kCategoryContentId[] = "id"; | 54 const char kCategoryContentId[] = "id"; |
| 70 const char kCategoryContentTitle[] = "title"; | 55 const char kCategoryContentTitle[] = "title"; |
| 71 const char kCategoryContentProvidedByServer[] = "provided_by_server"; | 56 const char kCategoryContentProvidedByServer[] = "provided_by_server"; |
| 72 const char kCategoryContentAllowFetchingMore[] = "allow_fetching_more"; | 57 const char kCategoryContentAllowFetchingMore[] = "allow_fetching_more"; |
| 73 | 58 |
| 74 // TODO(treib): Remove after M57. | 59 // TODO(treib): Remove after M57. |
| 75 const char kDeprecatedSnippetHostsPref[] = "ntp_snippets.hosts"; | 60 const char kDeprecatedSnippetHostsPref[] = "ntp_snippets.hosts"; |
| 76 | 61 |
| 77 base::TimeDelta GetFetchingInterval(bool is_wifi, | |
| 78 UserClassifier::UserClass user_class) { | |
| 79 double value_hours = 0.0; | |
| 80 | |
| 81 const int index = is_wifi ? 1 : 0; | |
| 82 const char* param_name = ""; | |
| 83 switch (user_class) { | |
| 84 case UserClassifier::UserClass::RARE_NTP_USER: | |
| 85 value_hours = kDefaultFetchingIntervalRareNtpUser[index]; | |
| 86 param_name = kFetchingIntervalParamNameRareNtpUser[index]; | |
| 87 break; | |
| 88 case UserClassifier::UserClass::ACTIVE_NTP_USER: | |
| 89 value_hours = kDefaultFetchingIntervalActiveNtpUser[index]; | |
| 90 param_name = kFetchingIntervalParamNameActiveNtpUser[index]; | |
| 91 break; | |
| 92 case UserClassifier::UserClass::ACTIVE_SUGGESTIONS_CONSUMER: | |
| 93 value_hours = kDefaultFetchingIntervalActiveSuggestionsConsumer[index]; | |
| 94 param_name = kFetchingIntervalParamNameActiveSuggestionsConsumer[index]; | |
| 95 break; | |
| 96 } | |
| 97 | |
| 98 // The default value can be overridden by a variation parameter. | |
| 99 std::string param_value_str = variations::GetVariationParamValueByFeature( | |
| 100 ntp_snippets::kArticleSuggestionsFeature, param_name); | |
| 101 if (!param_value_str.empty()) { | |
| 102 double param_value_hours = 0.0; | |
| 103 if (base::StringToDouble(param_value_str, ¶m_value_hours)) { | |
| 104 value_hours = param_value_hours; | |
| 105 } else { | |
| 106 LOG(WARNING) << "Invalid value for variation parameter " << param_name; | |
| 107 } | |
| 108 } | |
| 109 | |
| 110 return base::TimeDelta::FromSecondsD(value_hours * 3600.0); | |
| 111 } | |
| 112 | |
| 113 std::unique_ptr<std::vector<std::string>> GetSnippetIDVector( | 62 std::unique_ptr<std::vector<std::string>> GetSnippetIDVector( |
| 114 const NTPSnippet::PtrVector& snippets) { | 63 const NTPSnippet::PtrVector& snippets) { |
| 115 auto result = base::MakeUnique<std::vector<std::string>>(); | 64 auto result = base::MakeUnique<std::vector<std::string>>(); |
| 116 for (const auto& snippet : snippets) { | 65 for (const auto& snippet : snippets) { |
| 117 result->push_back(snippet->id()); | 66 result->push_back(snippet->id()); |
| 118 } | 67 } |
| 119 return result; | 68 return result; |
| 120 } | 69 } |
| 121 | 70 |
| 122 bool HasIntersection(const std::vector<std::string>& a, | 71 bool HasIntersection(const std::vector<std::string>& a, |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 220 } | 169 } |
| 221 | 170 |
| 222 } // namespace | 171 } // namespace |
| 223 | 172 |
| 224 RemoteSuggestionsProvider::RemoteSuggestionsProvider( | 173 RemoteSuggestionsProvider::RemoteSuggestionsProvider( |
| 225 Observer* observer, | 174 Observer* observer, |
| 226 CategoryFactory* category_factory, | 175 CategoryFactory* category_factory, |
| 227 PrefService* pref_service, | 176 PrefService* pref_service, |
| 228 const std::string& application_language_code, | 177 const std::string& application_language_code, |
| 229 const UserClassifier* user_classifier, | 178 const UserClassifier* user_classifier, |
| 230 NTPSnippetsScheduler* scheduler, | 179 RemoteSuggestionsHardScheduler* hard_scheduler, |
| 231 std::unique_ptr<NTPSnippetsFetcher> snippets_fetcher, | 180 std::unique_ptr<NTPSnippetsFetcher> snippets_fetcher, |
| 232 std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher, | 181 std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher, |
| 233 std::unique_ptr<image_fetcher::ImageDecoder> image_decoder, | 182 std::unique_ptr<image_fetcher::ImageDecoder> image_decoder, |
| 234 std::unique_ptr<RemoteSuggestionsDatabase> database, | 183 std::unique_ptr<RemoteSuggestionsDatabase> database, |
| 235 std::unique_ptr<RemoteSuggestionsStatusService> status_service) | 184 std::unique_ptr<RemoteSuggestionsStatusService> status_service) |
| 236 : ContentSuggestionsProvider(observer, category_factory), | 185 : ContentSuggestionsProvider(observer, category_factory), |
| 237 state_(State::NOT_INITED), | 186 state_(State::NOT_INITED), |
| 238 pref_service_(pref_service), | 187 pref_service_(pref_service), |
| 239 articles_category_( | 188 articles_category_( |
| 240 category_factory->FromKnownCategory(KnownCategories::ARTICLES)), | 189 category_factory->FromKnownCategory(KnownCategories::ARTICLES)), |
| 241 application_language_code_(application_language_code), | 190 application_language_code_(application_language_code), |
| 242 user_classifier_(user_classifier), | 191 user_classifier_(user_classifier), |
| 243 scheduler_(scheduler), | 192 scheduler_(hard_scheduler, |
| 193 user_classifier, |
| 194 pref_service), |
| 244 snippets_fetcher_(std::move(snippets_fetcher)), | 195 snippets_fetcher_(std::move(snippets_fetcher)), |
| 245 image_fetcher_(std::move(image_fetcher)), | 196 image_fetcher_(std::move(image_fetcher)), |
| 246 image_decoder_(std::move(image_decoder)), | 197 image_decoder_(std::move(image_decoder)), |
| 247 database_(std::move(database)), | 198 database_(std::move(database)), |
| 248 status_service_(std::move(status_service)), | 199 status_service_(std::move(status_service)), |
| 249 fetch_when_ready_(false), | 200 fetch_when_ready_(false), |
| 250 nuke_when_initialized_(false), | 201 nuke_when_initialized_(false), |
| 251 thumbnail_requests_throttler_( | 202 thumbnail_requests_throttler_( |
| 252 pref_service, | 203 pref_service, |
| 253 RequestThrottler::RequestType::CONTENT_SUGGESTION_THUMBNAIL), | 204 RequestThrottler::RequestType::CONTENT_SUGGESTION_THUMBNAIL), |
| (...skipping 18 matching lines...) Expand all Loading... |
| 272 } | 223 } |
| 273 | 224 |
| 274 database_->SetErrorCallback(base::Bind( | 225 database_->SetErrorCallback(base::Bind( |
| 275 &RemoteSuggestionsProvider::OnDatabaseError, base::Unretained(this))); | 226 &RemoteSuggestionsProvider::OnDatabaseError, base::Unretained(this))); |
| 276 | 227 |
| 277 // We transition to other states while finalizing the initialization, when the | 228 // We transition to other states while finalizing the initialization, when the |
| 278 // database is done loading. | 229 // database is done loading. |
| 279 database_load_start_ = base::TimeTicks::Now(); | 230 database_load_start_ = base::TimeTicks::Now(); |
| 280 database_->LoadSnippets(base::Bind( | 231 database_->LoadSnippets(base::Bind( |
| 281 &RemoteSuggestionsProvider::OnDatabaseLoaded, base::Unretained(this))); | 232 &RemoteSuggestionsProvider::OnDatabaseLoaded, base::Unretained(this))); |
| 233 |
| 234 scheduler_.SetUpdater(this); |
| 282 } | 235 } |
| 283 | 236 |
| 284 RemoteSuggestionsProvider::~RemoteSuggestionsProvider() = default; | 237 RemoteSuggestionsProvider::~RemoteSuggestionsProvider() = default; |
| 285 | 238 |
| 286 // static | 239 // static |
| 287 void RemoteSuggestionsProvider::RegisterProfilePrefs( | 240 void RemoteSuggestionsProvider::RegisterProfilePrefs( |
| 288 PrefRegistrySimple* registry) { | 241 PrefRegistrySimple* registry) { |
| 289 // TODO(treib): Remove after M57. | 242 // TODO(treib): Remove after M57. |
| 290 registry->RegisterListPref(kDeprecatedSnippetHostsPref); | 243 registry->RegisterListPref(kDeprecatedSnippetHostsPref); |
| 291 registry->RegisterListPref(prefs::kRemoteSuggestionCategories); | 244 registry->RegisterListPref(prefs::kRemoteSuggestionCategories); |
| 292 registry->RegisterInt64Pref(prefs::kSnippetBackgroundFetchingIntervalWifi, 0); | |
| 293 registry->RegisterInt64Pref(prefs::kSnippetBackgroundFetchingIntervalFallback, | |
| 294 0); | |
| 295 registry->RegisterInt64Pref(prefs::kLastSuccessfulBackgroundFetchTime, 0); | 245 registry->RegisterInt64Pref(prefs::kLastSuccessfulBackgroundFetchTime, 0); |
| 296 | 246 |
| 247 RemoteSuggestionsScheduler::RegisterProfilePrefs(registry); |
| 297 RemoteSuggestionsStatusService::RegisterProfilePrefs(registry); | 248 RemoteSuggestionsStatusService::RegisterProfilePrefs(registry); |
| 298 } | 249 } |
| 299 | 250 |
| 300 void RemoteSuggestionsProvider::FetchSnippetsInTheBackground() { | |
| 301 FetchSnippets(/*interactive_request=*/false); | |
| 302 } | |
| 303 | |
| 304 void RemoteSuggestionsProvider::FetchSnippetsForAllCategories() { | 251 void RemoteSuggestionsProvider::FetchSnippetsForAllCategories() { |
| 305 // TODO(markusheintz): Investigate whether we can call the Fetch method | 252 // TODO(markusheintz): Investigate whether we can call the Fetch method |
| 306 // instead of the FetchSnippets. | 253 // instead of the FetchSnippets. |
| 307 FetchSnippets(/*interactive_request=*/true); | 254 FetchSnippets(/*interactive_request=*/true); |
| 308 } | 255 } |
| 309 | 256 |
| 310 void RemoteSuggestionsProvider::FetchSnippets(bool interactive_request) { | 257 void RemoteSuggestionsProvider::FetchSnippets(bool interactive_request) { |
| 311 // TODO(markusheintz): Merge the FetchSnippets into the | 258 // TODO(markusheintz): Merge the FetchSnippets into the |
| 312 // FetchSnippetsInTheBackground method. | 259 // FetchSnippetsInTheBackground method. |
| 313 if (ready()) { | 260 if (ready()) { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 378 void RemoteSuggestionsProvider::MarkEmptyCategoriesAsLoading() { | 325 void RemoteSuggestionsProvider::MarkEmptyCategoriesAsLoading() { |
| 379 for (const auto& item : category_contents_) { | 326 for (const auto& item : category_contents_) { |
| 380 Category category = item.first; | 327 Category category = item.first; |
| 381 const CategoryContent& content = item.second; | 328 const CategoryContent& content = item.second; |
| 382 if (content.snippets.empty()) { | 329 if (content.snippets.empty()) { |
| 383 UpdateCategoryStatus(category, CategoryStatus::AVAILABLE_LOADING); | 330 UpdateCategoryStatus(category, CategoryStatus::AVAILABLE_LOADING); |
| 384 } | 331 } |
| 385 } | 332 } |
| 386 } | 333 } |
| 387 | 334 |
| 388 void RemoteSuggestionsProvider::RescheduleFetching(bool force) { | |
| 389 // The scheduler only exists on Android so far, it's null on other platforms. | |
| 390 if (!scheduler_) { | |
| 391 return; | |
| 392 } | |
| 393 | |
| 394 if (ready()) { | |
| 395 base::TimeDelta old_interval_wifi = base::TimeDelta::FromInternalValue( | |
| 396 pref_service_->GetInt64(prefs::kSnippetBackgroundFetchingIntervalWifi)); | |
| 397 base::TimeDelta old_interval_fallback = | |
| 398 base::TimeDelta::FromInternalValue(pref_service_->GetInt64( | |
| 399 prefs::kSnippetBackgroundFetchingIntervalFallback)); | |
| 400 UserClassifier::UserClass user_class = user_classifier_->GetUserClass(); | |
| 401 base::TimeDelta interval_wifi = | |
| 402 GetFetchingInterval(/*is_wifi=*/true, user_class); | |
| 403 base::TimeDelta interval_fallback = | |
| 404 GetFetchingInterval(/*is_wifi=*/false, user_class); | |
| 405 if (force || interval_wifi != old_interval_wifi || | |
| 406 interval_fallback != old_interval_fallback) { | |
| 407 scheduler_->Schedule(interval_wifi, interval_fallback); | |
| 408 pref_service_->SetInt64(prefs::kSnippetBackgroundFetchingIntervalWifi, | |
| 409 interval_wifi.ToInternalValue()); | |
| 410 pref_service_->SetInt64(prefs::kSnippetBackgroundFetchingIntervalFallback, | |
| 411 interval_fallback.ToInternalValue()); | |
| 412 } | |
| 413 } else { | |
| 414 // If we're NOT_INITED, we don't know whether to schedule or unschedule. | |
| 415 // If |force| is false, all is well: We'll reschedule on the next state | |
| 416 // change anyway. If it's true, then unschedule here, to make sure that the | |
| 417 // next reschedule actually happens. | |
| 418 if (state_ != State::NOT_INITED || force) { | |
| 419 scheduler_->Unschedule(); | |
| 420 pref_service_->ClearPref(prefs::kSnippetBackgroundFetchingIntervalWifi); | |
| 421 pref_service_->ClearPref( | |
| 422 prefs::kSnippetBackgroundFetchingIntervalFallback); | |
| 423 } | |
| 424 } | |
| 425 } | |
| 426 | |
| 427 CategoryStatus RemoteSuggestionsProvider::GetCategoryStatus(Category category) { | 335 CategoryStatus RemoteSuggestionsProvider::GetCategoryStatus(Category category) { |
| 428 auto content_it = category_contents_.find(category); | 336 auto content_it = category_contents_.find(category); |
| 429 DCHECK(content_it != category_contents_.end()); | 337 DCHECK(content_it != category_contents_.end()); |
| 430 return content_it->second.status; | 338 return content_it->second.status; |
| 431 } | 339 } |
| 432 | 340 |
| 433 CategoryInfo RemoteSuggestionsProvider::GetCategoryInfo(Category category) { | 341 CategoryInfo RemoteSuggestionsProvider::GetCategoryInfo(Category category) { |
| 434 auto content_it = category_contents_.find(category); | 342 auto content_it = category_contents_.find(category); |
| 435 DCHECK(content_it != category_contents_.end()); | 343 DCHECK(content_it != category_contents_.end()); |
| 436 return content_it->second.info; | 344 return content_it->second.info; |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 574 } | 482 } |
| 575 if (!found) { | 483 if (!found) { |
| 576 return; | 484 return; |
| 577 } | 485 } |
| 578 | 486 |
| 579 // Only cache the data in the DB, the actual serving is done in the callback | 487 // Only cache the data in the DB, the actual serving is done in the callback |
| 580 // provided to |image_fetcher_| (OnSnippetImageDecodedFromNetwork()). | 488 // provided to |image_fetcher_| (OnSnippetImageDecodedFromNetwork()). |
| 581 database_->SaveImage(id_within_category, image_data); | 489 database_->SaveImage(id_within_category, image_data); |
| 582 } | 490 } |
| 583 | 491 |
| 492 void RemoteSuggestionsProvider::UpdateRemoteSuggestionsBySchedule() { |
| 493 FetchSnippets(/*interactive_request=*/false); |
| 494 } |
| 495 |
| 584 void RemoteSuggestionsProvider::OnDatabaseLoaded( | 496 void RemoteSuggestionsProvider::OnDatabaseLoaded( |
| 585 NTPSnippet::PtrVector snippets) { | 497 NTPSnippet::PtrVector snippets) { |
| 586 if (state_ == State::ERROR_OCCURRED) { | 498 if (state_ == State::ERROR_OCCURRED) { |
| 587 return; | 499 return; |
| 588 } | 500 } |
| 589 DCHECK(state_ == State::NOT_INITED); | 501 DCHECK(state_ == State::NOT_INITED); |
| 590 DCHECK(base::ContainsKey(category_contents_, articles_category_)); | 502 DCHECK(base::ContainsKey(category_contents_, articles_category_)); |
| 591 | 503 |
| 592 base::TimeDelta database_load_time = | 504 base::TimeDelta database_load_time = |
| 593 base::TimeTicks::Now() - database_load_start_; | 505 base::TimeTicks::Now() - database_load_start_; |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 778 content.snippets.size()); | 690 content.snippets.size()); |
| 779 if (content.snippets.empty() && !content.dismissed.empty()) { | 691 if (content.snippets.empty() && !content.dismissed.empty()) { |
| 780 UMA_HISTOGRAM_COUNTS("NewTabPage.Snippets.NumArticlesZeroDueToDiscarded", | 692 UMA_HISTOGRAM_COUNTS("NewTabPage.Snippets.NumArticlesZeroDueToDiscarded", |
| 781 content.dismissed.size()); | 693 content.dismissed.size()); |
| 782 } | 694 } |
| 783 | 695 |
| 784 // Reschedule after a successful fetch. This resets all currently scheduled | 696 // Reschedule after a successful fetch. This resets all currently scheduled |
| 785 // fetches, to make sure the fallback interval triggers only if no wifi fetch | 697 // fetches, to make sure the fallback interval triggers only if no wifi fetch |
| 786 // succeeded, and also that we don't do a background fetch immediately after | 698 // succeeded, and also that we don't do a background fetch immediately after |
| 787 // a user-initiated one. | 699 // a user-initiated one. |
| 788 if (fetched_categories) { | 700 if (fetch_result == NTPSnippetsFetcher::FetchResult::SUCCESS) { |
| 789 RescheduleFetching(true); | 701 scheduler_.OnSuccessfulUpdate(); |
| 790 } | 702 } |
| 791 } | 703 } |
| 792 | 704 |
| 793 void RemoteSuggestionsProvider::ArchiveSnippets( | 705 void RemoteSuggestionsProvider::ArchiveSnippets( |
| 794 CategoryContent* content, | 706 CategoryContent* content, |
| 795 NTPSnippet::PtrVector* to_archive) { | 707 NTPSnippet::PtrVector* to_archive) { |
| 796 // Archive previous snippets - move them at the beginning of the list. | 708 // Archive previous snippets - move them at the beginning of the list. |
| 797 content->archived.insert(content->archived.begin(), | 709 content->archived.insert(content->archived.begin(), |
| 798 std::make_move_iterator(to_archive->begin()), | 710 std::make_move_iterator(to_archive->begin()), |
| 799 std::make_move_iterator(to_archive->end())); | 711 std::make_move_iterator(to_archive->end())); |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1140 // Initial state, it should not be possible to get back there. | 1052 // Initial state, it should not be possible to get back there. |
| 1141 NOTREACHED(); | 1053 NOTREACHED(); |
| 1142 break; | 1054 break; |
| 1143 | 1055 |
| 1144 case State::READY: | 1056 case State::READY: |
| 1145 DCHECK(state_ == State::NOT_INITED || state_ == State::DISABLED); | 1057 DCHECK(state_ == State::NOT_INITED || state_ == State::DISABLED); |
| 1146 | 1058 |
| 1147 DVLOG(1) << "Entering state: READY"; | 1059 DVLOG(1) << "Entering state: READY"; |
| 1148 state_ = State::READY; | 1060 state_ = State::READY; |
| 1149 EnterStateReady(); | 1061 EnterStateReady(); |
| 1062 scheduler_.Schedule(); |
| 1150 break; | 1063 break; |
| 1151 | 1064 |
| 1152 case State::DISABLED: | 1065 case State::DISABLED: |
| 1153 DCHECK(state_ == State::NOT_INITED || state_ == State::READY); | 1066 DCHECK(state_ == State::NOT_INITED || state_ == State::READY); |
| 1154 | 1067 |
| 1155 DVLOG(1) << "Entering state: DISABLED"; | 1068 DVLOG(1) << "Entering state: DISABLED"; |
| 1156 state_ = State::DISABLED; | 1069 state_ = State::DISABLED; |
| 1157 EnterStateDisabled(); | 1070 EnterStateDisabled(); |
| 1071 scheduler_.Unschedule(); |
| 1158 break; | 1072 break; |
| 1159 | 1073 |
| 1160 case State::ERROR_OCCURRED: | 1074 case State::ERROR_OCCURRED: |
| 1161 DVLOG(1) << "Entering state: ERROR_OCCURRED"; | 1075 DVLOG(1) << "Entering state: ERROR_OCCURRED"; |
| 1162 state_ = State::ERROR_OCCURRED; | 1076 state_ = State::ERROR_OCCURRED; |
| 1163 EnterStateError(); | 1077 EnterStateError(); |
| 1078 scheduler_.Unschedule(); |
| 1164 break; | 1079 break; |
| 1165 | 1080 |
| 1166 case State::COUNT: | 1081 case State::COUNT: |
| 1167 NOTREACHED(); | 1082 NOTREACHED(); |
| 1168 break; | 1083 break; |
| 1169 } | 1084 } |
| 1170 | |
| 1171 // Schedule or un-schedule background fetching after each state change. | |
| 1172 RescheduleFetching(false); | |
| 1173 } | 1085 } |
| 1174 | 1086 |
| 1175 void RemoteSuggestionsProvider::NotifyNewSuggestions( | 1087 void RemoteSuggestionsProvider::NotifyNewSuggestions( |
| 1176 Category category, | 1088 Category category, |
| 1177 const CategoryContent& content) { | 1089 const CategoryContent& content) { |
| 1178 DCHECK(IsCategoryStatusAvailable(content.status)); | 1090 DCHECK(IsCategoryStatusAvailable(content.status)); |
| 1179 | 1091 |
| 1180 std::vector<ContentSuggestion> result = | 1092 std::vector<ContentSuggestion> result = |
| 1181 ConvertToContentSuggestions(category, content.snippets); | 1093 ConvertToContentSuggestions(category, content.snippets); |
| 1182 | 1094 |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1345 RemoteSuggestionsProvider::CategoryContent::CategoryContent(CategoryContent&&) = | 1257 RemoteSuggestionsProvider::CategoryContent::CategoryContent(CategoryContent&&) = |
| 1346 default; | 1258 default; |
| 1347 | 1259 |
| 1348 RemoteSuggestionsProvider::CategoryContent::~CategoryContent() = default; | 1260 RemoteSuggestionsProvider::CategoryContent::~CategoryContent() = default; |
| 1349 | 1261 |
| 1350 RemoteSuggestionsProvider::CategoryContent& | 1262 RemoteSuggestionsProvider::CategoryContent& |
| 1351 RemoteSuggestionsProvider::CategoryContent::operator=(CategoryContent&&) = | 1263 RemoteSuggestionsProvider::CategoryContent::operator=(CategoryContent&&) = |
| 1352 default; | 1264 default; |
| 1353 | 1265 |
| 1354 } // namespace ntp_snippets | 1266 } // namespace ntp_snippets |
| OLD | NEW |