[sql] Remove _HAS_EXCEPTIONS=0 from build info.
[chromium-blink-merge.git] / chrome / browser / sync / glue / sync_backend_host_core.cc
blob12bafbb8aad2df7545261918c8cf776c9092750b
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/sync/glue/sync_backend_host_core.h"
7 #include "base/files/file_util.h"
8 #include "base/location.h"
9 #include "base/metrics/histogram.h"
10 #include "base/single_thread_task_runner.h"
11 #include "chrome/browser/sync/glue/invalidation_adapter.h"
12 #include "chrome/browser/sync/glue/local_device_info_provider_impl.h"
13 #include "chrome/browser/sync/glue/sync_backend_registrar.h"
14 #include "components/invalidation/public/invalidation_util.h"
15 #include "components/invalidation/public/object_id_invalidation_map.h"
16 #include "sync/internal_api/public/events/protocol_event.h"
17 #include "sync/internal_api/public/http_post_provider_factory.h"
18 #include "sync/internal_api/public/internal_components_factory.h"
19 #include "sync/internal_api/public/sessions/commit_counters.h"
20 #include "sync/internal_api/public/sessions/status_counters.h"
21 #include "sync/internal_api/public/sessions/sync_session_snapshot.h"
22 #include "sync/internal_api/public/sessions/update_counters.h"
23 #include "sync/internal_api/public/sync_context_proxy.h"
24 #include "sync/internal_api/public/sync_manager.h"
25 #include "sync/internal_api/public/sync_manager_factory.h"
26 #include "url/gurl.h"
28 // Helper macros to log with the syncer thread name; useful when there
29 // are multiple syncers involved.
31 #define SLOG(severity) LOG(severity) << name_ << ": "
33 #define SDVLOG(verbose_level) DVLOG(verbose_level) << name_ << ": "
35 static const int kSaveChangesIntervalSeconds = 10;
37 namespace syncer {
38 class InternalComponentsFactory;
39 } // namespace syncer
41 namespace {
43 // Enums for UMAs.
44 enum SyncBackendInitState {
45 SETUP_COMPLETED_FOUND_RESTORED_TYPES = 0,
46 SETUP_COMPLETED_NO_RESTORED_TYPES,
47 FIRST_SETUP_NO_RESTORED_TYPES,
48 FIRST_SETUP_RESTORED_TYPES,
49 SYNC_BACKEND_INIT_STATE_COUNT
52 } // namespace
54 namespace browser_sync {
56 DoInitializeOptions::DoInitializeOptions(
57 base::MessageLoop* sync_loop,
58 SyncBackendRegistrar* registrar,
59 const syncer::ModelSafeRoutingInfo& routing_info,
60 const std::vector<scoped_refptr<syncer::ModelSafeWorker>>& workers,
61 const scoped_refptr<syncer::ExtensionsActivity>& extensions_activity,
62 const syncer::WeakHandle<syncer::JsEventHandler>& event_handler,
63 const GURL& service_url,
64 scoped_ptr<syncer::HttpPostProviderFactory> http_bridge_factory,
65 const syncer::SyncCredentials& credentials,
66 const std::string& invalidator_client_id,
67 scoped_ptr<syncer::SyncManagerFactory> sync_manager_factory,
68 bool delete_sync_data_folder,
69 const std::string& restored_key_for_bootstrapping,
70 const std::string& restored_keystore_key_for_bootstrapping,
71 scoped_ptr<syncer::InternalComponentsFactory> internal_components_factory,
72 scoped_ptr<syncer::UnrecoverableErrorHandler> unrecoverable_error_handler,
73 const base::Closure& report_unrecoverable_error_function,
74 scoped_ptr<syncer::SyncEncryptionHandler::NigoriState> saved_nigori_state,
75 syncer::PassphraseTransitionClearDataOption clear_data_option,
76 const std::map<syncer::ModelType, int64>& invalidation_versions)
77 : sync_loop(sync_loop),
78 registrar(registrar),
79 routing_info(routing_info),
80 workers(workers),
81 extensions_activity(extensions_activity),
82 event_handler(event_handler),
83 service_url(service_url),
84 http_bridge_factory(http_bridge_factory.Pass()),
85 credentials(credentials),
86 invalidator_client_id(invalidator_client_id),
87 sync_manager_factory(sync_manager_factory.Pass()),
88 delete_sync_data_folder(delete_sync_data_folder),
89 restored_key_for_bootstrapping(restored_key_for_bootstrapping),
90 restored_keystore_key_for_bootstrapping(
91 restored_keystore_key_for_bootstrapping),
92 internal_components_factory(internal_components_factory.Pass()),
93 unrecoverable_error_handler(unrecoverable_error_handler.Pass()),
94 report_unrecoverable_error_function(report_unrecoverable_error_function),
95 saved_nigori_state(saved_nigori_state.Pass()),
96 clear_data_option(clear_data_option),
97 invalidation_versions(invalidation_versions) {}
99 DoInitializeOptions::~DoInitializeOptions() {}
101 DoConfigureSyncerTypes::DoConfigureSyncerTypes() {}
103 DoConfigureSyncerTypes::~DoConfigureSyncerTypes() {}
105 SyncBackendHostCore::SyncBackendHostCore(
106 const std::string& name,
107 const base::FilePath& sync_data_folder_path,
108 bool has_sync_setup_completed,
109 const base::WeakPtr<SyncBackendHostImpl>& backend)
110 : name_(name),
111 sync_data_folder_path_(sync_data_folder_path),
112 host_(backend),
113 sync_loop_(NULL),
114 registrar_(NULL),
115 has_sync_setup_completed_(has_sync_setup_completed),
116 forward_protocol_events_(false),
117 forward_type_info_(false),
118 weak_ptr_factory_(this) {
119 DCHECK(backend.get());
122 SyncBackendHostCore::~SyncBackendHostCore() {
123 DCHECK(!sync_manager_.get());
126 void SyncBackendHostCore::OnSyncCycleCompleted(
127 const syncer::sessions::SyncSessionSnapshot& snapshot) {
128 if (!sync_loop_)
129 return;
130 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
132 host_.Call(
133 FROM_HERE,
134 &SyncBackendHostImpl::HandleSyncCycleCompletedOnFrontendLoop,
135 snapshot);
138 void SyncBackendHostCore::DoRefreshTypes(syncer::ModelTypeSet types) {
139 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
140 sync_manager_->RefreshTypes(types);
143 void SyncBackendHostCore::OnInitializationComplete(
144 const syncer::WeakHandle<syncer::JsBackend>& js_backend,
145 const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>&
146 debug_info_listener,
147 bool success,
148 const syncer::ModelTypeSet restored_types) {
149 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
151 if (!success) {
152 DoDestroySyncManager(syncer::STOP_SYNC);
153 host_.Call(FROM_HERE,
154 &SyncBackendHostImpl::HandleInitializationFailureOnFrontendLoop);
155 return;
158 // Register for encryption related changes now. We have to do this before
159 // the initializing downloading control types or initializing the encryption
160 // handler in order to receive notifications triggered during encryption
161 // startup.
162 sync_manager_->GetEncryptionHandler()->AddObserver(this);
164 // Sync manager initialization is complete, so we can schedule recurring
165 // SaveChanges.
166 sync_loop_->task_runner()->PostTask(
167 FROM_HERE, base::Bind(&SyncBackendHostCore::StartSavingChanges,
168 weak_ptr_factory_.GetWeakPtr()));
170 // Hang on to these for a while longer. We're not ready to hand them back to
171 // the UI thread yet.
172 js_backend_ = js_backend;
173 debug_info_listener_ = debug_info_listener;
175 // Track whether or not sync DB and preferences were in sync.
176 SyncBackendInitState backend_init_state;
177 if (has_sync_setup_completed_ && !restored_types.Empty()) {
178 backend_init_state = SETUP_COMPLETED_FOUND_RESTORED_TYPES;
179 } else if (has_sync_setup_completed_ && restored_types.Empty()) {
180 backend_init_state = SETUP_COMPLETED_NO_RESTORED_TYPES;
181 } else if (!has_sync_setup_completed_ && restored_types.Empty()) {
182 backend_init_state = FIRST_SETUP_NO_RESTORED_TYPES;
183 } else { // (!has_sync_setup_completed_ && !restored_types.Empty())
184 backend_init_state = FIRST_SETUP_RESTORED_TYPES;
187 UMA_HISTOGRAM_ENUMERATION("Sync.BackendInitializeRestoreState",
188 backend_init_state,
189 SYNC_BACKEND_INIT_STATE_COUNT);
191 // Before proceeding any further, we need to download the control types and
192 // purge any partial data (ie. data downloaded for a type that was on its way
193 // to being initially synced, but didn't quite make it.). The following
194 // configure cycle will take care of this. It depends on the registrar state
195 // which we initialize below to ensure that we don't perform any downloads if
196 // all control types have already completed their initial sync.
197 registrar_->SetInitialTypes(restored_types);
199 syncer::ConfigureReason reason =
200 restored_types.Empty() ?
201 syncer::CONFIGURE_REASON_NEW_CLIENT :
202 syncer::CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE;
204 syncer::ModelTypeSet new_control_types = registrar_->ConfigureDataTypes(
205 syncer::ControlTypes(), syncer::ModelTypeSet());
206 syncer::ModelSafeRoutingInfo routing_info;
207 registrar_->GetModelSafeRoutingInfo(&routing_info);
208 SDVLOG(1) << "Control Types "
209 << syncer::ModelTypeSetToString(new_control_types)
210 << " added; calling ConfigureSyncer";
212 syncer::ModelTypeSet types_to_purge =
213 syncer::Difference(syncer::ModelTypeSet::All(),
214 GetRoutingInfoTypes(routing_info));
216 sync_manager_->ConfigureSyncer(
217 reason,
218 new_control_types,
219 types_to_purge,
220 syncer::ModelTypeSet(),
221 syncer::ModelTypeSet(),
222 routing_info,
223 base::Bind(&SyncBackendHostCore::DoInitialProcessControlTypes,
224 weak_ptr_factory_.GetWeakPtr()),
225 base::Closure());
228 void SyncBackendHostCore::OnConnectionStatusChange(
229 syncer::ConnectionStatus status) {
230 if (!sync_loop_)
231 return;
232 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
233 host_.Call(
234 FROM_HERE,
235 &SyncBackendHostImpl::HandleConnectionStatusChangeOnFrontendLoop, status);
238 void SyncBackendHostCore::OnPassphraseRequired(
239 syncer::PassphraseRequiredReason reason,
240 const sync_pb::EncryptedData& pending_keys) {
241 if (!sync_loop_)
242 return;
243 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
244 host_.Call(
245 FROM_HERE,
246 &SyncBackendHostImpl::NotifyPassphraseRequired, reason, pending_keys);
249 void SyncBackendHostCore::OnPassphraseAccepted() {
250 if (!sync_loop_)
251 return;
252 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
253 host_.Call(
254 FROM_HERE,
255 &SyncBackendHostImpl::NotifyPassphraseAccepted);
258 void SyncBackendHostCore::OnBootstrapTokenUpdated(
259 const std::string& bootstrap_token,
260 syncer::BootstrapTokenType type) {
261 if (!sync_loop_)
262 return;
263 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
264 host_.Call(FROM_HERE,
265 &SyncBackendHostImpl::PersistEncryptionBootstrapToken,
266 bootstrap_token,
267 type);
270 void SyncBackendHostCore::OnEncryptedTypesChanged(
271 syncer::ModelTypeSet encrypted_types,
272 bool encrypt_everything) {
273 if (!sync_loop_)
274 return;
275 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
276 // NOTE: We're in a transaction.
277 host_.Call(
278 FROM_HERE,
279 &SyncBackendHostImpl::NotifyEncryptedTypesChanged,
280 encrypted_types, encrypt_everything);
283 void SyncBackendHostCore::OnEncryptionComplete() {
284 if (!sync_loop_)
285 return;
286 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
287 // NOTE: We're in a transaction.
288 host_.Call(
289 FROM_HERE,
290 &SyncBackendHostImpl::NotifyEncryptionComplete);
293 void SyncBackendHostCore::OnCryptographerStateChanged(
294 syncer::Cryptographer* cryptographer) {
295 // Do nothing.
298 void SyncBackendHostCore::OnPassphraseTypeChanged(
299 syncer::PassphraseType type, base::Time passphrase_time) {
300 host_.Call(
301 FROM_HERE,
302 &SyncBackendHostImpl::HandlePassphraseTypeChangedOnFrontendLoop,
303 type, passphrase_time);
306 void SyncBackendHostCore::OnLocalSetPassphraseEncryption(
307 const syncer::SyncEncryptionHandler::NigoriState& nigori_state) {
308 host_.Call(
309 FROM_HERE,
310 &SyncBackendHostImpl::HandleLocalSetPassphraseEncryptionOnFrontendLoop,
311 nigori_state);
314 void SyncBackendHostCore::OnCommitCountersUpdated(
315 syncer::ModelType type,
316 const syncer::CommitCounters& counters) {
317 host_.Call(
318 FROM_HERE,
319 &SyncBackendHostImpl::HandleDirectoryCommitCountersUpdatedOnFrontendLoop,
320 type, counters);
323 void SyncBackendHostCore::OnUpdateCountersUpdated(
324 syncer::ModelType type,
325 const syncer::UpdateCounters& counters) {
326 host_.Call(
327 FROM_HERE,
328 &SyncBackendHostImpl::HandleDirectoryUpdateCountersUpdatedOnFrontendLoop,
329 type, counters);
332 void SyncBackendHostCore::OnStatusCountersUpdated(
333 syncer::ModelType type,
334 const syncer::StatusCounters& counters) {
335 host_.Call(
336 FROM_HERE,
337 &SyncBackendHostImpl::HandleDirectoryStatusCountersUpdatedOnFrontendLoop,
338 type, counters);
341 void SyncBackendHostCore::OnActionableError(
342 const syncer::SyncProtocolError& sync_error) {
343 if (!sync_loop_)
344 return;
345 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
346 host_.Call(
347 FROM_HERE,
348 &SyncBackendHostImpl::HandleActionableErrorEventOnFrontendLoop,
349 sync_error);
352 void SyncBackendHostCore::OnMigrationRequested(syncer::ModelTypeSet types) {
353 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
354 host_.Call(
355 FROM_HERE,
356 &SyncBackendHostImpl::HandleMigrationRequestedOnFrontendLoop,
357 types);
360 void SyncBackendHostCore::OnProtocolEvent(
361 const syncer::ProtocolEvent& event) {
362 // TODO(rlarocque): Find a way to pass event_clone as a scoped_ptr.
363 if (forward_protocol_events_) {
364 scoped_ptr<syncer::ProtocolEvent> event_clone(event.Clone());
365 host_.Call(
366 FROM_HERE,
367 &SyncBackendHostImpl::HandleProtocolEventOnFrontendLoop,
368 event_clone.release());
372 void SyncBackendHostCore::DoOnInvalidatorStateChange(
373 syncer::InvalidatorState state) {
374 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
375 sync_manager_->SetInvalidatorEnabled(state == syncer::INVALIDATIONS_ENABLED);
378 void SyncBackendHostCore::DoOnIncomingInvalidation(
379 const syncer::ObjectIdInvalidationMap& invalidation_map) {
380 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
382 syncer::ObjectIdSet ids = invalidation_map.GetObjectIds();
383 for (const invalidation::ObjectId& object_id : ids) {
384 syncer::ModelType type;
385 if (!NotificationTypeToRealModelType(object_id.name(), &type)) {
386 DLOG(WARNING) << "Notification has invalid id: "
387 << syncer::ObjectIdToString(object_id);
388 } else {
389 syncer::SingleObjectInvalidationSet invalidation_set =
390 invalidation_map.ForObject(object_id);
391 for (syncer::Invalidation invalidation : invalidation_set) {
392 auto last_invalidation = last_invalidation_versions_.find(type);
393 if (!invalidation.is_unknown_version() &&
394 last_invalidation != last_invalidation_versions_.end() &&
395 invalidation.version() <= last_invalidation->second) {
396 DVLOG(1) << "Ignoring redundant invalidation for "
397 << syncer::ModelTypeToString(type) << " with version "
398 << invalidation.version() << ", last seen version was "
399 << last_invalidation->second;
400 continue;
402 scoped_ptr<syncer::InvalidationInterface> inv_adapter(
403 new InvalidationAdapter(invalidation));
404 sync_manager_->OnIncomingInvalidation(type, inv_adapter.Pass());
405 if (!invalidation.is_unknown_version())
406 last_invalidation_versions_[type] = invalidation.version();
411 host_.Call(
412 FROM_HERE,
413 &SyncBackendHostImpl::UpdateInvalidationVersions,
414 last_invalidation_versions_);
417 void SyncBackendHostCore::DoInitialize(
418 scoped_ptr<DoInitializeOptions> options) {
419 DCHECK(!sync_loop_);
420 sync_loop_ = options->sync_loop;
421 DCHECK(sync_loop_);
423 // Finish initializing the HttpBridgeFactory. We do this here because
424 // building the user agent may block on some platforms.
425 options->http_bridge_factory->Init(
426 LocalDeviceInfoProviderImpl::MakeUserAgentForSyncApi());
428 // Blow away the partial or corrupt sync data folder before doing any more
429 // initialization, if necessary.
430 if (options->delete_sync_data_folder) {
431 DeleteSyncDataFolder();
434 // Make sure that the directory exists before initializing the backend.
435 // If it already exists, this will do no harm.
436 if (!base::CreateDirectory(sync_data_folder_path_)) {
437 DLOG(FATAL) << "Sync Data directory creation failed.";
440 // Load the previously persisted set of invalidation versions into memory.
441 last_invalidation_versions_ = options->invalidation_versions;
443 DCHECK(!registrar_);
444 registrar_ = options->registrar;
445 DCHECK(registrar_);
447 sync_manager_ = options->sync_manager_factory->CreateSyncManager(name_);
448 sync_manager_->AddObserver(this);
450 syncer::SyncManager::InitArgs args;
451 args.database_location = sync_data_folder_path_;
452 args.event_handler = options->event_handler;
453 args.service_url = options->service_url;
454 args.post_factory = options->http_bridge_factory.Pass();
455 args.workers = options->workers;
456 args.extensions_activity = options->extensions_activity.get();
457 args.change_delegate = options->registrar; // as SyncManager::ChangeDelegate
458 args.credentials = options->credentials;
459 args.invalidator_client_id = options->invalidator_client_id;
460 args.restored_key_for_bootstrapping = options->restored_key_for_bootstrapping;
461 args.restored_keystore_key_for_bootstrapping =
462 options->restored_keystore_key_for_bootstrapping;
463 args.internal_components_factory =
464 options->internal_components_factory.Pass();
465 args.encryptor = &encryptor_;
466 args.unrecoverable_error_handler =
467 options->unrecoverable_error_handler.Pass();
468 args.report_unrecoverable_error_function =
469 options->report_unrecoverable_error_function;
470 args.cancelation_signal = &stop_syncing_signal_;
471 args.saved_nigori_state = options->saved_nigori_state.Pass();
472 args.clear_data_option = options->clear_data_option;
473 sync_manager_->Init(&args);
476 void SyncBackendHostCore::DoUpdateCredentials(
477 const syncer::SyncCredentials& credentials) {
478 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
479 // UpdateCredentials can be called during backend initialization, possibly
480 // when backend initialization has failed but hasn't notified the UI thread
481 // yet. In that case, the sync manager may have been destroyed on the sync
482 // thread before this task was executed, so we do nothing.
483 if (sync_manager_) {
484 sync_manager_->UpdateCredentials(credentials);
488 void SyncBackendHostCore::DoStartSyncing(
489 const syncer::ModelSafeRoutingInfo& routing_info,
490 base::Time last_poll_time) {
491 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
492 sync_manager_->StartSyncingNormally(routing_info, last_poll_time);
495 void SyncBackendHostCore::DoSetEncryptionPassphrase(
496 const std::string& passphrase,
497 bool is_explicit) {
498 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
499 sync_manager_->GetEncryptionHandler()->SetEncryptionPassphrase(
500 passphrase, is_explicit);
503 void SyncBackendHostCore::DoInitialProcessControlTypes() {
504 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
506 DVLOG(1) << "Initilalizing Control Types";
508 // Initialize encryption.
509 sync_manager_->GetEncryptionHandler()->Init();
511 // Note: experiments are currently handled via SBH::AddExperimentalTypes,
512 // which is called at the end of every sync cycle.
513 // TODO(zea): eventually add an experiment handler and initialize it here.
515 if (!sync_manager_->GetUserShare()) { // NULL in some tests.
516 DVLOG(1) << "Skipping initialization of DeviceInfo";
517 host_.Call(
518 FROM_HERE,
519 &SyncBackendHostImpl::HandleInitializationFailureOnFrontendLoop);
520 return;
523 if (!sync_manager_->InitialSyncEndedTypes().HasAll(syncer::ControlTypes())) {
524 LOG(ERROR) << "Failed to download control types";
525 host_.Call(
526 FROM_HERE,
527 &SyncBackendHostImpl::HandleInitializationFailureOnFrontendLoop);
528 return;
531 host_.Call(FROM_HERE,
532 &SyncBackendHostImpl::HandleInitializationSuccessOnFrontendLoop,
533 js_backend_,
534 debug_info_listener_,
535 sync_manager_->GetSyncContextProxy(),
536 sync_manager_->cache_guid());
538 js_backend_.Reset();
539 debug_info_listener_.Reset();
542 void SyncBackendHostCore::DoSetDecryptionPassphrase(
543 const std::string& passphrase) {
544 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
545 sync_manager_->GetEncryptionHandler()->SetDecryptionPassphrase(
546 passphrase);
549 void SyncBackendHostCore::DoEnableEncryptEverything() {
550 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
551 sync_manager_->GetEncryptionHandler()->EnableEncryptEverything();
554 void SyncBackendHostCore::ShutdownOnUIThread() {
555 // This will cut short any blocking network tasks, cut short any in-progress
556 // sync cycles, and prevent the creation of new blocking network tasks and new
557 // sync cycles. If there was an in-progress network request, it would have
558 // had a reference to the RequestContextGetter. This reference will be
559 // dropped by the time this function returns.
561 // It is safe to call this even if Sync's backend classes have not been
562 // initialized yet. Those classes will receive the message when the sync
563 // thread finally getes around to constructing them.
564 stop_syncing_signal_.Signal();
566 // This will drop the HttpBridgeFactory's reference to the
567 // RequestContextGetter. Once this has been called, the HttpBridgeFactory can
568 // no longer be used to create new HttpBridge instances. We can get away with
569 // this because the stop_syncing_signal_ has already been signalled, which
570 // guarantees that the ServerConnectionManager will no longer attempt to
571 // create new connections.
572 release_request_context_signal_.Signal();
575 void SyncBackendHostCore::DoShutdown(syncer::ShutdownReason reason) {
576 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
578 DoDestroySyncManager(reason);
580 registrar_ = NULL;
582 if (reason == syncer::DISABLE_SYNC)
583 DeleteSyncDataFolder();
585 host_.Reset();
586 weak_ptr_factory_.InvalidateWeakPtrs();
589 void SyncBackendHostCore::DoDestroySyncManager(syncer::ShutdownReason reason) {
590 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
591 if (sync_manager_) {
592 DisableDirectoryTypeDebugInfoForwarding();
593 save_changes_timer_.reset();
594 sync_manager_->RemoveObserver(this);
595 sync_manager_->ShutdownOnSyncThread(reason);
596 sync_manager_.reset();
600 void SyncBackendHostCore::DoConfigureSyncer(
601 syncer::ConfigureReason reason,
602 const DoConfigureSyncerTypes& config_types,
603 const syncer::ModelSafeRoutingInfo routing_info,
604 const base::Callback<void(syncer::ModelTypeSet,
605 syncer::ModelTypeSet)>& ready_task,
606 const base::Closure& retry_callback) {
607 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
608 DCHECK(!ready_task.is_null());
609 DCHECK(!retry_callback.is_null());
610 base::Closure chained_ready_task(
611 base::Bind(&SyncBackendHostCore::DoFinishConfigureDataTypes,
612 weak_ptr_factory_.GetWeakPtr(),
613 config_types.to_download,
614 ready_task));
615 base::Closure chained_retry_task(
616 base::Bind(&SyncBackendHostCore::DoRetryConfiguration,
617 weak_ptr_factory_.GetWeakPtr(),
618 retry_callback));
619 sync_manager_->ConfigureSyncer(reason,
620 config_types.to_download,
621 config_types.to_purge,
622 config_types.to_journal,
623 config_types.to_unapply,
624 routing_info,
625 chained_ready_task,
626 chained_retry_task);
629 void SyncBackendHostCore::DoFinishConfigureDataTypes(
630 syncer::ModelTypeSet types_to_config,
631 const base::Callback<void(syncer::ModelTypeSet,
632 syncer::ModelTypeSet)>& ready_task) {
633 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
635 // Update the enabled types for the bridge and sync manager.
636 syncer::ModelSafeRoutingInfo routing_info;
637 registrar_->GetModelSafeRoutingInfo(&routing_info);
638 syncer::ModelTypeSet enabled_types = GetRoutingInfoTypes(routing_info);
639 enabled_types.RemoveAll(syncer::ProxyTypes());
641 const syncer::ModelTypeSet failed_configuration_types =
642 Difference(types_to_config, sync_manager_->InitialSyncEndedTypes());
643 const syncer::ModelTypeSet succeeded_configuration_types =
644 Difference(types_to_config, failed_configuration_types);
645 host_.Call(FROM_HERE,
646 &SyncBackendHostImpl::FinishConfigureDataTypesOnFrontendLoop,
647 enabled_types,
648 succeeded_configuration_types,
649 failed_configuration_types,
650 ready_task);
653 void SyncBackendHostCore::DoRetryConfiguration(
654 const base::Closure& retry_callback) {
655 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
656 host_.Call(FROM_HERE,
657 &SyncBackendHostImpl::RetryConfigurationOnFrontendLoop,
658 retry_callback);
661 void SyncBackendHostCore::SendBufferedProtocolEventsAndEnableForwarding() {
662 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
663 forward_protocol_events_ = true;
665 if (sync_manager_) {
666 // Grab our own copy of the buffered events.
667 // The buffer is not modified by this operation.
668 std::vector<syncer::ProtocolEvent*> buffered_events;
669 sync_manager_->GetBufferedProtocolEvents().release(&buffered_events);
671 // Send them all over the fence to the host.
672 for (std::vector<syncer::ProtocolEvent*>::iterator it =
673 buffered_events.begin(); it != buffered_events.end(); ++it) {
674 // TODO(rlarocque): Make it explicit that host_ takes ownership.
675 host_.Call(
676 FROM_HERE,
677 &SyncBackendHostImpl::HandleProtocolEventOnFrontendLoop,
678 *it);
683 void SyncBackendHostCore::DisableProtocolEventForwarding() {
684 forward_protocol_events_ = false;
687 void SyncBackendHostCore::EnableDirectoryTypeDebugInfoForwarding() {
688 DCHECK(sync_manager_);
690 forward_type_info_ = true;
692 if (!sync_manager_->HasDirectoryTypeDebugInfoObserver(this))
693 sync_manager_->RegisterDirectoryTypeDebugInfoObserver(this);
694 sync_manager_->RequestEmitDebugInfo();
697 void SyncBackendHostCore::DisableDirectoryTypeDebugInfoForwarding() {
698 DCHECK(sync_manager_);
700 if (!forward_type_info_)
701 return;
703 forward_type_info_ = false;
705 if (sync_manager_->HasDirectoryTypeDebugInfoObserver(this))
706 sync_manager_->UnregisterDirectoryTypeDebugInfoObserver(this);
709 void SyncBackendHostCore::DeleteSyncDataFolder() {
710 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
711 if (base::DirectoryExists(sync_data_folder_path_)) {
712 if (!base::DeleteFile(sync_data_folder_path_, true))
713 SLOG(DFATAL) << "Could not delete the Sync Data folder.";
717 void SyncBackendHostCore::GetAllNodesForTypes(
718 syncer::ModelTypeSet types,
719 scoped_refptr<base::SequencedTaskRunner> task_runner,
720 base::Callback<void(const std::vector<syncer::ModelType>& type,
721 ScopedVector<base::ListValue>)> callback) {
722 std::vector<syncer::ModelType> types_vector;
723 ScopedVector<base::ListValue> node_lists;
725 syncer::ModelSafeRoutingInfo routes;
726 registrar_->GetModelSafeRoutingInfo(&routes);
727 syncer::ModelTypeSet enabled_types = GetRoutingInfoTypes(routes);
729 for (syncer::ModelTypeSet::Iterator it = types.First(); it.Good(); it.Inc()) {
730 types_vector.push_back(it.Get());
731 if (!enabled_types.Has(it.Get())) {
732 node_lists.push_back(new base::ListValue());
733 } else {
734 node_lists.push_back(
735 sync_manager_->GetAllNodesForType(it.Get()).release());
739 task_runner->PostTask(
740 FROM_HERE,
741 base::Bind(callback, types_vector, base::Passed(&node_lists)));
744 void SyncBackendHostCore::StartSavingChanges() {
745 // We may already be shut down.
746 if (!sync_loop_)
747 return;
748 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
749 DCHECK(!save_changes_timer_.get());
750 save_changes_timer_.reset(new base::RepeatingTimer<SyncBackendHostCore>());
751 save_changes_timer_->Start(FROM_HERE,
752 base::TimeDelta::FromSeconds(kSaveChangesIntervalSeconds),
753 this, &SyncBackendHostCore::SaveChanges);
756 void SyncBackendHostCore::SaveChanges() {
757 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
758 sync_manager_->SaveChanges();
761 void SyncBackendHostCore::DoClearServerData(
762 const syncer::SyncManager::ClearServerDataCallback& frontend_callback) {
763 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
764 const syncer::SyncManager::ClearServerDataCallback callback =
765 base::Bind(&SyncBackendHostCore::ClearServerDataDone,
766 weak_ptr_factory_.GetWeakPtr(), frontend_callback);
767 sync_manager_->ClearServerData(callback);
770 void SyncBackendHostCore::ClearServerDataDone(
771 const base::Closure& frontend_callback) {
772 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
773 host_.Call(FROM_HERE, &SyncBackendHostImpl::ClearServerDataDoneOnFrontendLoop,
774 frontend_callback);
778 } // namespace browser_sync