| 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/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 10 matching lines...) Expand all Loading... |
| 21 #include "base/values.h" | 21 #include "base/values.h" |
| 22 #include "components/image_fetcher/image_decoder.h" | 22 #include "components/image_fetcher/image_decoder.h" |
| 23 #include "components/image_fetcher/image_fetcher.h" | 23 #include "components/image_fetcher/image_fetcher.h" |
| 24 #include "components/ntp_snippets/ntp_snippets_constants.h" | 24 #include "components/ntp_snippets/ntp_snippets_constants.h" |
| 25 #include "components/ntp_snippets/ntp_snippets_database.h" | 25 #include "components/ntp_snippets/ntp_snippets_database.h" |
| 26 #include "components/ntp_snippets/pref_names.h" | 26 #include "components/ntp_snippets/pref_names.h" |
| 27 #include "components/ntp_snippets/switches.h" | 27 #include "components/ntp_snippets/switches.h" |
| 28 #include "components/prefs/pref_registry_simple.h" | 28 #include "components/prefs/pref_registry_simple.h" |
| 29 #include "components/prefs/pref_service.h" | 29 #include "components/prefs/pref_service.h" |
| 30 #include "components/suggestions/proto/suggestions.pb.h" | 30 #include "components/suggestions/proto/suggestions.pb.h" |
| 31 #include "components/sync_driver/sync_service.h" | |
| 32 #include "components/variations/variations_associated_data.h" | 31 #include "components/variations/variations_associated_data.h" |
| 33 #include "ui/gfx/image/image.h" | 32 #include "ui/gfx/image/image.h" |
| 34 | 33 |
| 35 using image_fetcher::ImageDecoder; | 34 using image_fetcher::ImageDecoder; |
| 36 using image_fetcher::ImageFetcher; | 35 using image_fetcher::ImageFetcher; |
| 37 using suggestions::ChromeSuggestion; | 36 using suggestions::ChromeSuggestion; |
| 38 using suggestions::SuggestionsProfile; | 37 using suggestions::SuggestionsProfile; |
| 39 using suggestions::SuggestionsService; | 38 using suggestions::SuggestionsService; |
| 40 | 39 |
| 41 namespace ntp_snippets { | 40 namespace ntp_snippets { |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 snippets->begin(), snippets->end(), | 174 snippets->begin(), snippets->end(), |
| 176 [](const std::unique_ptr<NTPSnippet>& snippet) { return !snippet; }), | 175 [](const std::unique_ptr<NTPSnippet>& snippet) { return !snippet; }), |
| 177 snippets->end()); | 176 snippets->end()); |
| 178 } | 177 } |
| 179 | 178 |
| 180 } // namespace | 179 } // namespace |
| 181 | 180 |
| 182 NTPSnippetsService::NTPSnippetsService( | 181 NTPSnippetsService::NTPSnippetsService( |
| 183 bool enabled, | 182 bool enabled, |
| 184 PrefService* pref_service, | 183 PrefService* pref_service, |
| 185 sync_driver::SyncService* sync_service, | |
| 186 SuggestionsService* suggestions_service, | 184 SuggestionsService* suggestions_service, |
| 187 const std::string& application_language_code, | 185 const std::string& application_language_code, |
| 188 NTPSnippetsScheduler* scheduler, | 186 NTPSnippetsScheduler* scheduler, |
| 189 std::unique_ptr<NTPSnippetsFetcher> snippets_fetcher, | 187 std::unique_ptr<NTPSnippetsFetcher> snippets_fetcher, |
| 190 std::unique_ptr<ImageFetcher> image_fetcher, | 188 std::unique_ptr<ImageFetcher> image_fetcher, |
| 191 std::unique_ptr<ImageDecoder> image_decoder, | 189 std::unique_ptr<ImageDecoder> image_decoder, |
| 192 std::unique_ptr<NTPSnippetsDatabase> database) | 190 std::unique_ptr<NTPSnippetsDatabase> database, |
| 191 std::unique_ptr<NTPSnippetsStatusService> status_service) |
| 193 : state_(State::NOT_INITED), | 192 : state_(State::NOT_INITED), |
| 194 explicitly_disabled_(!enabled), | |
| 195 pref_service_(pref_service), | 193 pref_service_(pref_service), |
| 196 sync_service_(sync_service), | |
| 197 sync_service_observer_(this), | |
| 198 suggestions_service_(suggestions_service), | 194 suggestions_service_(suggestions_service), |
| 199 application_language_code_(application_language_code), | 195 application_language_code_(application_language_code), |
| 200 scheduler_(scheduler), | 196 scheduler_(scheduler), |
| 201 snippets_fetcher_(std::move(snippets_fetcher)), | 197 snippets_fetcher_(std::move(snippets_fetcher)), |
| 202 image_fetcher_(std::move(image_fetcher)), | 198 image_fetcher_(std::move(image_fetcher)), |
| 203 image_decoder_(std::move(image_decoder)), | 199 image_decoder_(std::move(image_decoder)), |
| 204 database_(std::move(database)), | 200 database_(std::move(database)), |
| 201 snippets_status_service_(std::move(status_service)), |
| 205 fetch_after_load_(false) { | 202 fetch_after_load_(false) { |
| 206 // TODO(dgn) should be removed after branch point (https://crbug.com/617585). | 203 // TODO(dgn) should be removed after branch point (https://crbug.com/617585). |
| 207 ClearDeprecatedPrefs(); | 204 ClearDeprecatedPrefs(); |
| 208 | 205 |
| 209 if (explicitly_disabled_) { | 206 if (!enabled || database_->IsErrorState()) { |
| 210 EnterState(State::DISABLED); | 207 // Don't even bother loading the database. |
| 211 return; | |
| 212 } | |
| 213 | |
| 214 if (database_->IsErrorState()) { | |
| 215 EnterState(State::SHUT_DOWN); | 208 EnterState(State::SHUT_DOWN); |
| 216 return; | 209 return; |
| 217 } | 210 } |
| 218 | 211 |
| 219 database_->SetErrorCallback(base::Bind(&NTPSnippetsService::OnDatabaseError, | 212 database_->SetErrorCallback(base::Bind(&NTPSnippetsService::OnDatabaseError, |
| 220 base::Unretained(this))); | 213 base::Unretained(this))); |
| 221 | 214 |
| 222 // We transition to other states while finalizing the initialization, when the | 215 // We transition to other states while finalizing the initialization, when the |
| 223 // database is done loading. | 216 // database is done loading. |
| 224 database_->LoadSnippets(base::Bind(&NTPSnippetsService::OnDatabaseLoaded, | 217 database_->LoadSnippets(base::Bind(&NTPSnippetsService::OnDatabaseLoaded, |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 } | 334 } |
| 342 | 335 |
| 343 void NTPSnippetsService::AddObserver(NTPSnippetsServiceObserver* observer) { | 336 void NTPSnippetsService::AddObserver(NTPSnippetsServiceObserver* observer) { |
| 344 observers_.AddObserver(observer); | 337 observers_.AddObserver(observer); |
| 345 } | 338 } |
| 346 | 339 |
| 347 void NTPSnippetsService::RemoveObserver(NTPSnippetsServiceObserver* observer) { | 340 void NTPSnippetsService::RemoveObserver(NTPSnippetsServiceObserver* observer) { |
| 348 observers_.RemoveObserver(observer); | 341 observers_.RemoveObserver(observer); |
| 349 } | 342 } |
| 350 | 343 |
| 351 DisabledReason NTPSnippetsService::GetDisabledReason() const { | |
| 352 if (explicitly_disabled_) | |
| 353 return DisabledReason::EXPLICITLY_DISABLED; | |
| 354 | |
| 355 if (!sync_service_ || !sync_service_->CanSyncStart()) { | |
| 356 DVLOG(1) << "[GetDisabledReason] Sync disabled"; | |
| 357 return DisabledReason::HISTORY_SYNC_DISABLED; | |
| 358 } | |
| 359 | |
| 360 // !IsSyncActive in cases where CanSyncStart is true hints at the backend not | |
| 361 // being initialized. | |
| 362 // ConfigurationDone() verifies that the sync service has properly loaded its | |
| 363 // configuration and is aware of the different data types to sync. | |
| 364 if (!sync_service_->IsSyncActive() || !sync_service_->ConfigurationDone()) { | |
| 365 DVLOG(1) << "[GetDisabledReason] Sync initialization is not complete."; | |
| 366 return DisabledReason::HISTORY_SYNC_STATE_UNKNOWN; | |
| 367 } | |
| 368 | |
| 369 if (!sync_service_->GetActiveDataTypes().Has( | |
| 370 syncer::HISTORY_DELETE_DIRECTIVES)) { | |
| 371 DVLOG(1) << "[GetDisabledReason] History sync disabled"; | |
| 372 return DisabledReason::HISTORY_SYNC_DISABLED; | |
| 373 } | |
| 374 | |
| 375 DVLOG(1) << "[GetDisabledReason] Enabled"; | |
| 376 return DisabledReason::NONE; | |
| 377 } | |
| 378 | |
| 379 // static | 344 // static |
| 380 int NTPSnippetsService::GetMaxSnippetCountForTesting() { | 345 int NTPSnippetsService::GetMaxSnippetCountForTesting() { |
| 381 return kMaxSnippetCount; | 346 return kMaxSnippetCount; |
| 382 } | 347 } |
| 383 | 348 |
| 384 //////////////////////////////////////////////////////////////////////////////// | 349 //////////////////////////////////////////////////////////////////////////////// |
| 385 // Private methods | 350 // Private methods |
| 386 | 351 |
| 387 void NTPSnippetsService::OnStateChanged() { | |
| 388 if (state_ == State::SHUT_DOWN) | |
| 389 return; | |
| 390 | |
| 391 DVLOG(1) << "[OnStateChanged]"; | |
| 392 EnterState(GetStateForDependenciesStatus()); | |
| 393 } | |
| 394 | |
| 395 // image_fetcher::ImageFetcherDelegate implementation. | 352 // image_fetcher::ImageFetcherDelegate implementation. |
| 396 void NTPSnippetsService::OnImageDataFetched(const std::string& snippet_id, | 353 void NTPSnippetsService::OnImageDataFetched(const std::string& snippet_id, |
| 397 const std::string& image_data) { | 354 const std::string& image_data) { |
| 398 if (image_data.empty()) | 355 if (image_data.empty()) |
| 399 return; | 356 return; |
| 400 | 357 |
| 401 // Only save the image if the corresponding snippet still exists. | 358 // Only save the image if the corresponding snippet still exists. |
| 402 auto it = | 359 auto it = |
| 403 std::find_if(snippets_.begin(), snippets_.end(), | 360 std::find_if(snippets_.begin(), snippets_.end(), |
| 404 [&snippet_id](const std::unique_ptr<NTPSnippet>& snippet) { | 361 [&snippet_id](const std::unique_ptr<NTPSnippet>& snippet) { |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 687 &NTPSnippetsService::OnSuggestionsChanged, base::Unretained(this))); | 644 &NTPSnippetsService::OnSuggestionsChanged, base::Unretained(this))); |
| 688 } | 645 } |
| 689 | 646 |
| 690 RescheduleFetching(); | 647 RescheduleFetching(); |
| 691 } | 648 } |
| 692 | 649 |
| 693 void NTPSnippetsService::EnterStateDisabled() { | 650 void NTPSnippetsService::EnterStateDisabled() { |
| 694 ClearSnippets(); | 651 ClearSnippets(); |
| 695 ClearDiscardedSnippets(); | 652 ClearDiscardedSnippets(); |
| 696 | 653 |
| 654 expiry_timer_.Stop(); |
| 697 suggestions_service_subscription_.reset(); | 655 suggestions_service_subscription_.reset(); |
| 698 expiry_timer_.Stop(); | |
| 699 | |
| 700 RescheduleFetching(); | 656 RescheduleFetching(); |
| 701 FOR_EACH_OBSERVER(NTPSnippetsServiceObserver, observers_, | |
| 702 NTPSnippetsServiceDisabled()); | |
| 703 } | 657 } |
| 704 | 658 |
| 705 void NTPSnippetsService::EnterStateShutdown() { | 659 void NTPSnippetsService::EnterStateShutdown() { |
| 706 FOR_EACH_OBSERVER(NTPSnippetsServiceObserver, observers_, | 660 FOR_EACH_OBSERVER(NTPSnippetsServiceObserver, observers_, |
| 707 NTPSnippetsServiceShutdown()); | 661 NTPSnippetsServiceShutdown()); |
| 708 | 662 |
| 709 expiry_timer_.Stop(); | 663 expiry_timer_.Stop(); |
| 710 suggestions_service_subscription_.reset(); | 664 suggestions_service_subscription_.reset(); |
| 665 RescheduleFetching(); |
| 711 | 666 |
| 712 if (sync_service_) | 667 snippets_status_service_.reset(); |
| 713 sync_service_observer_.Remove(sync_service_); | |
| 714 } | 668 } |
| 715 | 669 |
| 716 void NTPSnippetsService::FinishInitialization() { | 670 void NTPSnippetsService::FinishInitialization() { |
| 717 snippets_fetcher_->SetCallback( | 671 snippets_fetcher_->SetCallback( |
| 718 base::Bind(&NTPSnippetsService::OnFetchFinished, base::Unretained(this))); | 672 base::Bind(&NTPSnippetsService::OnFetchFinished, base::Unretained(this))); |
| 719 | 673 |
| 720 // |image_fetcher_| can be null in tests. | 674 // |image_fetcher_| can be null in tests. |
| 721 if (image_fetcher_) | 675 if (image_fetcher_) |
| 722 image_fetcher_->SetImageFetcherDelegate(this); | 676 image_fetcher_->SetImageFetcherDelegate(this); |
| 723 | 677 |
| 724 // |sync_service_| can be null in tests or if sync is disabled. | 678 // Note: Initializing the status service will run the callback right away with |
| 725 // This is a service we want to keep listening to all the time, independently | 679 // the current state. |
| 726 // from the state, since it will allow us to enable or disable the snippets | 680 snippets_status_service_->Init(base::Bind( |
| 727 // service. | 681 &NTPSnippetsService::UpdateStateForStatus, base::Unretained(this))); |
| 728 if (sync_service_) | |
| 729 sync_service_observer_.Add(sync_service_); | |
| 730 | |
| 731 // Change state after we started loading the snippets. During startup, the | |
| 732 // Sync service might not be completely loaded when we initialize this | |
| 733 // service, so we might stay in the NOT_INITED state until the sync state is | |
| 734 // updated. See |GetStateForDependenciesStatus|. | |
| 735 EnterState(GetStateForDependenciesStatus()); | |
| 736 | 682 |
| 737 FOR_EACH_OBSERVER(NTPSnippetsServiceObserver, observers_, | 683 FOR_EACH_OBSERVER(NTPSnippetsServiceObserver, observers_, |
| 738 NTPSnippetsServiceLoaded()); | 684 NTPSnippetsServiceLoaded()); |
| 739 | |
| 740 // Start a fetch if we don't have any snippets yet, or a fetch was requested | |
| 741 // earlier. | |
| 742 if (ready() && (snippets_.empty() || fetch_after_load_)) { | |
| 743 fetch_after_load_ = false; | |
| 744 FetchSnippets(); | |
| 745 } | |
| 746 } | 685 } |
| 747 | 686 |
| 748 NTPSnippetsService::State NTPSnippetsService::GetStateForDependenciesStatus() { | 687 void NTPSnippetsService::UpdateStateForStatus(DisabledReason disabled_reason) { |
| 749 switch (GetDisabledReason()) { | 688 FOR_EACH_OBSERVER(NTPSnippetsServiceObserver, observers_, |
| 689 NTPSnippetsServiceDisabledReasonChanged(disabled_reason)); |
| 690 |
| 691 State new_state; |
| 692 switch (disabled_reason) { |
| 750 case DisabledReason::NONE: | 693 case DisabledReason::NONE: |
| 751 return State::READY; | 694 new_state = State::READY; |
| 695 break; |
| 752 | 696 |
| 753 case DisabledReason::HISTORY_SYNC_STATE_UNKNOWN: | 697 case DisabledReason::HISTORY_SYNC_STATE_UNKNOWN: |
| 754 // HistorySync is not initialized yet, so we don't know what the actual | 698 // HistorySync is not initialized yet, so we don't know what the actual |
| 755 // state is and we just return the current one. If things change, | 699 // state is and we just return the current one. If things change, |
| 756 // |OnStateChanged| will call this function again to update the state. | 700 // |OnStateChanged| will call this function again to update the state. |
| 757 DVLOG(1) << "Sync configuration incomplete, continuing based on the " | 701 DVLOG(1) << "Sync configuration incomplete, continuing based on the " |
| 758 "current state."; | 702 "current state."; |
| 759 return state_; | 703 new_state = state_; |
| 704 break; |
| 760 | 705 |
| 761 case DisabledReason::EXPLICITLY_DISABLED: | 706 case DisabledReason::EXPLICITLY_DISABLED: |
| 707 case DisabledReason::SIGNED_OUT: |
| 708 case DisabledReason::SYNC_DISABLED: |
| 709 case DisabledReason::PASSPHRASE_ENCRYPTION_ENABLED: |
| 762 case DisabledReason::HISTORY_SYNC_DISABLED: | 710 case DisabledReason::HISTORY_SYNC_DISABLED: |
| 763 return State::DISABLED; | 711 new_state = State::DISABLED; |
| 712 break; |
| 713 |
| 714 default: |
| 715 // All cases should be handled by the above switch |
| 716 NOTREACHED(); |
| 717 new_state = State::DISABLED; |
| 718 break; |
| 764 } | 719 } |
| 765 | 720 |
| 766 // All cases should be handled by the above switch | 721 EnterState(new_state); |
| 767 NOTREACHED(); | |
| 768 return State::DISABLED; | |
| 769 } | 722 } |
| 770 | 723 |
| 771 void NTPSnippetsService::EnterState(State state) { | 724 void NTPSnippetsService::EnterState(State state) { |
| 772 if (state == state_) | 725 if (state == state_) |
| 773 return; | 726 return; |
| 774 | 727 |
| 775 switch (state) { | 728 switch (state) { |
| 776 case State::NOT_INITED: | 729 case State::NOT_INITED: |
| 777 // Initial state, it should not be possible to get back there. | 730 // Initial state, it should not be possible to get back there. |
| 778 NOTREACHED(); | 731 NOTREACHED(); |
| 779 return; | 732 return; |
| 780 | 733 |
| 781 case State::READY: { | 734 case State::READY: { |
| 782 DCHECK(state_ == State::NOT_INITED || state_ == State::DISABLED); | 735 DCHECK(state_ == State::NOT_INITED || state_ == State::DISABLED); |
| 783 | 736 |
| 784 // If the service was previously disabled, we will need to start a fetch | 737 bool fetch_snippets = snippets_.empty() || fetch_after_load_; |
| 785 // because otherwise there won't be any. | |
| 786 bool fetch_snippets = state_ == State::DISABLED || fetch_after_load_; | |
| 787 DVLOG(1) << "Entering state: READY"; | 738 DVLOG(1) << "Entering state: READY"; |
| 788 state_ = State::READY; | 739 state_ = State::READY; |
| 789 fetch_after_load_ = false; | 740 fetch_after_load_ = false; |
| 790 EnterStateEnabled(fetch_snippets); | 741 EnterStateEnabled(fetch_snippets); |
| 791 return; | 742 return; |
| 792 } | 743 } |
| 793 | 744 |
| 794 case State::DISABLED: | 745 case State::DISABLED: |
| 795 DCHECK(state_ == State::NOT_INITED || state_ == State::READY); | 746 DCHECK(state_ == State::NOT_INITED || state_ == State::READY); |
| 796 | 747 |
| 797 DVLOG(1) << "Entering state: DISABLED"; | 748 DVLOG(1) << "Entering state: DISABLED"; |
| 798 state_ = State::DISABLED; | 749 state_ = State::DISABLED; |
| 799 EnterStateDisabled(); | 750 EnterStateDisabled(); |
| 800 return; | 751 return; |
| 801 | 752 |
| 802 case State::SHUT_DOWN: | 753 case State::SHUT_DOWN: |
| 803 DVLOG(1) << "Entering state: SHUT_DOWN"; | 754 DVLOG(1) << "Entering state: SHUT_DOWN"; |
| 804 state_ = State::SHUT_DOWN; | 755 state_ = State::SHUT_DOWN; |
| 805 EnterStateShutdown(); | 756 EnterStateShutdown(); |
| 806 return; | 757 return; |
| 807 } | 758 } |
| 808 } | 759 } |
| 809 | 760 |
| 810 void NTPSnippetsService::ClearDeprecatedPrefs() { | 761 void NTPSnippetsService::ClearDeprecatedPrefs() { |
| 811 pref_service_->ClearPref(prefs::kDeprecatedSnippets); | 762 pref_service_->ClearPref(prefs::kDeprecatedSnippets); |
| 812 pref_service_->ClearPref(prefs::kDeprecatedDiscardedSnippets); | 763 pref_service_->ClearPref(prefs::kDeprecatedDiscardedSnippets); |
| 813 } | 764 } |
| 814 | 765 |
| 815 } // namespace ntp_snippets | 766 } // namespace ntp_snippets |
| OLD | NEW |