Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(243)

Side by Side Diff: components/ntp_snippets/remote/remote_suggestions_provider.cc

Issue 2557363002: [NTP Snippets] Refactor background scheduling for remote suggestions (Closed)
Patch Set: Make unit-tests pass Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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, &param_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
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,
markusheintz_ 2016/12/12 14:36:16 Should we pass in the scheduler instead of the har
jkrcal 2016/12/14 09:42:09 Done.
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),
markusheintz_ 2016/12/12 15:32:28 This is not used in this class any more. So we can
jkrcal 2016/12/14 09:42:09 Done.
243 scheduler_(scheduler), 192 scheduler_(hard_scheduler,
193 user_classifier,
194 pref_service),
Marc Treib 2016/12/09 12:25:26 I think this fits on one line? Maybe for a later
jkrcal 2016/12/14 09:42:09 Done.
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
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
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) {
Marc Treib 2016/12/09 12:25:26 Is this case still handled in the new world?
jkrcal 2016/12/14 09:42:09 It is. - Unschedule() is not called on state cha
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
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
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();
tschumann 2016/12/09 17:27:28 this has a smell, especially when reading the comm
jkrcal 2016/12/14 09:42:09 Done.
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698