Index: chrome/browser/sync/glue/sync_backend_host.cc |
diff --git a/chrome/browser/sync/glue/sync_backend_host.cc b/chrome/browser/sync/glue/sync_backend_host.cc |
index ac98e9990c07552b58e82bbb28ebc05d03c406f6..c4f3e95a4b6007dda265d8cb89f94e7d295b9923 100644 |
--- a/chrome/browser/sync/glue/sync_backend_host.cc |
+++ b/chrome/browser/sync/glue/sync_backend_host.cc |
@@ -60,30 +60,31 @@ using sync_api::SyncCredentials; |
SyncBackendHost::SyncBackendHost(const std::string& name, |
Profile* profile, |
const base::WeakPtr<SyncPrefs>& sync_prefs) |
- : core_(new Core(name, ALLOW_THIS_IN_INITIALIZER_LIST(this))), |
- initialization_state_(NOT_ATTEMPTED), |
+ : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
sync_thread_("Chrome_SyncThread"), |
frontend_loop_(MessageLoop::current()), |
profile_(profile), |
- sync_prefs_(sync_prefs), |
name_(name), |
+ core_(new Core(name, profile_->GetPath().Append(kSyncDataFolderName), |
+ weak_ptr_factory_.GetWeakPtr())), |
+ initialization_state_(NOT_ATTEMPTED), |
+ sync_prefs_(sync_prefs), |
sync_notifier_factory_( |
content::GetUserAgent(GURL()), |
profile_->GetRequestContext(), |
sync_prefs, |
*CommandLine::ForCurrentProcess()), |
frontend_(NULL), |
- sync_data_folder_path_( |
- profile_->GetPath().Append(kSyncDataFolderName)), |
last_auth_error_(AuthError::None()) { |
} |
SyncBackendHost::SyncBackendHost() |
- : initialization_state_(NOT_ATTEMPTED), |
+ : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
sync_thread_("Chrome_SyncThread"), |
frontend_loop_(MessageLoop::current()), |
profile_(NULL), |
name_("Unknown"), |
+ initialization_state_(NOT_ATTEMPTED), |
sync_notifier_factory_( |
content::GetUserAgent(GURL()), |
NULL, |
@@ -98,6 +99,15 @@ SyncBackendHost::~SyncBackendHost() { |
DCHECK(!registrar_.get()); |
} |
+namespace { |
+ |
+sync_api::HttpPostProviderFactory* MakeHttpBridgeFactory( |
+ const scoped_refptr<net::URLRequestContextGetter>& getter) { |
+ return new HttpBridgeFactory(getter); |
+} |
+ |
+} // namespace |
+ |
void SyncBackendHost::Initialize( |
SyncFrontend* frontend, |
const WeakHandle<JsEventHandler>& event_handler, |
@@ -122,23 +132,20 @@ void SyncBackendHost::Initialize( |
profile_, |
sync_thread_.message_loop())); |
initialization_state_ = CREATING_SYNC_MANAGER; |
- InitCore(Core::DoInitializeOptions( |
+ InitCore(DoInitializeOptions( |
sync_thread_.message_loop(), |
registrar_.get(), |
event_handler, |
sync_service_url, |
- profile_->GetRequestContext(), |
+ base::Bind(&MakeHttpBridgeFactory, |
+ make_scoped_refptr(profile_->GetRequestContext())), |
credentials, |
+ &sync_notifier_factory_, |
delete_sync_data_folder, |
sync_prefs_->GetEncryptionBootstrapToken(), |
false)); |
} |
-void SyncBackendHost::InitCore(const Core::DoInitializeOptions& options) { |
- sync_thread_.message_loop()->PostTask(FROM_HERE, |
- base::Bind(&SyncBackendHost::Core::DoInitialize, core_.get(),options)); |
-} |
- |
void SyncBackendHost::UpdateCredentials(const SyncCredentials& credentials) { |
sync_thread_.message_loop()->PostTask(FROM_HERE, |
base::Bind(&SyncBackendHost::Core::DoUpdateCredentials, core_.get(), |
@@ -380,13 +387,175 @@ void SyncBackendHost::GetModelSafeRoutingInfo( |
} |
} |
+void SyncBackendHost::InitCore(const DoInitializeOptions& options) { |
+ sync_thread_.message_loop()->PostTask(FROM_HERE, |
+ base::Bind(&SyncBackendHost::Core::DoInitialize, core_.get(),options)); |
+} |
+ |
+void SyncBackendHost::HandleSyncCycleCompletedOnFrontendLoop( |
+ SyncSessionSnapshot* snapshot) { |
+ if (!frontend_) |
+ return; |
+ DCHECK_EQ(MessageLoop::current(), frontend_loop_); |
+ |
+ last_snapshot_.reset(snapshot); |
+ |
+ SDVLOG(1) << "Got snapshot " << snapshot->ToString(); |
+ |
+ const syncable::ModelTypeSet to_migrate = |
+ snapshot->syncer_status.types_needing_local_migration; |
+ if (!to_migrate.Empty()) |
+ frontend_->OnMigrationNeededForTypes(to_migrate); |
+ |
+ // Process any changes to the datatypes we're syncing. |
+ // TODO(sync): add support for removing types. |
+ if (initialized()) |
+ AddExperimentalTypes(); |
+ |
+ // If we are waiting for a configuration change, check here to see |
+ // if this sync cycle has initialized all of the types we've been |
+ // waiting for. |
+ if (pending_download_state_.get()) { |
+ scoped_ptr<PendingConfigureDataTypesState> state( |
+ pending_download_state_.release()); |
+ const syncable::ModelTypeSet types_to_add = state->types_to_add; |
+ const syncable::ModelTypeSet added_types = state->added_types; |
+ DCHECK(types_to_add.HasAll(added_types)); |
+ const syncable::ModelTypeSet initial_sync_ended = |
+ snapshot->initial_sync_ended; |
+ const syncable::ModelTypeSet failed_configuration_types = |
+ Difference(added_types, initial_sync_ended); |
+ SDVLOG(1) |
+ << "Added types: " |
+ << syncable::ModelTypeSetToString(added_types) |
+ << ", configured types: " |
+ << syncable::ModelTypeSetToString(initial_sync_ended) |
+ << ", failed configuration types: " |
+ << syncable::ModelTypeSetToString(failed_configuration_types); |
+ state->ready_task.Run(failed_configuration_types); |
+ if (!failed_configuration_types.Empty()) |
+ return; |
+ } |
+ |
+ if (initialized()) |
+ frontend_->OnSyncCycleCompleted(); |
+} |
+ |
+void SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop() { |
+ DCHECK_EQ(MessageLoop::current(), frontend_loop_); |
+ // Nudge the syncer. This is necessary for both datatype addition/deletion. |
+ // |
+ // Deletions need a nudge in order to ensure the deletion occurs in a timely |
+ // manner (see issue 56416). |
+ // |
+ // In the case of additions, on the next sync cycle, the syncer should |
+ // notice that the routing info has changed and start the process of |
+ // downloading updates for newly added data types. Once this is |
+ // complete, the configure_state_.ready_task_ is run via an |
+ // OnInitializationComplete notification. |
+ |
+ SDVLOG(1) << "Syncer in config mode. SBH executing " |
+ << "FinishConfigureDataTypesOnFrontendLoop"; |
+ |
+ if (pending_config_mode_state_->added_types.Empty() && |
+ !core_->sync_manager()->InitialSyncEndedForAllEnabledTypes()) { |
+ |
+ syncable::ModelTypeSet enabled_types; |
+ ModelSafeRoutingInfo routing_info; |
+ registrar_->GetModelSafeRoutingInfo(&routing_info); |
+ for (ModelSafeRoutingInfo::const_iterator i = routing_info.begin(); |
+ i != routing_info.end(); ++i) { |
+ enabled_types.Put(i->first); |
+ } |
+ |
+ // TODO(tim): Log / UMA / count this somehow? |
+ // Add only the types with empty progress markers. Note: it is possible |
+ // that some types have their initial_sync_ended be false but with non |
+ // empty progress marker. Which is ok as the rest of the changes would |
+ // be downloaded on a regular nudge and initial_sync_ended should be set |
+ // to true. However this is a very corner case. So it is not explicitly |
+ // handled. |
+ pending_config_mode_state_->added_types = |
+ sync_api::GetTypesWithEmptyProgressMarkerToken(enabled_types, |
+ GetUserShare()); |
+ } |
+ |
+ // If we've added types, we always want to request a nudge/config (even if |
+ // the initial sync is ended), in case we could not decrypt the data. |
+ if (pending_config_mode_state_->added_types.Empty()) { |
+ SDVLOG(1) << "No new types added; calling ready_task directly"; |
+ // No new types - just notify the caller that the types are available. |
+ const syncable::ModelTypeSet failed_configuration_types; |
+ pending_config_mode_state_->ready_task.Run(failed_configuration_types); |
+ } else { |
+ pending_download_state_.reset(pending_config_mode_state_.release()); |
+ |
+ // Always configure nigori if it's enabled. |
+ syncable::ModelTypeSet types_to_config = |
+ pending_download_state_->added_types; |
+ if (IsNigoriEnabled()) { |
+ // Note: Nigori is the only type that gets added with a nonempty |
+ // progress marker during config. If the server returns a migration |
+ // error then we will go into unrecoverable error. We dont handle it |
+ // explicitly because server might help us out here by not sending a |
+ // migraiton error for nigori during config. |
+ types_to_config.Put(syncable::NIGORI); |
+ } |
+ SDVLOG(1) << "Types " |
+ << syncable::ModelTypeSetToString(types_to_config) |
+ << " added; calling DoRequestConfig"; |
+ sync_thread_.message_loop()->PostTask(FROM_HERE, |
+ base::Bind(&SyncBackendHost::Core::DoRequestConfig, |
+ core_.get(), |
+ types_to_config, |
+ pending_download_state_->reason)); |
+ } |
+ |
+ pending_config_mode_state_.reset(); |
+ |
+ // Notify the SyncManager about the new types. |
+ sync_thread_.message_loop()->PostTask(FROM_HERE, |
+ base::Bind(&SyncBackendHost::Core::DoUpdateEnabledTypes, core_.get())); |
+} |
+ |
+bool SyncBackendHost::IsDownloadingNigoriForTest() const { |
+ return initialization_state_ == DOWNLOADING_NIGORI; |
+} |
+ |
+SyncBackendHost::DoInitializeOptions::DoInitializeOptions( |
+ MessageLoop* sync_loop, |
+ SyncBackendRegistrar* registrar, |
+ const WeakHandle<JsEventHandler>& event_handler, |
+ const GURL& service_url, |
+ MakeHttpBridgeFactoryFn make_http_bridge_factory_fn, |
+ const sync_api::SyncCredentials& credentials, |
+ sync_notifier::SyncNotifierFactory* sync_notifier_factory, |
+ bool delete_sync_data_folder, |
+ const std::string& restored_key_for_bootstrapping, |
+ bool setup_for_test_mode) |
+ : sync_loop(sync_loop), |
+ registrar(registrar), |
+ event_handler(event_handler), |
+ service_url(service_url), |
+ make_http_bridge_factory_fn(make_http_bridge_factory_fn), |
+ credentials(credentials), |
+ sync_notifier_factory(sync_notifier_factory), |
+ delete_sync_data_folder(delete_sync_data_folder), |
+ restored_key_for_bootstrapping(restored_key_for_bootstrapping), |
+ setup_for_test_mode(setup_for_test_mode) { |
+} |
+ |
+SyncBackendHost::DoInitializeOptions::~DoInitializeOptions() {} |
+ |
SyncBackendHost::Core::Core(const std::string& name, |
- SyncBackendHost* backend) |
+ const FilePath& sync_data_folder_path, |
+ const base::WeakPtr<SyncBackendHost>& backend) |
: name_(name), |
+ sync_data_folder_path_(sync_data_folder_path), |
host_(backend), |
sync_loop_(NULL), |
registrar_(NULL) { |
- DCHECK(host_); |
+ DCHECK(backend.get()); |
} |
SyncBackendHost::Core::~Core() { |
@@ -394,15 +563,22 @@ SyncBackendHost::Core::~Core() { |
DCHECK(!sync_loop_); |
} |
+SyncBackendHost::PendingConfigureDataTypesState:: |
+PendingConfigureDataTypesState() |
+ : reason(sync_api::CONFIGURE_REASON_UNKNOWN) {} |
+ |
+SyncBackendHost::PendingConfigureDataTypesState:: |
+~PendingConfigureDataTypesState() {} |
+ |
void SyncBackendHost::Core::OnSyncCycleCompleted( |
const SyncSessionSnapshot* snapshot) { |
if (!sync_loop_) |
return; |
DCHECK_EQ(MessageLoop::current(), sync_loop_); |
- host_->frontend_loop_->PostTask(FROM_HERE, base::Bind( |
- &Core::HandleSyncCycleCompletedOnFrontendLoop, |
- this, |
- new SyncSessionSnapshot(*snapshot))); |
+ host_.Call( |
+ FROM_HERE, |
+ &SyncBackendHost::HandleSyncCycleCompletedOnFrontendLoop, |
+ new SyncSessionSnapshot(*snapshot)); |
} |
@@ -410,10 +586,10 @@ void SyncBackendHost::Core::OnInitializationComplete( |
const WeakHandle<JsBackend>& js_backend, |
bool success) { |
DCHECK_EQ(MessageLoop::current(), sync_loop_); |
- |
- host_->frontend_loop_->PostTask(FROM_HERE, |
- base::Bind(&Core::HandleInitializationCompletedOnFrontendLoop, this, |
- js_backend, success)); |
+ host_.Call( |
+ FROM_HERE, |
+ &SyncBackendHost::HandleInitializationCompletedOnFrontendLoop, |
+ js_backend, success); |
if (success) { |
// Initialization is complete, so we can schedule recurring SaveChanges. |
@@ -426,9 +602,9 @@ void SyncBackendHost::Core::OnAuthError(const AuthError& auth_error) { |
if (!sync_loop_) |
return; |
DCHECK_EQ(MessageLoop::current(), sync_loop_); |
- // Post to our core loop so we can modify state. Could be on another thread. |
- host_->frontend_loop_->PostTask(FROM_HERE, |
- base::Bind(&Core::HandleAuthErrorEventOnFrontendLoop, this, auth_error)); |
+ host_.Call( |
+ FROM_HERE, |
+ &SyncBackendHost::HandleAuthErrorEventOnFrontendLoop, auth_error); |
} |
void SyncBackendHost::Core::OnPassphraseRequired( |
@@ -436,8 +612,9 @@ void SyncBackendHost::Core::OnPassphraseRequired( |
if (!sync_loop_) |
return; |
DCHECK_EQ(MessageLoop::current(), sync_loop_); |
- host_->frontend_loop_->PostTask(FROM_HERE, |
- base::Bind(&Core::NotifyPassphraseRequired, this, reason)); |
+ host_.Call( |
+ FROM_HERE, |
+ &SyncBackendHost::NotifyPassphraseRequired, reason); |
} |
void SyncBackendHost::Core::OnPassphraseAccepted( |
@@ -445,40 +622,45 @@ void SyncBackendHost::Core::OnPassphraseAccepted( |
if (!sync_loop_) |
return; |
DCHECK_EQ(MessageLoop::current(), sync_loop_); |
- host_->frontend_loop_->PostTask(FROM_HERE, |
- base::Bind(&Core::NotifyPassphraseAccepted, this, bootstrap_token)); |
+ host_.Call( |
+ FROM_HERE, |
+ &SyncBackendHost::NotifyPassphraseAccepted, bootstrap_token); |
} |
void SyncBackendHost::Core::OnStopSyncingPermanently() { |
if (!sync_loop_) |
return; |
DCHECK_EQ(MessageLoop::current(), sync_loop_); |
- host_->frontend_loop_->PostTask(FROM_HERE, base::Bind( |
- &Core::HandleStopSyncingPermanentlyOnFrontendLoop, this)); |
+ host_.Call( |
+ FROM_HERE, |
+ &SyncBackendHost::HandleStopSyncingPermanentlyOnFrontendLoop); |
} |
void SyncBackendHost::Core::OnUpdatedToken(const std::string& token) { |
if (!sync_loop_) |
return; |
DCHECK_EQ(MessageLoop::current(), sync_loop_); |
- host_->frontend_loop_->PostTask(FROM_HERE, base::Bind( |
- &Core::NotifyUpdatedToken, this, token)); |
+ host_.Call( |
+ FROM_HERE, |
+ &SyncBackendHost::NotifyUpdatedToken, token); |
} |
void SyncBackendHost::Core::OnClearServerDataFailed() { |
if (!sync_loop_) |
return; |
DCHECK_EQ(MessageLoop::current(), sync_loop_); |
- host_->frontend_loop_->PostTask(FROM_HERE, base::Bind( |
- &Core::HandleClearServerDataFailedOnFrontendLoop, this)); |
+ host_.Call( |
+ FROM_HERE, |
+ &SyncBackendHost::HandleClearServerDataFailedOnFrontendLoop); |
} |
void SyncBackendHost::Core::OnClearServerDataSucceeded() { |
if (!sync_loop_) |
return; |
DCHECK_EQ(MessageLoop::current(), sync_loop_); |
- host_->frontend_loop_->PostTask(FROM_HERE, base::Bind( |
- &Core::HandleClearServerDataSucceededOnFrontendLoop, this)); |
+ host_.Call( |
+ FROM_HERE, |
+ &SyncBackendHost::HandleClearServerDataSucceededOnFrontendLoop); |
} |
void SyncBackendHost::Core::OnEncryptedTypesChanged( |
@@ -488,10 +670,10 @@ void SyncBackendHost::Core::OnEncryptedTypesChanged( |
return; |
DCHECK_EQ(MessageLoop::current(), sync_loop_); |
// NOTE: We're in a transaction. |
- host_->frontend_loop_->PostTask( |
+ host_.Call( |
FROM_HERE, |
- base::Bind(&Core::NotifyEncryptedTypesChanged, this, |
- encrypted_types, encrypt_everything)); |
+ &SyncBackendHost::NotifyEncryptedTypesChanged, |
+ encrypted_types, encrypt_everything); |
} |
void SyncBackendHost::Core::OnEncryptionComplete() { |
@@ -499,9 +681,9 @@ void SyncBackendHost::Core::OnEncryptionComplete() { |
return; |
DCHECK_EQ(MessageLoop::current(), sync_loop_); |
// NOTE: We're in a transaction. |
- host_->frontend_loop_->PostTask( |
+ host_.Call( |
FROM_HERE, |
- base::Bind(&Core::NotifyEncryptionComplete, this)); |
+ &SyncBackendHost::NotifyEncryptionComplete); |
} |
void SyncBackendHost::Core::OnActionableError( |
@@ -509,36 +691,12 @@ void SyncBackendHost::Core::OnActionableError( |
if (!sync_loop_) |
return; |
DCHECK_EQ(MessageLoop::current(), sync_loop_); |
- host_->frontend_loop_->PostTask( |
+ host_.Call( |
FROM_HERE, |
- base::Bind(&Core::HandleActionableErrorEventOnFrontendLoop, this, |
- sync_error)); |
+ &SyncBackendHost::HandleActionableErrorEventOnFrontendLoop, |
+ sync_error); |
} |
-SyncBackendHost::Core::DoInitializeOptions::DoInitializeOptions( |
- MessageLoop* sync_loop, |
- SyncBackendRegistrar* registrar, |
- const WeakHandle<JsEventHandler>& event_handler, |
- const GURL& service_url, |
- const scoped_refptr<net::URLRequestContextGetter>& |
- request_context_getter, |
- const sync_api::SyncCredentials& credentials, |
- bool delete_sync_data_folder, |
- const std::string& restored_key_for_bootstrapping, |
- bool setup_for_test_mode) |
- : sync_loop(sync_loop), |
- registrar(registrar), |
- event_handler(event_handler), |
- service_url(service_url), |
- request_context_getter(request_context_getter), |
- credentials(credentials), |
- delete_sync_data_folder(delete_sync_data_folder), |
- restored_key_for_bootstrapping(restored_key_for_bootstrapping), |
- setup_for_test_mode(setup_for_test_mode) { |
-} |
- |
-SyncBackendHost::Core::DoInitializeOptions::~DoInitializeOptions() {} |
- |
// Helper to construct a user agent string (ASCII) suitable for use by |
// the syncapi for any HTTP communication. This string is used by the sync |
// backend for classifying client types when calculating statistics. |
@@ -582,7 +740,7 @@ void SyncBackendHost::Core::DoInitialize(const DoInitializeOptions& options) { |
// Make sure that the directory exists before initializing the backend. |
// If it already exists, this will do no harm. |
- bool success = file_util::CreateDirectory(host_->sync_data_folder_path()); |
+ bool success = file_util::CreateDirectory(sync_data_folder_path_); |
DCHECK(success); |
DCHECK(!registrar_); |
@@ -591,19 +749,18 @@ void SyncBackendHost::Core::DoInitialize(const DoInitializeOptions& options) { |
sync_manager_.reset(new sync_api::SyncManager(name_)); |
sync_manager_->AddObserver(this); |
- const FilePath& path_str = host_->sync_data_folder_path(); |
success = sync_manager_->Init( |
- path_str, |
+ sync_data_folder_path_, |
options.event_handler, |
options.service_url.host() + options.service_url.path(), |
options.service_url.EffectiveIntPort(), |
options.service_url.SchemeIsSecure(), |
- host_->MakeHttpBridgeFactory(options.request_context_getter), |
+ options.make_http_bridge_factory_fn.Run(), |
options.registrar /* as ModelSafeWorkerRegistrar */, |
options.registrar /* as SyncManager::ChangeDelegate */, |
MakeUserAgentForSyncApi(), |
options.credentials, |
- host_->sync_notifier_factory_.CreateSyncNotifier(), |
+ options.sync_notifier_factory->CreateSyncNotifier(), |
options.restored_key_for_bootstrapping, |
options.setup_for_test_mode); |
LOG_IF(ERROR, !success) << "Syncapi initialization failed!"; |
@@ -680,7 +837,7 @@ void SyncBackendHost::Core::DoShutdown(bool sync_disabled) { |
sync_loop_ = NULL; |
- host_ = NULL; |
+ host_.Reset(); |
} |
void SyncBackendHost::Core::DoRequestConfig( |
@@ -698,35 +855,17 @@ void SyncBackendHost::Core::DoStartConfiguration( |
void SyncBackendHost::Core::DeleteSyncDataFolder() { |
DCHECK_EQ(MessageLoop::current(), sync_loop_); |
- if (file_util::DirectoryExists(host_->sync_data_folder_path())) { |
- if (!file_util::Delete(host_->sync_data_folder_path(), true)) |
+ if (file_util::DirectoryExists(sync_data_folder_path_)) { |
+ if (!file_util::Delete(sync_data_folder_path_, true)) |
SLOG(DFATAL) << "Could not delete the Sync Data folder."; |
} |
} |
void SyncBackendHost::Core::FinishConfigureDataTypes() { |
DCHECK_EQ(MessageLoop::current(), sync_loop_); |
- if (!host_ || !host_->frontend_) |
- return; |
- host_->frontend_loop_->PostTask(FROM_HERE, base::Bind( |
- &SyncBackendHost::Core::FinishConfigureDataTypesOnFrontendLoop, this)); |
-} |
- |
-void SyncBackendHost::Core::HandleInitializationCompletedOnFrontendLoop( |
- const WeakHandle<JsBackend>& js_backend, |
- bool success) { |
- if (!host_) |
- return; |
- host_->HandleInitializationCompletedOnFrontendLoop(js_backend, success); |
-} |
- |
-void SyncBackendHost::Core::HandleNigoriConfigurationCompletedOnFrontendLoop( |
- const WeakHandle<JsBackend>& js_backend, |
- const syncable::ModelTypeSet failed_configuration_types) { |
- if (!host_) |
- return; |
- host_->HandleInitializationCompletedOnFrontendLoop( |
- js_backend, failed_configuration_types.Empty()); |
+ host_.Call( |
+ FROM_HERE, |
+ &SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop); |
} |
void SyncBackendHost::Core::StartSavingChanges() { |
@@ -744,147 +883,6 @@ void SyncBackendHost::Core::SaveChanges() { |
sync_manager_->SaveChanges(); |
} |
-void SyncBackendHost::Core::HandleActionableErrorEventOnFrontendLoop( |
- const browser_sync::SyncProtocolError& sync_error) { |
- if (!host_ || !host_->frontend_) |
- return; |
- DCHECK_EQ(MessageLoop::current(), host_->frontend_loop_); |
- host_->frontend_->OnActionableError(sync_error); |
-} |
- |
-void SyncBackendHost::Core::HandleAuthErrorEventOnFrontendLoop( |
- const GoogleServiceAuthError& new_auth_error) { |
- if (!host_ || !host_->frontend_) |
- return; |
- |
- DCHECK_EQ(MessageLoop::current(), host_->frontend_loop_); |
- |
- host_->last_auth_error_ = new_auth_error; |
- host_->frontend_->OnAuthError(); |
-} |
- |
-void SyncBackendHost::Core::NotifyPassphraseRequired( |
- sync_api::PassphraseRequiredReason reason) { |
- if (!host_ || !host_->frontend_) |
- return; |
- |
- DCHECK_EQ(MessageLoop::current(), host_->frontend_loop_); |
- |
- host_->frontend_->OnPassphraseRequired(reason); |
-} |
- |
-void SyncBackendHost::Core::NotifyPassphraseAccepted( |
- const std::string& bootstrap_token) { |
- if (!host_ || !host_->frontend_) |
- return; |
- |
- DCHECK_EQ(MessageLoop::current(), host_->frontend_loop_); |
- |
- host_->PersistEncryptionBootstrapToken(bootstrap_token); |
- host_->frontend_->OnPassphraseAccepted(); |
-} |
- |
-void SyncBackendHost::Core::NotifyUpdatedToken(const std::string& token) { |
- if (!host_) |
- return; |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- TokenAvailableDetails details(GaiaConstants::kSyncService, token); |
- content::NotificationService::current()->Notify( |
- chrome::NOTIFICATION_TOKEN_UPDATED, |
- content::Source<Profile>(host_->profile_), |
- content::Details<const TokenAvailableDetails>(&details)); |
-} |
- |
-void SyncBackendHost::Core::NotifyEncryptedTypesChanged( |
- syncable::ModelTypeSet encrypted_types, |
- bool encrypt_everything) { |
- if (!host_) |
- return; |
- DCHECK_EQ(MessageLoop::current(), host_->frontend_loop_); |
- host_->frontend_->OnEncryptedTypesChanged( |
- encrypted_types, encrypt_everything); |
-} |
- |
-void SyncBackendHost::Core::NotifyEncryptionComplete() { |
- if (!host_) |
- return; |
- DCHECK_EQ(MessageLoop::current(), host_->frontend_loop_); |
- host_->frontend_->OnEncryptionComplete(); |
-} |
- |
-void SyncBackendHost::Core::HandleSyncCycleCompletedOnFrontendLoop( |
- SyncSessionSnapshot* snapshot) { |
- if (!host_ || !host_->frontend_) |
- return; |
- DCHECK_EQ(MessageLoop::current(), host_->frontend_loop_); |
- |
- host_->last_snapshot_.reset(snapshot); |
- |
- SDVLOG(1) << "Got snapshot " << snapshot->ToString(); |
- |
- const syncable::ModelTypeSet to_migrate = |
- snapshot->syncer_status.types_needing_local_migration; |
- if (!to_migrate.Empty()) |
- host_->frontend_->OnMigrationNeededForTypes(to_migrate); |
- |
- // Process any changes to the datatypes we're syncing. |
- // TODO(sync): add support for removing types. |
- if (host_->initialized()) |
- host_->AddExperimentalTypes(); |
- |
- // If we are waiting for a configuration change, check here to see |
- // if this sync cycle has initialized all of the types we've been |
- // waiting for. |
- if (host_->pending_download_state_.get()) { |
- scoped_ptr<PendingConfigureDataTypesState> state( |
- host_->pending_download_state_.release()); |
- const syncable::ModelTypeSet types_to_add = state->types_to_add; |
- const syncable::ModelTypeSet added_types = state->added_types; |
- DCHECK(types_to_add.HasAll(added_types)); |
- const syncable::ModelTypeSet initial_sync_ended = |
- snapshot->initial_sync_ended; |
- const syncable::ModelTypeSet failed_configuration_types = |
- Difference(added_types, initial_sync_ended); |
- SDVLOG(1) |
- << "Added types: " |
- << syncable::ModelTypeSetToString(added_types) |
- << ", configured types: " |
- << syncable::ModelTypeSetToString(initial_sync_ended) |
- << ", failed configuration types: " |
- << syncable::ModelTypeSetToString(failed_configuration_types); |
- state->ready_task.Run(failed_configuration_types); |
- if (!failed_configuration_types.Empty()) |
- return; |
- } |
- |
- if (host_->initialized()) |
- host_->frontend_->OnSyncCycleCompleted(); |
-} |
- |
-void SyncBackendHost::Core::HandleStopSyncingPermanentlyOnFrontendLoop() { |
- if (!host_ || !host_->frontend_) |
- return; |
- host_->frontend_->OnStopSyncingPermanently(); |
-} |
- |
-void SyncBackendHost::Core::HandleClearServerDataSucceededOnFrontendLoop() { |
- if (!host_ || !host_->frontend_) |
- return; |
- host_->frontend_->OnClearServerDataSucceeded(); |
-} |
- |
-void SyncBackendHost::Core::HandleClearServerDataFailedOnFrontendLoop() { |
- if (!host_ || !host_->frontend_) |
- return; |
- host_->frontend_->OnClearServerDataFailed(); |
-} |
- |
-void SyncBackendHost::Core::FinishConfigureDataTypesOnFrontendLoop() { |
- if (!host_) |
- return; |
- host_->FinishConfigureDataTypesOnFrontendLoop(); |
-} |
- |
void SyncBackendHost::AddExperimentalTypes() { |
CHECK(initialized()); |
syncable::ModelTypeSet to_add; |
@@ -928,9 +926,9 @@ void SyncBackendHost::HandleInitializationCompletedOnFrontendLoop( |
sync_api::CONFIGURE_REASON_NEW_CLIENT, |
// Calls back into this function. |
base::Bind( |
- &SyncBackendHost::Core:: |
+ &SyncBackendHost:: |
HandleNigoriConfigurationCompletedOnFrontendLoop, |
- core_.get(), js_backend), |
+ weak_ptr_factory_.GetWeakPtr(), js_backend), |
true); |
break; |
case DOWNLOADING_NIGORI: |
@@ -939,9 +937,9 @@ void SyncBackendHost::HandleInitializationCompletedOnFrontendLoop( |
// if necessary. |
RefreshEncryption( |
base::Bind( |
- &SyncBackendHost::Core:: |
+ &SyncBackendHost:: |
HandleInitializationCompletedOnFrontendLoop, |
- core_.get(), js_backend, true)); |
+ weak_ptr_factory_.GetWeakPtr(), js_backend, true)); |
break; |
case REFRESHING_ENCRYPTION: |
initialization_state_ = INITIALIZED; |
@@ -962,99 +960,104 @@ void SyncBackendHost::HandleInitializationCompletedOnFrontendLoop( |
} |
} |
-void SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop() { |
+void SyncBackendHost::PersistEncryptionBootstrapToken( |
+ const std::string& token) { |
+ CHECK(sync_prefs_.get()); |
+ sync_prefs_->SetEncryptionBootstrapToken(token); |
+} |
+ |
+void SyncBackendHost::HandleActionableErrorEventOnFrontendLoop( |
+ const browser_sync::SyncProtocolError& sync_error) { |
+ if (!frontend_) |
+ return; |
DCHECK_EQ(MessageLoop::current(), frontend_loop_); |
- // Nudge the syncer. This is necessary for both datatype addition/deletion. |
- // |
- // Deletions need a nudge in order to ensure the deletion occurs in a timely |
- // manner (see issue 56416). |
- // |
- // In the case of additions, on the next sync cycle, the syncer should |
- // notice that the routing info has changed and start the process of |
- // downloading updates for newly added data types. Once this is |
- // complete, the configure_state_.ready_task_ is run via an |
- // OnInitializationComplete notification. |
+ frontend_->OnActionableError(sync_error); |
+} |
- SDVLOG(1) << "Syncer in config mode. SBH executing " |
- << "FinishConfigureDataTypesOnFrontendLoop"; |
+void SyncBackendHost::NotifyPassphraseRequired( |
+ sync_api::PassphraseRequiredReason reason) { |
+ if (!frontend_) |
+ return; |
- if (pending_config_mode_state_->added_types.Empty() && |
- !core_->sync_manager()->InitialSyncEndedForAllEnabledTypes()) { |
+ DCHECK_EQ(MessageLoop::current(), frontend_loop_); |
- syncable::ModelTypeSet enabled_types; |
- ModelSafeRoutingInfo routing_info; |
- registrar_->GetModelSafeRoutingInfo(&routing_info); |
- for (ModelSafeRoutingInfo::const_iterator i = routing_info.begin(); |
- i != routing_info.end(); ++i) { |
- enabled_types.Put(i->first); |
- } |
+ frontend_->OnPassphraseRequired(reason); |
+} |
- // TODO(tim): Log / UMA / count this somehow? |
- // Add only the types with empty progress markers. Note: it is possible |
- // that some types have their initial_sync_ended be false but with non |
- // empty progress marker. Which is ok as the rest of the changes would |
- // be downloaded on a regular nudge and initial_sync_ended should be set |
- // to true. However this is a very corner case. So it is not explicitly |
- // handled. |
- pending_config_mode_state_->added_types = |
- sync_api::GetTypesWithEmptyProgressMarkerToken(enabled_types, |
- GetUserShare()); |
- } |
+void SyncBackendHost::NotifyPassphraseAccepted( |
+ const std::string& bootstrap_token) { |
+ if (!frontend_) |
+ return; |
- // If we've added types, we always want to request a nudge/config (even if |
- // the initial sync is ended), in case we could not decrypt the data. |
- if (pending_config_mode_state_->added_types.Empty()) { |
- SDVLOG(1) << "No new types added; calling ready_task directly"; |
- // No new types - just notify the caller that the types are available. |
- const syncable::ModelTypeSet failed_configuration_types; |
- pending_config_mode_state_->ready_task.Run(failed_configuration_types); |
- } else { |
- pending_download_state_.reset(pending_config_mode_state_.release()); |
+ DCHECK_EQ(MessageLoop::current(), frontend_loop_); |
- // Always configure nigori if it's enabled. |
- syncable::ModelTypeSet types_to_config = |
- pending_download_state_->added_types; |
- if (IsNigoriEnabled()) { |
- // Note: Nigori is the only type that gets added with a nonempty |
- // progress marker during config. If the server returns a migration |
- // error then we will go into unrecoverable error. We dont handle it |
- // explicitly because server might help us out here by not sending a |
- // migraiton error for nigori during config. |
- types_to_config.Put(syncable::NIGORI); |
- } |
- SDVLOG(1) << "Types " << syncable::ModelTypeSetToString(types_to_config) |
- << " added; calling DoRequestConfig"; |
- sync_thread_.message_loop()->PostTask(FROM_HERE, |
- base::Bind(&SyncBackendHost::Core::DoRequestConfig, |
- core_.get(), |
- types_to_config, |
- pending_download_state_->reason)); |
- } |
+ PersistEncryptionBootstrapToken(bootstrap_token); |
+ frontend_->OnPassphraseAccepted(); |
+} |
- pending_config_mode_state_.reset(); |
+void SyncBackendHost::NotifyUpdatedToken(const std::string& token) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ TokenAvailableDetails details(GaiaConstants::kSyncService, token); |
+ content::NotificationService::current()->Notify( |
+ chrome::NOTIFICATION_TOKEN_UPDATED, |
+ content::Source<Profile>(profile_), |
+ content::Details<const TokenAvailableDetails>(&details)); |
+} |
- // Notify the SyncManager about the new types. |
- sync_thread_.message_loop()->PostTask(FROM_HERE, |
- base::Bind(&SyncBackendHost::Core::DoUpdateEnabledTypes, core_.get())); |
+void SyncBackendHost::NotifyEncryptedTypesChanged( |
+ syncable::ModelTypeSet encrypted_types, |
+ bool encrypt_everything) { |
+ if (!frontend_) |
+ return; |
+ |
+ DCHECK_EQ(MessageLoop::current(), frontend_loop_); |
+ frontend_->OnEncryptedTypesChanged( |
+ encrypted_types, encrypt_everything); |
} |
-sync_api::HttpPostProviderFactory* SyncBackendHost::MakeHttpBridgeFactory( |
- const scoped_refptr<net::URLRequestContextGetter>& getter) { |
- return new HttpBridgeFactory(getter); |
+void SyncBackendHost::NotifyEncryptionComplete() { |
+ if (!frontend_) |
+ return; |
+ |
+ DCHECK_EQ(MessageLoop::current(), frontend_loop_); |
+ frontend_->OnEncryptionComplete(); |
} |
-void SyncBackendHost::PersistEncryptionBootstrapToken( |
- const std::string& token) { |
- CHECK(sync_prefs_.get()); |
- sync_prefs_->SetEncryptionBootstrapToken(token); |
+void SyncBackendHost::HandleStopSyncingPermanentlyOnFrontendLoop() { |
+ if (!frontend_) |
+ return; |
+ frontend_->OnStopSyncingPermanently(); |
} |
-SyncBackendHost::PendingConfigureDataTypesState:: |
-PendingConfigureDataTypesState() |
- : reason(sync_api::CONFIGURE_REASON_UNKNOWN) {} |
+void SyncBackendHost::HandleClearServerDataSucceededOnFrontendLoop() { |
+ if (!frontend_) |
+ return; |
+ frontend_->OnClearServerDataSucceeded(); |
+} |
-SyncBackendHost::PendingConfigureDataTypesState:: |
-~PendingConfigureDataTypesState() {} |
+void SyncBackendHost::HandleClearServerDataFailedOnFrontendLoop() { |
+ if (!frontend_) |
+ return; |
+ frontend_->OnClearServerDataFailed(); |
+} |
+ |
+void SyncBackendHost::HandleAuthErrorEventOnFrontendLoop( |
+ const GoogleServiceAuthError& new_auth_error) { |
+ if (!frontend_) |
+ return; |
+ |
+ DCHECK_EQ(MessageLoop::current(), frontend_loop_); |
+ |
+ last_auth_error_ = new_auth_error; |
+ frontend_->OnAuthError(); |
+} |
+ |
+void SyncBackendHost::HandleNigoriConfigurationCompletedOnFrontendLoop( |
+ const WeakHandle<JsBackend>& js_backend, |
+ const syncable::ModelTypeSet failed_configuration_types) { |
+ HandleInitializationCompletedOnFrontendLoop( |
+ js_backend, failed_configuration_types.Empty()); |
+} |
namespace { |