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

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

Issue 2190353002: 📰Fix SnippetsService's status reporting (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: cleanup 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
« no previous file with comments | « components/ntp_snippets/ntp_snippets_service.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 FetchSnippetsFromHosts(GetSuggestionsHosts(), force_request); 252 FetchSnippetsFromHosts(GetSuggestionsHosts(), force_request);
253 else 253 else
254 fetch_after_load_ = true; 254 fetch_after_load_ = true;
255 } 255 }
256 256
257 void NTPSnippetsService::FetchSnippetsFromHosts( 257 void NTPSnippetsService::FetchSnippetsFromHosts(
258 const std::set<std::string>& hosts, 258 const std::set<std::string>& hosts,
259 bool force_request) { 259 bool force_request) {
260 if (!ready()) 260 if (!ready())
261 return; 261 return;
262
263 if (snippets_.empty())
264 UpdateCategoryStatus(ContentSuggestionsCategoryStatus::AVAILABLE_LOADING);
Marc Treib 2016/08/01 09:03:31 Hm, so this status effectively means "no suggestio
dgn 2016/08/01 10:54:40 Yes, that's how I understand it and the doc of the
265
262 snippets_fetcher_->FetchSnippetsFromHosts(hosts, application_language_code_, 266 snippets_fetcher_->FetchSnippetsFromHosts(hosts, application_language_code_,
263 kMaxSnippetCount, force_request); 267 kMaxSnippetCount, force_request);
264 } 268 }
265 269
266 void NTPSnippetsService::RescheduleFetching() { 270 void NTPSnippetsService::RescheduleFetching() {
267 // The scheduler only exists on Android so far, it's null on other platforms. 271 // The scheduler only exists on Android so far, it's null on other platforms.
268 if (!scheduler_) 272 if (!scheduler_)
269 return; 273 return;
270 274
271 if (ready()) { 275 if (ready()) {
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 }); 413 });
410 414
411 ClearExpiredSnippets(); 415 ClearExpiredSnippets();
412 FinishInitialization(); 416 FinishInitialization();
413 } 417 }
414 418
415 void NTPSnippetsService::OnDatabaseError() { 419 void NTPSnippetsService::OnDatabaseError() {
416 EnterState(State::SHUT_DOWN, ContentSuggestionsCategoryStatus::LOADING_ERROR); 420 EnterState(State::SHUT_DOWN, ContentSuggestionsCategoryStatus::LOADING_ERROR);
417 } 421 }
418 422
423 // TODO(dgn): name clash between content suggestions and suggestions hosts.
424 // method name should be changed.
419 void NTPSnippetsService::OnSuggestionsChanged( 425 void NTPSnippetsService::OnSuggestionsChanged(
420 const SuggestionsProfile& suggestions) { 426 const SuggestionsProfile& suggestions) {
421 DCHECK(initialized()); 427 DCHECK(initialized());
422 428
423 std::set<std::string> hosts = GetSuggestionsHostsImpl(suggestions); 429 std::set<std::string> hosts = GetSuggestionsHostsImpl(suggestions);
424 if (hosts == GetSnippetHostsFromPrefs()) 430 if (hosts == GetSnippetHostsFromPrefs())
425 return; 431 return;
426 432
427 // Remove existing snippets that aren't in the suggestions anymore. 433 // Remove existing snippets that aren't in the suggestions anymore.
428 // TODO(treib,maybelle): If there is another source with an allowed host, 434 // TODO(treib,maybelle): If there is another source with an allowed host,
429 // then we should fall back to that. 435 // then we should fall back to that.
430 // First, move them over into |to_delete|. 436 // First, move them over into |to_delete|.
431 NTPSnippet::PtrVector to_delete; 437 NTPSnippet::PtrVector to_delete;
432 for (std::unique_ptr<NTPSnippet>& snippet : snippets_) { 438 for (std::unique_ptr<NTPSnippet>& snippet : snippets_) {
433 if (!hosts.count(snippet->best_source().url.host())) 439 if (!hosts.count(snippet->best_source().url.host()))
434 to_delete.emplace_back(std::move(snippet)); 440 to_delete.emplace_back(std::move(snippet));
435 } 441 }
436 Compact(&snippets_); 442 Compact(&snippets_);
437 // Then delete the removed snippets from the database. 443 // Then delete the removed snippets from the database.
438 database_->DeleteSnippets(to_delete); 444 database_->DeleteSnippets(to_delete);
439 445
440 StoreSnippetHostsToPrefs(hosts); 446 StoreSnippetHostsToPrefs(hosts);
441 447
448 // We removed some suggestions, so we want to let the client know about that.
449 // The fetch might take a long time or not complete so we don't want to wait
450 // for its callback.
442 NotifyNewSuggestions(); 451 NotifyNewSuggestions();
443 452
444 FetchSnippetsFromHosts(hosts, /*force_request=*/false); 453 FetchSnippetsFromHosts(hosts, /*force_request=*/false);
445 } 454 }
446 455
447 void NTPSnippetsService::OnFetchFinished( 456 void NTPSnippetsService::OnFetchFinished(
448 NTPSnippetsFetcher::OptionalSnippets snippets) { 457 NTPSnippetsFetcher::OptionalSnippets snippets) {
449 if (!ready()) 458 if (!ready())
450 return; 459 return;
451 460
461 DCHECK(category_status_ == ContentSuggestionsCategoryStatus::AVAILABLE ||
Philipp Keck 2016/08/01 09:14:10 What if we shut down during a fetch? Or if the use
Marc Treib 2016/08/01 09:34:34 I thought about that too :) But there's a ready()
462 category_status_ ==
463 ContentSuggestionsCategoryStatus::AVAILABLE_LOADING);
464
452 if (snippets) { 465 if (snippets) {
453 // Sparse histogram used because the number of snippets is small (bound by 466 // Sparse histogram used because the number of snippets is small (bound by
454 // kMaxSnippetCount). 467 // kMaxSnippetCount).
455 DCHECK_LE(snippets->size(), static_cast<size_t>(kMaxSnippetCount)); 468 DCHECK_LE(snippets->size(), static_cast<size_t>(kMaxSnippetCount));
456 UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.Snippets.NumArticlesFetched", 469 UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.Snippets.NumArticlesFetched",
457 snippets->size()); 470 snippets->size());
458 MergeSnippets(std::move(*snippets)); 471 MergeSnippets(std::move(*snippets));
459 } 472 }
460 473
461 ClearExpiredSnippets(); 474 ClearExpiredSnippets();
462 475
463 // If there are more snippets than we want to show, delete the extra ones. 476 // If there are more snippets than we want to show, delete the extra ones.
464 if (snippets_.size() > kMaxSnippetCount) { 477 if (snippets_.size() > kMaxSnippetCount) {
465 NTPSnippet::PtrVector to_delete( 478 NTPSnippet::PtrVector to_delete(
466 std::make_move_iterator(snippets_.begin() + kMaxSnippetCount), 479 std::make_move_iterator(snippets_.begin() + kMaxSnippetCount),
467 std::make_move_iterator(snippets_.end())); 480 std::make_move_iterator(snippets_.end()));
468 snippets_.resize(kMaxSnippetCount); 481 snippets_.resize(kMaxSnippetCount);
469 database_->DeleteSnippets(to_delete); 482 database_->DeleteSnippets(to_delete);
470 } 483 }
471 484
472 UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.Snippets.NumArticles", 485 UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.Snippets.NumArticles",
473 snippets_.size()); 486 snippets_.size());
474 if (snippets_.empty() && !dismissed_snippets_.empty()) { 487 if (snippets_.empty() && !dismissed_snippets_.empty()) {
475 UMA_HISTOGRAM_COUNTS("NewTabPage.Snippets.NumArticlesZeroDueToDiscarded", 488 UMA_HISTOGRAM_COUNTS("NewTabPage.Snippets.NumArticlesZeroDueToDiscarded",
476 dismissed_snippets_.size()); 489 dismissed_snippets_.size());
477 } 490 }
478 491
492 UpdateCategoryStatus(ContentSuggestionsCategoryStatus::AVAILABLE);
479 NotifyNewSuggestions(); 493 NotifyNewSuggestions();
480 } 494 }
481 495
482 void NTPSnippetsService::MergeSnippets(NTPSnippet::PtrVector new_snippets) { 496 void NTPSnippetsService::MergeSnippets(NTPSnippet::PtrVector new_snippets) {
483 DCHECK(ready()); 497 DCHECK(ready());
484 498
485 // Remove new snippets that we already have, or that have been dismissed. 499 // Remove new snippets that we already have, or that have been dismissed.
486 std::set<std::string> old_snippet_ids; 500 std::set<std::string> old_snippet_ids;
487 InsertAllIDs(dismissed_snippets_, &old_snippet_ids); 501 InsertAllIDs(dismissed_snippets_, &old_snippet_ids);
488 InsertAllIDs(snippets_, &old_snippet_ids); 502 InsertAllIDs(snippets_, &old_snippet_ids);
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
651 665
652 const NTPSnippet& snippet = *it->get(); 666 const NTPSnippet& snippet = *it->get();
653 image_fetcher_->StartOrQueueNetworkRequest( 667 image_fetcher_->StartOrQueueNetworkRequest(
654 snippet.id(), snippet.salient_image_url(), callback); 668 snippet.id(), snippet.salient_image_url(), callback);
655 } 669 }
656 670
657 void NTPSnippetsService::EnterStateEnabled(bool fetch_snippets) { 671 void NTPSnippetsService::EnterStateEnabled(bool fetch_snippets) {
658 if (fetch_snippets) 672 if (fetch_snippets)
659 FetchSnippets(/*force_request=*/false); 673 FetchSnippets(/*force_request=*/false);
660 674
675 // FetchSnippets should set the status to |AVAILABLE_LOADING| if relevant,
676 // otherwise we transition to |AVAILABLE| here.
677 if (category_status_ != ContentSuggestionsCategoryStatus::AVAILABLE_LOADING)
678 UpdateCategoryStatus(ContentSuggestionsCategoryStatus::AVAILABLE);
679
661 // If host restrictions are enabled, register for host list updates. 680 // If host restrictions are enabled, register for host list updates.
662 // |suggestions_service_| can be null in tests. 681 // |suggestions_service_| can be null in tests.
663 if (snippets_fetcher_->UsesHostRestrictions() && suggestions_service_) { 682 if (snippets_fetcher_->UsesHostRestrictions() && suggestions_service_) {
664 suggestions_service_subscription_ = 683 suggestions_service_subscription_ =
665 suggestions_service_->AddCallback(base::Bind( 684 suggestions_service_->AddCallback(base::Bind(
666 &NTPSnippetsService::OnSuggestionsChanged, base::Unretained(this))); 685 &NTPSnippetsService::OnSuggestionsChanged, base::Unretained(this)));
667 } 686 }
668 687
669 RescheduleFetching(); 688 RescheduleFetching();
670 } 689 }
(...skipping 27 matching lines...) Expand all
698 image_fetcher_->SetImageFetcherDelegate(this); 717 image_fetcher_->SetImageFetcherDelegate(this);
699 image_fetcher_->SetDataUseServiceName( 718 image_fetcher_->SetDataUseServiceName(
700 data_use_measurement::DataUseUserData::NTP_SNIPPETS); 719 data_use_measurement::DataUseUserData::NTP_SNIPPETS);
701 } 720 }
702 721
703 // Note: Initializing the status service will run the callback right away with 722 // Note: Initializing the status service will run the callback right away with
704 // the current state. 723 // the current state.
705 snippets_status_service_->Init(base::Bind( 724 snippets_status_service_->Init(base::Bind(
706 &NTPSnippetsService::OnDisabledReasonChanged, base::Unretained(this))); 725 &NTPSnippetsService::OnDisabledReasonChanged, base::Unretained(this)));
707 726
727 // Always notify here even if we got nothing from the database, because we
728 // don't know how long the fetch will take or if it will even complete.
708 NotifyNewSuggestions(); 729 NotifyNewSuggestions();
709 } 730 }
710 731
711 void NTPSnippetsService::OnDisabledReasonChanged( 732 void NTPSnippetsService::OnDisabledReasonChanged(
712 DisabledReason disabled_reason) { 733 DisabledReason disabled_reason) {
713 FOR_EACH_OBSERVER(NTPSnippetsServiceObserver, observers_, 734 FOR_EACH_OBSERVER(NTPSnippetsServiceObserver, observers_,
714 NTPSnippetsServiceDisabledReasonChanged(disabled_reason)); 735 NTPSnippetsServiceDisabledReasonChanged(disabled_reason));
715 736
716 switch (disabled_reason) { 737 switch (disabled_reason) {
717 case DisabledReason::NONE: 738 case DisabledReason::NONE:
718 EnterState(State::READY, ContentSuggestionsCategoryStatus::AVAILABLE); 739 // Do not change the status. That will be done in EnterStateEnabled()
740 EnterState(State::READY, category_status_);
719 break; 741 break;
720 742
721 case DisabledReason::EXPLICITLY_DISABLED: 743 case DisabledReason::EXPLICITLY_DISABLED:
722 EnterState( 744 EnterState(
723 State::DISABLED, 745 State::DISABLED,
724 ContentSuggestionsCategoryStatus::CATEGORY_EXPLICITLY_DISABLED); 746 ContentSuggestionsCategoryStatus::CATEGORY_EXPLICITLY_DISABLED);
725 break; 747 break;
726 748
727 case DisabledReason::SIGNED_OUT: 749 case DisabledReason::SIGNED_OUT:
728 EnterState(State::DISABLED, ContentSuggestionsCategoryStatus::SIGNED_OUT); 750 EnterState(State::DISABLED, ContentSuggestionsCategoryStatus::SIGNED_OUT);
729 break; 751 break;
730 } 752 }
731 } 753 }
732 754
733 void NTPSnippetsService::EnterState(State state, 755 void NTPSnippetsService::EnterState(State state,
734 ContentSuggestionsCategoryStatus status) { 756 ContentSuggestionsCategoryStatus status) {
735 if (status != category_status_) { 757 UpdateCategoryStatus(status);
736 category_status_ = status;
737 NotifyCategoryStatusChanged();
738 }
739 758
740 if (state == state_) 759 if (state == state_)
741 return; 760 return;
742 761
743 switch (state) { 762 switch (state) {
744 case State::NOT_INITED: 763 case State::NOT_INITED:
745 // Initial state, it should not be possible to get back there. 764 // Initial state, it should not be possible to get back there.
746 NOTREACHED(); 765 NOTREACHED();
747 return; 766 return;
748 767
749 case State::READY: { 768 case State::READY: {
750 DCHECK(state_ == State::NOT_INITED || state_ == State::DISABLED); 769 DCHECK(state_ == State::NOT_INITED || state_ == State::DISABLED);
751 770
752 bool fetch_snippets = snippets_.empty() || fetch_after_load_; 771 bool fetch_snippets = snippets_.empty() || fetch_after_load_;
753 DVLOG(1) << "Entering state: READY"; 772 DVLOG(1) << "Entering state: READY";
754 state_ = State::READY; 773 state_ = State::READY;
755 fetch_after_load_ = false; 774 fetch_after_load_ = false;
756 EnterStateEnabled(fetch_snippets); 775 EnterStateEnabled(fetch_snippets);
757 return; 776 return;
758 } 777 }
759 778
760 case State::DISABLED: 779 case State::DISABLED:
761 DCHECK(state_ == State::NOT_INITED || state_ == State::READY); 780 DCHECK(state_ == State::NOT_INITED || state_ == State::READY);
762
763 DVLOG(1) << "Entering state: DISABLED"; 781 DVLOG(1) << "Entering state: DISABLED";
764 state_ = State::DISABLED; 782 state_ = State::DISABLED;
765 EnterStateDisabled(); 783 EnterStateDisabled();
766 return; 784 return;
767 785
768 case State::SHUT_DOWN: 786 case State::SHUT_DOWN:
769 DVLOG(1) << "Entering state: SHUT_DOWN"; 787 DVLOG(1) << "Entering state: SHUT_DOWN";
770 state_ = State::SHUT_DOWN; 788 state_ = State::SHUT_DOWN;
771 EnterStateShutdown(); 789 EnterStateShutdown();
772 return; 790 return;
(...skipping 20 matching lines...) Expand all
793 suggestion.set_snippet_text(snippet->snippet()); 811 suggestion.set_snippet_text(snippet->snippet());
794 suggestion.set_publish_date(snippet->publish_date()); 812 suggestion.set_publish_date(snippet->publish_date());
795 suggestion.set_publisher_name(snippet->best_source().publisher_name); 813 suggestion.set_publisher_name(snippet->best_source().publisher_name);
796 suggestion.set_score(snippet->score()); 814 suggestion.set_score(snippet->score());
797 result.emplace_back(std::move(suggestion)); 815 result.emplace_back(std::move(suggestion));
798 } 816 }
799 observer_->OnNewSuggestions(ContentSuggestionsCategory::ARTICLES, 817 observer_->OnNewSuggestions(ContentSuggestionsCategory::ARTICLES,
800 std::move(result)); 818 std::move(result));
801 } 819 }
802 820
803 void NTPSnippetsService::NotifyCategoryStatusChanged() { 821 void NTPSnippetsService::UpdateCategoryStatus(
822 ContentSuggestionsCategoryStatus status) {
823 if (status == category_status_)
824 return;
825
826 category_status_ = status;
804 if (observer_) { 827 if (observer_) {
805 observer_->OnCategoryStatusChanged(ContentSuggestionsCategory::ARTICLES, 828 observer_->OnCategoryStatusChanged(ContentSuggestionsCategory::ARTICLES,
806 category_status_); 829 category_status_);
807 } 830 }
808 } 831 }
809 832
810 } // namespace ntp_snippets 833 } // namespace ntp_snippets
OLDNEW
« no previous file with comments | « components/ntp_snippets/ntp_snippets_service.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698