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

Unified Diff: components/ntp_snippets/remote/ntp_snippets_service.cc

Issue 2421463002: FetchMore functionality backend (Closed)
Patch Set: NTBR. Rebasing a lot. Created 4 years, 1 month 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 side-by-side diff with in-line comments
Download patch
Index: components/ntp_snippets/remote/ntp_snippets_service.cc
diff --git a/components/ntp_snippets/remote/ntp_snippets_service.cc b/components/ntp_snippets/remote/ntp_snippets_service.cc
index 6d7c5418da939ae436a566f9fd329852dea18c03..e63939ba81639c1f0a0d72e8df140c8825a5a578 100644
--- a/components/ntp_snippets/remote/ntp_snippets_service.cc
+++ b/components/ntp_snippets/remote/ntp_snippets_service.cc
@@ -157,6 +157,45 @@ void RemoveNullPointers(NTPSnippet::PtrVector* snippets) {
snippets->end());
}
+void AssignExpiryAndPublishDates(NTPSnippet::PtrVector* snippets) {
+ for (std::unique_ptr<NTPSnippet>& snippet : *snippets) {
+ if (snippet->publish_date().is_null())
+ snippet->set_publish_date(base::Time::Now());
+ if (snippet->expiry_date().is_null()) {
+ snippet->set_expiry_date(
+ snippet->publish_date() +
+ base::TimeDelta::FromMinutes(kDefaultExpiryTimeMins));
+ }
+ }
+}
+
+void RemoveIncompleteSnippets(NTPSnippet::PtrVector* snippets) {
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kAddIncompleteSnippets)) {
+ return;
+ }
+ int num_snippets = snippets->size();
+ // Remove snippets that do not have all the info we need to display it to
+ // the user.
+ snippets->erase(
+ std::remove_if(snippets->begin(), snippets->end(),
+ [](const std::unique_ptr<NTPSnippet>& snippet) {
+ return !snippet->is_complete();
+ }),
+ snippets->end());
+ int num_snippets_dismissed = num_snippets - snippets->size();
vitaliii 2016/11/01 23:29:57 s/dismissed/removed? "dismissed" is usually used i
fhorschig 2016/11/02 05:05:27 Done in CL 2466863003.
+ UMA_HISTOGRAM_BOOLEAN("NewTabPage.Snippets.IncompleteSnippetsAfterFetch",
+ num_snippets_dismissed > 0);
+ if (num_snippets_dismissed > 0) {
+ UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.Snippets.NumIncompleteSnippets",
+ num_snippets_dismissed);
+ }
+}
+
+NTPSnippetsService::FetchedMoreCallback NullCallback() {
+ return NTPSnippetsService::FetchedMoreCallback();
+}
+
} // namespace
NTPSnippetsService::NTPSnippetsService(
@@ -243,28 +282,74 @@ void NTPSnippetsService::FetchSnippets(bool interactive_request) {
void NTPSnippetsService::FetchSnippetsFromHosts(
const std::set<std::string>& hosts,
bool interactive_request) {
+ FetchSnippetsFromHostsImpl(hosts, interactive_request,
+ /*fetch_more=*/false,
+ base::Optional<Category>(),
+ NullCallback());
vitaliii 2016/11/01 23:29:57 Actually writing here |NTPSnippetsService::Fetched
fhorschig 2016/11/02 05:05:27 Done in 2446163005.
+}
+
+void NTPSnippetsService::FetchMore(const Category& category,
+ const FetchedMoreCallback& callback) {
+ FetchSnippetsFromHostsImpl(std::set<std::string>(),
+ /*interactive_request=*/true,
+ /*fetch_more=*/true,
+ base::Optional<Category>(category),
+ callback);
+}
+
+void NTPSnippetsService::FetchSnippetsFromHostsImpl(
+ const std::set<std::string>& hosts,
+ bool interactive_request,
+ bool fetch_more,
+ base::Optional<Category> exclusive_category,
+ const FetchedMoreCallback& callback) {
if (!ready())
return;
- // Empty categories are marked as loading; others are unchanged.
- for (const auto& item : categories_) {
- Category category = item.first;
- const CategoryContent& content = item.second;
- if (content.snippets.empty())
- UpdateCategoryStatus(category, CategoryStatus::AVAILABLE_LOADING);
- }
-
NTPSnippetsFetcher::Params params;
params.language_code = application_language_code_;
params.count_to_fetch = kMaxSnippetCount;
params.hosts = hosts;
params.interactive_request = interactive_request;
+ params.exclusive_category = exclusive_category;
+ params.excluded_ids = CollectIdsToExclude(fetch_more);
+ params.snippets_available_callback =
+ base::BindOnce(&NTPSnippetsService::OnFetchFinished,
+ base::Unretained(this),
+ fetch_more,
+ std::move(callback));
+
+ MarkEmptyCategoriesAsLoading(&params);
+
+ snippets_fetcher_->FetchSnippets(params);
+}
+
+std::set<std::string> NTPSnippetsService::CollectIdsToExclude(bool fetch_more) {
+ std::set<std::string> ids;
for (const auto& item : categories_) {
const CategoryContent& content = item.second;
for (const auto& snippet : content.dismissed)
- params.excluded_ids.insert(snippet->id());
+ ids.insert(snippet->id());
+ if (!fetch_more)
+ continue;
+ for (const auto& snippet : content.archived)
+ ids.insert(snippet->id());
+ for (const auto& snippet : content.snippets)
+ ids.insert(snippet->id());
+ }
+ return ids;
+}
+
+void NTPSnippetsService::MarkEmptyCategoriesAsLoading(
+ NTPSnippetsFetcher::Params* params) {
+ for (const auto& item : categories_) {
+ Category category = item.first;
+ const CategoryContent& content = item.second;
+ for (const auto& snippet : content.dismissed)
+ params->excluded_ids.insert(snippet->id());
vitaliii 2016/11/01 23:29:57 I cannot understand why this is done here. First,
fhorschig 2016/11/02 05:05:27 This is a false merge. It is completely dropped la
+ if (content.snippets.empty())
+ UpdateCategoryStatus(category, CategoryStatus::AVAILABLE_LOADING);
}
- snippets_fetcher_->FetchSnippets(params);
}
void NTPSnippetsService::RescheduleFetching(bool force) {
@@ -529,6 +614,8 @@ void NTPSnippetsService::OnDatabaseError() {
}
void NTPSnippetsService::OnFetchFinished(
+ bool fetched_more,
+ const FetchedMoreCallback& fetched_more_callback,
NTPSnippetsFetcher::OptionalFetchedCategories fetched_categories) {
if (!ready())
return;
@@ -573,7 +660,8 @@ void NTPSnippetsService::OnFetchFinished(
std::min(fetched_category.snippets.size(),
static_cast<size_t>(kMaxSnippetCount + 1)));
}
- ReplaceSnippets(category, std::move(fetched_category.snippets));
+ IncludeSnippets(category, std::move(fetched_category.snippets),
+ /*replace_snippets=*/!fetched_more);
}
}
@@ -585,7 +673,7 @@ void NTPSnippetsService::OnFetchFinished(
Category category = item.first;
UpdateCategoryStatus(category, CategoryStatus::AVAILABLE);
// TODO(sfiera): notify only when a category changed above.
- NotifyNewSuggestions(category);
+ NotifyNewSuggestionsOrInvokeCallback(category, fetched_more_callback);
}
// TODO(sfiera): equivalent metrics for non-articles.
@@ -605,68 +693,17 @@ void NTPSnippetsService::OnFetchFinished(
RescheduleFetching(true);
}
-void NTPSnippetsService::ArchiveSnippets(Category category,
- NTPSnippet::PtrVector* to_archive) {
- CategoryContent* content = &categories_[category];
- database_->DeleteSnippets(GetSnippetIDVector(*to_archive));
- // Do not delete the thumbnail images as they are still handy on open NTPs.
-
- // Archive previous snippets - move them at the beginning of the list.
- content->archived.insert(content->archived.begin(),
- std::make_move_iterator(to_archive->begin()),
- std::make_move_iterator(to_archive->end()));
- RemoveNullPointers(to_archive);
-
- // If there are more archived snippets than we want to keep, delete the
- // oldest ones by their fetch time (which are always in the back).
- if (content->archived.size() > kMaxArchivedSnippetCount) {
- NTPSnippet::PtrVector to_delete(
- std::make_move_iterator(content->archived.begin() +
- kMaxArchivedSnippetCount),
- std::make_move_iterator(content->archived.end()));
- content->archived.resize(kMaxArchivedSnippetCount);
- database_->DeleteImages(GetSnippetIDVector(to_delete));
- }
-}
-
-void NTPSnippetsService::ReplaceSnippets(Category category,
- NTPSnippet::PtrVector new_snippets) {
+void NTPSnippetsService::IncludeSnippets(const Category& category,
+ NTPSnippet::PtrVector new_snippets,
+ bool replace_snippets) {
DCHECK(ready());
CategoryContent* content = &categories_[category];
// Remove new snippets that have been dismissed.
EraseMatchingSnippets(&new_snippets, content->dismissed);
- // Fill in default publish/expiry dates where required.
- for (std::unique_ptr<NTPSnippet>& snippet : new_snippets) {
- if (snippet->publish_date().is_null())
- snippet->set_publish_date(base::Time::Now());
- if (snippet->expiry_date().is_null()) {
- snippet->set_expiry_date(
- snippet->publish_date() +
- base::TimeDelta::FromMinutes(kDefaultExpiryTimeMins));
- }
- }
-
- if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kAddIncompleteSnippets)) {
- int num_new_snippets = new_snippets.size();
- // Remove snippets that do not have all the info we need to display it to
- // the user.
- new_snippets.erase(
- std::remove_if(new_snippets.begin(), new_snippets.end(),
- [](const std::unique_ptr<NTPSnippet>& snippet) {
- return !snippet->is_complete();
- }),
- new_snippets.end());
- int num_snippets_dismissed = num_new_snippets - new_snippets.size();
- UMA_HISTOGRAM_BOOLEAN("NewTabPage.Snippets.IncompleteSnippetsAfterFetch",
- num_snippets_dismissed > 0);
- if (num_snippets_dismissed > 0) {
- UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.Snippets.NumIncompleteSnippets",
- num_snippets_dismissed);
- }
- }
+ AssignExpiryAndPublishDates(&new_snippets);
+ RemoveIncompleteSnippets(&new_snippets);
// Do not touch the current set of snippets if the newly fetched one is empty.
if (new_snippets.empty())
@@ -679,14 +716,51 @@ void NTPSnippetsService::ReplaceSnippets(Category category,
// appear with the same ID in the new suggestions (it's fine for additional
// IDs though).
EraseByPrimaryID(&content->snippets, *GetSnippetIDVector(new_snippets));
- ArchiveSnippets(category, &content->snippets);
- // Save new articles to the DB.
+ SaveSnippets(category, std::move(new_snippets), replace_snippets);
+}
+
+void NTPSnippetsService::SaveSnippets(const Category& category,
+ NTPSnippet::PtrVector new_snippets,
+ bool replace_snippets) {
database_->SaveSnippets(new_snippets);
- content->snippets = std::move(new_snippets);
+ CategoryContent* content = &categories_[category];
+
+ if (replace_snippets) {
+ ArchiveSnippets(category, &content->snippets);
+ content->snippets = std::move(new_snippets);
+ return;
+ }
+
+ content->snippets.insert(content->snippets.end(),
+ std::make_move_iterator(new_snippets.begin()),
+ std::make_move_iterator(new_snippets.end()));
}
+void NTPSnippetsService::ArchiveSnippets(Category category,
+ NTPSnippet::PtrVector* to_archive) {
+ CategoryContent* content = &categories_[category];
+ database_->DeleteSnippets(GetSnippetIDVector(*to_archive));
+ // Do not delete the thumbnail images as they are still handy on open NTPs.
+
+ // Archive previous snippets - move them at the beginning of the list.
+ content->archived.insert(content->archived.begin(),
+ std::make_move_iterator(to_archive->begin()),
+ std::make_move_iterator(to_archive->end()));
+ RemoveNullPointers(to_archive);
+
+ // If there are more archived snippets than we want to keep, delete the
+ // oldest ones by their fetch time (which are always in the back).
+ if (content->archived.size() > kMaxArchivedSnippetCount) {
+ NTPSnippet::PtrVector to_delete(
+ std::make_move_iterator(content->archived.begin() +
+ kMaxArchivedSnippetCount),
+ std::make_move_iterator(content->archived.end()));
+ content->archived.resize(kMaxArchivedSnippetCount);
+ database_->DeleteImages(GetSnippetIDVector(to_delete));
+ }
+}
void NTPSnippetsService::ClearExpiredDismissedSnippets() {
std::vector<Category> categories_to_erase;
@@ -870,9 +944,6 @@ void NTPSnippetsService::FinishInitialization() {
nuke_when_initialized_ = false;
}
- snippets_fetcher_->SetCallback(
- base::Bind(&NTPSnippetsService::OnFetchFinished, base::Unretained(this)));
-
// |image_fetcher_| can be null in tests.
if (image_fetcher_) {
image_fetcher_->SetImageFetcherDelegate(this);
@@ -973,10 +1044,15 @@ void NTPSnippetsService::EnterState(State state) {
}
void NTPSnippetsService::NotifyNewSuggestions(Category category) {
+ NotifyNewSuggestionsOrInvokeCallback(category, NullCallback());
+}
+
+void NTPSnippetsService::NotifyNewSuggestionsOrInvokeCallback(
+ Category category,
+ FetchedMoreCallback fetched_more_callback) {
DCHECK(base::ContainsKey(categories_, category));
const CategoryContent& content = categories_[category];
DCHECK(IsCategoryStatusAvailable(content.status));
-
std::vector<ContentSuggestion> result;
for (const std::unique_ptr<NTPSnippet>& snippet : content.snippets) {
// TODO(sfiera): if a snippet is not going to be displayed, move it
@@ -985,21 +1061,17 @@ void NTPSnippetsService::NotifyNewSuggestions(Category category) {
// incomplete ones we kept.
if (!snippet->is_complete())
continue;
- ContentSuggestion suggestion(category, snippet->id(),
- snippet->best_source().url);
- suggestion.set_amp_url(snippet->best_source().amp_url);
- suggestion.set_title(base::UTF8ToUTF16(snippet->title()));
- suggestion.set_snippet_text(base::UTF8ToUTF16(snippet->snippet()));
- suggestion.set_publish_date(snippet->publish_date());
- suggestion.set_publisher_name(
- base::UTF8ToUTF16(snippet->best_source().publisher_name));
- suggestion.set_score(snippet->score());
- result.emplace_back(std::move(suggestion));
+ result.emplace_back(
+ ContentSuggestion::FromSnippet(category, snippet.get()));
}
DVLOG(1) << "NotifyNewSuggestions(" << category << "): " << result.size()
<< " items.";
- observer()->OnNewSuggestions(this, category, std::move(result));
+ if (fetched_more_callback.is_null()) {
+ observer()->OnNewSuggestions(this, category, std::move(result));
+ } else {
+ fetched_more_callback.Run(std::move(result));
+ }
}
void NTPSnippetsService::UpdateCategoryStatus(Category category,

Powered by Google App Engine
This is Rietveld 408576698