| 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_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 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 268 Category::FromKnownCategory(KnownCategories::ARTICLES)), | 268 Category::FromKnownCategory(KnownCategories::ARTICLES)), |
| 269 application_language_code_(application_language_code), | 269 application_language_code_(application_language_code), |
| 270 category_ranker_(category_ranker), | 270 category_ranker_(category_ranker), |
| 271 remote_suggestions_scheduler_(scheduler), | 271 remote_suggestions_scheduler_(scheduler), |
| 272 suggestions_fetcher_(std::move(suggestions_fetcher)), | 272 suggestions_fetcher_(std::move(suggestions_fetcher)), |
| 273 database_(std::move(database)), | 273 database_(std::move(database)), |
| 274 image_fetcher_(std::move(image_fetcher), pref_service, database_.get()), | 274 image_fetcher_(std::move(image_fetcher), pref_service, database_.get()), |
| 275 status_service_(std::move(status_service)), | 275 status_service_(std::move(status_service)), |
| 276 fetch_when_ready_(false), | 276 fetch_when_ready_(false), |
| 277 fetch_when_ready_interactive_(false), | 277 fetch_when_ready_interactive_(false), |
| 278 fetch_when_ready_callback_(nullptr), | |
| 279 clear_history_dependent_state_when_initialized_(false), | 278 clear_history_dependent_state_when_initialized_(false), |
| 280 clock_(base::MakeUnique<base::DefaultClock>()) { | 279 clock_(base::MakeUnique<base::DefaultClock>()) { |
| 281 RestoreCategoriesFromPrefs(); | 280 RestoreCategoriesFromPrefs(); |
| 282 // The articles category always exists. Add it if we didn't get it from prefs. | 281 // The articles category always exists. Add it if we didn't get it from prefs. |
| 283 // TODO(treib): Rethink this. | 282 // TODO(treib): Rethink this. |
| 284 category_contents_.insert( | 283 category_contents_.insert( |
| 285 std::make_pair(articles_category_, | 284 std::make_pair(articles_category_, |
| 286 CategoryContent(BuildArticleCategoryInfo(base::nullopt)))); | 285 CategoryContent(BuildArticleCategoryInfo(base::nullopt)))); |
| 287 // Tell the observer about all the categories. | 286 // Tell the observer about all the categories. |
| 288 for (const auto& entry : category_contents_) { | 287 for (const auto& entry : category_contents_) { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 316 | 315 |
| 317 RemoteSuggestionsStatusService::RegisterProfilePrefs(registry); | 316 RemoteSuggestionsStatusService::RegisterProfilePrefs(registry); |
| 318 } | 317 } |
| 319 | 318 |
| 320 void RemoteSuggestionsProviderImpl::ReloadSuggestions() { | 319 void RemoteSuggestionsProviderImpl::ReloadSuggestions() { |
| 321 if (!remote_suggestions_scheduler_->AcquireQuotaForInteractiveFetch()) { | 320 if (!remote_suggestions_scheduler_->AcquireQuotaForInteractiveFetch()) { |
| 322 return; | 321 return; |
| 323 } | 322 } |
| 324 FetchSuggestions( | 323 FetchSuggestions( |
| 325 /*interactive_request=*/true, | 324 /*interactive_request=*/true, |
| 326 base::MakeUnique<FetchStatusCallback>(base::Bind( | 325 base::Bind( |
| 327 [](RemoteSuggestionsScheduler* scheduler, Status status_code) { | 326 [](RemoteSuggestionsScheduler* scheduler, Status status_code) { |
| 328 scheduler->OnInteractiveFetchFinished(status_code); | 327 scheduler->OnInteractiveFetchFinished(status_code); |
| 329 }, | 328 }, |
| 330 base::Unretained(remote_suggestions_scheduler_)))); | 329 base::Unretained(remote_suggestions_scheduler_))); |
| 331 } | 330 } |
| 332 | 331 |
| 333 void RemoteSuggestionsProviderImpl::RefetchInTheBackground( | 332 void RemoteSuggestionsProviderImpl::RefetchInTheBackground( |
| 334 std::unique_ptr<FetchStatusCallback> callback) { | 333 const FetchStatusCallback& callback) { |
| 335 FetchSuggestions(/*interactive_request=*/false, std::move(callback)); | 334 FetchSuggestions(/*interactive_request=*/false, callback); |
| 336 } | 335 } |
| 337 | 336 |
| 338 const RemoteSuggestionsFetcher* | 337 const RemoteSuggestionsFetcher* |
| 339 RemoteSuggestionsProviderImpl::suggestions_fetcher_for_debugging() const { | 338 RemoteSuggestionsProviderImpl::suggestions_fetcher_for_debugging() const { |
| 340 return suggestions_fetcher_.get(); | 339 return suggestions_fetcher_.get(); |
| 341 } | 340 } |
| 342 | 341 |
| 343 void RemoteSuggestionsProviderImpl::FetchSuggestions( | 342 void RemoteSuggestionsProviderImpl::FetchSuggestions( |
| 344 bool interactive_request, | 343 bool interactive_request, |
| 345 std::unique_ptr<FetchStatusCallback> callback) { | 344 const FetchStatusCallback& callback) { |
| 346 if (!ready()) { | 345 if (!ready()) { |
| 347 fetch_when_ready_ = true; | 346 fetch_when_ready_ = true; |
| 348 fetch_when_ready_interactive_ = interactive_request; | 347 fetch_when_ready_interactive_ = interactive_request; |
| 349 fetch_when_ready_callback_ = std::move(callback); | 348 fetch_when_ready_callback_ = callback; |
| 350 return; | 349 return; |
| 351 } | 350 } |
| 352 | 351 |
| 353 MarkEmptyCategoriesAsLoading(); | 352 MarkEmptyCategoriesAsLoading(); |
| 354 | 353 |
| 355 RequestParams params = BuildFetchParams(); | 354 RequestParams params = BuildFetchParams(); |
| 356 params.interactive_request = interactive_request; | 355 params.interactive_request = interactive_request; |
| 357 suggestions_fetcher_->FetchSnippets( | 356 suggestions_fetcher_->FetchSnippets( |
| 358 params, base::BindOnce(&RemoteSuggestionsProviderImpl::OnFetchFinished, | 357 params, |
| 359 base::Unretained(this), std::move(callback), | 358 base::BindOnce(&RemoteSuggestionsProviderImpl::OnFetchFinished, |
| 360 interactive_request)); | 359 base::Unretained(this), callback, interactive_request)); |
| 361 } | 360 } |
| 362 | 361 |
| 363 void RemoteSuggestionsProviderImpl::Fetch( | 362 void RemoteSuggestionsProviderImpl::Fetch( |
| 364 const Category& category, | 363 const Category& category, |
| 365 const std::set<std::string>& known_suggestion_ids, | 364 const std::set<std::string>& known_suggestion_ids, |
| 366 const FetchDoneCallback& callback) { | 365 const FetchDoneCallback& callback) { |
| 367 if (!ready()) { | 366 if (!ready()) { |
| 368 CallWithEmptyResults(callback, | 367 CallWithEmptyResults(callback, |
| 369 Status(StatusCode::TEMPORARY_ERROR, | 368 Status(StatusCode::TEMPORARY_ERROR, |
| 370 "RemoteSuggestionsProvider is not ready!")); | 369 "RemoteSuggestionsProvider is not ready!")); |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 657 // TODO(tschumann): We should properly honor the existing category state, | 656 // TODO(tschumann): We should properly honor the existing category state, |
| 658 // e.g. to make sure we don't serve results after the sign-out. Revisit this: | 657 // e.g. to make sure we don't serve results after the sign-out. Revisit this: |
| 659 // Should Nuke also cancel outstanding requests, or do we want to check the | 658 // Should Nuke also cancel outstanding requests, or do we want to check the |
| 660 // status? | 659 // status? |
| 661 UpdateCategoryStatus(category, CategoryStatus::AVAILABLE); | 660 UpdateCategoryStatus(category, CategoryStatus::AVAILABLE); |
| 662 fetching_callback.Run(Status::Success(), std::move(result)); | 661 fetching_callback.Run(Status::Success(), std::move(result)); |
| 663 NotifyNewSuggestions(category, *existing_content); | 662 NotifyNewSuggestions(category, *existing_content); |
| 664 } | 663 } |
| 665 | 664 |
| 666 void RemoteSuggestionsProviderImpl::OnFetchFinished( | 665 void RemoteSuggestionsProviderImpl::OnFetchFinished( |
| 667 std::unique_ptr<FetchStatusCallback> callback, | 666 const FetchStatusCallback& callback, |
| 668 bool interactive_request, | 667 bool interactive_request, |
| 669 Status status, | 668 Status status, |
| 670 RemoteSuggestionsFetcher::OptionalFetchedCategories fetched_categories) { | 669 RemoteSuggestionsFetcher::OptionalFetchedCategories fetched_categories) { |
| 671 if (!ready()) { | 670 if (!ready()) { |
| 672 // TODO(tschumann): What happens if this was a user-triggered, interactive | 671 // TODO(tschumann): What happens if this was a user-triggered, interactive |
| 673 // request? Is the UI waiting indefinitely now? | 672 // request? Is the UI waiting indefinitely now? |
| 674 return; | 673 return; |
| 675 } | 674 } |
| 676 | 675 |
| 677 // Record the fetch time of a successfull background fetch. | 676 // Record the fetch time of a successfull background fetch. |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 737 DCHECK(content_it != category_contents_.end()); | 736 DCHECK(content_it != category_contents_.end()); |
| 738 const CategoryContent& content = content_it->second; | 737 const CategoryContent& content = content_it->second; |
| 739 UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.Snippets.NumArticles", | 738 UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.Snippets.NumArticles", |
| 740 content.suggestions.size()); | 739 content.suggestions.size()); |
| 741 if (content.suggestions.empty() && !content.dismissed.empty()) { | 740 if (content.suggestions.empty() && !content.dismissed.empty()) { |
| 742 UMA_HISTOGRAM_COUNTS("NewTabPage.Snippets.NumArticlesZeroDueToDiscarded", | 741 UMA_HISTOGRAM_COUNTS("NewTabPage.Snippets.NumArticlesZeroDueToDiscarded", |
| 743 content.dismissed.size()); | 742 content.dismissed.size()); |
| 744 } | 743 } |
| 745 | 744 |
| 746 if (callback) { | 745 if (callback) { |
| 747 callback->Run(status); | 746 callback.Run(status); |
| 748 } | 747 } |
| 749 } | 748 } |
| 750 | 749 |
| 751 void RemoteSuggestionsProviderImpl::ArchiveSuggestions( | 750 void RemoteSuggestionsProviderImpl::ArchiveSuggestions( |
| 752 CategoryContent* content, | 751 CategoryContent* content, |
| 753 RemoteSuggestion::PtrVector* to_archive) { | 752 RemoteSuggestion::PtrVector* to_archive) { |
| 754 // Archive previous suggestions - move them at the beginning of the list. | 753 // Archive previous suggestions - move them at the beginning of the list. |
| 755 content->archived.insert(content->archived.begin(), | 754 content->archived.insert(content->archived.begin(), |
| 756 std::make_move_iterator(to_archive->begin()), | 755 std::make_move_iterator(to_archive->begin()), |
| 757 std::make_move_iterator(to_archive->end())); | 756 std::make_move_iterator(to_archive->end())); |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 937 | 936 |
| 938 void RemoteSuggestionsProviderImpl::EnterStateReady() { | 937 void RemoteSuggestionsProviderImpl::EnterStateReady() { |
| 939 if (clear_history_dependent_state_when_initialized_) { | 938 if (clear_history_dependent_state_when_initialized_) { |
| 940 clear_history_dependent_state_when_initialized_ = false; | 939 clear_history_dependent_state_when_initialized_ = false; |
| 941 ClearHistoryDependentState(); | 940 ClearHistoryDependentState(); |
| 942 } | 941 } |
| 943 | 942 |
| 944 auto article_category_it = category_contents_.find(articles_category_); | 943 auto article_category_it = category_contents_.find(articles_category_); |
| 945 DCHECK(article_category_it != category_contents_.end()); | 944 DCHECK(article_category_it != category_contents_.end()); |
| 946 if (fetch_when_ready_) { | 945 if (fetch_when_ready_) { |
| 947 FetchSuggestions(fetch_when_ready_interactive_, | 946 FetchSuggestions(fetch_when_ready_interactive_, fetch_when_ready_callback_); |
| 948 std::move(fetch_when_ready_callback_)); | |
| 949 fetch_when_ready_ = false; | 947 fetch_when_ready_ = false; |
| 950 } | 948 } |
| 951 | 949 |
| 952 for (const auto& item : category_contents_) { | 950 for (const auto& item : category_contents_) { |
| 953 Category category = item.first; | 951 Category category = item.first; |
| 954 const CategoryContent& content = item.second; | 952 const CategoryContent& content = item.second; |
| 955 // FetchSuggestions has set the status to |AVAILABLE_LOADING| if relevant, | 953 // FetchSuggestions has set the status to |AVAILABLE_LOADING| if relevant, |
| 956 // otherwise we transition to |AVAILABLE| here. | 954 // otherwise we transition to |AVAILABLE| here. |
| 957 if (content.status != CategoryStatus::AVAILABLE_LOADING) { | 955 if (content.status != CategoryStatus::AVAILABLE_LOADING) { |
| 958 UpdateCategoryStatus(category, CategoryStatus::AVAILABLE); | 956 UpdateCategoryStatus(category, CategoryStatus::AVAILABLE); |
| (...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1279 RemoteSuggestionsProviderImpl::CategoryContent::CategoryContent( | 1277 RemoteSuggestionsProviderImpl::CategoryContent::CategoryContent( |
| 1280 CategoryContent&&) = default; | 1278 CategoryContent&&) = default; |
| 1281 | 1279 |
| 1282 RemoteSuggestionsProviderImpl::CategoryContent::~CategoryContent() = default; | 1280 RemoteSuggestionsProviderImpl::CategoryContent::~CategoryContent() = default; |
| 1283 | 1281 |
| 1284 RemoteSuggestionsProviderImpl::CategoryContent& | 1282 RemoteSuggestionsProviderImpl::CategoryContent& |
| 1285 RemoteSuggestionsProviderImpl::CategoryContent::operator=(CategoryContent&&) = | 1283 RemoteSuggestionsProviderImpl::CategoryContent::operator=(CategoryContent&&) = |
| 1286 default; | 1284 default; |
| 1287 | 1285 |
| 1288 } // namespace ntp_snippets | 1286 } // namespace ntp_snippets |
| OLD | NEW |