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 d5cb1b53c6165ab5d004c64a43d8b5bd8b3a06cc..13a366ee0b7fc2ba4e248fe4e6d0bf34b68268bd 100644 |
--- a/chrome/browser/sync/glue/sync_backend_host.cc |
+++ b/chrome/browser/sync/glue/sync_backend_host.cc |
@@ -345,20 +345,24 @@ void SyncBackendHost::ConfigureAutofillMigration() { |
} |
} |
+SyncBackendHost::PendingConfigureDataTypesState:: |
+PendingConfigureDataTypesState() : deleted_type(false) {} |
+ |
void SyncBackendHost::ConfigureDataTypes( |
const DataTypeController::TypeMap& data_type_controllers, |
const syncable::ModelTypeSet& types, |
CancelableTask* ready_task) { |
// Only one configure is allowed at a time. |
- DCHECK(!configure_ready_task_.get()); |
+ DCHECK(!pending_config_mode_state_.get()); |
+ DCHECK(!pending_download_state_.get()); |
DCHECK(syncapi_initialized_); |
if (types.count(syncable::AUTOFILL_PROFILE) != 0) { |
ConfigureAutofillMigration(); |
} |
- bool deleted_type = false; |
- syncable::ModelTypeBitSet added_types; |
+ scoped_ptr<PendingConfigureDataTypesState> state(new |
+ PendingConfigureDataTypesState()); |
{ |
base::AutoLock lock(registrar_lock_); |
@@ -370,32 +374,34 @@ void SyncBackendHost::ConfigureDataTypes( |
// If a type is not specified, remove it from the routing_info. |
if (types.count(type) == 0) { |
registrar_.routing_info.erase(type); |
- deleted_type = true; |
+ state->deleted_type = true; |
} else { |
// Add a newly specified data type as GROUP_PASSIVE into the |
// routing_info, if it does not already exist. |
if (registrar_.routing_info.count(type) == 0) { |
registrar_.routing_info[type] = GROUP_PASSIVE; |
- added_types.set(type); |
+ state->added_types.set(type); |
} |
} |
} |
} |
- // If no new data types were added to the passive group, no need to |
- // wait for the syncer. |
- if (core_->syncapi()->InitialSyncEndedForAllEnabledTypes()) { |
- ready_task->Run(); |
- delete ready_task; |
+ state->ready_task.reset(ready_task); |
+ state->initial_types = types; |
+ pending_config_mode_state_.reset(state.release()); |
+ |
+ // If we're doing the first configure (at startup) this is redundant as the |
+ // syncer thread always must start in config mode. |
+ if (using_new_syncer_thread_) { |
+ core_->syncapi()->StartConfigurationMode(NewCallback(core_.get(), |
+ &SyncBackendHost::Core::FinishConfigureDataTypes)); |
} else { |
- // Save the task here so we can run it when the syncer finishes |
- // initializing the new data types. It will be run only when the |
- // set of initially synced data types matches the types requested in |
- // this configure. |
- configure_ready_task_.reset(ready_task); |
- configure_initial_sync_types_ = types; |
+ FinishConfigureDataTypesOnFrontendLoop(); |
} |
+} |
+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 |
@@ -404,9 +410,45 @@ void SyncBackendHost::ConfigureDataTypes( |
// 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_ready_task_ is run via an |
+ // complete, the configure_state_.ready_task_ is run via an |
// OnInitializationComplete notification. |
- ScheduleSyncEventForConfigChange(deleted_type, added_types); |
+ bool request_nudge = false; |
+ if (pending_config_mode_state_->deleted_type) { |
+ if (using_new_syncer_thread_) { |
+ core_thread_.message_loop()->PostTask(FROM_HERE, |
+ NewRunnableMethod(core_.get(), |
+ &SyncBackendHost::Core::DeferNudgeForCleanup)); |
+ } else { |
+ request_nudge = true; |
+ } |
+ } |
+ |
+ if (core_->syncapi()->InitialSyncEndedForAllEnabledTypes()) { |
+ pending_config_mode_state_->ready_task->Run(); |
+ } else { |
+ if (!pending_config_mode_state_->added_types.any()) { |
+ LOG(WARNING) << "No new types, but initial sync not finished." |
+ << "Possible sync db corruption / removal."; |
+ // TODO(tim): Log / UMA / count this somehow? |
+ // TODO(tim): If no added types, we could (should?) config only for |
+ // types that are needed... but this is a rare corruption edge case or |
+ // implies the user mucked around with their syncdb, so for now do all. |
+ pending_config_mode_state_->added_types = |
+ syncable::ModelTypeBitSetFromSet( |
+ pending_config_mode_state_->initial_types); |
+ } |
+ pending_download_state_.reset(pending_config_mode_state_.release()); |
+ if (using_new_syncer_thread_) { |
+ RequestConfig(pending_download_state_->added_types); |
+ } else { |
+ request_nudge = true; |
+ } |
+ } |
+ |
+ if (request_nudge) |
+ RequestNudge(); |
+ |
+ pending_config_mode_state_.reset(); |
// Notify the SyncManager about the new types. |
core_thread_.message_loop()->PostTask(FROM_HERE, |
@@ -414,26 +456,6 @@ void SyncBackendHost::ConfigureDataTypes( |
&SyncBackendHost::Core::DoUpdateEnabledTypes)); |
} |
-void SyncBackendHost::ScheduleSyncEventForConfigChange(bool deleted_type, |
- const syncable::ModelTypeBitSet& added_types) { |
- // We can only nudge when we've either deleted a dataype or added one, else |
- // we can cause unnecessary syncs. Unit tests cover this. |
- if (using_new_syncer_thread_) { |
- if (added_types.size() > 0) |
- RequestConfig(added_types); |
- |
- // TODO(tim): Bug 76233. Fix this once only one impl exists. |
- if (deleted_type) { |
- core_thread_.message_loop()->PostTask(FROM_HERE, |
- NewRunnableMethod(core_.get(), |
- &SyncBackendHost::Core::DeferNudgeForCleanup)); |
- } |
- } else if (deleted_type || |
- !core_->syncapi()->InitialSyncEndedForAllEnabledTypes()) { |
- RequestNudge(); |
- } |
-} |
- |
void SyncBackendHost::EncryptDataTypes( |
const syncable::ModelTypeSet& encrypted_types) { |
core_thread_.message_loop()->PostTask(FROM_HERE, |
@@ -450,7 +472,12 @@ void SyncBackendHost::RequestNudge() { |
void SyncBackendHost::RequestConfig( |
const syncable::ModelTypeBitSet& added_types) { |
DCHECK(core_->syncapi()); |
- core_->syncapi()->RequestConfig(added_types); |
+ |
+ syncable::ModelTypeBitSet types_copy(added_types); |
+ if (IsNigoriEnabled()) |
+ types_copy.set(syncable::NIGORI); |
+ |
+ core_->syncapi()->RequestConfig(types_copy); |
} |
void SyncBackendHost::ActivateDataType( |
@@ -579,6 +606,15 @@ void SyncBackendHost::Core::NotifyEncryptionComplete( |
host_->frontend_->OnEncryptionComplete(encrypted_types); |
} |
+void SyncBackendHost::Core::FinishConfigureDataTypes() { |
+ host_->frontend_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, |
+ &SyncBackendHost::Core::FinishConfigureDataTypesOnFrontendLoop)); |
+} |
+ |
+void SyncBackendHost::Core::FinishConfigureDataTypesOnFrontendLoop() { |
+ host_->FinishConfigureDataTypesOnFrontendLoop(); |
+} |
+ |
SyncBackendHost::Core::DoInitializeOptions::DoInitializeOptions( |
const GURL& service_url, |
sync_api::HttpPostProviderFactory* http_bridge_factory, |
@@ -865,18 +901,21 @@ void SyncBackendHost::Core::HandleSyncCycleCompletedOnFrontendLoop( |
// 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_->configure_ready_task_.get()) { |
- bool found_all = true; |
+ if (host_->pending_download_state_.get()) { |
+ bool found_all_added = true; |
for (syncable::ModelTypeSet::const_iterator it = |
- host_->configure_initial_sync_types_.begin(); |
- it != host_->configure_initial_sync_types_.end(); ++it) { |
- found_all &= snapshot->initial_sync_ended.test(*it); |
+ host_->pending_download_state_->initial_types.begin(); |
+ it != host_->pending_download_state_->initial_types.end(); |
+ ++it) { |
+ if (host_->pending_download_state_->added_types.test(*it)) |
+ found_all_added &= snapshot->initial_sync_ended.test(*it); |
} |
- |
- if (found_all) { |
- host_->configure_ready_task_->Run(); |
- host_->configure_ready_task_.reset(); |
- host_->configure_initial_sync_types_.clear(); |
+ if (!found_all_added) { |
+ CHECK(false); |
+ DCHECK(!host_->using_new_syncer_thread_); |
+ } else { |
+ host_->pending_download_state_->ready_task->Run(); |
+ host_->pending_download_state_.reset(); |
} |
} |
host_->frontend_->OnSyncCycleCompleted(); |