Chromium Code Reviews| 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 |