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/ntp_snippets_service.h" | 5 #include "components/ntp_snippets/remote/ntp_snippets_service.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <iterator> | 8 #include <iterator> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
373 if (!base::ContainsKey(categories_, category)) | 373 if (!base::ContainsKey(categories_, category)) |
374 return; | 374 return; |
375 CategoryContent* content = &categories_[category]; | 375 CategoryContent* content = &categories_[category]; |
376 if (content->snippets.empty()) | 376 if (content->snippets.empty()) |
377 return; | 377 return; |
378 | 378 |
379 database_->DeleteSnippets(GetSnippetIDVector(content->snippets)); | 379 database_->DeleteSnippets(GetSnippetIDVector(content->snippets)); |
380 database_->DeleteImages(GetSnippetIDVector(content->snippets)); | 380 database_->DeleteImages(GetSnippetIDVector(content->snippets)); |
381 content->snippets.clear(); | 381 content->snippets.clear(); |
382 | 382 |
383 NotifyNewSuggestions(); | 383 NotifyNewSuggestions(category); |
384 } | 384 } |
385 | 385 |
386 void NTPSnippetsService::GetDismissedSuggestionsForDebugging( | 386 void NTPSnippetsService::GetDismissedSuggestionsForDebugging( |
387 Category category, | 387 Category category, |
388 const DismissedSuggestionsCallback& callback) { | 388 const DismissedSuggestionsCallback& callback) { |
389 DCHECK(base::ContainsKey(categories_, category)); | 389 DCHECK(base::ContainsKey(categories_, category)); |
390 | 390 |
391 std::vector<ContentSuggestion> result; | 391 std::vector<ContentSuggestion> result; |
392 const CategoryContent& content = categories_[category]; | 392 const CategoryContent& content = categories_[category]; |
393 for (const std::unique_ptr<NTPSnippet>& snippet : content.dismissed) { | 393 for (const std::unique_ptr<NTPSnippet>& snippet : content.dismissed) { |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
574 } | 574 } |
575 } | 575 } |
576 | 576 |
577 // We might have gotten new categories (or updated the titles of existing | 577 // We might have gotten new categories (or updated the titles of existing |
578 // ones), so update the pref. | 578 // ones), so update the pref. |
579 StoreCategoriesToPrefs(); | 579 StoreCategoriesToPrefs(); |
580 | 580 |
581 for (const auto& item : categories_) { | 581 for (const auto& item : categories_) { |
582 Category category = item.first; | 582 Category category = item.first; |
583 UpdateCategoryStatus(category, CategoryStatus::AVAILABLE); | 583 UpdateCategoryStatus(category, CategoryStatus::AVAILABLE); |
584 // TODO(sfiera): notify only when a category changed above. | |
dgn
2016/10/20 14:07:33
todo not needed anymore?
Marc Treib
2016/10/20 14:29:50
I think it's still needed: We still notify about a
| |
585 NotifyNewSuggestions(category); | |
584 } | 586 } |
585 | 587 |
586 // TODO(sfiera): equivalent metrics for non-articles. | 588 // TODO(sfiera): equivalent metrics for non-articles. |
587 const CategoryContent& content = categories_[articles_category_]; | 589 const CategoryContent& content = categories_[articles_category_]; |
588 UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.Snippets.NumArticles", | 590 UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.Snippets.NumArticles", |
589 content.snippets.size()); | 591 content.snippets.size()); |
590 if (content.snippets.empty() && !content.dismissed.empty()) { | 592 if (content.snippets.empty() && !content.dismissed.empty()) { |
591 UMA_HISTOGRAM_COUNTS("NewTabPage.Snippets.NumArticlesZeroDueToDiscarded", | 593 UMA_HISTOGRAM_COUNTS("NewTabPage.Snippets.NumArticlesZeroDueToDiscarded", |
592 content.dismissed.size()); | 594 content.dismissed.size()); |
593 } | 595 } |
594 | 596 |
595 // TODO(sfiera): notify only when a category changed above. | |
596 NotifyNewSuggestions(); | |
597 | |
598 // Reschedule after a successful fetch. This resets all currently scheduled | 597 // Reschedule after a successful fetch. This resets all currently scheduled |
599 // fetches, to make sure the fallback interval triggers only if no wifi fetch | 598 // fetches, to make sure the fallback interval triggers only if no wifi fetch |
600 // succeeded, and also that we don't do a background fetch immediately after | 599 // succeeded, and also that we don't do a background fetch immediately after |
601 // a user-initiated one. | 600 // a user-initiated one. |
602 if (fetched_categories) | 601 if (fetched_categories) |
603 RescheduleFetching(true); | 602 RescheduleFetching(true); |
604 } | 603 } |
605 | 604 |
606 void NTPSnippetsService::ArchiveSnippets(Category category, | 605 void NTPSnippetsService::ArchiveSnippets(Category category, |
607 NTPSnippet::PtrVector* to_archive) { | 606 NTPSnippet::PtrVector* to_archive) { |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
735 } | 734 } |
736 | 735 |
737 void NTPSnippetsService::NukeAllSnippets() { | 736 void NTPSnippetsService::NukeAllSnippets() { |
738 std::vector<Category> categories_to_erase; | 737 std::vector<Category> categories_to_erase; |
739 | 738 |
740 // Empty the ARTICLES category and remove all others, since they may or may | 739 // Empty the ARTICLES category and remove all others, since they may or may |
741 // not be personalized. | 740 // not be personalized. |
742 for (const auto& item : categories_) { | 741 for (const auto& item : categories_) { |
743 Category category = item.first; | 742 Category category = item.first; |
744 | 743 |
745 ClearCachedSuggestions(category); | 744 ClearCachedSuggestions(category); |
Marc Treib
2016/10/20 13:04:58
The bug was triggered from here: ClearCachedSugges
| |
746 ClearDismissedSuggestionsForDebugging(category); | 745 ClearDismissedSuggestionsForDebugging(category); |
747 | 746 |
748 UpdateCategoryStatus(category, CategoryStatus::NOT_PROVIDED); | 747 UpdateCategoryStatus(category, CategoryStatus::NOT_PROVIDED); |
749 | 748 |
750 // Remove the category entirely; it may or may not reappear. | 749 // Remove the category entirely; it may or may not reappear. |
751 if (category != articles_category_) | 750 if (category != articles_category_) |
752 categories_to_erase.push_back(category); | 751 categories_to_erase.push_back(category); |
753 } | 752 } |
754 | 753 |
755 for (Category category : categories_to_erase) { | 754 for (Category category : categories_to_erase) { |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
878 data_use_measurement::DataUseUserData::NTP_SNIPPETS); | 877 data_use_measurement::DataUseUserData::NTP_SNIPPETS); |
879 } | 878 } |
880 | 879 |
881 // Note: Initializing the status service will run the callback right away with | 880 // Note: Initializing the status service will run the callback right away with |
882 // the current state. | 881 // the current state. |
883 snippets_status_service_->Init(base::Bind( | 882 snippets_status_service_->Init(base::Bind( |
884 &NTPSnippetsService::OnSnippetsStatusChanged, base::Unretained(this))); | 883 &NTPSnippetsService::OnSnippetsStatusChanged, base::Unretained(this))); |
885 | 884 |
886 // Always notify here even if we got nothing from the database, because we | 885 // Always notify here even if we got nothing from the database, because we |
887 // don't know how long the fetch will take or if it will even complete. | 886 // don't know how long the fetch will take or if it will even complete. |
888 NotifyNewSuggestions(); | 887 for (const auto& item : categories_) { |
888 Category category = item.first; | |
889 NotifyNewSuggestions(category); | |
890 } | |
889 } | 891 } |
890 | 892 |
891 void NTPSnippetsService::OnSnippetsStatusChanged( | 893 void NTPSnippetsService::OnSnippetsStatusChanged( |
892 SnippetsStatus old_snippets_status, | 894 SnippetsStatus old_snippets_status, |
893 SnippetsStatus new_snippets_status) { | 895 SnippetsStatus new_snippets_status) { |
894 switch (new_snippets_status) { | 896 switch (new_snippets_status) { |
895 case SnippetsStatus::ENABLED_AND_SIGNED_IN: | 897 case SnippetsStatus::ENABLED_AND_SIGNED_IN: |
896 if (old_snippets_status == SnippetsStatus::ENABLED_AND_SIGNED_OUT) { | 898 if (old_snippets_status == SnippetsStatus::ENABLED_AND_SIGNED_OUT) { |
897 DCHECK(state_ == State::READY); | 899 DCHECK(state_ == State::READY); |
898 // Clear nonpersonalized suggestions. | 900 // Clear nonpersonalized suggestions. |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
960 DVLOG(1) << "Entering state: ERROR_OCCURRED"; | 962 DVLOG(1) << "Entering state: ERROR_OCCURRED"; |
961 state_ = State::ERROR_OCCURRED; | 963 state_ = State::ERROR_OCCURRED; |
962 EnterStateError(); | 964 EnterStateError(); |
963 break; | 965 break; |
964 } | 966 } |
965 | 967 |
966 // Schedule or un-schedule background fetching after each state change. | 968 // Schedule or un-schedule background fetching after each state change. |
967 RescheduleFetching(false); | 969 RescheduleFetching(false); |
968 } | 970 } |
969 | 971 |
970 void NTPSnippetsService::NotifyNewSuggestions() { | 972 void NTPSnippetsService::NotifyNewSuggestions(Category category) { |
971 for (const auto& item : categories_) { | 973 DCHECK(base::ContainsKey(categories_, category)); |
972 Category category = item.first; | 974 const CategoryContent& content = categories_[category]; |
973 const CategoryContent& content = item.second; | 975 DCHECK(IsCategoryStatusAvailable(content.status)); |
974 | 976 |
975 std::vector<ContentSuggestion> result; | 977 std::vector<ContentSuggestion> result; |
976 for (const std::unique_ptr<NTPSnippet>& snippet : content.snippets) { | 978 for (const std::unique_ptr<NTPSnippet>& snippet : content.snippets) { |
977 // TODO(sfiera): if a snippet is not going to be displayed, move it | 979 // TODO(sfiera): if a snippet is not going to be displayed, move it |
978 // directly to content.dismissed on fetch. Otherwise, we might prune | 980 // directly to content.dismissed on fetch. Otherwise, we might prune |
979 // other snippets to get down to kMaxSnippetCount, only to hide one of the | 981 // other snippets to get down to kMaxSnippetCount, only to hide one of the |
980 // incomplete ones we kept. | 982 // incomplete ones we kept. |
981 if (!snippet->is_complete()) | 983 if (!snippet->is_complete()) |
982 continue; | 984 continue; |
983 ContentSuggestion suggestion(category, snippet->id(), | 985 ContentSuggestion suggestion(category, snippet->id(), |
984 snippet->best_source().url); | 986 snippet->best_source().url); |
985 suggestion.set_amp_url(snippet->best_source().amp_url); | 987 suggestion.set_amp_url(snippet->best_source().amp_url); |
986 suggestion.set_title(base::UTF8ToUTF16(snippet->title())); | 988 suggestion.set_title(base::UTF8ToUTF16(snippet->title())); |
987 suggestion.set_snippet_text(base::UTF8ToUTF16(snippet->snippet())); | 989 suggestion.set_snippet_text(base::UTF8ToUTF16(snippet->snippet())); |
988 suggestion.set_publish_date(snippet->publish_date()); | 990 suggestion.set_publish_date(snippet->publish_date()); |
989 suggestion.set_publisher_name( | 991 suggestion.set_publisher_name( |
990 base::UTF8ToUTF16(snippet->best_source().publisher_name)); | 992 base::UTF8ToUTF16(snippet->best_source().publisher_name)); |
991 suggestion.set_score(snippet->score()); | 993 suggestion.set_score(snippet->score()); |
992 result.emplace_back(std::move(suggestion)); | 994 result.emplace_back(std::move(suggestion)); |
993 } | 995 } |
994 | 996 |
995 DVLOG(1) << "NotifyNewSuggestions(): " << result.size() | 997 DVLOG(1) << "NotifyNewSuggestions(" << category << "): " << result.size() |
996 << " items in category " << category; | 998 << " items."; |
997 observer()->OnNewSuggestions(this, category, std::move(result)); | 999 observer()->OnNewSuggestions(this, category, std::move(result)); |
998 } | |
999 } | 1000 } |
1000 | 1001 |
1001 void NTPSnippetsService::UpdateCategoryStatus(Category category, | 1002 void NTPSnippetsService::UpdateCategoryStatus(Category category, |
1002 CategoryStatus status) { | 1003 CategoryStatus status) { |
1003 DCHECK(base::ContainsKey(categories_, category)); | 1004 DCHECK(base::ContainsKey(categories_, category)); |
1004 CategoryContent& content = categories_[category]; | 1005 CategoryContent& content = categories_[category]; |
1005 if (status == content.status) | 1006 if (status == content.status) |
1006 return; | 1007 return; |
1007 | 1008 |
1008 DVLOG(1) << "UpdateCategoryStatus(): " << category.id() << ": " | 1009 DVLOG(1) << "UpdateCategoryStatus(): " << category.id() << ": " |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1108 } | 1109 } |
1109 | 1110 |
1110 NTPSnippetsService::CategoryContent::CategoryContent() = default; | 1111 NTPSnippetsService::CategoryContent::CategoryContent() = default; |
1111 NTPSnippetsService::CategoryContent::CategoryContent(CategoryContent&&) = | 1112 NTPSnippetsService::CategoryContent::CategoryContent(CategoryContent&&) = |
1112 default; | 1113 default; |
1113 NTPSnippetsService::CategoryContent::~CategoryContent() = default; | 1114 NTPSnippetsService::CategoryContent::~CategoryContent() = default; |
1114 NTPSnippetsService::CategoryContent& NTPSnippetsService::CategoryContent:: | 1115 NTPSnippetsService::CategoryContent& NTPSnippetsService::CategoryContent:: |
1115 operator=(CategoryContent&&) = default; | 1116 operator=(CategoryContent&&) = default; |
1116 | 1117 |
1117 } // namespace ntp_snippets | 1118 } // namespace ntp_snippets |
OLD | NEW |