| 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 |