diff options
Diffstat (limited to 'chromium/components/browser_sync/profile_sync_service.cc')
-rw-r--r-- | chromium/components/browser_sync/profile_sync_service.cc | 1088 |
1 files changed, 456 insertions, 632 deletions
diff --git a/chromium/components/browser_sync/profile_sync_service.cc b/chromium/components/browser_sync/profile_sync_service.cc index edb33dafe55..348bcf10291 100644 --- a/chromium/components/browser_sync/profile_sync_service.cc +++ b/chromium/components/browser_sync/profile_sync_service.cc @@ -16,14 +16,14 @@ #include "base/logging.h" #include "base/memory/ref_counted.h" #include "base/metrics/histogram_macros.h" -#include "base/threading/thread_restrictions.h" -#include "base/threading/thread_task_runner_handle.h" +#include "base/threading/sequenced_task_runner_handle.h" #include "components/browser_sync/browser_sync_switches.h" +#include "components/browser_sync/sync_auth_manager.h" #include "components/invalidation/impl/invalidation_prefs.h" #include "components/invalidation/public/invalidation_service.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/reading_list/features/reading_list_buildflags.h" -#include "components/signin/core/browser/profile_oauth2_token_service.h" +#include "components/signin/core/browser/account_info.h" #include "components/signin/core/browser/signin_manager.h" #include "components/signin/core/browser/signin_metrics.h" #include "components/sync/base/bind_to_task_runner.h" @@ -37,7 +37,6 @@ #include "components/sync/device_info/device_info_tracker.h" #include "components/sync/driver/backend_migrator.h" #include "components/sync/driver/directory_data_type_controller.h" -#include "components/sync/driver/glue/sync_backend_host_impl.h" #include "components/sync/driver/signin_manager_wrapper.h" #include "components/sync/driver/sync_api_component_factory.h" #include "components/sync/driver/sync_driver_switches.h" @@ -46,10 +45,11 @@ #include "components/sync/driver/sync_util.h" #include "components/sync/driver/user_selectable_sync_type.h" #include "components/sync/engine/configure_reason.h" -#include "components/sync/engine/cycle/model_neutral_state.h" #include "components/sync/engine/cycle/type_debug_info_observer.h" +#include "components/sync/engine/engine_components_factory_impl.h" #include "components/sync/engine/net/http_bridge_network_resources.h" #include "components/sync/engine/net/network_resources.h" +#include "components/sync/engine/polling_constants.h" #include "components/sync/engine/sync_encryption_handler.h" #include "components/sync/engine/sync_string_conversions.h" #include "components/sync/js/js_event_details.h" @@ -57,43 +57,38 @@ #include "components/sync/model/model_type_change_processor.h" #include "components/sync/model/sync_error.h" #include "components/sync/model_impl/client_tag_based_model_type_processor.h" -#include "components/sync/protocol/sync.pb.h" #include "components/sync/syncable/directory.h" -#include "components/sync/syncable/sync_db_util.h" #include "components/sync/syncable/syncable_read_transaction.h" #include "components/sync_preferences/pref_service_syncable.h" #include "components/sync_sessions/favicon_cache.h" #include "components/sync_sessions/session_data_type_controller.h" +#include "components/sync_sessions/session_sync_bridge.h" #include "components/sync_sessions/sessions_sync_manager.h" #include "components/sync_sessions/sync_sessions_client.h" #include "components/version_info/version_info_values.h" -#include "net/cookies/cookie_monster.h" #include "net/url_request/url_request_context_getter.h" -#if defined(OS_ANDROID) -#include "components/sync/syncable/read_transaction.h" -#endif - -using sync_sessions::SessionsSyncManager; using syncer::BackendMigrator; -using syncer::ChangeProcessor; using syncer::ClientTagBasedModelTypeProcessor; using syncer::DataTypeController; using syncer::DataTypeManager; using syncer::DataTypeStatusTable; using syncer::DeviceInfoSyncBridge; +using syncer::EngineComponentsFactory; +using syncer::EngineComponentsFactoryImpl; using syncer::JsBackend; using syncer::JsController; -using syncer::JsEventDetails; using syncer::JsEventHandler; using syncer::ModelSafeRoutingInfo; using syncer::ModelType; -using syncer::ModelTypeChangeProcessor; using syncer::ModelTypeSet; using syncer::ModelTypeStore; using syncer::ProtocolEventObserver; -using syncer::SyncEngine; +using syncer::SyncBackendRegistrar; +using syncer::SyncClient; using syncer::SyncCredentials; +using syncer::SyncEngine; +using syncer::SyncManagerFactory; using syncer::SyncProtocolError; using syncer::WeakHandle; @@ -101,35 +96,44 @@ namespace browser_sync { namespace { -const char kSyncUnrecoverableErrorHistogram[] = "Sync.UnrecoverableErrors"; - -const net::BackoffEntry::Policy kRequestAccessTokenBackoffPolicy = { - // Number of initial errors (in sequence) to ignore before applying - // exponential back-off rules. - 0, +constexpr char kSyncUnrecoverableErrorHistogram[] = "Sync.UnrecoverableErrors"; - // Initial delay for exponential back-off in ms. - 2000, +constexpr base::FilePath::CharType kSyncDataFolderName[] = + FILE_PATH_LITERAL("Sync Data"); - // Factor by which the waiting time will be multiplied. - 2, +constexpr base::FilePath::CharType kLevelDBFolderName[] = + FILE_PATH_LITERAL("LevelDB"); - // Fuzzing percentage. ex: 10% will spread requests randomly - // between 90%-100% of the calculated time. - 0.2, // 20% +base::FilePath FormatSyncDataPath(const base::FilePath& base_directory) { + return base_directory.Append(base::FilePath(kSyncDataFolderName)); +} - // Maximum amount of time we are willing to delay our request in ms. - // TODO(pavely): crbug.com/246686 ProfileSyncService should retry - // RequestAccessToken on connection state change after backoff - 1000 * 3600 * 4, // 4 hours. +base::FilePath FormatSharedModelTypeStorePath( + const base::FilePath& base_directory) { + return FormatSyncDataPath(base_directory) + .Append(base::FilePath(kLevelDBFolderName)); +} - // Time to keep an entry from being discarded even when it - // has no significant state, -1 to never discard. - -1, +EngineComponentsFactory::Switches EngineSwitchesFromCommandLine() { + EngineComponentsFactory::Switches factory_switches = { + EngineComponentsFactory::ENCRYPTION_KEYSTORE, + EngineComponentsFactory::BACKOFF_NORMAL}; - // Don't use initial delay unless the last request was an error. - false, -}; + base::CommandLine* cl = base::CommandLine::ForCurrentProcess(); + if (cl->HasSwitch(switches::kSyncShortInitialRetryOverride)) { + factory_switches.backoff_override = + EngineComponentsFactory::BACKOFF_SHORT_INITIAL_RETRY_OVERRIDE; + } + if (cl->HasSwitch(switches::kSyncEnableGetUpdateAvoidance)) { + factory_switches.pre_commit_updates_policy = + EngineComponentsFactory::FORCE_ENABLE_PRE_COMMIT_UPDATE_AVOIDANCE; + } + if (cl->HasSwitch(switches::kSyncShortNudgeDelayForTest)) { + factory_switches.nudge_delay = + EngineComponentsFactory::NudgeDelay::SHORT_NUDGE_DELAY; + } + return factory_switches; +} } // namespace @@ -138,41 +142,43 @@ ProfileSyncService::InitParams::InitParams(InitParams&& other) = default; ProfileSyncService::InitParams::~InitParams() = default; ProfileSyncService::ProfileSyncService(InitParams init_params) - : SyncServiceBase(std::move(init_params.sync_client), - std::move(init_params.signin_wrapper), - init_params.channel, - init_params.base_directory, - init_params.debug_identifier), - OAuth2TokenService::Consumer("sync"), - signin_scoped_device_id_callback_( - init_params.signin_scoped_device_id_callback), - last_auth_error_(GoogleServiceAuthError::AuthErrorNone()), + : sync_client_(std::move(init_params.sync_client)), + sync_prefs_(sync_client_->GetPrefService()), + signin_(std::move(init_params.signin_wrapper)), + auth_manager_(std::make_unique<SyncAuthManager>( + this, + &sync_prefs_, + signin_ ? signin_->GetIdentityManager() : nullptr, + init_params.oauth2_token_service)), + channel_(init_params.channel), + base_directory_(init_params.base_directory), + debug_identifier_(init_params.debug_identifier), sync_service_url_( syncer::GetSyncServiceURL(*base::CommandLine::ForCurrentProcess(), init_params.channel)), + signin_scoped_device_id_callback_( + init_params.signin_scoped_device_id_callback), network_time_update_callback_( std::move(init_params.network_time_update_callback)), url_request_context_(init_params.url_request_context), is_first_time_sync_configure_(false), engine_initialized_(false), sync_disabled_by_admin_(false), - is_auth_in_progress_(false), unrecoverable_error_reason_(ERROR_REASON_UNSET), expect_sync_configuration_aborted_(false), - configure_status_(DataTypeManager::UNKNOWN), - oauth2_token_service_(init_params.oauth2_token_service), - request_access_token_backoff_(&kRequestAccessTokenBackoffPolicy), - connection_status_(syncer::CONNECTION_NOT_ATTEMPTED), - last_get_token_error_(GoogleServiceAuthError::AuthErrorNone()), gaia_cookie_manager_service_(init_params.gaia_cookie_manager_service), - network_resources_(new syncer::HttpBridgeNetworkResources), + network_resources_( + std::make_unique<syncer::HttpBridgeNetworkResources>()), start_behavior_(init_params.start_behavior), passphrase_prompt_triggered_by_version_(false), sync_enabled_weak_factory_(this), weak_factory_(this) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(signin_scoped_device_id_callback_); DCHECK(sync_client_); + + ResetCryptoState(); + std::string last_version = sync_prefs_.GetLastRunVersion(); std::string current_version = PRODUCT_VERSION; sync_prefs_.SetLastRunVersion(current_version); @@ -192,7 +198,7 @@ ProfileSyncService::ProfileSyncService(InitParams init_params) } ProfileSyncService::~ProfileSyncService() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (gaia_cookie_manager_service_) gaia_cookie_manager_service_->RemoveObserver(this); sync_prefs_.RemoveSyncPrefObserver(this); @@ -201,31 +207,47 @@ ProfileSyncService::~ProfileSyncService() { } bool ProfileSyncService::CanSyncStart() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return (IsSyncAllowed() && IsSyncRequested() && (IsLocalSyncEnabled() || IsSignedIn())); } void ProfileSyncService::Initialize() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); sync_client_->Initialize(); // We don't pass StartupController an Unretained reference to future-proof // against the controller impl changing to post tasks. startup_controller_ = std::make_unique<syncer::StartupController>( &sync_prefs_, - base::Bind(&ProfileSyncService::CanEngineStart, base::Unretained(this)), - base::Bind(&ProfileSyncService::StartUpSlowEngineComponents, - weak_factory_.GetWeakPtr())); + base::BindRepeating(&ProfileSyncService::CanEngineStart, + base::Unretained(this)), + base::BindRepeating(&ProfileSyncService::StartUpSlowEngineComponents, + weak_factory_.GetWeakPtr())); local_device_ = sync_client_->GetSyncApiComponentFactory() ->CreateLocalDeviceInfoProvider(); sync_stopped_reporter_ = std::make_unique<syncer::SyncStoppedReporter>( sync_service_url_, local_device_->GetSyncUserAgent(), url_request_context_, syncer::SyncStoppedReporter::ResultCallback()); - sessions_sync_manager_ = std::make_unique<SessionsSyncManager>( - sync_client_->GetSyncSessionsClient(), &sync_prefs_, local_device_.get(), - base::Bind(&ProfileSyncService::NotifyForeignSessionUpdated, - sync_enabled_weak_factory_.GetWeakPtr())); + + if (base::FeatureList::IsEnabled(switches::kSyncUSSSessions)) { + sessions_sync_manager_ = std::make_unique<sync_sessions::SessionSyncBridge>( + sync_client_->GetSyncSessionsClient(), &sync_prefs_, + local_device_.get(), model_type_store_factory_, + base::BindRepeating(&ProfileSyncService::NotifyForeignSessionUpdated, + sync_enabled_weak_factory_.GetWeakPtr()), + std::make_unique<ClientTagBasedModelTypeProcessor>( + syncer::SESSIONS, + base::BindRepeating(&syncer::ReportUnrecoverableError, channel_))); + } else { + sessions_sync_manager_ = + std::make_unique<sync_sessions::SessionsSyncManager>( + sync_client_->GetSyncSessionsClient(), &sync_prefs_, + local_device_.get(), + base::BindRepeating( + &ProfileSyncService::NotifyForeignSessionUpdated, + sync_enabled_weak_factory_.GetWeakPtr())); + } device_info_sync_bridge_ = std::make_unique<DeviceInfoSyncBridge>( local_device_.get(), model_type_store_factory_, @@ -279,7 +301,7 @@ void ProfileSyncService::Initialize() { } if (!IsLocalSyncEnabled()) { - RegisterAuthNotifications(); + auth_manager_->RegisterForAuthNotifications(); if (!IsSignedIn()) { // Clean up in case of previous crash during signout. @@ -303,8 +325,8 @@ void ProfileSyncService::Initialize() { #endif memory_pressure_listener_ = std::make_unique<base::MemoryPressureListener>( - base::Bind(&ProfileSyncService::OnMemoryPressure, - sync_enabled_weak_factory_.GetWeakPtr())); + base::BindRepeating(&ProfileSyncService::OnMemoryPressure, + sync_enabled_weak_factory_.GetWeakPtr())); startup_controller_->Reset(GetRegisteredDataTypes()); // Auto-start means the first time the profile starts up, sync should start up @@ -334,24 +356,9 @@ void ProfileSyncService::StartSyncingWithServer() { engine_->StartSyncingWithServer(); } -void ProfileSyncService::RegisterAuthNotifications() { - DCHECK(thread_checker_.CalledOnValidThread()); - oauth2_token_service_->AddObserver(this); - if (signin_) - signin_->GetSigninManager()->AddObserver(this); -} - -void ProfileSyncService::UnregisterAuthNotifications() { - DCHECK(thread_checker_.CalledOnValidThread()); - if (signin_) - signin_->GetSigninManager()->RemoveObserver(this); - if (oauth2_token_service_) - oauth2_token_service_->RemoveObserver(this); -} - void ProfileSyncService::RegisterDataTypeController( - std::unique_ptr<syncer::DataTypeController> data_type_controller) { - DCHECK(thread_checker_.CalledOnValidThread()); + std::unique_ptr<DataTypeController> data_type_controller) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_EQ(data_type_controllers_.count(data_type_controller->type()), 0U); data_type_controllers_[data_type_controller->type()] = std::move(data_type_controller); @@ -359,7 +366,7 @@ void ProfileSyncService::RegisterDataTypeController( bool ProfileSyncService::IsDataTypeControllerRunning( syncer::ModelType type) const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DataTypeController::TypeMap::const_iterator iter = data_type_controllers_.find(type); if (iter == data_type_controllers_.end()) { @@ -369,7 +376,7 @@ bool ProfileSyncService::IsDataTypeControllerRunning( } sync_sessions::OpenTabsUIDelegate* ProfileSyncService::GetOpenTabsUIDelegate() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // Although the backing data actually is of type |SESSIONS|, the desire to use // open tabs functionality is tracked by the state of the |PROXY_TABS| type. if (!IsDataTypeControllerRunning(syncer::PROXY_TABS)) { @@ -381,32 +388,23 @@ sync_sessions::OpenTabsUIDelegate* ProfileSyncService::GetOpenTabsUIDelegate() { } sync_sessions::FaviconCache* ProfileSyncService::GetFaviconCache() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return sessions_sync_manager_->GetFaviconCache(); } syncer::DeviceInfoTracker* ProfileSyncService::GetDeviceInfoTracker() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return device_info_sync_bridge_.get(); } syncer::LocalDeviceInfoProvider* ProfileSyncService::GetLocalDeviceInfoProvider() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return local_device_.get(); } -void ProfileSyncService::GetDataTypeControllerStates( - DataTypeController::StateMap* state_map) const { - DCHECK(thread_checker_.CalledOnValidThread()); - for (DataTypeController::TypeMap::const_iterator iter = - data_type_controllers_.begin(); - iter != data_type_controllers_.end(); ++iter) - (*state_map)[iter->first] = iter->second.get()->state(); -} - void ProfileSyncService::OnSessionRestoreComplete() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DataTypeController::TypeMap::const_iterator iter = data_type_controllers_.find(syncer::SESSIONS); if (iter == data_type_controllers_.end()) { @@ -414,28 +412,12 @@ void ProfileSyncService::OnSessionRestoreComplete() { } DCHECK(iter->second); - static_cast<sync_sessions::SessionDataTypeController*>(iter->second.get()) - ->OnSessionRestoreComplete(); -} - -SyncCredentials ProfileSyncService::GetCredentials() { - SyncCredentials credentials; - - // No credentials exist or are needed for the local sync backend. - if (IsLocalSyncEnabled()) - return credentials; - - credentials.account_id = signin_->GetAccountIdToUse(); - DCHECK(!credentials.account_id.empty()); - credentials.email = signin_->GetEffectiveUsername(); - credentials.sync_token = access_token_; - - if (credentials.sync_token.empty()) - credentials.sync_token = "credentials_lost"; - - credentials.scope_set.insert(signin_->GetSyncScopeToUse()); - - return credentials; + if (base::FeatureList::IsEnabled(switches::kSyncUSSSessions)) { + sessions_sync_manager_->OnSessionRestoreComplete(); + } else { + static_cast<sync_sessions::SessionDataTypeController*>(iter->second.get()) + ->OnSessionRestoreComplete(); + } } syncer::WeakHandle<syncer::JsEventHandler> @@ -445,9 +427,10 @@ ProfileSyncService::GetJsEventHandler() { syncer::SyncEngine::HttpPostProviderFactoryGetter ProfileSyncService::MakeHttpPostProviderFactoryGetter() { - return base::Bind(&syncer::NetworkResources::GetHttpPostProviderFactory, - base::Unretained(network_resources_.get()), - url_request_context_, network_time_update_callback_); + return base::BindRepeating( + &syncer::NetworkResources::GetHttpPostProviderFactory, + base::Unretained(network_resources_.get()), url_request_context_, + network_time_update_callback_); } syncer::WeakHandle<syncer::UnrecoverableErrorHandler> @@ -455,6 +438,15 @@ ProfileSyncService::GetUnrecoverableErrorHandler() { return syncer::MakeWeakHandle(sync_enabled_weak_factory_.GetWeakPtr()); } +void ProfileSyncService::ResetCryptoState() { + crypto_ = std::make_unique<syncer::SyncServiceCrypto>( + base::BindRepeating(&ProfileSyncService::NotifyObservers, + base::Unretained(this)), + base::BindRepeating(&ProfileSyncService::GetPreferredDataTypes, + base::Unretained(this)), + &sync_prefs_); +} + bool ProfileSyncService::IsEncryptedDatatypeEnabled() const { if (encryption_pending()) return true; @@ -465,7 +457,7 @@ bool ProfileSyncService::IsEncryptedDatatypeEnabled() const { } void ProfileSyncService::OnProtocolEvent(const syncer::ProtocolEvent& event) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); for (auto& observer : protocol_event_observers_) observer.OnProtocolEvent(event); } @@ -473,7 +465,7 @@ void ProfileSyncService::OnProtocolEvent(const syncer::ProtocolEvent& event) { void ProfileSyncService::OnDirectoryTypeCommitCounterUpdated( syncer::ModelType type, const syncer::CommitCounters& counters) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); for (auto& observer : type_debug_info_observers_) observer.OnCommitCountersUpdated(type, counters); } @@ -481,7 +473,7 @@ void ProfileSyncService::OnDirectoryTypeCommitCounterUpdated( void ProfileSyncService::OnDirectoryTypeUpdateCounterUpdated( syncer::ModelType type, const syncer::UpdateCounters& counters) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); for (auto& observer : type_debug_info_observers_) observer.OnUpdateCountersUpdated(type, counters); } @@ -489,13 +481,13 @@ void ProfileSyncService::OnDirectoryTypeUpdateCounterUpdated( void ProfileSyncService::OnDatatypeStatusCounterUpdated( syncer::ModelType type, const syncer::StatusCounters& counters) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); for (auto& observer : type_debug_info_observers_) observer.OnStatusCountersUpdated(type, counters); } void ProfileSyncService::OnDataTypeRequestsSyncStartup(syncer::ModelType type) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(syncer::UserTypes().Has(type)); if (!GetPreferredDataTypes().Has(type)) { @@ -529,9 +521,9 @@ void ProfileSyncService::StartUpSlowEngineComponents() { invalidation::InvalidationService* invalidator = sync_client_->GetInvalidationService(); - engine_.reset(sync_client_->GetSyncApiComponentFactory()->CreateSyncEngine( + engine_ = sync_client_->GetSyncApiComponentFactory()->CreateSyncEngine( debug_identifier_, invalidator, sync_prefs_.AsWeakPtr(), - FormatSyncDataPath(base_directory_))); + FormatSyncDataPath(base_directory_)); // Clear any old errors the first time sync starts. if (!IsFirstSetupComplete()) @@ -544,138 +536,121 @@ void ProfileSyncService::StartUpSlowEngineComponents() { ReportPreviousSessionMemoryWarningCount(); } -void ProfileSyncService::OnGetTokenSuccess( - const OAuth2TokenService::Request* request, - const std::string& access_token, - const base::Time& expiration_time) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK_EQ(access_token_request_.get(), request); - access_token_request_.reset(); - access_token_ = access_token; - token_receive_time_ = base::Time::Now(); - last_get_token_error_ = GoogleServiceAuthError::AuthErrorNone(); +void ProfileSyncService::InitializeEngine() { + DCHECK(engine_); + + if (!sync_thread_) { + sync_thread_ = std::make_unique<base::Thread>("Chrome_SyncThread"); + base::Thread::Options options; + options.timer_slack = base::TIMER_SLACK_MAXIMUM; + bool success = sync_thread_->StartWithOptions(options); + DCHECK(success); + } + + SyncEngine::InitParams params; + params.sync_task_runner = sync_thread_->task_runner(); + params.host = this; + params.registrar = std::make_unique<SyncBackendRegistrar>( + debug_identifier_, + base::BindRepeating(&SyncClient::CreateModelWorkerForGroup, + base::Unretained(sync_client_.get()))); + params.encryption_observer_proxy = crypto_->GetEncryptionObserverProxy(); + params.extensions_activity = sync_client_->GetExtensionsActivity(); + params.event_handler = GetJsEventHandler(); + params.service_url = sync_service_url(); + params.sync_user_agent = GetLocalDeviceInfoProvider()->GetSyncUserAgent(); + params.http_factory_getter = MakeHttpPostProviderFactoryGetter(); + params.credentials = auth_manager_->GetCredentials(); + DCHECK(!params.credentials.account_id.empty() || IsLocalSyncEnabled()); + invalidation::InvalidationService* invalidator = + sync_client_->GetInvalidationService(); + params.invalidator_client_id = + invalidator ? invalidator->GetInvalidatorClientId() : "", + params.sync_manager_factory = std::make_unique<SyncManagerFactory>(); + // The first time we start up the engine we want to ensure we have a clean + // directory, so delete any old one that might be there. + params.delete_sync_data_folder = !IsFirstSetupComplete(); + params.enable_local_sync_backend = sync_prefs_.IsLocalSyncEnabled(); + params.local_sync_backend_folder = sync_client_->GetLocalSyncBackendFolder(); + params.restored_key_for_bootstrapping = + sync_prefs_.GetEncryptionBootstrapToken(); + params.restored_keystore_key_for_bootstrapping = + sync_prefs_.GetKeystoreEncryptionBootstrapToken(); + params.engine_components_factory = + std::make_unique<EngineComponentsFactoryImpl>( + EngineSwitchesFromCommandLine()); + params.unrecoverable_error_handler = GetUnrecoverableErrorHandler(); + params.report_unrecoverable_error_function = + base::BindRepeating(syncer::ReportUnrecoverableError, channel_); + params.saved_nigori_state = crypto_->TakeSavedNigoriState(); + sync_prefs_.GetInvalidationVersions(¶ms.invalidation_versions); + params.short_poll_interval = sync_prefs_.GetShortPollInterval(); + if (params.short_poll_interval.is_zero()) { + params.short_poll_interval = + base::TimeDelta::FromSeconds(syncer::kDefaultShortPollIntervalSeconds); + } + params.long_poll_interval = sync_prefs_.GetLongPollInterval(); + if (params.long_poll_interval.is_zero()) { + params.long_poll_interval = + base::TimeDelta::FromSeconds(syncer::kDefaultLongPollIntervalSeconds); + } + + engine_->Initialize(std::move(params)); +} + +void ProfileSyncService::AccessTokenFetched( + const GoogleServiceAuthError& error) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (sync_prefs_.SyncHasAuthError()) { - sync_prefs_.SetSyncAuthError(false); + if (error.state() == GoogleServiceAuthError::NONE) { + if (HasSyncingEngine()) { + engine_->UpdateCredentials(auth_manager_->GetCredentials()); + } else { + startup_controller_->TryStart(); + } } + // Else: Some error happened. SyncAuthManager takes care of that (retry if + // appropriate etc), so there's nothing for us to do here. - if (HasSyncingEngine()) - engine_->UpdateCredentials(GetCredentials()); - else - startup_controller_->TryStart(); - - UpdateAuthErrorState(GoogleServiceAuthError(GoogleServiceAuthError::NONE)); + NotifyObservers(); } -void ProfileSyncService::OnGetTokenFailure( - const OAuth2TokenService::Request* request, - const GoogleServiceAuthError& error) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK_EQ(access_token_request_.get(), request); - DCHECK_NE(error.state(), GoogleServiceAuthError::NONE); - access_token_request_.reset(); - last_get_token_error_ = error; - switch (error.state()) { - case GoogleServiceAuthError::CONNECTION_FAILED: - case GoogleServiceAuthError::REQUEST_CANCELED: - case GoogleServiceAuthError::SERVICE_ERROR: - case GoogleServiceAuthError::SERVICE_UNAVAILABLE: { - // Transient error. Retry after some time. - request_access_token_backoff_.InformOfRequest(false); - next_token_request_time_ = - base::Time::Now() + - request_access_token_backoff_.GetTimeUntilRelease(); - request_access_token_retry_timer_.Start( - FROM_HERE, request_access_token_backoff_.GetTimeUntilRelease(), - base::Bind(&ProfileSyncService::RequestAccessToken, - sync_enabled_weak_factory_.GetWeakPtr())); - NotifyObservers(); - break; - } - case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS: { - if (!sync_prefs_.SyncHasAuthError()) { - sync_prefs_.SetSyncAuthError(true); - UMA_HISTOGRAM_ENUMERATION("Sync.SyncAuthError", AUTH_ERROR_ENCOUNTERED, - AUTH_ERROR_LIMIT); - } - FALLTHROUGH; - } - default: { - if (error.state() != GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS) { - LOG(ERROR) << "Unexpected persistent error: " << error.ToString(); - } - // Show error to user. - UpdateAuthErrorState(error); - } - } -} +void ProfileSyncService::OnRefreshTokenAvailable() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); -void ProfileSyncService::OnRefreshTokenAvailable( - const std::string& account_id) { - DCHECK(thread_checker_.CalledOnValidThread()); - if (account_id == signin_->GetAccountIdToUse()) - OnRefreshTokensLoaded(); -} - -void ProfileSyncService::OnRefreshTokenRevoked(const std::string& account_id) { - DCHECK(thread_checker_.CalledOnValidThread()); - if (account_id == signin_->GetAccountIdToUse()) { - access_token_.clear(); - UpdateAuthErrorState( - GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED)); - } -} - -void ProfileSyncService::OnRefreshTokensLoaded() { - DCHECK(thread_checker_.CalledOnValidThread()); - - GoogleServiceAuthError token_error = - oauth2_token_service_->GetAuthError(signin_->GetAccountIdToUse()); - if (token_error == GoogleServiceAuthError::FromInvalidGaiaCredentialsReason( - GoogleServiceAuthError::InvalidGaiaCredentialsReason:: - CREDENTIALS_REJECTED_BY_CLIENT)) { - // When the refresh token is replaced by a new token with a - // CREDENTIALS_REJECTED_BY_CLIENT error, Sync must be stopped immediately, - // even if the current access token is still valid. This happens e.g. when - // the user signs out of the web with Dice enabled. - // It is not necessary to do this when the refresh token is - // CREDENTIALS_REJECTED_BY_SERVER, because in that case the access token - // will be rejected by the server too. - // We only do this in OnRefreshTokensLoaded(), as opposed to - // OAuth2TokenService::Observer::OnAuthErrorChanged(), because - // CREDENTIALS_REJECTED_BY_CLIENT is only set by the signin component when - // the refresh token is created. - access_token_.clear(); - request_access_token_retry_timer_.Stop(); - access_token_request_.reset(); - is_auth_in_progress_ = false; - if (HasSyncingEngine()) - engine_->InvalidateCredentials(); - } - - // This notification gets fired when OAuth2TokenService loads the tokens from - // storage. Initialize the engine if sync is enabled. If the sync token was - // not loaded, GetCredentials() will generate invalid credentials to cause the - // engine to generate an auth error (crbug.com/121755). if (HasSyncingEngine()) { - RequestAccessToken(); + auth_manager_->RequestAccessToken(); } else { startup_controller_->TryStart(); } } +void ProfileSyncService::OnRefreshTokenRevoked() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + if (HasSyncingEngine()) + engine_->InvalidateCredentials(); + + NotifyObservers(); +} + void ProfileSyncService::Shutdown() { - DCHECK(thread_checker_.CalledOnValidThread()); - UnregisterAuthNotifications(); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); ShutdownImpl(syncer::BROWSER_SHUTDOWN); NotifyShutdown(); + // TODO(treib): DCHECK that all observers are gone now. All KeyedServices + // should have unregistered their observers already before, in their own + // Shutdown(), and all others should have done it now when they got the + // shutdown notification. if (sync_error_controller_) { // Destroy the SyncErrorController when the service shuts down for good. RemoveObserver(sync_error_controller_.get()); sync_error_controller_.reset(); } + auth_manager_.reset(); + signin_scoped_device_id_callback_.Reset(); if (sync_thread_) @@ -689,8 +664,8 @@ void ProfileSyncService::ShutdownImpl(syncer::ShutdownReason reason) { // the data directory needs to be cleaned up here. sync_thread_->task_runner()->PostTask( FROM_HERE, - base::Bind(&syncer::syncable::Directory::DeleteDirectoryFiles, - FormatSyncDataPath(base_directory_))); + base::BindOnce(&syncer::syncable::Directory::DeleteDirectoryFiles, + FormatSyncDataPath(base_directory_))); } return; } @@ -744,14 +719,9 @@ void ProfileSyncService::ShutdownImpl(syncer::ShutdownReason reason) { // Clear various state. ResetCryptoState(); expect_sync_configuration_aborted_ = false; - is_auth_in_progress_ = false; engine_initialized_ = false; - access_token_.clear(); - request_access_token_retry_timer_.Stop(); last_snapshot_ = syncer::SyncCycleSnapshot(); - // Revert to "no auth error". - if (last_auth_error_.state() != GoogleServiceAuthError::NONE) - UpdateAuthErrorState(GoogleServiceAuthError::AuthErrorNone()); + auth_manager_->Clear(); NotifyObservers(); @@ -775,12 +745,12 @@ void ProfileSyncService::StopImpl(SyncStopDataFate data_fate) { } bool ProfileSyncService::IsFirstSetupComplete() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return sync_prefs_.IsFirstSetupComplete(); } void ProfileSyncService::SetFirstSetupComplete() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); sync_prefs_.SetFirstSetupComplete(); if (IsEngineInitialized()) { ReconfigureDatatypeManager(); @@ -788,7 +758,7 @@ void ProfileSyncService::SetFirstSetupComplete() { } bool ProfileSyncService::IsSyncConfirmationNeeded() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return (!IsLocalSyncEnabled() && IsSignedIn()) && !IsFirstSetupInProgress() && !IsFirstSetupComplete() && IsSyncRequested(); } @@ -797,6 +767,12 @@ void ProfileSyncService::UpdateLastSyncedTime() { sync_prefs_.SetLastSyncedTime(base::Time::Now()); } +void ProfileSyncService::NotifyObservers() { + for (auto& observer : observers_) { + observer.OnStateChanged(this); + } +} + void ProfileSyncService::NotifySyncCycleCompleted() { for (auto& observer : observers_) observer.OnSyncCycleCompleted(this); @@ -816,7 +792,7 @@ void ProfileSyncService::ClearStaleErrors() { ClearUnrecoverableError(); last_actionable_error_ = SyncProtocolError(); // Clear the data type errors as well. - if (data_type_manager_.get()) + if (data_type_manager_) data_type_manager_->ResetDataTypeErrors(); } @@ -830,7 +806,7 @@ void ProfileSyncService::ClearUnrecoverableError() { // to do as little work as possible, to avoid further corruption or crashes. void ProfileSyncService::OnUnrecoverableError(const base::Location& from_here, const std::string& message) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // Unrecoverable errors that arrive via the syncer::UnrecoverableErrorHandler // interface are assumed to originate within the syncer. unrecoverable_error_reason_ = ERROR_REASON_SYNCER; @@ -851,15 +827,15 @@ void ProfileSyncService::OnUnrecoverableErrorImpl( << " -- ProfileSyncService unusable: " << message; // Shut all data types down. - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&ProfileSyncService::ShutdownImpl, - sync_enabled_weak_factory_.GetWeakPtr(), - delete_sync_database ? syncer::DISABLE_SYNC - : syncer::STOP_SYNC)); + base::SequencedTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(&ProfileSyncService::ShutdownImpl, + sync_enabled_weak_factory_.GetWeakPtr(), + delete_sync_database ? syncer::DISABLE_SYNC + : syncer::STOP_SYNC)); } void ProfileSyncService::ReenableDatatype(syncer::ModelType type) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!engine_initialized_ || !data_type_manager_) return; data_type_manager_->ReenableType(type); @@ -891,7 +867,7 @@ void ProfileSyncService::OnEngineInitialized( debug_info_listener, const std::string& cache_guid, bool success) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); UpdateEngineInitUMA(success); if (!success) { @@ -915,7 +891,6 @@ void ProfileSyncService::OnEngineInitialized( engine_initialized_ = true; sync_js_controller_.AttachJsBackend(js_backend); - debug_info_listener_ = debug_info_listener; // Initialize local device info. local_device_->Initialize(cache_guid, @@ -936,10 +911,10 @@ void ProfileSyncService::OnEngineInitialized( UpdateLastSyncedTime(); } - data_type_manager_.reset( + data_type_manager_ = sync_client_->GetSyncApiComponentFactory()->CreateDataTypeManager( - initial_types, debug_info_listener_, &data_type_controllers_, this, - engine_.get(), this)); + initial_types, debug_info_listener, &data_type_controllers_, this, + engine_.get(), this); crypto_->SetSyncEngine(engine_.get()); crypto_->SetDataTypeManager(data_type_manager_.get()); @@ -971,13 +946,18 @@ void ProfileSyncService::OnEngineInitialized( void ProfileSyncService::OnSyncCycleCompleted( const syncer::SyncCycleSnapshot& snapshot) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); last_snapshot_ = snapshot; UpdateLastSyncedTime(); if (!snapshot.poll_finish_time().is_null()) sync_prefs_.SetLastPollTime(snapshot.poll_finish_time()); + DCHECK(!snapshot.short_poll_interval().is_zero()); + sync_prefs_.SetShortPollInterval(snapshot.short_poll_interval()); + + DCHECK(!snapshot.long_poll_interval().is_zero()); + sync_prefs_.SetLongPollInterval(snapshot.long_poll_interval()); if (IsDataTypeControllerRunning(syncer::SESSIONS) && snapshot.model_neutral_state().get_updates_request_types.Has( @@ -985,9 +965,7 @@ void ProfileSyncService::OnSyncCycleCompleted( !syncer::HasSyncerError(snapshot.model_neutral_state())) { // Trigger garbage collection of old sessions now that we've downloaded // any new session data. - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&SessionsSyncManager::DoGarbageCollection, - base::AsWeakPtr(sessions_sync_manager_.get()))); + sessions_sync_manager_->ScheduleGarbageCollection(); } DVLOG(2) << "Notifying observers sync cycle completed"; NotifySyncCycleCompleted(); @@ -995,7 +973,7 @@ void ProfileSyncService::OnSyncCycleCompleted( void ProfileSyncService::OnExperimentsChanged( const syncer::Experiments& experiments) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (current_experiments_.Matches(experiments)) return; @@ -1006,102 +984,15 @@ void ProfileSyncService::OnExperimentsChanged( experiments.gcm_invalidations_enabled); } -void ProfileSyncService::UpdateAuthErrorState( - const GoogleServiceAuthError& error) { - is_auth_in_progress_ = false; - last_auth_error_ = error; - - NotifyObservers(); -} - -namespace { - -GoogleServiceAuthError ConnectionStatusToAuthError( - syncer::ConnectionStatus status) { - switch (status) { - case syncer::CONNECTION_OK: - return GoogleServiceAuthError::AuthErrorNone(); - break; - case syncer::CONNECTION_AUTH_ERROR: - return GoogleServiceAuthError::FromInvalidGaiaCredentialsReason( - GoogleServiceAuthError::InvalidGaiaCredentialsReason:: - CREDENTIALS_REJECTED_BY_SERVER); - break; - case syncer::CONNECTION_SERVER_ERROR: - return GoogleServiceAuthError(GoogleServiceAuthError::CONNECTION_FAILED); - break; - default: - NOTREACHED(); - return GoogleServiceAuthError(GoogleServiceAuthError::CONNECTION_FAILED); - } -} - -} // namespace - void ProfileSyncService::OnConnectionStatusChange( syncer::ConnectionStatus status) { - DCHECK(thread_checker_.CalledOnValidThread()); - connection_status_update_time_ = base::Time::Now(); - connection_status_ = status; - if (status == syncer::CONNECTION_AUTH_ERROR) { - // Sync server returned error indicating that access token is invalid. It - // could be either expired or access is revoked. Let's request another - // access token and if access is revoked then request for token will fail - // with corresponding error. If access token is repeatedly reported - // invalid, there may be some issues with server, e.g. authentication - // state is inconsistent on sync and token server. In that case, we - // backoff token requests exponentially to avoid hammering token server - // too much and to avoid getting same token due to token server's caching - // policy. |request_access_token_retry_timer_| is used to backoff request - // triggered by both auth error and failure talking to GAIA server. - // Therefore, we're likely to reach the backoff ceiling more quickly than - // you would expect from looking at the BackoffPolicy if both types of - // errors happen. We shouldn't receive two errors back-to-back without - // attempting a token/sync request in between, thus crank up request delay - // unnecessary. This is because we won't make a sync request if we hit an - // error until GAIA succeeds at sending a new token, and we won't request - // a new token unless sync reports a token failure. But to be safe, don't - // schedule request if this happens. - if (request_access_token_retry_timer_.IsRunning()) { - // The timer to perform a request later is already running; nothing - // further needs to be done at this point. - } else if (request_access_token_backoff_.failure_count() == 0) { - // First time request without delay. Currently invalid token is used - // to initialize sync engine and we'll always end up here. We don't - // want to delay initialization. - request_access_token_backoff_.InformOfRequest(false); - RequestAccessToken(); - } else { - request_access_token_backoff_.InformOfRequest(false); - request_access_token_retry_timer_.Start( - FROM_HERE, request_access_token_backoff_.GetTimeUntilRelease(), - base::Bind(&ProfileSyncService::RequestAccessToken, - sync_enabled_weak_factory_.GetWeakPtr())); - } - // Make observers aware of the change. This call is unnecessary in the - // block below because UpdateAuthErrorState() will notify observers. - NotifyObservers(); - } else { - // Reset backoff time after successful connection. - if (status == syncer::CONNECTION_OK) { - // Request shouldn't be scheduled at this time. But if it is, it's - // possible that sync flips between OK and auth error states rapidly, - // thus hammers token server. To be safe, only reset backoff delay when - // no scheduled request. - if (!request_access_token_retry_timer_.IsRunning()) { - request_access_token_backoff_.Reset(); - } - } - - const GoogleServiceAuthError auth_error = - ConnectionStatusToAuthError(status); - DVLOG(1) << "Connection status change: " << auth_error.ToString(); - UpdateAuthErrorState(auth_error); - } + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + auth_manager_->ConnectionStatusChanged(status); + NotifyObservers(); } void ProfileSyncService::OnMigrationNeededForTypes(syncer::ModelTypeSet types) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(engine_initialized_); DCHECK(data_type_manager_); @@ -1111,7 +1002,7 @@ void ProfileSyncService::OnMigrationNeededForTypes(syncer::ModelTypeSet types) { } void ProfileSyncService::OnActionableError(const SyncProtocolError& error) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); last_actionable_error_ = error; DCHECK_NE(last_actionable_error_.action, syncer::UNKNOWN_ACTION); switch (error.action) { @@ -1168,10 +1059,10 @@ void ProfileSyncService::OnActionableError(const SyncProtocolError& error) { } void ProfileSyncService::ClearAndRestartSyncForPassphraseEncryption() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); engine_->ClearServerData( - base::Bind(&ProfileSyncService::OnClearServerDataDone, - sync_enabled_weak_factory_.GetWeakPtr())); + base::BindRepeating(&ProfileSyncService::OnClearServerDataDone, + sync_enabled_weak_factory_.GetWeakPtr())); } void ProfileSyncService::OnClearServerDataDone() { @@ -1192,7 +1083,7 @@ void ProfileSyncService::OnClearServerDataDone() { } void ProfileSyncService::ClearServerDataForTest(const base::Closure& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // Sync has a restriction that the engine must be in configuration mode // in order to run clear server data. engine_->StartConfiguration(); @@ -1201,12 +1092,11 @@ void ProfileSyncService::ClearServerDataForTest(const base::Closure& callback) { void ProfileSyncService::OnConfigureDone( const DataTypeManager::ConfigureResult& result) { - DCHECK(thread_checker_.CalledOnValidThread()); - configure_status_ = result.status; + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); data_type_status_table_ = result.data_type_status_table; if (!sync_configure_start_time_.is_null()) { - if (configure_status_ == DataTypeManager::OK) { + if (result.status == DataTypeManager::OK) { base::Time sync_configure_stop_time = base::Time::Now(); base::TimeDelta delta = sync_configure_stop_time - sync_configure_start_time_; @@ -1223,7 +1113,7 @@ void ProfileSyncService::OnConfigureDone( for (auto& observer : observers_) observer.OnSyncConfigurationCompleted(this); - DVLOG(1) << "PSS OnConfigureDone called with status: " << configure_status_; + DVLOG(1) << "PSS OnConfigureDone called with status: " << result.status; // The possible status values: // ABORT - Configuration was aborted. This is not an error, if // initiated by user. @@ -1231,7 +1121,7 @@ void ProfileSyncService::OnConfigureDone( // Everything else is an UnrecoverableError. So treat it as such. // First handle the abort case. - if (configure_status_ == DataTypeManager::ABORTED && + if (result.status == DataTypeManager::ABORTED && expect_sync_configuration_aborted_) { DVLOG(0) << "ProfileSyncService::Observe Sync Configure aborted"; expect_sync_configuration_aborted_ = false; @@ -1239,7 +1129,7 @@ void ProfileSyncService::OnConfigureDone( } // Handle unrecoverable error. - if (configure_status_ != DataTypeManager::OK) { + if (result.status != DataTypeManager::OK) { if (result.was_catch_up_configure) { // Record catchup configuration failure. UMA_HISTOGRAM_ENUMERATION("Sync.ClearServerDataEvents", @@ -1252,7 +1142,7 @@ void ProfileSyncService::OnConfigureDone( DCHECK(error.IsSet()); std::string message = "Sync configuration failed with status " + - DataTypeManager::ConfigureStatusToString(configure_status_) + + DataTypeManager::ConfigureStatusToString(result.status) + " caused by " + syncer::ModelTypeSetToString( data_type_status_table_.GetUnrecoverableErrorTypes()) + @@ -1263,7 +1153,7 @@ void ProfileSyncService::OnConfigureDone( return; } - DCHECK_EQ(DataTypeManager::OK, configure_status_); + DCHECK_EQ(DataTypeManager::OK, result.status); // We should never get in a state where we have no encrypted datatypes // enabled, and yet we still think we require a passphrase for decryption. @@ -1295,67 +1185,43 @@ void ProfileSyncService::OnConfigureDone( } void ProfileSyncService::OnConfigureStart() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); sync_configure_start_time_ = base::Time::Now(); engine_->StartConfiguration(); NotifyObservers(); } -ProfileSyncService::SyncStatusSummary -ProfileSyncService::QuerySyncStatusSummary() { - DCHECK(thread_checker_.CalledOnValidThread()); +std::string ProfileSyncService::QuerySyncStatusSummaryString() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (HasUnrecoverableError()) - return UNRECOVERABLE_ERROR; + return "Unrecoverable error detected"; if (!engine_) - return NOT_ENABLED; - if (engine_ && !IsFirstSetupComplete()) - return SETUP_INCOMPLETE; - if (engine_ && IsFirstSetupComplete() && data_type_manager_ && + return "Syncing not enabled"; + if (!IsFirstSetupComplete()) + return "First time sync setup incomplete"; + if (data_type_manager_ && data_type_manager_->state() == DataTypeManager::STOPPED) { - return DATATYPES_NOT_INITIALIZED; + return "Datatypes not fully initialized"; } if (IsSyncActive()) - return INITIALIZED; - return UNKNOWN_ERROR; -} + return "Sync service initialized"; -std::string ProfileSyncService::QuerySyncStatusSummaryString() { - DCHECK(thread_checker_.CalledOnValidThread()); - SyncStatusSummary status = QuerySyncStatusSummary(); - - std::string config_status_str = - configure_status_ != DataTypeManager::UNKNOWN - ? DataTypeManager::ConfigureStatusToString(configure_status_) - : ""; - - switch (status) { - case UNRECOVERABLE_ERROR: - return "Unrecoverable error detected"; - case NOT_ENABLED: - return "Syncing not enabled"; - case SETUP_INCOMPLETE: - return "First time sync setup incomplete"; - case DATATYPES_NOT_INITIALIZED: - return "Datatypes not fully initialized"; - case INITIALIZED: - return "Sync service initialized"; - default: - return "Status unknown: Internal error?"; - } + return "Status unknown: Internal error?"; } std::string ProfileSyncService::GetEngineInitializationStateString() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return startup_controller_->GetEngineInitializationStateString(); } bool ProfileSyncService::IsSetupInProgress() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return startup_controller_->IsSetupInProgress(); } bool ProfileSyncService::QueryDetailedSyncStatus(SyncEngine::Status* result) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (engine_ && engine_initialized_) { *result = engine_->GetDetailedStatus(); return true; @@ -1367,8 +1233,8 @@ bool ProfileSyncService::QueryDetailedSyncStatus(SyncEngine::Status* result) { } const GoogleServiceAuthError& ProfileSyncService::GetAuthError() const { - DCHECK(thread_checker_.CalledOnValidThread()); - return last_auth_error_; + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + return auth_manager_->GetLastAuthError(); } bool ProfileSyncService::CanConfigureDataTypes() const { @@ -1376,13 +1242,13 @@ bool ProfileSyncService::CanConfigureDataTypes() const { } bool ProfileSyncService::IsFirstSetupInProgress() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return !IsFirstSetupComplete() && startup_controller_->IsSetupInProgress(); } std::unique_ptr<syncer::SyncSetupInProgressHandle> ProfileSyncService::GetSetupInProgressHandle() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (++outstanding_setup_in_progress_handles_ == 1) { DCHECK(!startup_controller_->IsSetupInProgress()); @@ -1391,81 +1257,73 @@ ProfileSyncService::GetSetupInProgressHandle() { NotifyObservers(); } - return std::unique_ptr<syncer::SyncSetupInProgressHandle>( - new syncer::SyncSetupInProgressHandle( - base::Bind(&ProfileSyncService::OnSetupInProgressHandleDestroyed, - weak_factory_.GetWeakPtr()))); + return std::make_unique<syncer::SyncSetupInProgressHandle>( + base::BindRepeating(&ProfileSyncService::OnSetupInProgressHandleDestroyed, + weak_factory_.GetWeakPtr())); } bool ProfileSyncService::IsSyncAllowed() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return IsSyncAllowedByFlag() && !IsManaged() && IsSyncAllowedByPlatform(); } bool ProfileSyncService::IsSyncActive() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return engine_initialized_ && data_type_manager_ && data_type_manager_->state() != DataTypeManager::STOPPED; } bool ProfileSyncService::IsLocalSyncEnabled() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return sync_prefs_.IsLocalSyncEnabled(); } void ProfileSyncService::TriggerRefresh(const syncer::ModelTypeSet& types) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (engine_initialized_) engine_->TriggerRefresh(types); } bool ProfileSyncService::IsSignedIn() const { - // Sync is logged in if there is a non-empty effective account id. - return !signin_->GetAccountIdToUse().empty(); + // Sync is logged in if there is a non-empty account id. + return !GetAuthenticatedAccountInfo().account_id.empty(); } bool ProfileSyncService::CanEngineStart() const { if (IsLocalSyncEnabled()) return true; - return CanSyncStart() && oauth2_token_service_ && - oauth2_token_service_->RefreshTokenIsAvailable( - signin_->GetAccountIdToUse()); + return CanSyncStart() && auth_manager_->RefreshTokenIsAvailable(); } bool ProfileSyncService::IsEngineInitialized() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return engine_initialized_; } bool ProfileSyncService::ConfigurationDone() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return data_type_manager_ && data_type_manager_->state() == DataTypeManager::CONFIGURED; } bool ProfileSyncService::waiting_for_auth() const { - DCHECK(thread_checker_.CalledOnValidThread()); - return is_auth_in_progress_; -} - -const syncer::Experiments& ProfileSyncService::current_experiments() const { - DCHECK(thread_checker_.CalledOnValidThread()); - return current_experiments_; + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + return auth_manager_->IsAuthInProgress(); } bool ProfileSyncService::HasUnrecoverableError() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return unrecoverable_error_reason_ != ERROR_REASON_UNSET; } bool ProfileSyncService::IsPassphraseRequired() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return crypto_->passphrase_required_reason() != syncer::REASON_PASSPHRASE_NOT_REQUIRED; } bool ProfileSyncService::IsPassphraseRequiredForDecryption() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // If there is an encrypted datatype enabled and we don't have the proper // passphrase, we must prompt the user for a passphrase. The only way for the // user to avoid entering their passphrase is to disable the encrypted types. @@ -1503,7 +1361,7 @@ void ProfileSyncService::UpdateSelectedTypesHistogram( syncer::user_selectable_type::PROXY_TABS, }; - static_assert(40 == syncer::MODEL_TYPE_COUNT, + static_assert(41 == syncer::MODEL_TYPE_COUNT, "If adding a user selectable type, update " "UserSelectableSyncType in user_selectable_sync_type.h and " "histograms.xml."); @@ -1533,7 +1391,7 @@ void ProfileSyncService::UpdateSelectedTypesHistogram( void ProfileSyncService::OnUserChoseDatatypes( bool sync_everything, syncer::ModelTypeSet chosen_types) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(syncer::UserSelectableTypes().HasAll(chosen_types)); if (!engine_ && !HasUnrecoverableError()) { @@ -1549,23 +1407,9 @@ void ProfileSyncService::OnUserChoseDatatypes( ChangePreferredDataTypes(chosen_types); } -void ProfileSyncService::OnUserChangedSyncEverythingOnly(bool sync_everything) { - DCHECK(thread_checker_.CalledOnValidThread()); - if (!engine_ && !HasUnrecoverableError()) { - NOTREACHED(); - return; - } - - sync_prefs_.SetKeepEverythingSynced(sync_everything); - UpdateSelectedTypesHistogram(sync_everything, GetPreferredDataTypes()); - if (data_type_manager_) - data_type_manager_->ResetDataTypeErrors(); - ReconfigureDatatypeManager(); -} - void ProfileSyncService::ChangePreferredDataTypes( syncer::ModelTypeSet preferred_types) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DVLOG(1) << "ChangePreferredDataTypes invoked"; const syncer::ModelTypeSet registered_types = GetRegisteredDataTypes(); // Will only enable those types that are registered and preferred. @@ -1576,19 +1420,35 @@ void ProfileSyncService::ChangePreferredDataTypes( } syncer::ModelTypeSet ProfileSyncService::GetActiveDataTypes() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!data_type_manager_) return syncer::ModelTypeSet(); return data_type_manager_->GetActiveDataTypes(); } syncer::SyncClient* ProfileSyncService::GetSyncClient() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return sync_client_.get(); } +void ProfileSyncService::AddObserver(syncer::SyncServiceObserver* observer) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + observers_.AddObserver(observer); +} + +void ProfileSyncService::RemoveObserver(syncer::SyncServiceObserver* observer) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + observers_.RemoveObserver(observer); +} + +bool ProfileSyncService::HasObserver( + const syncer::SyncServiceObserver* observer) const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + return observers_.HasObserver(observer); +} + syncer::ModelTypeSet ProfileSyncService::GetPreferredDataTypes() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); const syncer::ModelTypeSet registered_types = GetRegisteredDataTypes(); const syncer::ModelTypeSet preferred_types = Union(sync_prefs_.GetPreferredDataTypes(registered_types), @@ -1599,7 +1459,7 @@ syncer::ModelTypeSet ProfileSyncService::GetPreferredDataTypes() const { } syncer::ModelTypeSet ProfileSyncService::GetForcedDataTypes() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // TODO(treib,zea): When SyncPrefs also implements SyncTypePreferenceProvider, // we'll need another way to distinguish user-choosable types from // programmatically-enabled types. @@ -1607,25 +1467,25 @@ syncer::ModelTypeSet ProfileSyncService::GetForcedDataTypes() const { } syncer::ModelTypeSet ProfileSyncService::GetRegisteredDataTypes() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); syncer::ModelTypeSet registered_types; // The data_type_controllers_ are determined by command-line flags; // that's effectively what controls the values returned here. - for (DataTypeController::TypeMap::const_iterator it = - data_type_controllers_.begin(); - it != data_type_controllers_.end(); ++it) { - registered_types.Put(it->first); + for (const std::pair<const syncer::ModelType, + std::unique_ptr<DataTypeController>>& + type_and_controller : data_type_controllers_) { + registered_types.Put(type_and_controller.first); } return registered_types; } bool ProfileSyncService::IsUsingSecondaryPassphrase() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return crypto_->IsUsingSecondaryPassphrase(); } std::string ProfileSyncService::GetCustomPassphraseKey() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); syncer::SystemEncryptor encryptor; syncer::Cryptographer cryptographer(&encryptor); cryptographer.Bootstrap(sync_prefs_.GetEncryptionBootstrapToken()); @@ -1633,24 +1493,24 @@ std::string ProfileSyncService::GetCustomPassphraseKey() const { } syncer::PassphraseType ProfileSyncService::GetPassphraseType() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return crypto_->GetPassphraseType(); } base::Time ProfileSyncService::GetExplicitPassphraseTime() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return crypto_->GetExplicitPassphraseTime(); } bool ProfileSyncService::IsCryptographerReady( const syncer::BaseTransaction* trans) const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return engine_ && engine_->IsCryptographerReady(trans); } void ProfileSyncService::SetPlatformSyncAllowedProvider( const PlatformSyncAllowedProvider& platform_sync_allowed_provider) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); platform_sync_allowed_provider_ = platform_sync_allowed_provider; } @@ -1684,8 +1544,8 @@ void ProfileSyncService::ConfigureDataTypeManager() { // We create the migrator at the same time. migrator_ = std::make_unique<BackendMigrator>( debug_identifier_, GetUserShare(), this, data_type_manager_.get(), - base::Bind(&ProfileSyncService::StartSyncingWithServer, - base::Unretained(this))); + base::BindRepeating(&ProfileSyncService::StartSyncingWithServer, + base::Unretained(this))); } syncer::ModelTypeSet types; @@ -1707,7 +1567,7 @@ void ProfileSyncService::ConfigureDataTypeManager() { } syncer::UserShare* ProfileSyncService::GetUserShare() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (engine_ && engine_initialized_) { return engine_->GetUserShare(); } @@ -1716,36 +1576,25 @@ syncer::UserShare* ProfileSyncService::GetUserShare() const { } syncer::SyncCycleSnapshot ProfileSyncService::GetLastCycleSnapshot() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return last_snapshot_; } -bool ProfileSyncService::HasUnsyncedItems() const { - DCHECK(thread_checker_.CalledOnValidThread()); - if (HasSyncingEngine() && engine_initialized_) { - return engine_->HasUnsyncedItems(); - } - NOTREACHED(); - return false; +void ProfileSyncService::HasUnsyncedItemsForTest( + base::OnceCallback<void(bool)> cb) const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(HasSyncingEngine()); + DCHECK(engine_initialized_); + engine_->HasUnsyncedItemsForTest(std::move(cb)); } BackendMigrator* ProfileSyncService::GetBackendMigratorForTest() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return migrator_.get(); } -void ProfileSyncService::GetModelSafeRoutingInfo( - syncer::ModelSafeRoutingInfo* out) const { - DCHECK(thread_checker_.CalledOnValidThread()); - if (engine_ && engine_initialized_) { - engine_->GetModelSafeRoutingInfo(out); - } else { - NOTREACHED(); - } -} - std::unique_ptr<base::Value> ProfileSyncService::GetTypeStatusMap() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); auto result = std::make_unique<base::ListValue>(); if (!engine_ || !engine_initialized_) { @@ -1814,9 +1663,10 @@ std::unique_ptr<base::Value> ProfileSyncService::GetTypeStatusMap() { // OnDatatypeStatusCounterUpdated that posts back to the UI thread so that // real results can't get overwritten by the empty counters set at the end // of this method. - dtc_iter->second->GetStatusCounters(BindToCurrentThread( - base::Bind(&ProfileSyncService::OnDatatypeStatusCounterUpdated, - base::Unretained(this)))); + dtc_iter->second->GetStatusCounters( + BindToCurrentSequence(base::BindRepeating( + &ProfileSyncService::OnDatatypeStatusCounterUpdated, + base::Unretained(this)))); type_status->SetString("state", DataTypeController::StateToString( dtc_iter->second->state())); } @@ -1826,40 +1676,15 @@ std::unique_ptr<base::Value> ProfileSyncService::GetTypeStatusMap() { return std::move(result); } -void ProfileSyncService::RequestAccessToken() { - // Only one active request at a time. - if (access_token_request_ != nullptr) - return; - request_access_token_retry_timer_.Stop(); - OAuth2TokenService::ScopeSet oauth2_scopes; - oauth2_scopes.insert(signin_->GetSyncScopeToUse()); - - // Invalidate previous token, otherwise token service will return the same - // token again. - const std::string& account_id = signin_->GetAccountIdToUse(); - if (!access_token_.empty()) { - oauth2_token_service_->InvalidateAccessToken(account_id, oauth2_scopes, - access_token_); - } - - access_token_.clear(); - - token_request_time_ = base::Time::Now(); - token_receive_time_ = base::Time(); - next_token_request_time_ = base::Time(); - access_token_request_ = - oauth2_token_service_->StartRequest(account_id, oauth2_scopes, this); -} - void ProfileSyncService::SetEncryptionPassphrase(const std::string& passphrase, PassphraseType type) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); crypto_->SetEncryptionPassphrase(passphrase, type == EXPLICIT); } bool ProfileSyncService::SetDecryptionPassphrase( const std::string& passphrase) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (IsPassphraseRequired()) { DVLOG(1) << "Setting passphrase for decryption."; bool result = crypto_->SetDecryptionPassphrase(passphrase); @@ -1872,22 +1697,22 @@ bool ProfileSyncService::SetDecryptionPassphrase( } bool ProfileSyncService::IsEncryptEverythingAllowed() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return crypto_->IsEncryptEverythingAllowed(); } void ProfileSyncService::SetEncryptEverythingAllowed(bool allowed) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); crypto_->SetEncryptEverythingAllowed(allowed); } void ProfileSyncService::EnableEncryptEverything() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); crypto_->EnableEncryptEverything(); } bool ProfileSyncService::encryption_pending() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // We may be called during the setup process before we're // initialized (via IsEncryptedDatatypeEnabled and // IsPassphraseRequiredForDecryption). @@ -1895,17 +1720,17 @@ bool ProfileSyncService::encryption_pending() const { } bool ProfileSyncService::IsEncryptEverythingEnabled() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return crypto_->IsEncryptEverythingEnabled(); } syncer::ModelTypeSet ProfileSyncService::GetEncryptedDataTypes() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return crypto_->GetEncryptedDataTypes(); } void ProfileSyncService::OnSyncManagedPrefChange(bool is_sync_managed) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (is_sync_managed) { StopImpl(CLEAR_DATA); } else { @@ -1914,26 +1739,16 @@ void ProfileSyncService::OnSyncManagedPrefChange(bool is_sync_managed) { } } -void ProfileSyncService::GoogleSigninSucceeded(const std::string& account_id, - const std::string& username) { - DCHECK(thread_checker_.CalledOnValidThread()); - if (!IsEngineInitialized() || - GetAuthError().state() != GoogleServiceAuthError::NONE) { - // Track the fact that we're still waiting for auth to complete. - is_auth_in_progress_ = true; - } - - if (oauth2_token_service_->RefreshTokenIsAvailable(account_id)) - OnRefreshTokenAvailable(account_id); +void ProfileSyncService::OnPrimaryAccountSet() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(!engine_); } -void ProfileSyncService::GoogleSignedOut(const std::string& account_id, - const std::string& username) { - DCHECK(thread_checker_.CalledOnValidThread()); +void ProfileSyncService::OnPrimaryAccountCleared() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); sync_disabled_by_admin_ = false; - UMA_HISTOGRAM_ENUMERATION("Sync.StopSource", syncer::SIGN_OUT, - syncer::STOP_SOURCE_LIMIT); RequestStop(CLEAR_DATA); + DCHECK(!engine_); } void ProfileSyncService::OnGaiaAccountsInCookieUpdated( @@ -1946,7 +1761,7 @@ void ProfileSyncService::OnGaiaAccountsInCookieUpdated( void ProfileSyncService::OnGaiaAccountsInCookieUpdatedWithCallback( const std::vector<gaia::ListedAccount>& accounts, const base::Closure& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!IsEngineInitialized()) return; @@ -1960,7 +1775,7 @@ void ProfileSyncService::OnGaiaAccountsInCookieUpdatedWithCallback( bool ProfileSyncService::HasCookieJarMismatch( const std::vector<gaia::ListedAccount>& cookie_jar_accounts) { - std::string account_id = signin_->GetAccountIdToUse(); + std::string account_id = GetAuthenticatedAccountInfo().account_id; // Iterate through list of accounts, looking for current sync account. for (const auto& account : cookie_jar_accounts) { if (account.id == account_id) @@ -1971,7 +1786,7 @@ bool ProfileSyncService::HasCookieJarMismatch( void ProfileSyncService::AddProtocolEventObserver( ProtocolEventObserver* observer) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); protocol_event_observers_.AddObserver(observer); if (HasSyncingEngine()) { engine_->RequestBufferedProtocolEventsAndEnableForwarding(); @@ -1980,7 +1795,7 @@ void ProfileSyncService::AddProtocolEventObserver( void ProfileSyncService::RemoveProtocolEventObserver( ProtocolEventObserver* observer) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); protocol_event_observers_.RemoveObserver(observer); if (HasSyncingEngine() && !protocol_event_observers_.might_have_observers()) { engine_->DisableProtocolEventForwarding(); @@ -1989,7 +1804,7 @@ void ProfileSyncService::RemoveProtocolEventObserver( void ProfileSyncService::AddTypeDebugInfoObserver( syncer::TypeDebugInfoObserver* type_debug_info_observer) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); type_debug_info_observers_.AddObserver(type_debug_info_observer); if (type_debug_info_observers_.might_have_observers() && engine_initialized_) { @@ -1999,7 +1814,7 @@ void ProfileSyncService::AddTypeDebugInfoObserver( void ProfileSyncService::RemoveTypeDebugInfoObserver( syncer::TypeDebugInfoObserver* type_debug_info_observer) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); type_debug_info_observers_.RemoveObserver(type_debug_info_observer); if (!type_debug_info_observers_.might_have_observers() && engine_initialized_) { @@ -2009,7 +1824,7 @@ void ProfileSyncService::RemoveTypeDebugInfoObserver( void ProfileSyncService::AddPreferenceProvider( syncer::SyncTypePreferenceProvider* provider) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!HasPreferenceProvider(provider)) << "Providers may only be added once!"; preference_providers_.insert(provider); @@ -2017,7 +1832,7 @@ void ProfileSyncService::AddPreferenceProvider( void ProfileSyncService::RemovePreferenceProvider( syncer::SyncTypePreferenceProvider* provider) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(HasPreferenceProvider(provider)) << "Only providers that have been added before can be removed!"; preference_providers_.erase(provider); @@ -2025,7 +1840,7 @@ void ProfileSyncService::RemovePreferenceProvider( bool ProfileSyncService::HasPreferenceProvider( syncer::SyncTypePreferenceProvider* provider) const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return preference_providers_.count(provider) > 0; } @@ -2036,7 +1851,7 @@ class GetAllNodesRequestHelper public: GetAllNodesRequestHelper( syncer::ModelTypeSet requested_types, - const base::Callback<void(std::unique_ptr<base::ListValue>)>& callback); + base::OnceCallback<void(std::unique_ptr<base::ListValue>)> callback); void OnReceivedNodesForType(const syncer::ModelType type, std::unique_ptr<base::ListValue> node_list); @@ -2047,18 +1862,18 @@ class GetAllNodesRequestHelper std::unique_ptr<base::ListValue> result_accumulator_; syncer::ModelTypeSet awaiting_types_; - base::Callback<void(std::unique_ptr<base::ListValue>)> callback_; - base::ThreadChecker thread_checker_; + base::OnceCallback<void(std::unique_ptr<base::ListValue>)> callback_; + SEQUENCE_CHECKER(sequence_checker_); DISALLOW_COPY_AND_ASSIGN(GetAllNodesRequestHelper); }; GetAllNodesRequestHelper::GetAllNodesRequestHelper( syncer::ModelTypeSet requested_types, - const base::Callback<void(std::unique_ptr<base::ListValue>)>& callback) - : result_accumulator_(new base::ListValue()), + base::OnceCallback<void(std::unique_ptr<base::ListValue>)> callback) + : result_accumulator_(std::make_unique<base::ListValue>()), awaiting_types_(requested_types), - callback_(callback) {} + callback_(std::move(callback)) {} GetAllNodesRequestHelper::~GetAllNodesRequestHelper() { if (!awaiting_types_.Empty()) { @@ -2073,20 +1888,20 @@ GetAllNodesRequestHelper::~GetAllNodesRequestHelper() { void GetAllNodesRequestHelper::OnReceivedNodesForType( const syncer::ModelType type, std::unique_ptr<base::ListValue> node_list) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // Add these results to our list. - std::unique_ptr<base::DictionaryValue> type_dict(new base::DictionaryValue()); - type_dict->SetString("type", ModelTypeToString(type)); - type_dict->Set("nodes", std::move(node_list)); - result_accumulator_->Append(std::move(type_dict)); + base::DictionaryValue type_dict; + type_dict.SetKey("type", base::Value(ModelTypeToString(type))); + type_dict.SetKey("nodes", + base::Value::FromUniquePtrValue(std::move(node_list))); + result_accumulator_->GetList().push_back(std::move(type_dict)); // Remember that this part of the request is satisfied. awaiting_types_.Remove(type); if (awaiting_types_.Empty()) { - callback_.Run(std::move(result_accumulator_)); - callback_.Reset(); + std::move(callback_).Run(std::move(result_accumulator_)); } } @@ -2094,42 +1909,46 @@ void GetAllNodesRequestHelper::OnReceivedNodesForType( void ProfileSyncService::GetAllNodes( const base::Callback<void(std::unique_ptr<base::ListValue>)>& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); - ModelTypeSet all_types = GetActiveDataTypes(); - all_types.PutAll(syncer::ControlTypes()); - scoped_refptr<GetAllNodesRequestHelper> helper = - new GetAllNodesRequestHelper(all_types, callback); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // If the engine isn't initialized yet, then there are no nodes to return. if (!engine_initialized_) { - // If there's no engine available to fulfill the request, handle it here. - for (ModelTypeSet::Iterator it = all_types.First(); it.Good(); it.Inc()) { - helper->OnReceivedNodesForType(it.Get(), - std::make_unique<base::ListValue>()); - } + callback.Run(std::make_unique<base::ListValue>()); return; } + ModelTypeSet all_types = GetActiveDataTypes(); + all_types.PutAll(syncer::ControlTypes()); + scoped_refptr<GetAllNodesRequestHelper> helper = + new GetAllNodesRequestHelper(all_types, callback); + for (ModelTypeSet::Iterator it = all_types.First(); it.Good(); it.Inc()) { - const auto& dtc_iter = data_type_controllers_.find(it.Get()); + ModelType type = it.Get(); + const auto dtc_iter = data_type_controllers_.find(type); if (dtc_iter != data_type_controllers_.end()) { - dtc_iter->second->GetAllNodes(base::Bind( + dtc_iter->second->GetAllNodes(base::BindRepeating( &GetAllNodesRequestHelper::OnReceivedNodesForType, helper)); } else { - // Control Types + // Control Types. helper->OnReceivedNodesForType( - it.Get(), + type, syncer::DirectoryDataTypeController::GetAllNodesForTypeFromDirectory( - it.Get(), GetUserShare()->directory.get())); + type, GetUserShare()->directory.get())); } } } +AccountInfo ProfileSyncService::GetAuthenticatedAccountInfo() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + return auth_manager_->GetAuthenticatedAccountInfo(); +} + syncer::GlobalIdMapper* ProfileSyncService::GetGlobalIdMapper() const { return sessions_sync_manager_->GetGlobalIdMapper(); } base::WeakPtr<syncer::JsController> ProfileSyncService::GetJsController() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return sync_js_controller_.AsWeakPtr(); } @@ -2145,31 +1964,31 @@ bool ProfileSyncService::IsSyncAllowedByFlag() { } bool ProfileSyncService::IsSyncAllowedByPlatform() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return platform_sync_allowed_provider_.is_null() || platform_sync_allowed_provider_.Run(); } bool ProfileSyncService::IsManaged() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return sync_prefs_.IsManaged() || sync_disabled_by_admin_; } void ProfileSyncService::RequestStop(SyncStopDataFate data_fate) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); sync_prefs_.SetSyncRequested(false); StopImpl(data_fate); } bool ProfileSyncService::IsSyncRequested() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // When local sync is on sync should be considered requsted or otherwise it // will not resume after the policy or the flag has been removed. return sync_prefs_.IsSyncRequested() || sync_prefs_.IsLocalSyncEnabled(); } void ProfileSyncService::RequestStart() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!IsSyncAllowed()) { // Sync cannot be requested if it's not allowed. return; @@ -2183,7 +2002,7 @@ void ProfileSyncService::RequestStart() { } void ProfileSyncService::ReconfigureDatatypeManager() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // If we haven't initialized yet, don't configure the DTM as it could cause // association to start before a Directory has even been created. if (engine_initialized_) { @@ -2204,16 +2023,15 @@ void ProfileSyncService::ReconfigureDatatypeManager() { syncer::ModelTypeSet ProfileSyncService::GetDataTypesFromPreferenceProviders() const { syncer::ModelTypeSet types; - for (std::set<syncer::SyncTypePreferenceProvider*>::const_iterator it = - preference_providers_.begin(); - it != preference_providers_.end(); ++it) { - types.PutAll((*it)->GetPreferredDataTypes()); + for (const syncer::SyncTypePreferenceProvider* provider : + preference_providers_) { + types.PutAll(provider->GetPreferredDataTypes()); } return types; } const DataTypeStatusTable& ProfileSyncService::data_type_status_table() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return data_type_status_table_; } @@ -2228,42 +2046,47 @@ void ProfileSyncService::OnInternalUnrecoverableError( } bool ProfileSyncService::IsRetryingAccessTokenFetchForTest() const { - DCHECK(thread_checker_.CalledOnValidThread()); - return request_access_token_retry_timer_.IsRunning(); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + return auth_manager_->IsRetryingAccessTokenFetchForTest(); } std::string ProfileSyncService::GetAccessTokenForTest() const { - DCHECK(thread_checker_.CalledOnValidThread()); - return access_token_; + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + return auth_manager_->access_token(); } syncer::SyncableService* ProfileSyncService::GetSessionsSyncableService() { - DCHECK(thread_checker_.CalledOnValidThread()); - return sessions_sync_manager_.get(); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (!sessions_sync_manager_) + return nullptr; + return sessions_sync_manager_->GetSyncableService(); } -syncer::ModelTypeSyncBridge* ProfileSyncService::GetDeviceInfoSyncBridge() { - DCHECK(thread_checker_.CalledOnValidThread()); - return device_info_sync_bridge_.get(); +base::WeakPtr<syncer::ModelTypeControllerDelegate> +ProfileSyncService::GetSessionSyncControllerDelegateOnUIThread() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (!sessions_sync_manager_) + return nullptr; + return sessions_sync_manager_->GetModelTypeSyncBridge() + ->change_processor() + ->GetControllerDelegateOnUIThread(); } -syncer::SyncService::SyncTokenStatus ProfileSyncService::GetSyncTokenStatus() - const { - DCHECK(thread_checker_.CalledOnValidThread()); - SyncTokenStatus status; - status.connection_status_update_time = connection_status_update_time_; - status.connection_status = connection_status_; - status.token_request_time = token_request_time_; - status.token_receive_time = token_receive_time_; - status.last_get_token_error = last_get_token_error_; - if (request_access_token_retry_timer_.IsRunning()) - status.next_token_request_time = next_token_request_time_; - return status; +base::WeakPtr<syncer::ModelTypeControllerDelegate> +ProfileSyncService::GetDeviceInfoSyncControllerDelegateOnUIThread() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + return device_info_sync_bridge_->change_processor() + ->GetControllerDelegateOnUIThread(); +} + +syncer::SyncTokenStatus ProfileSyncService::GetSyncTokenStatus() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + return auth_manager_->GetSyncTokenStatus(); } void ProfileSyncService::OverrideNetworkResourcesForTest( std::unique_ptr<syncer::NetworkResources> network_resources) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); network_resources_ = std::move(network_resources); } @@ -2281,7 +2104,7 @@ void ProfileSyncService::UpdateFirstSyncTimePref() { } void ProfileSyncService::FlushDirectory() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // engine_initialized_ implies engine_ isn't null and the manager exists. // If sync is not initialized yet, we fail silently. if (engine_initialized_) @@ -2289,12 +2112,12 @@ void ProfileSyncService::FlushDirectory() const { } base::FilePath ProfileSyncService::GetDirectoryPathForTest() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return FormatSyncDataPath(base_directory_); } base::MessageLoop* ProfileSyncService::GetSyncLoopForTest() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return sync_thread_ ? sync_thread_->message_loop() : nullptr; } @@ -2312,8 +2135,9 @@ void ProfileSyncService::RemoveClientFromServer() const { if (user_share && user_share->directory.get()) { birthday = user_share->directory->store_birthday(); } - if (!access_token_.empty() && !cache_guid.empty() && !birthday.empty()) { - sync_stopped_reporter_->ReportSyncStopped(access_token_, cache_guid, + const std::string& access_token = auth_manager_->access_token(); + if (!access_token.empty() && !cache_guid.empty() && !birthday.empty()) { + sync_stopped_reporter_->ReportSyncStopped(access_token, cache_guid, birthday); } } @@ -2357,17 +2181,17 @@ void ProfileSyncService::RecordMemoryUsageHistograms() { } const GURL& ProfileSyncService::sync_service_url() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return sync_service_url_; } std::string ProfileSyncService::unrecoverable_error_message() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return unrecoverable_error_message_; } base::Location ProfileSyncService::unrecoverable_error_location() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return unrecoverable_error_location_; } |