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

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

Issue 2205233002: Combine all suggestions factories into ContentSuggestionsServiceFactory (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Bernhard's comments Created 4 years, 4 months 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/ntp_snippets_service.h" 5 #include "components/ntp_snippets/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 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 snippets->erase( 178 snippets->erase(
179 std::remove_if( 179 std::remove_if(
180 snippets->begin(), snippets->end(), 180 snippets->begin(), snippets->end(),
181 [](const std::unique_ptr<NTPSnippet>& snippet) { return !snippet; }), 181 [](const std::unique_ptr<NTPSnippet>& snippet) { return !snippet; }),
182 snippets->end()); 182 snippets->end());
183 } 183 }
184 184
185 } // namespace 185 } // namespace
186 186
187 NTPSnippetsService::NTPSnippetsService( 187 NTPSnippetsService::NTPSnippetsService(
188 bool enabled, 188 Observer* observer,
189 CategoryFactory* category_factory,
189 PrefService* pref_service, 190 PrefService* pref_service,
190 SuggestionsService* suggestions_service, 191 SuggestionsService* suggestions_service,
191 CategoryFactory* category_factory,
192 const std::string& application_language_code, 192 const std::string& application_language_code,
193 NTPSnippetsScheduler* scheduler, 193 NTPSnippetsScheduler* scheduler,
194 std::unique_ptr<NTPSnippetsFetcher> snippets_fetcher, 194 std::unique_ptr<NTPSnippetsFetcher> snippets_fetcher,
195 std::unique_ptr<ImageFetcher> image_fetcher, 195 std::unique_ptr<ImageFetcher> image_fetcher,
196 std::unique_ptr<ImageDecoder> image_decoder, 196 std::unique_ptr<ImageDecoder> image_decoder,
197 std::unique_ptr<NTPSnippetsDatabase> database, 197 std::unique_ptr<NTPSnippetsDatabase> database,
198 std::unique_ptr<NTPSnippetsStatusService> status_service) 198 std::unique_ptr<NTPSnippetsStatusService> status_service)
199 : ContentSuggestionsProvider(category_factory), 199 : ContentSuggestionsProvider(observer, category_factory),
200 state_(State::NOT_INITED), 200 state_(State::NOT_INITED),
201 category_status_(CategoryStatus::INITIALIZING), 201 category_status_(CategoryStatus::INITIALIZING),
202 pref_service_(pref_service), 202 pref_service_(pref_service),
203 suggestions_service_(suggestions_service), 203 suggestions_service_(suggestions_service),
204 application_language_code_(application_language_code), 204 application_language_code_(application_language_code),
205 observer_(nullptr),
206 scheduler_(scheduler), 205 scheduler_(scheduler),
207 snippets_fetcher_(std::move(snippets_fetcher)), 206 snippets_fetcher_(std::move(snippets_fetcher)),
208 image_fetcher_(std::move(image_fetcher)), 207 image_fetcher_(std::move(image_fetcher)),
209 image_decoder_(std::move(image_decoder)), 208 image_decoder_(std::move(image_decoder)),
210 database_(std::move(database)), 209 database_(std::move(database)),
211 snippets_status_service_(std::move(status_service)), 210 snippets_status_service_(std::move(status_service)),
212 fetch_after_load_(false), 211 fetch_after_load_(false),
213 provided_category_( 212 provided_category_(
214 category_factory->FromKnownCategory(KnownCategories::ARTICLES)) { 213 category_factory->FromKnownCategory(KnownCategories::ARTICLES)) {
215 // In some cases, don't even bother loading the database.
216 if (!enabled) {
217 EnterState(State::SHUT_DOWN, CategoryStatus::CATEGORY_EXPLICITLY_DISABLED);
218 return;
219 }
220 if (database_->IsErrorState()) { 214 if (database_->IsErrorState()) {
221 EnterState(State::SHUT_DOWN, CategoryStatus::LOADING_ERROR); 215 EnterState(State::ERROR_OCCURRED, CategoryStatus::LOADING_ERROR);
222 return; 216 return;
223 } 217 }
224 218
225 database_->SetErrorCallback(base::Bind(&NTPSnippetsService::OnDatabaseError, 219 database_->SetErrorCallback(base::Bind(&NTPSnippetsService::OnDatabaseError,
226 base::Unretained(this))); 220 base::Unretained(this)));
227 221
228 // TODO(pke): Move this to SetObserver as soon as the UI reads from the
229 // ContentSuggestionsService directly.
230 // We transition to other states while finalizing the initialization, when the 222 // We transition to other states while finalizing the initialization, when the
231 // database is done loading. 223 // database is done loading.
232 database_->LoadSnippets(base::Bind(&NTPSnippetsService::OnDatabaseLoaded, 224 database_->LoadSnippets(base::Bind(&NTPSnippetsService::OnDatabaseLoaded,
233 base::Unretained(this))); 225 base::Unretained(this)));
234 } 226 }
235 227
236 NTPSnippetsService::~NTPSnippetsService() { 228 NTPSnippetsService::~NTPSnippetsService() {
237 DCHECK(state_ == State::SHUT_DOWN);
238 } 229 }
239 230
240 // static 231 // static
241 void NTPSnippetsService::RegisterProfilePrefs(PrefRegistrySimple* registry) { 232 void NTPSnippetsService::RegisterProfilePrefs(PrefRegistrySimple* registry) {
242 registry->RegisterListPref(prefs::kSnippetHosts); 233 registry->RegisterListPref(prefs::kSnippetHosts);
243 234
244 NTPSnippetsStatusService::RegisterProfilePrefs(registry); 235 NTPSnippetsStatusService::RegisterProfilePrefs(registry);
245 } 236 }
246 237
247 // Inherited from KeyedService.
248 void NTPSnippetsService::Shutdown() {
249 EnterState(State::SHUT_DOWN, CategoryStatus::NOT_PROVIDED);
250 }
251
252 void NTPSnippetsService::FetchSnippets(bool force_request) { 238 void NTPSnippetsService::FetchSnippets(bool force_request) {
253 if (ready()) 239 if (ready())
254 FetchSnippetsFromHosts(GetSuggestionsHosts(), force_request); 240 FetchSnippetsFromHosts(GetSuggestionsHosts(), force_request);
255 else 241 else
256 fetch_after_load_ = true; 242 fetch_after_load_ = true;
257 } 243 }
258 244
259 void NTPSnippetsService::FetchSnippetsFromHosts( 245 void NTPSnippetsService::FetchSnippetsFromHosts(
260 const std::set<std::string>& hosts, 246 const std::set<std::string>& hosts,
261 bool force_request) { 247 bool force_request) {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 if (!initialized()) 334 if (!initialized())
349 return; 335 return;
350 336
351 if (dismissed_snippets_.empty()) 337 if (dismissed_snippets_.empty())
352 return; 338 return;
353 339
354 database_->DeleteSnippets(dismissed_snippets_); 340 database_->DeleteSnippets(dismissed_snippets_);
355 dismissed_snippets_.clear(); 341 dismissed_snippets_.clear();
356 } 342 }
357 343
358 void NTPSnippetsService::SetObserver(Observer* observer) {
359 observer_ = observer;
360 }
361
362 CategoryStatus NTPSnippetsService::GetCategoryStatus(Category category) { 344 CategoryStatus NTPSnippetsService::GetCategoryStatus(Category category) {
363 DCHECK(category.IsKnownCategory(KnownCategories::ARTICLES)); 345 DCHECK(category.IsKnownCategory(KnownCategories::ARTICLES));
364 return category_status_; 346 return category_status_;
365 } 347 }
366 348
367 void NTPSnippetsService::AddObserver(NTPSnippetsServiceObserver* observer) {
368 observers_.AddObserver(observer);
369 }
370
371 void NTPSnippetsService::RemoveObserver(NTPSnippetsServiceObserver* observer) {
372 observers_.RemoveObserver(observer);
373 }
374
375 // static 349 // static
376 int NTPSnippetsService::GetMaxSnippetCountForTesting() { 350 int NTPSnippetsService::GetMaxSnippetCountForTesting() {
377 return kMaxSnippetCount; 351 return kMaxSnippetCount;
378 } 352 }
379 353
380 //////////////////////////////////////////////////////////////////////////////// 354 ////////////////////////////////////////////////////////////////////////////////
381 // Private methods 355 // Private methods
382 356
383 // image_fetcher::ImageFetcherDelegate implementation. 357 // image_fetcher::ImageFetcherDelegate implementation.
384 void NTPSnippetsService::OnImageDataFetched(const std::string& snippet_id, 358 void NTPSnippetsService::OnImageDataFetched(const std::string& snippet_id,
385 const std::string& image_data) { 359 const std::string& image_data) {
386 if (image_data.empty()) 360 if (image_data.empty())
387 return; 361 return;
388 362
389 // Only save the image if the corresponding snippet still exists. 363 // Only save the image if the corresponding snippet still exists.
390 auto it = 364 auto it =
391 std::find_if(snippets_.begin(), snippets_.end(), 365 std::find_if(snippets_.begin(), snippets_.end(),
392 [&snippet_id](const std::unique_ptr<NTPSnippet>& snippet) { 366 [&snippet_id](const std::unique_ptr<NTPSnippet>& snippet) {
393 return snippet->id() == snippet_id; 367 return snippet->id() == snippet_id;
394 }); 368 });
395 if (it == snippets_.end()) 369 if (it == snippets_.end())
396 return; 370 return;
397 371
398 database_->SaveImage(snippet_id, image_data); 372 database_->SaveImage(snippet_id, image_data);
399 } 373 }
400 374
401 void NTPSnippetsService::OnDatabaseLoaded(NTPSnippet::PtrVector snippets) { 375 void NTPSnippetsService::OnDatabaseLoaded(NTPSnippet::PtrVector snippets) {
402 DCHECK(state_ == State::NOT_INITED || state_ == State::SHUT_DOWN); 376 if (state_ == State::ERROR_OCCURRED)
403 if (state_ == State::SHUT_DOWN)
404 return; 377 return;
405 378 DCHECK(state_ == State::NOT_INITED);
406 DCHECK(snippets_.empty()); 379 DCHECK(snippets_.empty());
407 DCHECK(dismissed_snippets_.empty()); 380 DCHECK(dismissed_snippets_.empty());
408 for (std::unique_ptr<NTPSnippet>& snippet : snippets) { 381 for (std::unique_ptr<NTPSnippet>& snippet : snippets) {
409 if (snippet->is_dismissed()) 382 if (snippet->is_dismissed())
410 dismissed_snippets_.emplace_back(std::move(snippet)); 383 dismissed_snippets_.emplace_back(std::move(snippet));
411 else 384 else
412 snippets_.emplace_back(std::move(snippet)); 385 snippets_.emplace_back(std::move(snippet));
413 } 386 }
414 std::sort(snippets_.begin(), snippets_.end(), 387 std::sort(snippets_.begin(), snippets_.end(),
415 [](const std::unique_ptr<NTPSnippet>& lhs, 388 [](const std::unique_ptr<NTPSnippet>& lhs,
416 const std::unique_ptr<NTPSnippet>& rhs) { 389 const std::unique_ptr<NTPSnippet>& rhs) {
417 return lhs->score() > rhs->score(); 390 return lhs->score() > rhs->score();
418 }); 391 });
419 392
420 ClearExpiredSnippets(); 393 ClearExpiredSnippets();
421 FinishInitialization(); 394 FinishInitialization();
422 } 395 }
423 396
424 void NTPSnippetsService::OnDatabaseError() { 397 void NTPSnippetsService::OnDatabaseError() {
425 EnterState(State::SHUT_DOWN, CategoryStatus::LOADING_ERROR); 398 EnterState(State::ERROR_OCCURRED, CategoryStatus::LOADING_ERROR);
426 } 399 }
427 400
428 // TODO(dgn): name clash between content suggestions and suggestions hosts. 401 // TODO(dgn): name clash between content suggestions and suggestions hosts.
429 // method name should be changed. 402 // method name should be changed.
430 void NTPSnippetsService::OnSuggestionsChanged( 403 void NTPSnippetsService::OnSuggestionsChanged(
431 const SuggestionsProfile& suggestions) { 404 const SuggestionsProfile& suggestions) {
432 DCHECK(initialized()); 405 DCHECK(initialized());
433 406
434 std::set<std::string> hosts = GetSuggestionsHostsImpl(suggestions); 407 std::set<std::string> hosts = GetSuggestionsHostsImpl(suggestions);
435 if (hosts == GetSnippetHostsFromPrefs()) 408 if (hosts == GetSnippetHostsFromPrefs())
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
692 665
693 void NTPSnippetsService::EnterStateDisabled() { 666 void NTPSnippetsService::EnterStateDisabled() {
694 ClearCachedSuggestionsForDebugging(); 667 ClearCachedSuggestionsForDebugging();
695 ClearDismissedSuggestionsForDebugging(); 668 ClearDismissedSuggestionsForDebugging();
696 669
697 expiry_timer_.Stop(); 670 expiry_timer_.Stop();
698 suggestions_service_subscription_.reset(); 671 suggestions_service_subscription_.reset();
699 RescheduleFetching(); 672 RescheduleFetching();
700 } 673 }
701 674
702 void NTPSnippetsService::EnterStateShutdown() { 675 void NTPSnippetsService::EnterStateError() {
703 FOR_EACH_OBSERVER(NTPSnippetsServiceObserver, observers_,
704 NTPSnippetsServiceShutdown());
705
706 expiry_timer_.Stop(); 676 expiry_timer_.Stop();
707 suggestions_service_subscription_.reset(); 677 suggestions_service_subscription_.reset();
708 RescheduleFetching(); 678 RescheduleFetching();
709
710 snippets_status_service_.reset(); 679 snippets_status_service_.reset();
711 } 680 }
712 681
713 void NTPSnippetsService::FinishInitialization() { 682 void NTPSnippetsService::FinishInitialization() {
714 snippets_fetcher_->SetCallback( 683 snippets_fetcher_->SetCallback(
715 base::Bind(&NTPSnippetsService::OnFetchFinished, base::Unretained(this))); 684 base::Bind(&NTPSnippetsService::OnFetchFinished, base::Unretained(this)));
716 685
717 // |image_fetcher_| can be null in tests. 686 // |image_fetcher_| can be null in tests.
718 if (image_fetcher_) { 687 if (image_fetcher_) {
719 image_fetcher_->SetImageFetcherDelegate(this); 688 image_fetcher_->SetImageFetcherDelegate(this);
720 image_fetcher_->SetDataUseServiceName( 689 image_fetcher_->SetDataUseServiceName(
721 data_use_measurement::DataUseUserData::NTP_SNIPPETS); 690 data_use_measurement::DataUseUserData::NTP_SNIPPETS);
722 } 691 }
723 692
724 // Note: Initializing the status service will run the callback right away with 693 // Note: Initializing the status service will run the callback right away with
725 // the current state. 694 // the current state.
726 snippets_status_service_->Init(base::Bind( 695 snippets_status_service_->Init(base::Bind(
727 &NTPSnippetsService::OnDisabledReasonChanged, base::Unretained(this))); 696 &NTPSnippetsService::OnDisabledReasonChanged, base::Unretained(this)));
728 697
729 // Always notify here even if we got nothing from the database, because we 698 // Always notify here even if we got nothing from the database, because we
730 // don't know how long the fetch will take or if it will even complete. 699 // don't know how long the fetch will take or if it will even complete.
731 NotifyNewSuggestions(); 700 NotifyNewSuggestions();
732 } 701 }
733 702
734 void NTPSnippetsService::OnDisabledReasonChanged( 703 void NTPSnippetsService::OnDisabledReasonChanged(
735 DisabledReason disabled_reason) { 704 DisabledReason disabled_reason) {
736 FOR_EACH_OBSERVER(NTPSnippetsServiceObserver, observers_,
737 NTPSnippetsServiceDisabledReasonChanged(disabled_reason));
738
739 switch (disabled_reason) { 705 switch (disabled_reason) {
740 case DisabledReason::NONE: 706 case DisabledReason::NONE:
741 // Do not change the status. That will be done in EnterStateEnabled() 707 // Do not change the status. That will be done in EnterStateEnabled()
742 EnterState(State::READY, category_status_); 708 EnterState(State::READY, category_status_);
743 break; 709 break;
744 710
745 case DisabledReason::EXPLICITLY_DISABLED: 711 case DisabledReason::EXPLICITLY_DISABLED:
746 EnterState(State::DISABLED, CategoryStatus::CATEGORY_EXPLICITLY_DISABLED); 712 EnterState(State::DISABLED, CategoryStatus::CATEGORY_EXPLICITLY_DISABLED);
747 break; 713 break;
748 714
(...skipping 27 matching lines...) Expand all
776 } 742 }
777 743
778 case State::DISABLED: 744 case State::DISABLED:
779 DCHECK(state_ == State::NOT_INITED || state_ == State::READY); 745 DCHECK(state_ == State::NOT_INITED || state_ == State::READY);
780 746
781 DVLOG(1) << "Entering state: DISABLED"; 747 DVLOG(1) << "Entering state: DISABLED";
782 state_ = State::DISABLED; 748 state_ = State::DISABLED;
783 EnterStateDisabled(); 749 EnterStateDisabled();
784 return; 750 return;
785 751
786 case State::SHUT_DOWN: 752 case State::ERROR_OCCURRED:
787 DVLOG(1) << "Entering state: SHUT_DOWN"; 753 DVLOG(1) << "Entering state: ERROR_OCCURRED";
788 state_ = State::SHUT_DOWN; 754 state_ = State::ERROR_OCCURRED;
789 EnterStateShutdown(); 755 EnterStateError();
790 return; 756 return;
791 } 757 }
792 } 758 }
793 759
794 void NTPSnippetsService::NotifyNewSuggestions() { 760 void NTPSnippetsService::NotifyNewSuggestions() {
795 // TODO(pke): Remove this as soon as this becomes a pure provider.
796 FOR_EACH_OBSERVER(NTPSnippetsServiceObserver, observers_,
797 NTPSnippetsServiceLoaded());
798
799 if (!observer_)
800 return;
801
802 std::vector<ContentSuggestion> result; 761 std::vector<ContentSuggestion> result;
803 for (const std::unique_ptr<NTPSnippet>& snippet : snippets_) { 762 for (const std::unique_ptr<NTPSnippet>& snippet : snippets_) {
804 if (!snippet->is_complete()) 763 if (!snippet->is_complete())
805 continue; 764 continue;
806 ContentSuggestion suggestion( 765 ContentSuggestion suggestion(
807 MakeUniqueID(provided_category_, snippet->id()), 766 MakeUniqueID(provided_category_, snippet->id()),
808 snippet->best_source().url); 767 snippet->best_source().url);
809 suggestion.set_amp_url(snippet->best_source().amp_url); 768 suggestion.set_amp_url(snippet->best_source().amp_url);
810 suggestion.set_title(base::UTF8ToUTF16(snippet->title())); 769 suggestion.set_title(base::UTF8ToUTF16(snippet->title()));
811 suggestion.set_snippet_text(base::UTF8ToUTF16(snippet->snippet())); 770 suggestion.set_snippet_text(base::UTF8ToUTF16(snippet->snippet()));
812 suggestion.set_publish_date(snippet->publish_date()); 771 suggestion.set_publish_date(snippet->publish_date());
813 suggestion.set_publisher_name( 772 suggestion.set_publisher_name(
814 base::UTF8ToUTF16(snippet->best_source().publisher_name)); 773 base::UTF8ToUTF16(snippet->best_source().publisher_name));
815 suggestion.set_score(snippet->score()); 774 suggestion.set_score(snippet->score());
816 result.emplace_back(std::move(suggestion)); 775 result.emplace_back(std::move(suggestion));
817 } 776 }
818 observer_->OnNewSuggestions(this, provided_category_, std::move(result)); 777 observer()->OnNewSuggestions(this, provided_category_, std::move(result));
819 } 778 }
820 779
821 void NTPSnippetsService::UpdateCategoryStatus(CategoryStatus status) { 780 void NTPSnippetsService::UpdateCategoryStatus(CategoryStatus status) {
822 if (status == category_status_) 781 if (status == category_status_)
823 return; 782 return;
824 783
825 category_status_ = status; 784 category_status_ = status;
826 if (observer_) { 785 observer()->OnCategoryStatusChanged(this, provided_category_,
827 observer_->OnCategoryStatusChanged(this, provided_category_, 786 category_status_);
828 category_status_);
829 }
830 } 787 }
831 788
832 } // namespace ntp_snippets 789 } // namespace ntp_snippets
OLDNEW
« no previous file with comments | « components/ntp_snippets/ntp_snippets_service.h ('k') | components/ntp_snippets/ntp_snippets_service_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698