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

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

Issue 2774663002: [Remote suggestions] Refactor the scheduler (Closed)
Patch Set: Marc's nits #2 Created 3 years, 8 months 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_impl.h" 5 #include "components/ntp_snippets/remote/remote_suggestions_provider_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <iterator> 8 #include <iterator>
9 #include <utility> 9 #include <utility>
10 10
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 suggestion_id.id_within_category(), url, 249 suggestion_id.id_within_category(), url,
250 base::Bind(&CachedImageFetcher::OnImageDecodingDone, 250 base::Bind(&CachedImageFetcher::OnImageDecodingDone,
251 base::Unretained(this), callback)); 251 base::Unretained(this), callback));
252 } 252 }
253 253
254 RemoteSuggestionsProviderImpl::RemoteSuggestionsProviderImpl( 254 RemoteSuggestionsProviderImpl::RemoteSuggestionsProviderImpl(
255 Observer* observer, 255 Observer* observer,
256 PrefService* pref_service, 256 PrefService* pref_service,
257 const std::string& application_language_code, 257 const std::string& application_language_code,
258 CategoryRanker* category_ranker, 258 CategoryRanker* category_ranker,
259 RemoteSuggestionsScheduler* scheduler,
259 std::unique_ptr<RemoteSuggestionsFetcher> suggestions_fetcher, 260 std::unique_ptr<RemoteSuggestionsFetcher> suggestions_fetcher,
260 std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher, 261 std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher,
261 std::unique_ptr<RemoteSuggestionsDatabase> database, 262 std::unique_ptr<RemoteSuggestionsDatabase> database,
262 std::unique_ptr<RemoteSuggestionsStatusService> status_service) 263 std::unique_ptr<RemoteSuggestionsStatusService> status_service)
263 : RemoteSuggestionsProvider(observer), 264 : RemoteSuggestionsProvider(observer),
264 state_(State::NOT_INITED), 265 state_(State::NOT_INITED),
265 pref_service_(pref_service), 266 pref_service_(pref_service),
266 articles_category_( 267 articles_category_(
267 Category::FromKnownCategory(KnownCategories::ARTICLES)), 268 Category::FromKnownCategory(KnownCategories::ARTICLES)),
268 application_language_code_(application_language_code), 269 application_language_code_(application_language_code),
269 category_ranker_(category_ranker), 270 category_ranker_(category_ranker),
271 remote_suggestions_scheduler_(scheduler),
270 suggestions_fetcher_(std::move(suggestions_fetcher)), 272 suggestions_fetcher_(std::move(suggestions_fetcher)),
271 database_(std::move(database)), 273 database_(std::move(database)),
272 image_fetcher_(std::move(image_fetcher), pref_service, database_.get()), 274 image_fetcher_(std::move(image_fetcher), pref_service, database_.get()),
273 status_service_(std::move(status_service)), 275 status_service_(std::move(status_service)),
274 fetch_when_ready_(false), 276 fetch_when_ready_(false),
275 fetch_when_ready_interactive_(false), 277 fetch_when_ready_interactive_(false),
276 fetch_when_ready_callback_(nullptr), 278 fetch_when_ready_callback_(nullptr),
277 remote_suggestions_scheduler_(nullptr),
278 clear_history_dependent_state_when_initialized_(false), 279 clear_history_dependent_state_when_initialized_(false),
279 clock_(base::MakeUnique<base::DefaultClock>()) { 280 clock_(base::MakeUnique<base::DefaultClock>()) {
280 RestoreCategoriesFromPrefs(); 281 RestoreCategoriesFromPrefs();
281 // The articles category always exists. Add it if we didn't get it from prefs. 282 // The articles category always exists. Add it if we didn't get it from prefs.
282 // TODO(treib): Rethink this. 283 // TODO(treib): Rethink this.
283 category_contents_.insert( 284 category_contents_.insert(
284 std::make_pair(articles_category_, 285 std::make_pair(articles_category_,
285 CategoryContent(BuildArticleCategoryInfo(base::nullopt)))); 286 CategoryContent(BuildArticleCategoryInfo(base::nullopt))));
286 // Tell the observer about all the categories. 287 // Tell the observer about all the categories.
287 for (const auto& entry : category_contents_) { 288 for (const auto& entry : category_contents_) {
(...skipping 21 matching lines...) Expand all
309 310
310 // static 311 // static
311 void RemoteSuggestionsProviderImpl::RegisterProfilePrefs( 312 void RemoteSuggestionsProviderImpl::RegisterProfilePrefs(
312 PrefRegistrySimple* registry) { 313 PrefRegistrySimple* registry) {
313 registry->RegisterListPref(prefs::kRemoteSuggestionCategories); 314 registry->RegisterListPref(prefs::kRemoteSuggestionCategories);
314 registry->RegisterInt64Pref(prefs::kLastSuccessfulBackgroundFetchTime, 0); 315 registry->RegisterInt64Pref(prefs::kLastSuccessfulBackgroundFetchTime, 0);
315 316
316 RemoteSuggestionsStatusService::RegisterProfilePrefs(registry); 317 RemoteSuggestionsStatusService::RegisterProfilePrefs(registry);
317 } 318 }
318 319
319 void RemoteSuggestionsProviderImpl::SetRemoteSuggestionsScheduler(
320 RemoteSuggestionsScheduler* scheduler) {
321 remote_suggestions_scheduler_ = scheduler;
322 // Call the observer right away if we've reached any final state.
323 NotifyStateChanged();
324 }
325
326 void RemoteSuggestionsProviderImpl::ReloadSuggestions() { 320 void RemoteSuggestionsProviderImpl::ReloadSuggestions() {
327 FetchSuggestions(/*interactive_request=*/true, 321 if (!remote_suggestions_scheduler_->AcquireQuotaForInteractiveFetch()) {
328 /*callback=*/nullptr); 322 return;
323 }
324 FetchSuggestions(
325 /*interactive_request=*/true,
326 base::MakeUnique<FetchStatusCallback>(base::Bind(
327 [](RemoteSuggestionsScheduler* scheduler, Status status_code) {
328 scheduler->OnInteractiveFetchFinished(status_code);
329 },
330 base::Unretained(remote_suggestions_scheduler_))));
329 } 331 }
330 332
331 void RemoteSuggestionsProviderImpl::RefetchInTheBackground( 333 void RemoteSuggestionsProviderImpl::RefetchInTheBackground(
332 std::unique_ptr<FetchStatusCallback> callback) { 334 std::unique_ptr<FetchStatusCallback> callback) {
333 FetchSuggestions(/*interactive_request=*/false, std::move(callback)); 335 FetchSuggestions(/*interactive_request=*/false, std::move(callback));
334 } 336 }
335 337
336 const RemoteSuggestionsFetcher* 338 const RemoteSuggestionsFetcher*
337 RemoteSuggestionsProviderImpl::suggestions_fetcher_for_debugging() const { 339 RemoteSuggestionsProviderImpl::suggestions_fetcher_for_debugging() const {
338 return suggestions_fetcher_.get(); 340 return suggestions_fetcher_.get();
(...skipping 22 matching lines...) Expand all
361 void RemoteSuggestionsProviderImpl::Fetch( 363 void RemoteSuggestionsProviderImpl::Fetch(
362 const Category& category, 364 const Category& category,
363 const std::set<std::string>& known_suggestion_ids, 365 const std::set<std::string>& known_suggestion_ids,
364 const FetchDoneCallback& callback) { 366 const FetchDoneCallback& callback) {
365 if (!ready()) { 367 if (!ready()) {
366 CallWithEmptyResults(callback, 368 CallWithEmptyResults(callback,
367 Status(StatusCode::TEMPORARY_ERROR, 369 Status(StatusCode::TEMPORARY_ERROR,
368 "RemoteSuggestionsProvider is not ready!")); 370 "RemoteSuggestionsProvider is not ready!"));
369 return; 371 return;
370 } 372 }
373 if (!remote_suggestions_scheduler_->AcquireQuotaForInteractiveFetch()) {
374 CallWithEmptyResults(callback, Status(StatusCode::TEMPORARY_ERROR,
375 "Interactive quota exceeded!"));
376 return;
377 }
378 // Make sure after the fetch, the scheduler is informed about the status.
379 FetchDoneCallback callback_wrapper = base::Bind(
380 [](RemoteSuggestionsScheduler* scheduler,
381 const FetchDoneCallback& callback, Status status_code,
382 std::vector<ContentSuggestion> suggestions) {
383 scheduler->OnInteractiveFetchFinished(status_code);
384 callback.Run(status_code, std::move(suggestions));
385 },
386 base::Unretained(remote_suggestions_scheduler_), callback);
387
371 RequestParams params = BuildFetchParams(); 388 RequestParams params = BuildFetchParams();
372 params.excluded_ids.insert(known_suggestion_ids.begin(), 389 params.excluded_ids.insert(known_suggestion_ids.begin(),
373 known_suggestion_ids.end()); 390 known_suggestion_ids.end());
374 params.interactive_request = true; 391 params.interactive_request = true;
375 params.exclusive_category = category; 392 params.exclusive_category = category;
376 393
377 suggestions_fetcher_->FetchSnippets( 394 suggestions_fetcher_->FetchSnippets(
378 params, 395 params,
379 base::BindOnce(&RemoteSuggestionsProviderImpl::OnFetchMoreFinished, 396 base::BindOnce(&RemoteSuggestionsProviderImpl::OnFetchMoreFinished,
380 base::Unretained(this), callback)); 397 base::Unretained(this), callback_wrapper));
381 } 398 }
382 399
383 // Builds default fetcher params. 400 // Builds default fetcher params.
384 RequestParams RemoteSuggestionsProviderImpl::BuildFetchParams() const { 401 RequestParams RemoteSuggestionsProviderImpl::BuildFetchParams() const {
385 RequestParams result; 402 RequestParams result;
386 result.language_code = application_language_code_; 403 result.language_code = application_language_code_;
387 result.count_to_fetch = kMaxSuggestionCount; 404 result.count_to_fetch = kMaxSuggestionCount;
388 for (const auto& map_entry : category_contents_) { 405 for (const auto& map_entry : category_contents_) {
389 const CategoryContent& content = map_entry.second; 406 const CategoryContent& content = map_entry.second;
390 for (const auto& dismissed_suggestion : content.dismissed) { 407 for (const auto& dismissed_suggestion : content.dismissed) {
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
635 DCHECK(existing_content->suggestions.empty()); 652 DCHECK(existing_content->suggestions.empty());
636 653
637 IntegrateSuggestions(existing_content, 654 IntegrateSuggestions(existing_content,
638 std::move(fetched_category.suggestions)); 655 std::move(fetched_category.suggestions));
639 656
640 // TODO(tschumann): We should properly honor the existing category state, 657 // TODO(tschumann): We should properly honor the existing category state,
641 // e.g. to make sure we don't serve results after the sign-out. Revisit this: 658 // e.g. to make sure we don't serve results after the sign-out. Revisit this:
642 // Should Nuke also cancel outstanding requests, or do we want to check the 659 // Should Nuke also cancel outstanding requests, or do we want to check the
643 // status? 660 // status?
644 UpdateCategoryStatus(category, CategoryStatus::AVAILABLE); 661 UpdateCategoryStatus(category, CategoryStatus::AVAILABLE);
645 // Notify callers and observers.
646 fetching_callback.Run(Status::Success(), std::move(result)); 662 fetching_callback.Run(Status::Success(), std::move(result));
647 NotifyNewSuggestions(category, *existing_content); 663 NotifyNewSuggestions(category, *existing_content);
648 } 664 }
649 665
650 void RemoteSuggestionsProviderImpl::OnFetchFinished( 666 void RemoteSuggestionsProviderImpl::OnFetchFinished(
651 std::unique_ptr<FetchStatusCallback> callback, 667 std::unique_ptr<FetchStatusCallback> callback,
652 bool interactive_request, 668 bool interactive_request,
653 Status status, 669 Status status,
654 RemoteSuggestionsFetcher::OptionalFetchedCategories fetched_categories) { 670 RemoteSuggestionsFetcher::OptionalFetchedCategories fetched_categories) {
655 if (!ready()) { 671 if (!ready()) {
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
865 database_->GarbageCollectImages(std::move(alive_suggestions)); 881 database_->GarbageCollectImages(std::move(alive_suggestions));
866 } 882 }
867 883
868 void RemoteSuggestionsProviderImpl::ClearHistoryDependentState() { 884 void RemoteSuggestionsProviderImpl::ClearHistoryDependentState() {
869 if (!initialized()) { 885 if (!initialized()) {
870 clear_history_dependent_state_when_initialized_ = true; 886 clear_history_dependent_state_when_initialized_ = true;
871 return; 887 return;
872 } 888 }
873 889
874 NukeAllSuggestions(); 890 NukeAllSuggestions();
875 if (remote_suggestions_scheduler_) { 891 remote_suggestions_scheduler_->OnHistoryCleared();
876 remote_suggestions_scheduler_->OnHistoryCleared();
877 }
878 } 892 }
879 893
880 void RemoteSuggestionsProviderImpl::ClearSuggestions() { 894 void RemoteSuggestionsProviderImpl::ClearSuggestions() {
881 DCHECK(initialized()); 895 DCHECK(initialized());
882 896
883 NukeAllSuggestions(); 897 NukeAllSuggestions();
884 if (remote_suggestions_scheduler_) { 898 remote_suggestions_scheduler_->OnSuggestionsCleared();
885 remote_suggestions_scheduler_->OnSuggestionsCleared();
886 }
887 } 899 }
888 900
889 void RemoteSuggestionsProviderImpl::NukeAllSuggestions() { 901 void RemoteSuggestionsProviderImpl::NukeAllSuggestions() {
890 for (const auto& item : category_contents_) { 902 for (const auto& item : category_contents_) {
891 Category category = item.first; 903 Category category = item.first;
892 const CategoryContent& content = item.second; 904 const CategoryContent& content = item.second;
893 905
894 ClearCachedSuggestions(category); 906 ClearCachedSuggestions(category);
895 // Update listeners about the new (empty) state. 907 // Update listeners about the new (empty) state.
896 if (IsCategoryStatusAvailable(content.status)) { 908 if (IsCategoryStatusAvailable(content.status)) {
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
1063 EnterStateError(); 1075 EnterStateError();
1064 break; 1076 break;
1065 1077
1066 case State::COUNT: 1078 case State::COUNT:
1067 NOTREACHED(); 1079 NOTREACHED();
1068 break; 1080 break;
1069 } 1081 }
1070 } 1082 }
1071 1083
1072 void RemoteSuggestionsProviderImpl::NotifyStateChanged() { 1084 void RemoteSuggestionsProviderImpl::NotifyStateChanged() {
1073 if (!remote_suggestions_scheduler_) {
1074 return;
1075 }
1076
1077 switch (state_) { 1085 switch (state_) {
1078 case State::NOT_INITED: 1086 case State::NOT_INITED:
1079 // Initial state, not sure yet whether active or not. 1087 // Initial state, not sure yet whether active or not.
1080 break; 1088 break;
1081 case State::READY: 1089 case State::READY:
1082 remote_suggestions_scheduler_->OnProviderActivated(); 1090 remote_suggestions_scheduler_->OnProviderActivated();
1083 break; 1091 break;
1084 case State::DISABLED: 1092 case State::DISABLED:
1085 remote_suggestions_scheduler_->OnProviderDeactivated(); 1093 remote_suggestions_scheduler_->OnProviderDeactivated();
1086 break; 1094 break;
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
1271 RemoteSuggestionsProviderImpl::CategoryContent::CategoryContent( 1279 RemoteSuggestionsProviderImpl::CategoryContent::CategoryContent(
1272 CategoryContent&&) = default; 1280 CategoryContent&&) = default;
1273 1281
1274 RemoteSuggestionsProviderImpl::CategoryContent::~CategoryContent() = default; 1282 RemoteSuggestionsProviderImpl::CategoryContent::~CategoryContent() = default;
1275 1283
1276 RemoteSuggestionsProviderImpl::CategoryContent& 1284 RemoteSuggestionsProviderImpl::CategoryContent&
1277 RemoteSuggestionsProviderImpl::CategoryContent::operator=(CategoryContent&&) = 1285 RemoteSuggestionsProviderImpl::CategoryContent::operator=(CategoryContent&&) =
1278 default; 1286 default;
1279 1287
1280 } // namespace ntp_snippets 1288 } // namespace ntp_snippets
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698