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 |
11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
12 #include "base/files/file_path.h" | 12 #include "base/files/file_path.h" |
13 #include "base/files/file_util.h" | 13 #include "base/files/file_util.h" |
14 #include "base/location.h" | 14 #include "base/location.h" |
15 #include "base/metrics/histogram_macros.h" | 15 #include "base/metrics/histogram_macros.h" |
16 #include "base/metrics/sparse_histogram.h" | 16 #include "base/metrics/sparse_histogram.h" |
17 #include "base/path_service.h" | 17 #include "base/path_service.h" |
18 #include "base/strings/string_number_conversions.h" | 18 #include "base/strings/string_number_conversions.h" |
19 #include "base/task_runner_util.h" | 19 #include "base/task_runner_util.h" |
20 #include "base/time/time.h" | 20 #include "base/time/time.h" |
21 #include "base/values.h" | 21 #include "base/values.h" |
22 #include "components/image_fetcher/image_fetcher.h" | 22 #include "components/image_fetcher/image_fetcher.h" |
23 #include "components/ntp_snippets/ntp_snippets_constants.h" | 23 #include "components/ntp_snippets/ntp_snippets_constants.h" |
24 #include "components/ntp_snippets/ntp_snippets_database.h" | 24 #include "components/ntp_snippets/ntp_snippets_database.h" |
25 #include "components/ntp_snippets/pref_names.h" | 25 #include "components/ntp_snippets/pref_names.h" |
26 #include "components/ntp_snippets/switches.h" | 26 #include "components/ntp_snippets/switches.h" |
27 #include "components/prefs/pref_registry_simple.h" | 27 #include "components/prefs/pref_registry_simple.h" |
28 #include "components/prefs/pref_service.h" | 28 #include "components/prefs/pref_service.h" |
| 29 #include "components/signin/core/browser/signin_manager.h" |
29 #include "components/suggestions/proto/suggestions.pb.h" | 30 #include "components/suggestions/proto/suggestions.pb.h" |
30 #include "components/sync_driver/sync_service.h" | 31 #include "components/sync_driver/sync_service.h" |
31 #include "components/variations/variations_associated_data.h" | 32 #include "components/variations/variations_associated_data.h" |
32 #include "ui/gfx/image/image.h" | 33 #include "ui/gfx/image/image.h" |
33 | 34 |
34 using image_fetcher::ImageFetcher; | 35 using image_fetcher::ImageFetcher; |
35 using suggestions::ChromeSuggestion; | 36 using suggestions::ChromeSuggestion; |
36 using suggestions::SuggestionsProfile; | 37 using suggestions::SuggestionsProfile; |
37 using suggestions::SuggestionsService; | 38 using suggestions::SuggestionsService; |
38 | 39 |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 snippets->begin(), snippets->end(), | 174 snippets->begin(), snippets->end(), |
174 [](const std::unique_ptr<NTPSnippet>& snippet) { return !snippet; }), | 175 [](const std::unique_ptr<NTPSnippet>& snippet) { return !snippet; }), |
175 snippets->end()); | 176 snippets->end()); |
176 } | 177 } |
177 | 178 |
178 } // namespace | 179 } // namespace |
179 | 180 |
180 NTPSnippetsService::NTPSnippetsService( | 181 NTPSnippetsService::NTPSnippetsService( |
181 bool enabled, | 182 bool enabled, |
182 PrefService* pref_service, | 183 PrefService* pref_service, |
| 184 SigninManagerBase* signin_manager, |
183 sync_driver::SyncService* sync_service, | 185 sync_driver::SyncService* sync_service, |
184 SuggestionsService* suggestions_service, | 186 SuggestionsService* suggestions_service, |
185 const std::string& application_language_code, | 187 const std::string& application_language_code, |
186 NTPSnippetsScheduler* scheduler, | 188 NTPSnippetsScheduler* scheduler, |
187 std::unique_ptr<NTPSnippetsFetcher> snippets_fetcher, | 189 std::unique_ptr<NTPSnippetsFetcher> snippets_fetcher, |
188 std::unique_ptr<ImageFetcher> image_fetcher, | 190 std::unique_ptr<ImageFetcher> image_fetcher, |
189 std::unique_ptr<NTPSnippetsDatabase> database) | 191 std::unique_ptr<NTPSnippetsDatabase> database) |
190 : state_(State::NOT_INITED), | 192 : state_(State::NOT_INITED), |
191 explicitly_disabled_(!enabled), | 193 disabled_reason_(enabled ? DisabledReason::NONE |
| 194 : DisabledReason::EXPLICITLY_DISABLED), |
192 pref_service_(pref_service), | 195 pref_service_(pref_service), |
| 196 signin_manager_(signin_manager), |
193 sync_service_(sync_service), | 197 sync_service_(sync_service), |
194 sync_service_observer_(this), | 198 sync_service_observer_(this), |
195 suggestions_service_(suggestions_service), | 199 suggestions_service_(suggestions_service), |
196 application_language_code_(application_language_code), | 200 application_language_code_(application_language_code), |
197 scheduler_(scheduler), | 201 scheduler_(scheduler), |
198 snippets_fetcher_(std::move(snippets_fetcher)), | 202 snippets_fetcher_(std::move(snippets_fetcher)), |
199 image_fetcher_(std::move(image_fetcher)), | 203 image_fetcher_(std::move(image_fetcher)), |
200 database_(std::move(database)), | 204 database_(std::move(database)), |
201 fetch_after_load_(false) { | 205 fetch_after_load_(false) { |
202 // TODO(dgn) should be removed after branch point (https:://crbug.com/617585). | 206 // TODO(dgn) should be removed after branch point (https:://crbug.com/617585). |
203 ClearDeprecatedPrefs(); | 207 ClearDeprecatedPrefs(); |
204 | 208 |
205 if (explicitly_disabled_) { | 209 if (disabled_reason_ == DisabledReason::EXPLICITLY_DISABLED) { |
| 210 // Don't even bother loading the database. |
206 EnterState(State::DISABLED); | 211 EnterState(State::DISABLED); |
207 return; | 212 return; |
208 } | 213 } |
209 | 214 |
210 // We transition to other states while finalizing the initialization, when the | 215 // We transition to other states while finalizing the initialization, when the |
211 // database is done loading. | 216 // database is done loading. |
212 database_->Load(base::Bind(&NTPSnippetsService::OnDatabaseLoaded, | 217 database_->Load(base::Bind(&NTPSnippetsService::OnDatabaseLoaded, |
213 base::Unretained(this))); | 218 base::Unretained(this))); |
214 } | 219 } |
215 | 220 |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 } | 341 } |
337 | 342 |
338 void NTPSnippetsService::AddObserver(NTPSnippetsServiceObserver* observer) { | 343 void NTPSnippetsService::AddObserver(NTPSnippetsServiceObserver* observer) { |
339 observers_.AddObserver(observer); | 344 observers_.AddObserver(observer); |
340 } | 345 } |
341 | 346 |
342 void NTPSnippetsService::RemoveObserver(NTPSnippetsServiceObserver* observer) { | 347 void NTPSnippetsService::RemoveObserver(NTPSnippetsServiceObserver* observer) { |
343 observers_.RemoveObserver(observer); | 348 observers_.RemoveObserver(observer); |
344 } | 349 } |
345 | 350 |
346 DisabledReason NTPSnippetsService::GetDisabledReason() const { | |
347 if (explicitly_disabled_) | |
348 return DisabledReason::EXPLICITLY_DISABLED; | |
349 | |
350 if (!sync_service_ || !sync_service_->CanSyncStart()) { | |
351 DVLOG(1) << "[GetDisabledReason] Sync disabled"; | |
352 return DisabledReason::HISTORY_SYNC_DISABLED; | |
353 } | |
354 | |
355 // !IsSyncActive in cases where CanSyncStart is true hints at the backend not | |
356 // being initialized. | |
357 // ConfigurationDone() verifies that the sync service has properly loaded its | |
358 // configuration and is aware of the different data types to sync. | |
359 if (!sync_service_->IsSyncActive() || !sync_service_->ConfigurationDone()) { | |
360 DVLOG(1) << "[GetDisabledReason] Sync initialization is not complete."; | |
361 return DisabledReason::HISTORY_SYNC_STATE_UNKNOWN; | |
362 } | |
363 | |
364 if (!sync_service_->GetActiveDataTypes().Has( | |
365 syncer::HISTORY_DELETE_DIRECTIVES)) { | |
366 DVLOG(1) << "[GetDisabledReason] History sync disabled"; | |
367 return DisabledReason::HISTORY_SYNC_DISABLED; | |
368 } | |
369 | |
370 DVLOG(1) << "[GetDisabledReason] Enabled"; | |
371 return DisabledReason::NONE; | |
372 } | |
373 | |
374 // static | 351 // static |
375 int NTPSnippetsService::GetMaxSnippetCountForTesting() { | 352 int NTPSnippetsService::GetMaxSnippetCountForTesting() { |
376 return kMaxSnippetCount; | 353 return kMaxSnippetCount; |
377 } | 354 } |
378 | 355 |
379 //////////////////////////////////////////////////////////////////////////////// | 356 //////////////////////////////////////////////////////////////////////////////// |
380 // Private methods | 357 // Private methods |
381 | 358 |
382 void NTPSnippetsService::OnStateChanged() { | 359 void NTPSnippetsService::OnStateChanged() { |
383 if (state_ == State::SHUT_DOWN) | 360 if (state_ == State::SHUT_DOWN) |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
617 } | 594 } |
618 | 595 |
619 void NTPSnippetsService::EnterStateDisabled() { | 596 void NTPSnippetsService::EnterStateDisabled() { |
620 ClearSnippets(); | 597 ClearSnippets(); |
621 ClearDiscardedSnippets(); | 598 ClearDiscardedSnippets(); |
622 | 599 |
623 suggestions_service_subscription_.reset(); | 600 suggestions_service_subscription_.reset(); |
624 expiry_timer_.Stop(); | 601 expiry_timer_.Stop(); |
625 | 602 |
626 RescheduleFetching(); | 603 RescheduleFetching(); |
627 FOR_EACH_OBSERVER(NTPSnippetsServiceObserver, observers_, | |
628 NTPSnippetsServiceDisabled()); | |
629 } | 604 } |
630 | 605 |
631 void NTPSnippetsService::EnterStateShutdown() { | 606 void NTPSnippetsService::EnterStateShutdown() { |
632 FOR_EACH_OBSERVER(NTPSnippetsServiceObserver, observers_, | 607 FOR_EACH_OBSERVER(NTPSnippetsServiceObserver, observers_, |
633 NTPSnippetsServiceShutdown()); | 608 NTPSnippetsServiceShutdown()); |
634 | 609 |
635 expiry_timer_.Stop(); | 610 expiry_timer_.Stop(); |
636 suggestions_service_subscription_.reset(); | 611 suggestions_service_subscription_.reset(); |
637 | 612 |
638 if (sync_service_) | 613 // When explicity disabled we don't register the observer. |
| 614 if (sync_service_ && disabled_reason_ != DisabledReason::EXPLICITLY_DISABLED) |
639 sync_service_observer_.Remove(sync_service_); | 615 sync_service_observer_.Remove(sync_service_); |
640 } | 616 } |
641 | 617 |
642 void NTPSnippetsService::FinishInitialization() { | 618 void NTPSnippetsService::FinishInitialization() { |
643 snippets_fetcher_->SetCallback( | 619 snippets_fetcher_->SetCallback( |
644 base::Bind(&NTPSnippetsService::OnFetchFinished, base::Unretained(this))); | 620 base::Bind(&NTPSnippetsService::OnFetchFinished, base::Unretained(this))); |
645 | 621 |
646 // |sync_service_| can be null in tests or if sync is disabled. | 622 // |sync_service_| can be null in tests or if sync is disabled. |
647 // This is a service we want to keep listening to all the time, independently | 623 // This is a service we want to keep listening to all the time, independently |
648 // from the state, since it will allow us to enable or disable the snippets | 624 // from the state, since it will allow us to enable or disable the snippets |
649 // service. | 625 // service. |
650 if (sync_service_) | 626 if (sync_service_) |
651 sync_service_observer_.Add(sync_service_); | 627 sync_service_observer_.Add(sync_service_); |
652 | 628 |
653 // Change state after we started loading the snippets. During startup, the | 629 // Change state after we started loading the snippets. During startup, the |
654 // Sync service might not be completely loaded when we initialize this | 630 // Sync service might not be completely loaded when we initialize this |
655 // service, so we might stay in the NOT_INITED state until the sync state is | 631 // service, so we might stay in the NOT_INITED state until the sync state is |
656 // updated. See |GetStateForDependenciesStatus|. | 632 // updated. See |GetStateForDependenciesStatus|. |
657 EnterState(GetStateForDependenciesStatus()); | 633 EnterState(GetStateForDependenciesStatus()); |
658 | 634 |
659 FOR_EACH_OBSERVER(NTPSnippetsServiceObserver, observers_, | 635 FOR_EACH_OBSERVER(NTPSnippetsServiceObserver, observers_, |
660 NTPSnippetsServiceLoaded()); | 636 NTPSnippetsServiceLoaded()); |
| 637 } |
661 | 638 |
662 // Start a fetch if we don't have any snippets yet, or a fetch was requested | 639 void NTPSnippetsService::UpdateDisabledReason() { |
663 // earlier. | 640 DisabledReason new_disabled_reason = GetNewDisabledReason(); |
664 if (ready() && (snippets_.empty() || fetch_after_load_)) { | 641 |
665 fetch_after_load_ = false; | 642 if (new_disabled_reason == disabled_reason_) |
666 FetchSnippets(); | 643 return; |
| 644 |
| 645 disabled_reason_ = new_disabled_reason; |
| 646 FOR_EACH_OBSERVER(NTPSnippetsServiceObserver, observers_, |
| 647 NTPSnippetsServiceDisabledReasonChanged(disabled_reason_)); |
| 648 } |
| 649 |
| 650 DisabledReason NTPSnippetsService::GetNewDisabledReason() const { |
| 651 if (disabled_reason_ == DisabledReason::EXPLICITLY_DISABLED) { |
| 652 DVLOG(1) << "[GetNewDisabledReason] Explicitly disabled"; |
| 653 return DisabledReason::EXPLICITLY_DISABLED; |
667 } | 654 } |
| 655 |
| 656 if (!signin_manager_ || !signin_manager_->IsAuthenticated()) { |
| 657 DVLOG(1) << "[GetNewDisabledReason] Signed out"; |
| 658 return DisabledReason::SIGNED_OUT; |
| 659 } |
| 660 |
| 661 if (!sync_service_ || !sync_service_->CanSyncStart()) { |
| 662 DVLOG(1) << "[GetNewDisabledReason] Sync disabled"; |
| 663 return DisabledReason::SYNC_DISABLED; |
| 664 } |
| 665 |
| 666 // !IsSyncActive in cases where CanSyncStart is true hints at the backend not |
| 667 // being initialized. |
| 668 // ConfigurationDone() verifies that the sync service has properly loaded its |
| 669 // configuration and is aware of the different data types to sync. |
| 670 if (!sync_service_->IsSyncActive() || !sync_service_->ConfigurationDone()) { |
| 671 DVLOG(1) << "[GetNewDisabledReason] Sync initialization is not complete."; |
| 672 return DisabledReason::HISTORY_SYNC_STATE_UNKNOWN; |
| 673 } |
| 674 |
| 675 if (sync_service_->IsEncryptEverythingEnabled()) { |
| 676 DVLOG(1) << "[GetNewDisabledReason] Encryption is enabled"; |
| 677 return DisabledReason::PASSPHRASE_ENCRYPTION_ENABLED; |
| 678 } |
| 679 |
| 680 if (!sync_service_->GetActiveDataTypes().Has( |
| 681 syncer::HISTORY_DELETE_DIRECTIVES)) { |
| 682 DVLOG(1) << "[GetNewDisabledReason] History sync disabled"; |
| 683 return DisabledReason::HISTORY_SYNC_DISABLED; |
| 684 } |
| 685 |
| 686 DVLOG(1) << "[GetNewDisabledReason] Enabled"; |
| 687 return DisabledReason::NONE; |
668 } | 688 } |
669 | 689 |
670 NTPSnippetsService::State NTPSnippetsService::GetStateForDependenciesStatus() { | 690 NTPSnippetsService::State NTPSnippetsService::GetStateForDependenciesStatus() { |
671 switch (GetDisabledReason()) { | 691 UpdateDisabledReason(); |
| 692 switch (disabled_reason_) { |
672 case DisabledReason::NONE: | 693 case DisabledReason::NONE: |
673 return State::READY; | 694 return State::READY; |
674 | 695 |
675 case DisabledReason::HISTORY_SYNC_STATE_UNKNOWN: | 696 case DisabledReason::HISTORY_SYNC_STATE_UNKNOWN: |
676 // HistorySync is not initialized yet, so we don't know what the actual | 697 // HistorySync is not initialized yet, so we don't know what the actual |
677 // state is and we just return the current one. If things change, | 698 // state is and we just return the current one. If things change, |
678 // |OnStateChanged| will call this function again to update the state. | 699 // |OnStateChanged| will call this function again to update the state. |
679 DVLOG(1) << "Sync configuration incomplete, continuing based on the " | 700 DVLOG(1) << "Sync configuration incomplete, continuing based on the " |
680 "current state."; | 701 "current state."; |
681 return state_; | 702 return state_; |
682 | 703 |
683 case DisabledReason::EXPLICITLY_DISABLED: | 704 case DisabledReason::EXPLICITLY_DISABLED: |
| 705 case DisabledReason::SIGNED_OUT: |
| 706 case DisabledReason::SYNC_DISABLED: |
| 707 case DisabledReason::PASSPHRASE_ENCRYPTION_ENABLED: |
684 case DisabledReason::HISTORY_SYNC_DISABLED: | 708 case DisabledReason::HISTORY_SYNC_DISABLED: |
685 return State::DISABLED; | 709 return State::DISABLED; |
686 } | 710 } |
687 | 711 |
688 // All cases should be handled by the above switch | 712 // All cases should be handled by the above switch |
689 NOTREACHED(); | 713 NOTREACHED(); |
690 return State::DISABLED; | 714 return State::DISABLED; |
691 } | 715 } |
692 | 716 |
693 void NTPSnippetsService::EnterState(State state) { | 717 void NTPSnippetsService::EnterState(State state) { |
694 if (state == state_) | 718 if (state == state_) |
695 return; | 719 return; |
696 | 720 |
697 switch (state) { | 721 switch (state) { |
698 case State::NOT_INITED: | 722 case State::NOT_INITED: |
699 // Initial state, it should not be possible to get back there. | 723 // Initial state, it should not be possible to get back there. |
700 NOTREACHED(); | 724 NOTREACHED(); |
701 return; | 725 return; |
702 | 726 |
703 case State::READY: { | 727 case State::READY: { |
704 DCHECK(state_ == State::NOT_INITED || state_ == State::DISABLED); | 728 DCHECK(state_ == State::NOT_INITED || state_ == State::DISABLED); |
705 | 729 |
706 // If the service was previously disabled, we will need to start a fetch | 730 bool fetch_snippets = snippets_.empty() || fetch_after_load_; |
707 // because otherwise there won't be any. | |
708 bool fetch_snippets = state_ == State::DISABLED || fetch_after_load_; | |
709 DVLOG(1) << "Entering state: READY"; | 731 DVLOG(1) << "Entering state: READY"; |
710 state_ = State::READY; | 732 state_ = State::READY; |
711 fetch_after_load_ = false; | 733 fetch_after_load_ = false; |
712 EnterStateEnabled(fetch_snippets); | 734 EnterStateEnabled(fetch_snippets); |
713 return; | 735 return; |
714 } | 736 } |
715 | 737 |
716 case State::DISABLED: | 738 case State::DISABLED: |
717 DCHECK(state_ == State::NOT_INITED || state_ == State::READY); | 739 DCHECK(state_ == State::NOT_INITED || state_ == State::READY); |
718 | 740 |
719 DVLOG(1) << "Entering state: DISABLED"; | 741 DVLOG(1) << "Entering state: DISABLED"; |
720 state_ = State::DISABLED; | 742 state_ = State::DISABLED; |
721 EnterStateDisabled(); | 743 EnterStateDisabled(); |
722 return; | 744 return; |
723 | 745 |
724 case State::SHUT_DOWN: | 746 case State::SHUT_DOWN: |
725 DVLOG(1) << "Entering state: SHUT_DOWN"; | 747 DVLOG(1) << "Entering state: SHUT_DOWN"; |
726 state_ = State::SHUT_DOWN; | 748 state_ = State::SHUT_DOWN; |
727 EnterStateShutdown(); | 749 EnterStateShutdown(); |
728 return; | 750 return; |
729 } | 751 } |
730 } | 752 } |
731 | 753 |
732 void NTPSnippetsService::ClearDeprecatedPrefs() { | 754 void NTPSnippetsService::ClearDeprecatedPrefs() { |
733 pref_service_->ClearPref(prefs::kDeprecatedSnippets); | 755 pref_service_->ClearPref(prefs::kDeprecatedSnippets); |
734 pref_service_->ClearPref(prefs::kDeprecatedDiscardedSnippets); | 756 pref_service_->ClearPref(prefs::kDeprecatedDiscardedSnippets); |
735 } | 757 } |
736 | 758 |
737 } // namespace ntp_snippets | 759 } // namespace ntp_snippets |
OLD | NEW |