Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1522)

Unified Diff: chrome/browser/sync/glue/sync_backend_host.cc

Issue 10701085: Revert "Revert 142517 - [Sync] Refactor sync configuration logic." (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix deps Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 963ccaba599e2d8c73ee53f85c015595c5405c9f..84f98cddb831bd2d59cb69fbc69a78771c13e96a 100644
--- a/chrome/browser/sync/glue/sync_backend_host.cc
+++ b/chrome/browser/sync/glue/sync_backend_host.cc
@@ -126,10 +126,6 @@ class SyncBackendHost::Core
// initialization and authentication).
void DoStartSyncing(const syncer::ModelSafeRoutingInfo& routing_info);
- // Called to cleanup disabled types.
- void DoRequestCleanupDisabledTypes(
- const syncer::ModelSafeRoutingInfo& routing_info);
-
// Called to set the passphrase for encryption.
void DoSetEncryptionPassphrase(const std::string& passphrase,
bool is_explicit);
@@ -159,14 +155,18 @@ class SyncBackendHost::Core
void DoStopSyncManagerForShutdown(const base::Closure& closure);
void DoShutdown(bool stopping_sync);
- virtual void DoRequestConfig(
- const syncer::ModelSafeRoutingInfo& routing_info,
+ // Configuration methods that must execute on sync loop.
+ void DoConfigureSyncer(
+ syncer::ConfigureReason reason,
syncer::ModelTypeSet types_to_config,
- syncer::ConfigureReason reason);
-
- // Start the configuration mode. |callback| is called on the sync
- // thread.
- virtual void DoStartConfiguration(const base::Closure& callback);
+ const syncer::ModelSafeRoutingInfo routing_info,
+ const base::Callback<void(syncer::ModelTypeSet)>& ready_task,
+ const base::Closure& retry_callback);
+ void DoFinishConfigureDataTypes(
+ syncer::ModelTypeSet types_to_config,
+ const base::Callback<void(syncer::ModelTypeSet)>& ready_task);
+ void DoRetryConfiguration(
+ const base::Closure& retry_callback);
// Set the base request context to use when making HTTP calls.
// This method will add a reference to the context to persist it
@@ -179,9 +179,6 @@ class SyncBackendHost::Core
// sync databases), as well as shutdown when you're no longer syncing.
void DeleteSyncDataFolder();
- // A callback from the SyncerThread when it is safe to continue config.
- void FinishConfigureDataTypes();
-
private:
friend class base::RefCountedThreadSafe<SyncBackendHost::Core>;
friend class SyncBackendHostForProfileSyncTest;
@@ -355,9 +352,10 @@ std::string MakeUserAgentForSyncApi() {
return user_agent;
}
-syncer::HttpPostProviderFactory* MakeHttpBridgeFactory(
+scoped_ptr<syncer::HttpPostProviderFactory> MakeHttpBridgeFactory(
const scoped_refptr<net::URLRequestContextGetter>& getter) {
- return new syncer::HttpBridgeFactory(getter, MakeUserAgentForSyncApi());
+ return scoped_ptr<syncer::HttpPostProviderFactory>(
+ new syncer::HttpBridgeFactory(getter, MakeUserAgentForSyncApi()));
}
} // namespace
@@ -369,10 +367,11 @@ void SyncBackendHost::Initialize(
syncer::ModelTypeSet initial_types,
const SyncCredentials& credentials,
bool delete_sync_data_folder,
+ syncer::SyncManagerFactory* sync_manager_factory,
syncer::UnrecoverableErrorHandler* unrecoverable_error_handler,
syncer::ReportUnrecoverableErrorFunction
report_unrecoverable_error_function) {
- if (!sync_thread_.Start())
+ if (!StartSyncThread())
return;
frontend_ = frontend;
@@ -407,6 +406,7 @@ void SyncBackendHost::Initialize(
credentials,
&chrome_sync_notification_bridge_,
&sync_notifier_factory_,
+ sync_manager_factory,
delete_sync_data_folder,
sync_prefs_->GetEncryptionBootstrapToken(),
syncer::SyncManager::NON_TEST,
@@ -589,8 +589,8 @@ void SyncBackendHost::ConfigureDataTypes(
syncer::ModelTypeSet types_to_add,
syncer::ModelTypeSet types_to_remove,
NigoriState nigori_state,
- base::Callback<void(syncer::ModelTypeSet)> ready_task,
- base::Callback<void()> retry_callback) {
+ const base::Callback<void(syncer::ModelTypeSet)>& ready_task,
+ const base::Callback<void()>& retry_callback) {
syncer::ModelTypeSet types_to_add_with_nigori = types_to_add;
syncer::ModelTypeSet types_to_remove_with_nigori = types_to_remove;
if (nigori_state == WITH_NIGORI) {
@@ -600,44 +600,56 @@ void SyncBackendHost::ConfigureDataTypes(
types_to_add_with_nigori.Remove(syncer::NIGORI);
types_to_remove_with_nigori.Put(syncer::NIGORI);
}
- // Only one configure is allowed at a time.
- DCHECK(!pending_config_mode_state_.get());
- DCHECK(!pending_download_state_.get());
+ // Only one configure is allowed at a time (DataTypeManager handles user
+ // changes that happen while the syncer is reconfiguring, and will only
+ // trigger another call to ConfigureDataTypes once the current reconfiguration
+ // completes).
DCHECK_GT(initialization_state_, NOT_INITIALIZED);
- pending_config_mode_state_.reset(new PendingConfigureDataTypesState());
- pending_config_mode_state_->ready_task = ready_task;
- pending_config_mode_state_->types_to_add = types_to_add_with_nigori;
- pending_config_mode_state_->added_types =
- registrar_->ConfigureDataTypes(types_to_add_with_nigori,
- types_to_remove_with_nigori);
- pending_config_mode_state_->reason = reason;
- pending_config_mode_state_->retry_callback = retry_callback;
-
- // Cleanup disabled types before starting configuration so that
- // callers can assume that the data types are cleaned up once
- // configuration is done.
- if (!types_to_remove_with_nigori.Empty()) {
- syncer::ModelSafeRoutingInfo routing_info;
- registrar_->GetModelSafeRoutingInfo(&routing_info);
- sync_thread_.message_loop()->PostTask(
- FROM_HERE,
- base::Bind(&SyncBackendHost::Core::DoRequestCleanupDisabledTypes,
- core_.get(),
- routing_info));
- }
-
- StartConfiguration(
- base::Bind(&SyncBackendHost::Core::FinishConfigureDataTypes,
- core_.get()));
-}
-
-void SyncBackendHost::StartConfiguration(const base::Closure& callback) {
- // Put syncer in the config mode. DTM will put us in normal mode once it is
- // done. This is to ensure we dont do a normal sync when we are doing model
- // association.
- sync_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
- &SyncBackendHost::Core::DoStartConfiguration, core_.get(), callback));
+ // The new set of enabled types is types_to_add_with_nigori + the
+ // previously enabled types (on restart, the preferred types are already
+ // enabled) - types_to_remove_with_nigori. After reconfiguring the registrar,
+ // the new routing info will reflect the set of enabled types.
+ syncer::ModelSafeRoutingInfo routing_info;
+ registrar_->ConfigureDataTypes(types_to_add_with_nigori,
+ types_to_remove_with_nigori);
+ registrar_->GetModelSafeRoutingInfo(&routing_info);
+ const syncer::ModelTypeSet enabled_types =
+ GetRoutingInfoTypes(routing_info);
+
+ // Figure out which types need to actually be downloaded. We pass those on
+ // to the syncer while it's in configuration mode so that they can be
+ // downloaded before we perform association. Once we switch to normal mode
+ // downloads will get applied normally and hit the datatype's change
+ // processor.
+ // A datatype is in need of downloading if any of the following are true:
+ // 1. it's enabled and initial_sync_ended is false (initial_sync_ended is
+ // set after applying updates, and hence is a more conservative measure
+ // than having a non-empty progress marker, which is set during
+ // StoreTimestamps).
+ // 2. the type is NIGORI, and any other datatype is being downloaded (nigori
+ // is always included if we download a datatype).
+ // TODO(sync): consider moving this logic onto the sync thread (perhaps
+ // as part of SyncManager::ConfigureSyncer).
+ syncer::ModelTypeSet initial_sync_ended_types =
+ core_->sync_manager()->InitialSyncEndedTypes();
+ initial_sync_ended_types.RetainAll(enabled_types);
+ syncer::ModelTypeSet types_to_config =
+ Difference(enabled_types, initial_sync_ended_types);
+ if (!types_to_config.Empty() && enabled_types.Has(syncer::NIGORI))
+ types_to_config.Put(syncer::NIGORI);
+
+ SDVLOG(1) << "Types "
+ << syncer::ModelTypeSetToString(types_to_config)
+ << " added; calling DoConfigureSyncer";
+ // TODO(zea): figure out how to bypass this call if no types are being
+ // configured and GetKey is not needed. For now we rely on determining the
+ // need for GetKey as part of the SyncManager::ConfigureSyncer logic.
+ RequestConfigureSyncer(reason,
+ types_to_config,
+ routing_info,
+ ready_task,
+ retry_callback);
}
void SyncBackendHost::EnableEncryptEverything() {
@@ -703,159 +715,58 @@ void SyncBackendHost::GetModelSafeRoutingInfo(
}
}
+bool SyncBackendHost::StartSyncThread() {
+ if (!sync_thread_.IsRunning())
+ return sync_thread_.Start();
+ return true;
+}
+
void SyncBackendHost::InitCore(const DoInitializeOptions& options) {
sync_thread_.message_loop()->PostTask(FROM_HERE,
base::Bind(&SyncBackendHost::Core::DoInitialize, core_.get(), options));
}
-void SyncBackendHost::HandleSyncCycleCompletedOnFrontendLoop(
- const SyncSessionSnapshot& snapshot) {
- if (!frontend_)
- return;
- DCHECK_EQ(MessageLoop::current(), frontend_loop_);
-
- last_snapshot_ = snapshot;
-
- SDVLOG(1) << "Got snapshot " << snapshot.ToString();
-
- const syncer::ModelTypeSet to_migrate =
- snapshot.model_neutral_state().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()) {
- const syncer::ModelTypeSet types_to_add =
- pending_download_state_->types_to_add;
- const syncer::ModelTypeSet added_types =
- pending_download_state_->added_types;
- DCHECK(types_to_add.HasAll(added_types));
- const syncer::ModelTypeSet initial_sync_ended =
- snapshot.initial_sync_ended();
- const syncer::ModelTypeSet failed_configuration_types =
- Difference(added_types, initial_sync_ended);
- SDVLOG(1)
- << "Added types: "
- << syncer::ModelTypeSetToString(added_types)
- << ", configured types: "
- << syncer::ModelTypeSetToString(initial_sync_ended)
- << ", failed configuration types: "
- << syncer::ModelTypeSetToString(failed_configuration_types);
-
- if (!failed_configuration_types.Empty() &&
- snapshot.retry_scheduled()) {
- // Inform the caller that download failed but we are retrying.
- if (!pending_download_state_->retry_in_progress) {
- pending_download_state_->retry_callback.Run();
- pending_download_state_->retry_in_progress = true;
- }
- // Nothing more to do.
- return;
- }
-
- scoped_ptr<PendingConfigureDataTypesState> state(
- pending_download_state_.release());
- state->ready_task.Run(failed_configuration_types);
-
- // Syncer did not report an error but did not download everything
- // we requested either. So abort. The caller of the config will cleanup.
- 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";
-
- syncer::ModelSafeRoutingInfo routing_info;
- registrar_->GetModelSafeRoutingInfo(&routing_info);
- const syncer::ModelTypeSet enabled_types = GetRoutingInfoTypes(routing_info);
+void SyncBackendHost::RequestConfigureSyncer(
+ syncer::ConfigureReason reason,
+ syncer::ModelTypeSet types_to_config,
+ const syncer::ModelSafeRoutingInfo& routing_info,
+ const base::Callback<void(syncer::ModelTypeSet)>& ready_task,
+ const base::Closure& retry_callback) {
+ sync_thread_.message_loop()->PostTask(FROM_HERE,
+ base::Bind(&SyncBackendHost::Core::DoConfigureSyncer,
+ core_.get(),
+ reason,
+ types_to_config,
+ routing_info,
+ ready_task,
+ retry_callback));
+}
+
+void SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop(
+ syncer::ModelTypeSet types_to_configure,
+ syncer::ModelTypeSet configured_types,
+ const base::Callback<void(syncer::ModelTypeSet)>& ready_task) {
+ const syncer::ModelTypeSet failed_configuration_types =
+ Difference(types_to_configure, configured_types);
+ SDVLOG(1)
+ << "Added types: "
+ << syncer::ModelTypeSetToString(types_to_configure)
+ << ", configured types: "
+ << syncer::ModelTypeSetToString(configured_types)
+ << ", failed configuration types: "
+ << syncer::ModelTypeSetToString(failed_configuration_types);
// Update |chrome_sync_notification_bridge_|'s enabled types here as it has
// to happen on the UI thread.
- chrome_sync_notification_bridge_.UpdateEnabledTypes(enabled_types);
-
- if (pending_config_mode_state_->added_types.Empty() &&
- !core_->sync_manager()->InitialSyncEndedTypes().HasAll(enabled_types)) {
-
- // 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 =
- syncer::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 syncer::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.
- syncer::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(syncer::NIGORI);
- }
- SDVLOG(1) << "Types "
- << syncer::ModelTypeSetToString(types_to_config)
- << " added; calling DoRequestConfig";
- syncer::ModelSafeRoutingInfo routing_info;
- registrar_->GetModelSafeRoutingInfo(&routing_info);
- sync_thread_.message_loop()->PostTask(FROM_HERE,
- base::Bind(&SyncBackendHost::Core::DoRequestConfig,
- core_.get(),
- routing_info,
- types_to_config,
- pending_download_state_->reason));
- }
-
- pending_config_mode_state_.reset();
+ chrome_sync_notification_bridge_.UpdateEnabledTypes(configured_types);
// Notify SyncManager (especially the notification listener) about new types.
sync_thread_.message_loop()->PostTask(FROM_HERE,
base::Bind(&SyncBackendHost::Core::DoUpdateEnabledTypes, core_.get(),
- enabled_types));
-}
+ configured_types));
-bool SyncBackendHost::IsDownloadingNigoriForTest() const {
- return initialization_state_ == DOWNLOADING_NIGORI;
+ if (!ready_task.is_null())
+ ready_task.Run(failed_configuration_types);
}
SyncBackendHost::DoInitializeOptions::DoInitializeOptions(
@@ -870,6 +781,7 @@ SyncBackendHost::DoInitializeOptions::DoInitializeOptions(
const syncer::SyncCredentials& credentials,
ChromeSyncNotificationBridge* chrome_sync_notification_bridge,
syncer::SyncNotifierFactory* sync_notifier_factory,
+ syncer::SyncManagerFactory* sync_manager_factory,
bool delete_sync_data_folder,
const std::string& restored_key_for_bootstrapping,
syncer::SyncManager::TestingMode testing_mode,
@@ -887,6 +799,7 @@ SyncBackendHost::DoInitializeOptions::DoInitializeOptions(
credentials(credentials),
chrome_sync_notification_bridge(chrome_sync_notification_bridge),
sync_notifier_factory(sync_notifier_factory),
+ sync_manager_factory(sync_manager_factory),
delete_sync_data_folder(delete_sync_data_folder),
restored_key_for_bootstrapping(restored_key_for_bootstrapping),
testing_mode(testing_mode),
@@ -913,14 +826,6 @@ SyncBackendHost::Core::~Core() {
DCHECK(!sync_loop_);
}
-SyncBackendHost::PendingConfigureDataTypesState::
-PendingConfigureDataTypesState()
- : reason(syncer::CONFIGURE_REASON_UNKNOWN),
- retry_in_progress(false) {}
-
-SyncBackendHost::PendingConfigureDataTypesState::
-~PendingConfigureDataTypesState() {}
-
void SyncBackendHost::Core::OnSyncCycleCompleted(
const SyncSessionSnapshot& snapshot) {
if (!sync_loop_)
@@ -1061,7 +966,7 @@ void SyncBackendHost::Core::DoInitialize(const DoInitializeOptions& options) {
registrar_ = options.registrar;
DCHECK(registrar_);
- sync_manager_.reset(new syncer::SyncManager(name_));
+ sync_manager_ = options.sync_manager_factory->CreateSyncManager(name_);
sync_manager_->AddObserver(this);
success = sync_manager_->Init(
sync_data_folder_path_,
@@ -1070,15 +975,15 @@ void SyncBackendHost::Core::DoInitialize(const DoInitializeOptions& options) {
options.service_url.EffectiveIntPort(),
options.service_url.SchemeIsSecure(),
BrowserThread::GetBlockingPool(),
- options.make_http_bridge_factory_fn.Run(),
+ options.make_http_bridge_factory_fn.Run().Pass(),
options.routing_info,
options.workers,
options.extensions_activity_monitor,
options.registrar /* as SyncManager::ChangeDelegate */,
options.credentials,
- new BridgedSyncNotifier(
+ scoped_ptr<syncer::SyncNotifier>(new BridgedSyncNotifier(
options.chrome_sync_notification_bridge,
- options.sync_notifier_factory->CreateSyncNotifier()),
+ options.sync_notifier_factory->CreateSyncNotifier())),
options.restored_key_for_bootstrapping,
options.testing_mode,
&encryptor_,
@@ -1116,12 +1021,6 @@ void SyncBackendHost::Core::DoStartSyncing(
sync_manager_->StartSyncingNormally(routing_info);
}
-void SyncBackendHost::Core::DoRequestCleanupDisabledTypes(
- const syncer::ModelSafeRoutingInfo& routing_info) {
- DCHECK_EQ(MessageLoop::current(), sync_loop_);
- sync_manager_->RequestCleanupDisabledTypes(routing_info);
-}
-
void SyncBackendHost::Core::DoSetEncryptionPassphrase(
const std::string& passphrase,
bool is_explicit) {
@@ -1173,18 +1072,46 @@ void SyncBackendHost::Core::DoShutdown(bool sync_disabled) {
host_.Reset();
}
-void SyncBackendHost::Core::DoRequestConfig(
- const syncer::ModelSafeRoutingInfo& routing_info,
+void SyncBackendHost::Core::DoConfigureSyncer(
+ syncer::ConfigureReason reason,
syncer::ModelTypeSet types_to_config,
- syncer::ConfigureReason reason) {
+ const syncer::ModelSafeRoutingInfo routing_info,
+ const base::Callback<void(syncer::ModelTypeSet)>& ready_task,
+ const base::Closure& retry_callback) {
DCHECK_EQ(MessageLoop::current(), sync_loop_);
- sync_manager_->RequestConfig(routing_info, types_to_config, reason);
+ sync_manager_->ConfigureSyncer(
+ reason,
+ types_to_config,
+ routing_info,
+ base::Bind(&SyncBackendHost::Core::DoFinishConfigureDataTypes,
+ this,
+ types_to_config,
+ ready_task),
+ base::Bind(&SyncBackendHost::Core::DoRetryConfiguration,
+ this,
+ retry_callback));
}
-void SyncBackendHost::Core::DoStartConfiguration(
- const base::Closure& callback) {
+void SyncBackendHost::Core::DoFinishConfigureDataTypes(
+ syncer::ModelTypeSet types_to_config,
+ const base::Callback<void(syncer::ModelTypeSet)>& ready_task) {
DCHECK_EQ(MessageLoop::current(), sync_loop_);
- sync_manager_->StartConfigurationMode(callback);
+ syncer::ModelTypeSet configured_types =
+ sync_manager_->InitialSyncEndedTypes();
+ configured_types.RetainAll(types_to_config);
+ host_.Call(FROM_HERE,
+ &SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop,
+ types_to_config,
+ configured_types,
+ ready_task);
+}
+
+void SyncBackendHost::Core::DoRetryConfiguration(
+ const base::Closure& retry_callback) {
+ DCHECK_EQ(MessageLoop::current(), sync_loop_);
+ host_.Call(FROM_HERE,
+ &SyncBackendHost::RetryConfigurationOnFrontendLoop,
+ retry_callback);
}
void SyncBackendHost::Core::DeleteSyncDataFolder() {
@@ -1195,13 +1122,6 @@ void SyncBackendHost::Core::DeleteSyncDataFolder() {
}
}
-void SyncBackendHost::Core::FinishConfigureDataTypes() {
- DCHECK_EQ(MessageLoop::current(), sync_loop_);
- host_.Call(
- FROM_HERE,
- &SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop);
-}
-
void SyncBackendHost::Core::StartSavingChanges() {
// We may already be shut down.
if (!sync_loop_)
@@ -1234,6 +1154,21 @@ void SyncBackendHost::OnNigoriDownloadRetry() {
frontend_->OnSyncConfigureRetry();
}
+namespace {
+
+syncer::ModelTypeSet GetPartiallySyncedTypes(
+ syncer::SyncManager* sync_manager) {
+ syncer::ModelTypeSet partially_synced_types =
+ syncer::ModelTypeSet::All();
+ partially_synced_types.RemoveAll(sync_manager->InitialSyncEndedTypes());
+ partially_synced_types.RemoveAll(
+ sync_manager->GetTypesWithEmptyProgressMarkerToken(
+ syncer::ModelTypeSet::All()));
+ return partially_synced_types;
+}
+
+} // namespace
+
void SyncBackendHost::HandleInitializationCompletedOnFrontendLoop(
const syncer::WeakHandle<syncer::JsBackend>& js_backend, bool success) {
DCHECK_NE(NOT_ATTEMPTED, initialization_state_);
@@ -1253,17 +1188,61 @@ void SyncBackendHost::HandleInitializationCompletedOnFrontendLoop(
return;
}
- // If setup has completed, start off in DOWNLOADING_NIGORI so that
- // we start off by refreshing nigori.
- CHECK(sync_prefs_.get());
- if (sync_prefs_->HasSyncSetupCompleted() &&
- initialization_state_ < DOWNLOADING_NIGORI) {
- initialization_state_ = DOWNLOADING_NIGORI;
- }
-
// Run initialization state machine.
switch (initialization_state_) {
- case NOT_INITIALIZED:
+ case NOT_INITIALIZED: {
+ NigoriState nigori_state;
+ syncer::ModelTypeSet partially_synced_types = GetPartiallySyncedTypes(
+ core_->sync_manager());
+
+ // Although it's possible for any type to be in a partially downloaded
+ // state, we only care about nigori as it's the only one we download
+ // before the backend is fully initialized. Other types will be
+ // re-downloaded at configuration time, at which point we can handle
+ // migrations and other events.
+ UMA_HISTOGRAM_COUNTS("Sync.PartiallySyncedTypes",
+ partially_synced_types.Size());
+
+ if (partially_synced_types.Has(syncer::NIGORI)) {
+ // Configure without nigori to force it to be cleaned (
+ // SyncBackendRegistrar will remove nigori from routing info as part
+ // of the configuration).
+ nigori_state = WITHOUT_NIGORI;
+ initialization_state_ = CLEANING_NIGORI;
+ } else {
+ // Normal configuration. Will do nothing if the nigori is already
+ // downloaded and applied.
+ nigori_state = WITH_NIGORI;
+ initialization_state_ = DOWNLOADING_NIGORI;
+ }
+ ConfigureDataTypes(
+ syncer::CONFIGURE_REASON_NEW_CLIENT,
+ syncer::ModelTypeSet(),
+ syncer::ModelTypeSet(),
+ nigori_state,
+ // Calls back into this function.
+ base::Bind(
+ &SyncBackendHost::
+ HandleNigoriConfigurationCompletedOnFrontendLoop,
+ weak_ptr_factory_.GetWeakPtr(), js_backend),
+ base::Bind(&SyncBackendHost::OnNigoriDownloadRetry,
+ weak_ptr_factory_.GetWeakPtr()));
+ break;
+ }
+ case CLEANING_NIGORI: {
+ syncer::ModelTypeSet partially_synced_types = GetPartiallySyncedTypes(
+ core_->sync_manager());
+ if (partially_synced_types.Has(syncer::NIGORI)) {
+ // We apparently failed to clean the nigori somehow. Attempting
+ // to continue could lead to crashes (see bug 133219), so we fail
+ // gracefully instead by triggering an unrecoverable error.
+ LOG(ERROR) << "Failed to cleanup partial nigori.";
+ initialization_state_ = NOT_INITIALIZED;
+ frontend_->OnBackendInitialized(
+ syncer::WeakHandle<syncer::JsBackend>(), false);
+ return;
+ }
+
initialization_state_ = DOWNLOADING_NIGORI;
ConfigureDataTypes(
syncer::CONFIGURE_REASON_NEW_CLIENT,
@@ -1278,6 +1257,7 @@ void SyncBackendHost::HandleInitializationCompletedOnFrontendLoop(
base::Bind(&SyncBackendHost::OnNigoriDownloadRetry,
weak_ptr_factory_.GetWeakPtr()));
break;
+ }
case DOWNLOADING_NIGORI:
initialization_state_ = REFRESHING_NIGORI;
// Triggers OnEncryptedTypesChanged() and OnEncryptionComplete()
@@ -1301,6 +1281,36 @@ void SyncBackendHost::HandleInitializationCompletedOnFrontendLoop(
}
}
+void SyncBackendHost::HandleSyncCycleCompletedOnFrontendLoop(
+ const SyncSessionSnapshot& snapshot) {
+ if (!frontend_)
+ return;
+ DCHECK_EQ(MessageLoop::current(), frontend_loop_);
+
+ last_snapshot_ = snapshot;
+
+ SDVLOG(1) << "Got snapshot " << snapshot.ToString();
+
+ const syncer::ModelTypeSet to_migrate =
+ snapshot.model_neutral_state().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 (initialized())
+ frontend_->OnSyncCycleCompleted();
+}
+
+void SyncBackendHost::RetryConfigurationOnFrontendLoop(
+ const base::Closure& retry_callback) {
+ SDVLOG(1) << "Failed to complete configuration, informing of retry.";
+ retry_callback.Run();
+}
+
void SyncBackendHost::PersistEncryptionBootstrapToken(
const std::string& token) {
CHECK(sync_prefs_.get());

Powered by Google App Engine
This is Rietveld 408576698