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 532f18108d64cb136119e51f3f0206295d7dc8c3..811323b78518951e52a399f3b06864ac85a27d4b 100644 |
--- a/chrome/browser/sync/glue/sync_backend_host.cc |
+++ b/chrome/browser/sync/glue/sync_backend_host.cc |
@@ -352,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 |
@@ -366,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()) |
rlarocque
2012/07/04 06:39:35
Since the function is only a few lines long, non-v
Nicolas Zea
2012/07/09 18:40:45
Chromium style guide generally discourages inlinin
rlarocque
2012/07/09 19:22:58
By inline I meant "copy and paste the function bod
Nicolas Zea
2012/07/09 19:42:50
Oh, I see. I pulled it into its own method for use
|
return; |
frontend_ = frontend; |
@@ -404,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, |
@@ -598,7 +601,7 @@ void SyncBackendHost::ConfigureDataTypes( |
types_to_remove_with_nigori.Put(syncer::NIGORI); |
} |
// Only one configure is allowed at a time (DataTypeManager handles user |
- // changes that happen while the syncer is reconfiguraing, and will only |
+ // 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); |
@@ -712,6 +715,12 @@ 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)); |
@@ -772,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, |
@@ -789,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), |
@@ -955,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_, |
@@ -964,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_, |
@@ -1165,20 +1176,57 @@ void SyncBackendHost::HandleInitializationCompletedOnFrontendLoop( |
// Run initialization state machine. |
switch (initialization_state_) { |
case NOT_INITIALIZED: |
- initialization_state_ = DOWNLOADING_NIGORI; |
+ case CLEANING_NIGORI: { |
rlarocque
2012/07/04 06:39:35
I'm not sure it makes sense to share code between
Nicolas Zea
2012/07/09 18:40:45
Done.
|
+ syncer::ModelTypeSet partially_synced_types = |
+ syncer::ModelTypeSet::All(); |
+ partially_synced_types.RemoveAll( |
+ core_->sync_manager()->InitialSyncEndedTypes()); |
+ partially_synced_types.RemoveAll( |
+ core_->sync_manager()->GetTypesWithEmptyProgressMarkerToken( |
+ syncer::ModelTypeSet::All())); |
+ NigoriState nigori_state; |
+ // 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)) { |
+ if (initialization_state_ == CLEANING_NIGORI) { |
+ // We apparently failed to clean the nigori somehow. Attempting |
rlarocque
2012/07/04 06:39:35
Do you really expect this could happen?
If so, I
Nicolas Zea
2012/07/09 18:40:45
Yeah, I was planning on having that land separatel
|
+ // 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; |
+ } |
+ |
+ // We need to blow away the partially downloaded nigori data. |
+ // Just do a configuration with the nigori disabled. |
+ LOG(ERROR) << "Found partial nigori, attempting cleanup."; |
+ nigori_state = WITHOUT_NIGORI; |
rlarocque
2012/07/04 06:39:35
I spent a long time thinking about it, and I'm mos
|
+ initialization_state_ = CLEANING_NIGORI; |
+ } else { |
+ nigori_state = WITH_NIGORI; |
+ initialization_state_ = DOWNLOADING_NIGORI; |
+ } |
ConfigureDataTypes( |
syncer::CONFIGURE_REASON_NEW_CLIENT, |
syncer::ModelTypeSet(), |
syncer::ModelTypeSet(), |
- WITH_NIGORI, |
+ nigori_state, |
// Calls back into this function. |
base::Bind( |
&SyncBackendHost:: |
- HandleNigoriConfigurationCompletedOnFrontendLoop, |
+ HandleNigoriConfigurationCompletedOnFrontendLoop, |
weak_ptr_factory_.GetWeakPtr(), js_backend), |
base::Bind(&SyncBackendHost::OnNigoriDownloadRetry, |
weak_ptr_factory_.GetWeakPtr())); |
break; |
+ } |
case DOWNLOADING_NIGORI: |
initialization_state_ = REFRESHING_NIGORI; |
// Triggers OnEncryptedTypesChanged() and OnEncryptionComplete() |