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

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

Issue 2446163005: [NTP Snippets] FetchMore backend (Closed)
Patch Set: Address comments from https://codereview.chromium.org/2421463002/ 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 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/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 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 } 150 }
151 151
152 void RemoveNullPointers(NTPSnippet::PtrVector* snippets) { 152 void RemoveNullPointers(NTPSnippet::PtrVector* snippets) {
153 snippets->erase( 153 snippets->erase(
154 std::remove_if( 154 std::remove_if(
155 snippets->begin(), snippets->end(), 155 snippets->begin(), snippets->end(),
156 [](const std::unique_ptr<NTPSnippet>& snippet) { return !snippet; }), 156 [](const std::unique_ptr<NTPSnippet>& snippet) { return !snippet; }),
157 snippets->end()); 157 snippets->end());
158 } 158 }
159 159
160 void AssignExpiryAndPublishDates(NTPSnippet::PtrVector* snippets) {
161 for (std::unique_ptr<NTPSnippet>& snippet : *snippets) {
162 if (snippet->publish_date().is_null())
163 snippet->set_publish_date(base::Time::Now());
164 if (snippet->expiry_date().is_null()) {
165 snippet->set_expiry_date(
166 snippet->publish_date() +
167 base::TimeDelta::FromMinutes(kDefaultExpiryTimeMins));
168 }
169 }
170 }
171
172 void RemoveIncompleteSnippets(NTPSnippet::PtrVector* snippets) {
173 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
174 switches::kAddIncompleteSnippets)) {
175 return;
176 }
177 int num_snippets = snippets->size();
178 // Remove snippets that do not have all the info we need to display it to
179 // the user.
180 snippets->erase(
181 std::remove_if(snippets->begin(), snippets->end(),
182 [](const std::unique_ptr<NTPSnippet>& snippet) {
183 return !snippet->is_complete();
184 }),
185 snippets->end());
186 int num_snippets_dismissed = num_snippets - snippets->size();
187 UMA_HISTOGRAM_BOOLEAN("NewTabPage.Snippets.IncompleteSnippetsAfterFetch",
188 num_snippets_dismissed > 0);
189 if (num_snippets_dismissed > 0) {
190 UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.Snippets.NumIncompleteSnippets",
191 num_snippets_dismissed);
192 }
193 }
194
195 std::vector<ContentSuggestion> ConvertToContentSuggestions(
196 Category category,
197 const NTPSnippet::PtrVector& snippets) {
198 std::vector<ContentSuggestion> result;
199 for (const std::unique_ptr<NTPSnippet>& snippet : snippets) {
200 // TODO(sfiera): if a snippet is not going to be displayed, move it
201 // directly to content.dismissed on fetch. Otherwise, we might prune
202 // other snippets to get down to kMaxSnippetCount, only to hide one of the
203 // incomplete ones we kept.
204 if (!snippet->is_complete())
205 continue;
206 ContentSuggestion suggestion(category, snippet->id(),
207 snippet->best_source().url);
208 suggestion.set_amp_url(snippet->best_source().amp_url);
209 suggestion.set_title(base::UTF8ToUTF16(snippet->title()));
210 suggestion.set_snippet_text(base::UTF8ToUTF16(snippet->snippet()));
211 suggestion.set_publish_date(snippet->publish_date());
212 suggestion.set_publisher_name(
213 base::UTF8ToUTF16(snippet->best_source().publisher_name));
214 suggestion.set_score(snippet->score());
215 result.emplace_back(std::move(suggestion));
216 }
217 return result;
218 }
219
160 } // namespace 220 } // namespace
161 221
162 NTPSnippetsService::NTPSnippetsService( 222 NTPSnippetsService::NTPSnippetsService(
163 Observer* observer, 223 Observer* observer,
164 CategoryFactory* category_factory, 224 CategoryFactory* category_factory,
165 PrefService* pref_service, 225 PrefService* pref_service,
166 const std::string& application_language_code, 226 const std::string& application_language_code,
167 const UserClassifier* user_classifier, 227 const UserClassifier* user_classifier,
168 NTPSnippetsScheduler* scheduler, 228 NTPSnippetsScheduler* scheduler,
169 std::unique_ptr<NTPSnippetsFetcher> snippets_fetcher, 229 std::unique_ptr<NTPSnippetsFetcher> snippets_fetcher,
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 void NTPSnippetsService::FetchSnippets(bool interactive_request) { 296 void NTPSnippetsService::FetchSnippets(bool interactive_request) {
237 if (ready()) 297 if (ready())
238 FetchSnippetsFromHosts(std::set<std::string>(), interactive_request); 298 FetchSnippetsFromHosts(std::set<std::string>(), interactive_request);
239 else 299 else
240 fetch_when_ready_ = true; 300 fetch_when_ready_ = true;
241 } 301 }
242 302
243 void NTPSnippetsService::FetchSnippetsFromHosts( 303 void NTPSnippetsService::FetchSnippetsFromHosts(
244 const std::set<std::string>& hosts, 304 const std::set<std::string>& hosts,
245 bool interactive_request) { 305 bool interactive_request) {
246 if (!ready()) 306 FetchSnippetsFromHostsImpl(hosts, interactive_request,
307 /*fetch_more=*/false, FetchedMoreCallback(),
308 base::Optional<Category>());
309 }
310
311 void NTPSnippetsService::FetchMore(const Category& category,
312 FetchedMoreCallback callback) {
313 FetchSnippetsFromHostsImpl(std::set<std::string>(),
314 /*interactive_request=*/true,
315 /*fetch_more=*/true, callback,
316 base::Optional<Category>(category));
317 }
318
319 void NTPSnippetsService::FetchSnippetsFromHostsImpl(
320 const std::set<std::string>& hosts,
321 bool interactive_request,
322 bool fetch_more,
323 FetchedMoreCallback callback,
324 base::Optional<Category> exclusive_category) {
325 if (!ready()) {
326 // TODO(fhorschig): Call |callback| if it's non-null.
247 return; 327 return;
328 }
248 329
249 // Empty categories are marked as loading; others are unchanged. 330 MarkEmptyCategoriesAsLoading();
331
332 NTPSnippetsFetcher::Params params;
333 params.language_code = application_language_code_;
334 params.excluded_ids = CollectIdsToExclude(fetch_more);
335 params.count_to_fetch = kMaxSnippetCount;
336 params.hosts = hosts;
337 params.interactive_request = interactive_request;
338 params.exclusive_category = std::move(exclusive_category);
339
340 snippets_fetcher_->FetchSnippets(
341 params, base::BindOnce(&NTPSnippetsService::OnFetchFinished,
342 base::Unretained(this), fetch_more, callback));
343 }
344
345 std::set<std::string> NTPSnippetsService::CollectIdsToExclude(
346 bool fetch_more) const {
347 std::set<std::string> ids;
348 for (const auto& item : categories_) {
349 const CategoryContent& content = item.second;
350 for (const auto& snippet : content.dismissed)
351 ids.insert(snippet->id());
352 if (!fetch_more)
353 continue;
354 for (const auto& snippet : content.archived)
355 ids.insert(snippet->id());
356 for (const auto& snippet : content.snippets)
357 ids.insert(snippet->id());
358 }
359 return ids;
360 }
361
362 void NTPSnippetsService::MarkEmptyCategoriesAsLoading() {
250 for (const auto& item : categories_) { 363 for (const auto& item : categories_) {
251 Category category = item.first; 364 Category category = item.first;
252 const CategoryContent& content = item.second; 365 const CategoryContent& content = item.second;
253 if (content.snippets.empty()) 366 if (content.snippets.empty())
254 UpdateCategoryStatus(category, CategoryStatus::AVAILABLE_LOADING); 367 UpdateCategoryStatus(category, CategoryStatus::AVAILABLE_LOADING);
255 } 368 }
256
257 NTPSnippetsFetcher::Params params;
258 params.language_code = application_language_code_;
259 params.count_to_fetch = kMaxSnippetCount;
260 params.hosts = hosts;
261 params.interactive_request = interactive_request;
262 for (const auto& item : categories_) {
263 const CategoryContent& content = item.second;
264 for (const auto& snippet : content.dismissed)
265 params.excluded_ids.insert(snippet->id());
266 }
267 snippets_fetcher_->FetchSnippets(params);
268 } 369 }
269 370
270 void NTPSnippetsService::RescheduleFetching(bool force) { 371 void NTPSnippetsService::RescheduleFetching(bool force) {
271 // The scheduler only exists on Android so far, it's null on other platforms. 372 // The scheduler only exists on Android so far, it's null on other platforms.
272 if (!scheduler_) 373 if (!scheduler_)
273 return; 374 return;
274 375
275 if (ready()) { 376 if (ready()) {
276 base::TimeDelta old_interval_wifi = 377 base::TimeDelta old_interval_wifi =
277 base::TimeDelta::FromInternalValue(pref_service_->GetInt64( 378 base::TimeDelta::FromInternalValue(pref_service_->GetInt64(
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 ClearOrphanedImages(); 623 ClearOrphanedImages();
523 FinishInitialization(); 624 FinishInitialization();
524 } 625 }
525 626
526 void NTPSnippetsService::OnDatabaseError() { 627 void NTPSnippetsService::OnDatabaseError() {
527 EnterState(State::ERROR_OCCURRED); 628 EnterState(State::ERROR_OCCURRED);
528 UpdateAllCategoryStatus(CategoryStatus::LOADING_ERROR); 629 UpdateAllCategoryStatus(CategoryStatus::LOADING_ERROR);
529 } 630 }
530 631
531 void NTPSnippetsService::OnFetchFinished( 632 void NTPSnippetsService::OnFetchFinished(
633 bool fetched_more,
634 FetchedMoreCallback fetched_more_callback,
532 NTPSnippetsFetcher::OptionalFetchedCategories fetched_categories) { 635 NTPSnippetsFetcher::OptionalFetchedCategories fetched_categories) {
533 if (!ready()) 636 if (!ready())
534 return; 637 return;
535 638
639 // TODO(fhorschig): Check which of the things here should actually happen for
640 // |fetch_more| requests. Maybe it makes sense to have two separate
641 // "Finished" methods?
642
536 // Mark all categories as not provided by the server in the latest fetch. The 643 // Mark all categories as not provided by the server in the latest fetch. The
537 // ones we got will be marked again below. 644 // ones we got will be marked again below.
538 for (auto& item : categories_) { 645 for (auto& item : categories_) {
539 CategoryContent* content = &item.second; 646 CategoryContent* content = &item.second;
540 content->provided_by_server = false; 647 content->provided_by_server = false;
541 } 648 }
542 649
543 // Clear up expired dismissed snippets before we use them to filter new ones. 650 // Clear up expired dismissed snippets before we use them to filter new ones.
544 ClearExpiredDismissedSnippets(); 651 ClearExpiredDismissedSnippets();
545 652
(...skipping 20 matching lines...) Expand all
566 categories_[category].provided_by_server = true; 673 categories_[category].provided_by_server = true;
567 674
568 // TODO(tschumann): Remove this histogram once we only talk to the content 675 // TODO(tschumann): Remove this histogram once we only talk to the content
569 // suggestions cloud backend. 676 // suggestions cloud backend.
570 if (category == articles_category_) { 677 if (category == articles_category_) {
571 UMA_HISTOGRAM_SPARSE_SLOWLY( 678 UMA_HISTOGRAM_SPARSE_SLOWLY(
572 "NewTabPage.Snippets.NumArticlesFetched", 679 "NewTabPage.Snippets.NumArticlesFetched",
573 std::min(fetched_category.snippets.size(), 680 std::min(fetched_category.snippets.size(),
574 static_cast<size_t>(kMaxSnippetCount + 1))); 681 static_cast<size_t>(kMaxSnippetCount + 1)));
575 } 682 }
576 ReplaceSnippets(category, std::move(fetched_category.snippets)); 683 IncludeSnippets(category, std::move(fetched_category.snippets),
684 /*replace_snippets=*/!fetched_more);
577 } 685 }
578 } 686 }
579 687
580 // We might have gotten new categories (or updated the titles of existing 688 // We might have gotten new categories (or updated the titles of existing
581 // ones), so update the pref. 689 // ones), so update the pref.
582 StoreCategoriesToPrefs(); 690 StoreCategoriesToPrefs();
583 691
584 for (const auto& item : categories_) { 692 for (const auto& item : categories_) {
585 Category category = item.first; 693 Category category = item.first;
586 UpdateCategoryStatus(category, CategoryStatus::AVAILABLE); 694 UpdateCategoryStatus(category, CategoryStatus::AVAILABLE);
587 // TODO(sfiera): notify only when a category changed above. 695 // TODO(sfiera): notify only when a category changed above.
588 NotifyNewSuggestions(category); 696 if (fetched_more)
697 NotifyMoreSuggestions(category, fetched_more_callback);
698 else
699 NotifyNewSuggestions(category);
589 } 700 }
590 701
591 // TODO(sfiera): equivalent metrics for non-articles. 702 // TODO(sfiera): equivalent metrics for non-articles.
592 const CategoryContent& content = categories_[articles_category_]; 703 const CategoryContent& content = categories_[articles_category_];
593 UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.Snippets.NumArticles", 704 UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.Snippets.NumArticles",
594 content.snippets.size()); 705 content.snippets.size());
595 if (content.snippets.empty() && !content.dismissed.empty()) { 706 if (content.snippets.empty() && !content.dismissed.empty()) {
596 UMA_HISTOGRAM_COUNTS("NewTabPage.Snippets.NumArticlesZeroDueToDiscarded", 707 UMA_HISTOGRAM_COUNTS("NewTabPage.Snippets.NumArticlesZeroDueToDiscarded",
597 content.dismissed.size()); 708 content.dismissed.size());
598 } 709 }
(...skipping 23 matching lines...) Expand all
622 if (content->archived.size() > kMaxArchivedSnippetCount) { 733 if (content->archived.size() > kMaxArchivedSnippetCount) {
623 NTPSnippet::PtrVector to_delete( 734 NTPSnippet::PtrVector to_delete(
624 std::make_move_iterator(content->archived.begin() + 735 std::make_move_iterator(content->archived.begin() +
625 kMaxArchivedSnippetCount), 736 kMaxArchivedSnippetCount),
626 std::make_move_iterator(content->archived.end())); 737 std::make_move_iterator(content->archived.end()));
627 content->archived.resize(kMaxArchivedSnippetCount); 738 content->archived.resize(kMaxArchivedSnippetCount);
628 database_->DeleteImages(GetSnippetIDVector(to_delete)); 739 database_->DeleteImages(GetSnippetIDVector(to_delete));
629 } 740 }
630 } 741 }
631 742
632 void NTPSnippetsService::ReplaceSnippets(Category category, 743 void NTPSnippetsService::IncludeSnippets(const Category& category,
633 NTPSnippet::PtrVector new_snippets) { 744 NTPSnippet::PtrVector new_snippets,
745 bool replace_snippets) {
634 DCHECK(ready()); 746 DCHECK(ready());
635 CategoryContent* content = &categories_[category]; 747 CategoryContent* content = &categories_[category];
636 748
637 // Remove new snippets that have been dismissed. 749 // Remove new snippets that have been dismissed.
638 EraseMatchingSnippets(&new_snippets, content->dismissed); 750 EraseMatchingSnippets(&new_snippets, content->dismissed);
639 751
640 // Fill in default publish/expiry dates where required. 752 AssignExpiryAndPublishDates(&new_snippets);
641 for (std::unique_ptr<NTPSnippet>& snippet : new_snippets) { 753 RemoveIncompleteSnippets(&new_snippets);
642 if (snippet->publish_date().is_null())
643 snippet->set_publish_date(base::Time::Now());
644 if (snippet->expiry_date().is_null()) {
645 snippet->set_expiry_date(
646 snippet->publish_date() +
647 base::TimeDelta::FromMinutes(kDefaultExpiryTimeMins));
648 }
649 }
650
651 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
652 switches::kAddIncompleteSnippets)) {
653 int num_new_snippets = new_snippets.size();
654 // Remove snippets that do not have all the info we need to display it to
655 // the user.
656 new_snippets.erase(
657 std::remove_if(new_snippets.begin(), new_snippets.end(),
658 [](const std::unique_ptr<NTPSnippet>& snippet) {
659 return !snippet->is_complete();
660 }),
661 new_snippets.end());
662 int num_snippets_dismissed = num_new_snippets - new_snippets.size();
663 UMA_HISTOGRAM_BOOLEAN("NewTabPage.Snippets.IncompleteSnippetsAfterFetch",
664 num_snippets_dismissed > 0);
665 if (num_snippets_dismissed > 0) {
666 UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.Snippets.NumIncompleteSnippets",
667 num_snippets_dismissed);
668 }
669 }
670 754
671 // Do not touch the current set of snippets if the newly fetched one is empty. 755 // Do not touch the current set of snippets if the newly fetched one is empty.
672 if (new_snippets.empty()) 756 if (new_snippets.empty())
673 return; 757 return;
674 758
675 // It's entirely possible that the newly fetched snippets contain articles 759 // It's entirely possible that the newly fetched snippets contain articles
676 // that have been present before. 760 // that have been present before.
677 // Since archival removes snippets from the database (indexed by 761 // Since archival removes snippets from the database (indexed by
678 // snippet->id()), we need to make sure to only archive snippets that don't 762 // snippet->id()), we need to make sure to only archive snippets that don't
679 // appear with the same ID in the new suggestions (it's fine for additional 763 // appear with the same ID in the new suggestions (it's fine for additional
680 // IDs though). 764 // IDs though).
681 EraseByPrimaryID(&content->snippets, *GetSnippetIDVector(new_snippets)); 765 EraseByPrimaryID(&content->snippets, *GetSnippetIDVector(new_snippets));
682 ArchiveSnippets(category, &content->snippets);
683 766
684 // Save new articles to the DB.
685 database_->SaveSnippets(new_snippets); 767 database_->SaveSnippets(new_snippets);
686 768
687 content->snippets = std::move(new_snippets); 769 if (replace_snippets) {
770 ArchiveSnippets(category, &content->snippets);
771 content->snippets = std::move(new_snippets);
772 } else {
773 content->snippets.insert(content->snippets.end(),
774 std::make_move_iterator(new_snippets.begin()),
775 std::make_move_iterator(new_snippets.end()));
776 }
688 } 777 }
689 778
690 void NTPSnippetsService::ClearExpiredDismissedSnippets() { 779 void NTPSnippetsService::ClearExpiredDismissedSnippets() {
691 std::vector<Category> categories_to_erase; 780 std::vector<Category> categories_to_erase;
692 781
693 const base::Time now = base::Time::Now(); 782 const base::Time now = base::Time::Now();
694 783
695 for (auto& item : categories_) { 784 for (auto& item : categories_) {
696 Category category = item.first; 785 Category category = item.first;
697 CategoryContent* content = &item.second; 786 CategoryContent* content = &item.second;
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
863 } 952 }
864 953
865 void NTPSnippetsService::FinishInitialization() { 954 void NTPSnippetsService::FinishInitialization() {
866 if (nuke_when_initialized_) { 955 if (nuke_when_initialized_) {
867 // We nuke here in addition to EnterStateReady, so that it happens even if 956 // We nuke here in addition to EnterStateReady, so that it happens even if
868 // we enter the DISABLED state below. 957 // we enter the DISABLED state below.
869 NukeAllSnippets(); 958 NukeAllSnippets();
870 nuke_when_initialized_ = false; 959 nuke_when_initialized_ = false;
871 } 960 }
872 961
873 snippets_fetcher_->SetCallback(
874 base::Bind(&NTPSnippetsService::OnFetchFinished, base::Unretained(this)));
875
876 // |image_fetcher_| can be null in tests. 962 // |image_fetcher_| can be null in tests.
877 if (image_fetcher_) { 963 if (image_fetcher_) {
878 image_fetcher_->SetImageFetcherDelegate(this); 964 image_fetcher_->SetImageFetcherDelegate(this);
879 image_fetcher_->SetDataUseServiceName( 965 image_fetcher_->SetDataUseServiceName(
880 data_use_measurement::DataUseUserData::NTP_SNIPPETS); 966 data_use_measurement::DataUseUserData::NTP_SNIPPETS);
881 } 967 }
882 968
883 // Note: Initializing the status service will run the callback right away with 969 // Note: Initializing the status service will run the callback right away with
884 // the current state. 970 // the current state.
885 snippets_status_service_->Init(base::Bind( 971 snippets_status_service_->Init(base::Bind(
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
970 1056
971 // Schedule or un-schedule background fetching after each state change. 1057 // Schedule or un-schedule background fetching after each state change.
972 RescheduleFetching(false); 1058 RescheduleFetching(false);
973 } 1059 }
974 1060
975 void NTPSnippetsService::NotifyNewSuggestions(Category category) { 1061 void NTPSnippetsService::NotifyNewSuggestions(Category category) {
976 DCHECK(base::ContainsKey(categories_, category)); 1062 DCHECK(base::ContainsKey(categories_, category));
977 const CategoryContent& content = categories_[category]; 1063 const CategoryContent& content = categories_[category];
978 DCHECK(IsCategoryStatusAvailable(content.status)); 1064 DCHECK(IsCategoryStatusAvailable(content.status));
979 1065
980 std::vector<ContentSuggestion> result; 1066 std::vector<ContentSuggestion> result =
981 for (const std::unique_ptr<NTPSnippet>& snippet : content.snippets) { 1067 ConvertToContentSuggestions(category, content.snippets);
982 // TODO(sfiera): if a snippet is not going to be displayed, move it
983 // directly to content.dismissed on fetch. Otherwise, we might prune
984 // other snippets to get down to kMaxSnippetCount, only to hide one of the
985 // incomplete ones we kept.
986 if (!snippet->is_complete())
987 continue;
988 ContentSuggestion suggestion(category, snippet->id(),
989 snippet->best_source().url);
990 suggestion.set_amp_url(snippet->best_source().amp_url);
991 suggestion.set_title(base::UTF8ToUTF16(snippet->title()));
992 suggestion.set_snippet_text(base::UTF8ToUTF16(snippet->snippet()));
993 suggestion.set_publish_date(snippet->publish_date());
994 suggestion.set_publisher_name(
995 base::UTF8ToUTF16(snippet->best_source().publisher_name));
996 suggestion.set_score(snippet->score());
997 result.emplace_back(std::move(suggestion));
998 }
999 1068
1000 DVLOG(1) << "NotifyNewSuggestions(" << category << "): " << result.size() 1069 DVLOG(1) << "NotifyNewSuggestions(): " << result.size()
1001 << " items."; 1070 << " items in category " << category;
1002 observer()->OnNewSuggestions(this, category, std::move(result)); 1071 observer()->OnNewSuggestions(this, category, std::move(result));
1003 } 1072 }
1004 1073
1074 void NTPSnippetsService::NotifyMoreSuggestions(Category category,
1075 FetchedMoreCallback callback) {
1076 DCHECK(base::ContainsKey(categories_, category));
1077 const CategoryContent& content = categories_[category];
1078 DCHECK(IsCategoryStatusAvailable(content.status));
1079
1080 std::vector<ContentSuggestion> result =
1081 ConvertToContentSuggestions(category, content.snippets);
1082
1083 DVLOG(1) << "NotifyMoreSuggestions(): " << result.size()
1084 << " items in category " << category;
1085 DCHECK(!callback.is_null());
1086 callback.Run(std::move(result));
1087 }
1088
1005 void NTPSnippetsService::UpdateCategoryStatus(Category category, 1089 void NTPSnippetsService::UpdateCategoryStatus(Category category,
1006 CategoryStatus status) { 1090 CategoryStatus status) {
1007 DCHECK(base::ContainsKey(categories_, category)); 1091 DCHECK(base::ContainsKey(categories_, category));
1008 CategoryContent& content = categories_[category]; 1092 CategoryContent& content = categories_[category];
1009 if (status == content.status) 1093 if (status == content.status)
1010 return; 1094 return;
1011 1095
1012 DVLOG(1) << "UpdateCategoryStatus(): " << category.id() << ": " 1096 DVLOG(1) << "UpdateCategoryStatus(): " << category.id() << ": "
1013 << static_cast<int>(content.status) << " -> " 1097 << static_cast<int>(content.status) << " -> "
1014 << static_cast<int>(status); 1098 << static_cast<int>(status);
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1112 } 1196 }
1113 1197
1114 NTPSnippetsService::CategoryContent::CategoryContent() = default; 1198 NTPSnippetsService::CategoryContent::CategoryContent() = default;
1115 NTPSnippetsService::CategoryContent::CategoryContent(CategoryContent&&) = 1199 NTPSnippetsService::CategoryContent::CategoryContent(CategoryContent&&) =
1116 default; 1200 default;
1117 NTPSnippetsService::CategoryContent::~CategoryContent() = default; 1201 NTPSnippetsService::CategoryContent::~CategoryContent() = default;
1118 NTPSnippetsService::CategoryContent& NTPSnippetsService::CategoryContent:: 1202 NTPSnippetsService::CategoryContent& NTPSnippetsService::CategoryContent::
1119 operator=(CategoryContent&&) = default; 1203 operator=(CategoryContent&&) = default;
1120 1204
1121 } // namespace ntp_snippets 1205 } // namespace ntp_snippets
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698