diff options
author | Torne (Richard Coles) <torne@google.com> | 2013-05-09 18:35:53 +0100 |
---|---|---|
committer | Torne (Richard Coles) <torne@google.com> | 2013-05-13 13:57:14 +0100 |
commit | c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d (patch) | |
tree | 1dbdbb0624cc869ab25ee7f46971984c6fee3e7a /chrome/browser/sync/profile_sync_service.cc | |
parent | 2d519ce2457219605d4f472da8d2ffd469796035 (diff) | |
download | chromium_org-c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d.tar.gz |
Merge from Chromium at DEPS revision r198571
This commit was generated by merge_to_master.py.
Change-Id: I951118a03836157090561764dd2627f0add8118f
Diffstat (limited to 'chrome/browser/sync/profile_sync_service.cc')
-rw-r--r-- | chrome/browser/sync/profile_sync_service.cc | 192 |
1 files changed, 141 insertions, 51 deletions
diff --git a/chrome/browser/sync/profile_sync_service.cc b/chrome/browser/sync/profile_sync_service.cc index 8db6c45147..2be7544bc5 100644 --- a/chrome/browser/sync/profile_sync_service.cc +++ b/chrome/browser/sync/profile_sync_service.cc @@ -28,6 +28,8 @@ #include "chrome/browser/net/chrome_cookie_notification_details.h" #include "chrome/browser/prefs/pref_service_syncable.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/signin/about_signin_internals.h" +#include "chrome/browser/signin/about_signin_internals_factory.h" #include "chrome/browser/signin/signin_manager.h" #include "chrome/browser/signin/signin_manager_factory.h" #include "chrome/browser/signin/token_service.h" @@ -130,7 +132,7 @@ bool ShouldShowActionOnUI( ProfileSyncService::ProfileSyncService(ProfileSyncComponentsFactory* factory, Profile* profile, - SigninManager* signin_manager, + SigninManagerBase* signin_manager, StartBehavior start_behavior) : last_auth_error_(AuthError::AuthErrorNone()), passphrase_required_reason_(syncer::REASON_PASSPHRASE_NOT_REQUIRED), @@ -140,18 +142,19 @@ ProfileSyncService::ProfileSyncService(ProfileSyncComponentsFactory* factory, sync_prefs_(profile_ ? profile_->GetPrefs() : NULL), invalidator_storage_(profile_ ? profile_->GetPrefs(): NULL), sync_service_url_(kDevServerUrl), + data_type_requested_sync_startup_(false), is_first_time_sync_configure_(false), backend_initialized_(false), is_auth_in_progress_(false), signin_(signin_manager), unrecoverable_error_reason_(ERROR_REASON_UNSET), - weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), + weak_factory_(this), expect_sync_configuration_aborted_(false), encrypted_types_(syncer::SyncEncryptionHandler::SensitiveTypes()), encrypt_everything_(false), encryption_pending_(false), auto_start_enabled_(start_behavior == AUTO_START), - failed_datatypes_handler_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), + failed_datatypes_handler_(this), configure_status_(DataTypeManager::UNKNOWN), setup_in_progress_(false), invalidator_state_(syncer::DEFAULT_INVALIDATION_ERROR) { @@ -199,6 +202,10 @@ bool ProfileSyncService::ShouldEnablePasswordSyncForAndroid() const { sync_prefs_.GetPreferredDataTypes(registered_types); if (!preferred_types.Has(syncer::PASSWORDS)) return false; + // If backend has not completed initializing we cannot check if the + // cryptographer is ready. + if (!sync_initialized()) + return false; // On Android we do not want to prompt user to enter a passphrase. If // passwords cannot be decrypted we just disable them. syncer::ReadTransaction trans(FROM_HERE, GetUserShare()); @@ -301,7 +308,12 @@ void ProfileSyncService::TryStart() { // for performance reasons and maximizing parallelism at chrome startup, we // defer the heavy lifting for sync init until things have calmed down. if (HasSyncSetupCompleted()) { - StartUp(STARTUP_BACKEND_DEFERRED); + if (!data_type_requested_sync_startup_) + StartUp(STARTUP_BACKEND_DEFERRED); + else if (start_up_time_.is_null()) + StartUp(STARTUP_IMMEDIATE); + else + StartUpSlowBackendComponents(); } else if (setup_in_progress_ || auto_start_enabled_) { // We haven't completed sync setup. Start immediately if the user explicitly // kicked this off or we're supposed to automatically start syncing. @@ -310,7 +322,7 @@ void ProfileSyncService::TryStart() { } void ProfileSyncService::StartSyncingWithServer() { - if (backend_.get()) + if (backend_) backend_->StartSyncingWithServer(); } @@ -326,6 +338,9 @@ void ProfileSyncService::RegisterAuthNotifications() { chrome::NOTIFICATION_TOKEN_REQUEST_FAILED, content::Source<TokenService>(token_service)); registrar_.Add(this, + chrome::NOTIFICATION_TOKENS_CLEARED, + content::Source<TokenService>(token_service)); + registrar_.Add(this, chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL, content::Source<Profile>(profile_)); registrar_.Add(this, @@ -355,13 +370,24 @@ browser_sync::SessionModelAssociator* scoped_ptr<browser_sync::DeviceInfo> ProfileSyncService::GetLocalDeviceInfo() const { - DCHECK(sync_initialized()); - browser_sync::SyncedDeviceTracker* device_tracker = - backend_->GetSyncedDeviceTracker(); - if (device_tracker) - return device_tracker->ReadLocalDeviceInfo(); - else - return scoped_ptr<browser_sync::DeviceInfo>(); + if (backend_) { + browser_sync::SyncedDeviceTracker* device_tracker = + backend_->GetSyncedDeviceTracker(); + if (device_tracker) + return device_tracker->ReadLocalDeviceInfo(); + } + return scoped_ptr<browser_sync::DeviceInfo>(); +} + +scoped_ptr<browser_sync::DeviceInfo> +ProfileSyncService::GetDeviceInfo(const std::string& client_id) const { + if (backend_) { + browser_sync::SyncedDeviceTracker* device_tracker = + backend_->GetSyncedDeviceTracker(); + if (device_tracker) + return device_tracker->ReadDeviceInfo(client_id); + } + return scoped_ptr<browser_sync::DeviceInfo>(); } void ProfileSyncService::GetDataTypeControllerStates( @@ -398,8 +424,11 @@ SyncCredentials ProfileSyncService::GetCredentials() { DCHECK(!credentials.email.empty()); TokenService* service = TokenServiceFactory::GetForProfile(profile_); if (service->HasTokenForService(GaiaConstants::kSyncService)) { - credentials.sync_token = service->GetTokenForService( - GaiaConstants::kSyncService); + credentials.sync_token = service->GetTokenForService( + GaiaConstants::kSyncService); + credentials.sync_token_time = + AboutSigninInternalsFactory::GetForProfile(profile_)-> + GetTokenTime(GaiaConstants::kSyncService); UMA_HISTOGRAM_BOOLEAN("Sync.CredentialsLost", false); } else { // We've lost our sync credentials (crbug.com/121755), so just make up some @@ -411,7 +440,7 @@ SyncCredentials ProfileSyncService::GetCredentials() { } void ProfileSyncService::InitializeBackend(bool delete_stale_data) { - if (!backend_.get()) { + if (!backend_) { NOTREACHED(); return; } @@ -474,7 +503,7 @@ void ProfileSyncService::OnSyncConfigureRetry() { void ProfileSyncService::StartUp(StartUpDeferredOption deferred_option) { // Don't start up multiple times. - if (backend_.get()) { + if (backend_) { DVLOG(1) << "Skipping bringing up backend host."; return; } @@ -494,7 +523,7 @@ void ProfileSyncService::StartUp(StartUpDeferredOption deferred_option) { } #endif - if (!sync_global_error_.get()) { + if (!sync_global_error_) { #if !defined(OS_ANDROID) sync_global_error_.reset(new SyncGlobalError(this, signin())); #endif @@ -509,21 +538,56 @@ void ProfileSyncService::StartUp(StartUpDeferredOption deferred_option) { return; } - StartUpSlowBackendComponents(STARTUP_IMMEDIATE); + StartUpSlowBackendComponents(); } -void ProfileSyncService::StartUpSlowBackendComponents( - StartUpDeferredOption deferred_option) { - // Don't start up multiple times. +void ProfileSyncService::OnDataTypeRequestsSyncStartup( + syncer::ModelType type) { + DCHECK(syncer::UserTypes().Has(type)); if (backend_.get()) { - DVLOG(1) << "Skipping bringing up backend host."; + DVLOG(1) << "A data type requested sync startup, but it looks like " + "something else beat it to the punch."; return; } - DCHECK(!start_up_time_.is_null()); - if (deferred_option == STARTUP_BACKEND_DEFERRED) { - base::TimeDelta time_deferred = base::Time::Now() - start_up_time_; - UMA_HISTOGRAM_TIMES("Sync.Startup.TimeDeferred", time_deferred); + if (!GetPreferredDataTypes().Has(type)) { + // We can get here as datatype SyncableServices are typically wired up + // to the native datatype even if sync isn't enabled. + DVLOG(1) << "Dropping sync startup request because type " + << syncer::ModelTypeToString(type) << "not enabled."; + return; + } + + if (CommandLine::ForCurrentProcess()->HasSwitch( + switches::kSyncEnableDeferredStartup)) { + DVLOG(2) << "Data type requesting sync startup: " + << syncer::ModelTypeToString(type); + // Measure the time spent waiting for init and the type that triggered it. + // We could measure the time spent deferred on a per-datatype basis, but + // for now this is probably sufficient. + if (!start_up_time_.is_null()) { + // TODO(tim): Cache |type| and move this tracking to StartUp. I'd like + // to pull all the complicated init logic and state out of + // ProfileSyncService and have only a StartUp method, though. One step + // at a time. Bug 80149. + base::TimeDelta time_deferred = base::Time::Now() - start_up_time_; + UMA_HISTOGRAM_TIMES("Sync.Startup.TimeDeferred", time_deferred); + UMA_HISTOGRAM_ENUMERATION("Sync.Startup.TypeTriggeringInit", + ModelTypeToHistogramInt(type), + syncer::MODEL_TYPE_COUNT); + } + data_type_requested_sync_startup_ = true; + TryStart(); + } + DVLOG(2) << "Ignoring data type request for sync startup: " + << syncer::ModelTypeToString(type); +} + +void ProfileSyncService::StartUpSlowBackendComponents() { + // Don't start up multiple times. + if (backend_) { + DVLOG(1) << "Skipping bringing up backend host."; + return; } DCHECK(IsSyncEnabledAndLoggedIn()); @@ -539,7 +603,7 @@ void ProfileSyncService::StartUpSlowBackendComponents( // // TODO(akalin): Fix this horribly non-intuitive behavior (see // http://crbug.com/140354). - if (backend_.get()) { + if (backend_) { backend_->UpdateRegisteredInvalidationIds( invalidator_registrar_->GetAllRegisteredIds()); for (AckHandleReplayQueue::const_iterator it = ack_replay_queue_.begin(); @@ -562,7 +626,7 @@ void ProfileSyncService::UpdateRegisteredInvalidationIds( // If |backend_| is NULL, its registered IDs will be updated when // it's created and initialized. - if (backend_.get()) { + if (backend_) { backend_->UpdateRegisteredInvalidationIds( invalidator_registrar_->GetAllRegisteredIds()); } @@ -576,7 +640,7 @@ void ProfileSyncService::UnregisterInvalidationHandler( void ProfileSyncService::AcknowledgeInvalidation( const invalidation::ObjectId& id, const syncer::AckHandle& ack_handle) { - if (backend_.get()) { + if (backend_) { backend_->AcknowledgeInvalidation(id, ack_handle); } else { // If |backend_| is NULL, save the acknowledgements to replay when @@ -618,7 +682,7 @@ void ProfileSyncService::ShutdownImpl(bool sync_disabled) { // applying changes to the sync db that wouldn't get applied via // ChangeProcessors, leading to back-from-the-dead bugs. base::Time shutdown_start_time = base::Time::Now(); - if (backend_.get()) { + if (backend_) { backend_->StopSyncingForShutdown(); } @@ -627,7 +691,7 @@ void ProfileSyncService::ShutdownImpl(bool sync_disabled) { // change from a native model. In that case, it will get applied to the sync // database (which doesn't get destroyed until we destroy the backend below) // as an unsynced change. That will be persisted, and committed on restart. - if (data_type_manager_.get()) { + if (data_type_manager_) { if (data_type_manager_->state() != DataTypeManager::STOPPED) { // When aborting as part of shutdown, we should expect an aborted sync // configure result, else we'll dcheck when we try to read the sync error. @@ -645,7 +709,7 @@ void ProfileSyncService::ShutdownImpl(bool sync_disabled) { // Move aside the backend so nobody else tries to use it while we are // shutting it down. scoped_ptr<SyncBackendHost> doomed_backend(backend_.release()); - if (doomed_backend.get()) { + if (doomed_backend) { doomed_backend->Shutdown(sync_disabled); doomed_backend.reset(); @@ -660,7 +724,7 @@ void ProfileSyncService::ShutdownImpl(bool sync_disabled) { is_auth_in_progress_ = false; backend_initialized_ = false; // NULL if we're called from Shutdown(). - if (invalidator_registrar_.get()) + if (invalidator_registrar_) UpdateInvalidatorRegistrarState(); cached_passphrase_.clear(); encryption_pending_ = false; @@ -671,7 +735,7 @@ void ProfileSyncService::ShutdownImpl(bool sync_disabled) { if (last_auth_error_.state() != GoogleServiceAuthError::NONE) UpdateAuthErrorState(GoogleServiceAuthError::AuthErrorNone()); - if (sync_global_error_.get()) { + if (sync_global_error_) { GlobalErrorServiceFactory::GetForProfile(profile_)->RemoveGlobalError( sync_global_error_.get()); RemoveObserver(sync_global_error_.get()); @@ -713,6 +777,8 @@ void ProfileSyncService::NotifyObservers() { void ProfileSyncService::ClearStaleErrors() { ClearUnrecoverableError(); last_actionable_error_ = SyncProtocolError(); + // Clear the data type errors as well. + failed_datatypes_handler_.OnUserChoseDatatypes(); } void ProfileSyncService::ClearUnrecoverableError() { @@ -726,7 +792,7 @@ void ProfileSyncService::ClearUnrecoverableError() { std::string ProfileSyncService::GetExperimentNameForDataType( syncer::ModelType data_type) { NOTREACHED(); - return ""; + return std::string(); } void ProfileSyncService::RegisterNewDataType(syncer::ModelType data_type) { @@ -950,7 +1016,7 @@ void ProfileSyncService::OnExperimentsChanged( // Only automatically turn on types if we have already finished set up. // Otherwise, just leave the experimental types on by default. - if (!to_register.Empty() && HasSyncSetupCompleted() && migrator_.get()) { + if (!to_register.Empty() && HasSyncSetupCompleted() && migrator_) { DVLOG(1) << "Dynamically enabling new datatypes: " << syncer::ModelTypeSetToString(to_register); OnMigrationNeededForTypes(to_register); @@ -964,12 +1030,6 @@ void ProfileSyncService::OnExperimentsChanged( true); } - if (experiments.full_history_sync) { - about_flags::SetExperimentEnabled(g_browser_process->local_state(), - syncer::kFullHistorySyncFlag, - true); - } - if (experiments.favicon_sync) { about_flags::SetExperimentEnabled(g_browser_process->local_state(), syncer::kFaviconSyncFlag, @@ -1078,7 +1138,7 @@ void ProfileSyncService::OnPassphraseAccepted() { // this time. const syncer::ModelTypeSet types = GetPreferredDataTypes(); - if (data_type_manager_.get()) { + if (data_type_manager_) { // Unblock the data type manager if necessary. data_type_manager_->Configure(types, syncer::CONFIGURE_REASON_RECONFIGURATION); @@ -1097,6 +1157,15 @@ void ProfileSyncService::OnEncryptedTypesChanged( << " (encrypt everything is set to " << (encrypt_everything_ ? "true" : "false") << ")"; DCHECK(encrypted_types_.Has(syncer::PASSWORDS)); + + // If sessions are encrypted, full history sync is not possible, and + // delete directives are unnecessary. + if (GetPreferredDataTypes().Has(syncer::HISTORY_DELETE_DIRECTIVES) && + encrypted_types_.Has(syncer::SESSIONS)) { + DisableBrokenDatatype(syncer::HISTORY_DELETE_DIRECTIVES, + FROM_HERE, + "Delete directives not supported with encryption."); + } } void ProfileSyncService::OnEncryptionComplete() { @@ -1269,7 +1338,7 @@ void ProfileSyncService::OnConfigureStart() { std::string ProfileSyncService::QuerySyncStatusSummary() { if (HasUnrecoverableError()) { return "Unrecoverable error detected"; - } else if (!backend_.get()) { + } else if (!backend_) { return "Syncing not enabled"; } else if (backend_.get() && !HasSyncSetupCompleted()) { return "First time sync setup incomplete"; @@ -1394,7 +1463,7 @@ const browser_sync::user_selectable_type::UserSelectableSyncType browser_sync::user_selectable_type::PROXY_TABS }; - COMPILE_ASSERT(26 == syncer::MODEL_TYPE_COUNT, UpdateCustomConfigHistogram); + COMPILE_ASSERT(27 == syncer::MODEL_TYPE_COUNT, UpdateCustomConfigHistogram); if (!sync_everything) { const syncer::ModelTypeSet current_types = GetPreferredDataTypes(); @@ -1513,6 +1582,17 @@ SyncBackendHost* ProfileSyncService::GetBackendForTest() { return backend_.get(); } +void ProfileSyncService::ConfigurePriorityDataTypes() { + const syncer::ModelTypeSet priority_types = + Intersection(GetPreferredDataTypes(), syncer::PriorityUserTypes()); + if (!priority_types.Empty()) { + const syncer::ConfigureReason reason = HasSyncSetupCompleted() ? + syncer::CONFIGURE_REASON_RECONFIGURATION : + syncer::CONFIGURE_REASON_NEW_CLIENT; + data_type_manager_->Configure(priority_types, reason); + } +} + void ProfileSyncService::ConfigureDataTypeManager() { // Don't configure datatypes if the setup UI is still on the screen - this // is to help multi-screen setting UIs (like iOS) where they don't want to @@ -1523,7 +1603,7 @@ void ProfileSyncService::ConfigureDataTypeManager() { return; bool restart = false; - if (!data_type_manager_.get()) { + if (!data_type_manager_) { restart = true; data_type_manager_.reset( factory_->CreateDataTypeManager(debug_info_listener_, @@ -1541,6 +1621,9 @@ void ProfileSyncService::ConfigureDataTypeManager() { base::Unretained(this)))); } + // This is probably where we want to trigger configuration of priority + // datatypes, but we need to resolve crbug.com/226195 first. + #if defined(OS_ANDROID) if (GetPreferredDataTypes().Has(syncer::PASSWORDS) && !ShouldEnablePasswordSyncForAndroid()) { @@ -1700,7 +1783,7 @@ Value* ProfileSyncService::GetTypeStatusMap() const { void ProfileSyncService::ActivateDataType( syncer::ModelType type, syncer::ModelSafeGroup group, ChangeProcessor* change_processor) { - if (!backend_.get()) { + if (!backend_) { NOTREACHED(); return; } @@ -1709,7 +1792,7 @@ void ProfileSyncService::ActivateDataType( } void ProfileSyncService::DeactivateDataType(syncer::ModelType type) { - if (!backend_.get()) + if (!backend_) return; backend_->DeactivateDataType(type); } @@ -1872,12 +1955,19 @@ void ProfileSyncService::Observe(int type, // Initialize the backend if sync is enabled. If the sync token was // not loaded, GetCredentials() will generate invalid credentials to // cause the backend to generate an auth error (crbug.com/121755). - if (backend_.get()) + if (backend_) backend_->UpdateCredentials(GetCredentials()); else TryStart(); break; } + case chrome::NOTIFICATION_TOKENS_CLEARED: { + // GetCredentials() will generate invalid credentials to cause the backend + // to generate an auth error. + if (backend_) + backend_->UpdateCredentials(GetCredentials()); + break; + } case chrome::NOTIFICATION_GOOGLE_SIGNED_OUT: // Disable sync if the user is signed out. DisableForUser(); @@ -1926,7 +2016,7 @@ bool ProfileSyncService::ShouldPushChanges() { if (HasUnrecoverableError()) return false; - if (!data_type_manager_.get()) + if (!data_type_manager_) return false; return data_type_manager_->state() == DataTypeManager::CONFIGURED; @@ -2002,7 +2092,7 @@ void ProfileSyncService::UpdateInvalidatorRegistrarState() { void ProfileSyncService::ResetForTest() { Profile* profile = profile_; - SigninManager* signin = SigninManagerFactory::GetForProfile(profile); + SigninManagerBase* signin = SigninManagerFactory::GetForProfile(profile); ProfileSyncService::StartBehavior behavior = browser_defaults::kSyncAutoStarts ? ProfileSyncService::AUTO_START : ProfileSyncService::MANUAL_START; |