Add ENABLE_MEDIA_ROUTER define to builds other than Android and iOS.
[chromium-blink-merge.git] / chrome / browser / sync / glue / sync_backend_host_core.cc
blobcade5503b376b5a4cab4445d7d5eb609196fe894
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/metrics/histogram.h"
9 #include "chrome/browser/sync/glue/invalidation_adapter.h"
10 #include "chrome/browser/sync/glue/local_device_info_provider_impl.h"
11 #include "chrome/browser/sync/glue/sync_backend_registrar.h"
12 #include "chrome/common/chrome_version_info.h"
13 #include "components/invalidation/invalidation_util.h"
14 #include "components/invalidation/object_id_invalidation_map.h"
15 #include "sync/internal_api/public/events/protocol_event.h"
16 #include "sync/internal_api/public/http_post_provider_factory.h"
17 #include "sync/internal_api/public/internal_components_factory.h"
18 #include "sync/internal_api/public/sessions/commit_counters.h"
19 #include "sync/internal_api/public/sessions/status_counters.h"
20 #include "sync/internal_api/public/sessions/sync_session_snapshot.h"
21 #include "sync/internal_api/public/sessions/update_counters.h"
22 #include "sync/internal_api/public/sync_context_proxy.h"
23 #include "sync/internal_api/public/sync_manager.h"
24 #include "sync/internal_api/public/sync_manager_factory.h"
25 #include "url/gurl.h"
27 // Helper macros to log with the syncer thread name; useful when there
28 // are multiple syncers involved.
30 #define SLOG(severity) LOG(severity) << name_ << ": "
32 #define SDVLOG(verbose_level) DVLOG(verbose_level) << name_ << ": "
34 static const int kSaveChangesIntervalSeconds = 10;
36 namespace syncer {
37 class InternalComponentsFactory;
38 } // namespace syncer
40 namespace {
42 // Enums for UMAs.
43 enum SyncBackendInitState {
44 SETUP_COMPLETED_FOUND_RESTORED_TYPES = 0,
45 SETUP_COMPLETED_NO_RESTORED_TYPES,
46 FIRST_SETUP_NO_RESTORED_TYPES,
47 FIRST_SETUP_RESTORED_TYPES,
48 SYNC_BACKEND_INIT_STATE_COUNT
51 } // namespace
53 namespace browser_sync {
55 DoInitializeOptions::DoInitializeOptions(
56 base::MessageLoop* sync_loop,
57 SyncBackendRegistrar* registrar,
58 const syncer::ModelSafeRoutingInfo& routing_info,
59 const std::vector<scoped_refptr<syncer::ModelSafeWorker> >& workers,
60 const scoped_refptr<syncer::ExtensionsActivity>& extensions_activity,
61 const syncer::WeakHandle<syncer::JsEventHandler>& event_handler,
62 const GURL& service_url,
63 scoped_ptr<syncer::HttpPostProviderFactory> http_bridge_factory,
64 const syncer::SyncCredentials& credentials,
65 const std::string& invalidator_client_id,
66 scoped_ptr<syncer::SyncManagerFactory> sync_manager_factory,
67 bool delete_sync_data_folder,
68 const std::string& restored_key_for_bootstrapping,
69 const std::string& restored_keystore_key_for_bootstrapping,
70 scoped_ptr<syncer::InternalComponentsFactory> internal_components_factory,
71 scoped_ptr<syncer::UnrecoverableErrorHandler> unrecoverable_error_handler,
72 syncer::ReportUnrecoverableErrorFunction
73 report_unrecoverable_error_function)
74 : sync_loop(sync_loop),
75 registrar(registrar),
76 routing_info(routing_info),
77 workers(workers),
78 extensions_activity(extensions_activity),
79 event_handler(event_handler),
80 service_url(service_url),
81 http_bridge_factory(http_bridge_factory.Pass()),
82 credentials(credentials),
83 invalidator_client_id(invalidator_client_id),
84 sync_manager_factory(sync_manager_factory.Pass()),
85 delete_sync_data_folder(delete_sync_data_folder),
86 restored_key_for_bootstrapping(restored_key_for_bootstrapping),
87 restored_keystore_key_for_bootstrapping(
88 restored_keystore_key_for_bootstrapping),
89 internal_components_factory(internal_components_factory.Pass()),
90 unrecoverable_error_handler(unrecoverable_error_handler.Pass()),
91 report_unrecoverable_error_function(report_unrecoverable_error_function) {
94 DoInitializeOptions::~DoInitializeOptions() {}
96 DoConfigureSyncerTypes::DoConfigureSyncerTypes() {}
98 DoConfigureSyncerTypes::~DoConfigureSyncerTypes() {}
100 SyncBackendHostCore::SyncBackendHostCore(
101 const std::string& name,
102 const base::FilePath& sync_data_folder_path,
103 bool has_sync_setup_completed,
104 const base::WeakPtr<SyncBackendHostImpl>& backend)
105 : name_(name),
106 sync_data_folder_path_(sync_data_folder_path),
107 host_(backend),
108 sync_loop_(NULL),
109 registrar_(NULL),
110 has_sync_setup_completed_(has_sync_setup_completed),
111 forward_protocol_events_(false),
112 forward_type_info_(false),
113 weak_ptr_factory_(this) {
114 DCHECK(backend.get());
117 SyncBackendHostCore::~SyncBackendHostCore() {
118 DCHECK(!sync_manager_.get());
121 void SyncBackendHostCore::OnSyncCycleCompleted(
122 const syncer::sessions::SyncSessionSnapshot& snapshot) {
123 if (!sync_loop_)
124 return;
125 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
127 host_.Call(
128 FROM_HERE,
129 &SyncBackendHostImpl::HandleSyncCycleCompletedOnFrontendLoop,
130 snapshot);
133 void SyncBackendHostCore::DoRefreshTypes(syncer::ModelTypeSet types) {
134 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
135 sync_manager_->RefreshTypes(types);
138 void SyncBackendHostCore::OnInitializationComplete(
139 const syncer::WeakHandle<syncer::JsBackend>& js_backend,
140 const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>&
141 debug_info_listener,
142 bool success,
143 const syncer::ModelTypeSet restored_types) {
144 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
146 if (!success) {
147 DoDestroySyncManager(syncer::STOP_SYNC);
148 host_.Call(FROM_HERE,
149 &SyncBackendHostImpl::HandleInitializationFailureOnFrontendLoop);
150 return;
153 // Register for encryption related changes now. We have to do this before
154 // the initializing downloading control types or initializing the encryption
155 // handler in order to receive notifications triggered during encryption
156 // startup.
157 sync_manager_->GetEncryptionHandler()->AddObserver(this);
159 // Sync manager initialization is complete, so we can schedule recurring
160 // SaveChanges.
161 sync_loop_->PostTask(FROM_HERE,
162 base::Bind(&SyncBackendHostCore::StartSavingChanges,
163 weak_ptr_factory_.GetWeakPtr()));
165 // Hang on to these for a while longer. We're not ready to hand them back to
166 // the UI thread yet.
167 js_backend_ = js_backend;
168 debug_info_listener_ = debug_info_listener;
170 // Track whether or not sync DB and preferences were in sync.
171 SyncBackendInitState backend_init_state;
172 if (has_sync_setup_completed_ && !restored_types.Empty()) {
173 backend_init_state = SETUP_COMPLETED_FOUND_RESTORED_TYPES;
174 } else if (has_sync_setup_completed_ && restored_types.Empty()) {
175 backend_init_state = SETUP_COMPLETED_NO_RESTORED_TYPES;
176 } else if (!has_sync_setup_completed_ && restored_types.Empty()) {
177 backend_init_state = FIRST_SETUP_NO_RESTORED_TYPES;
178 } else { // (!has_sync_setup_completed_ && !restored_types.Empty())
179 backend_init_state = FIRST_SETUP_RESTORED_TYPES;
182 UMA_HISTOGRAM_ENUMERATION("Sync.BackendInitializeRestoreState",
183 backend_init_state,
184 SYNC_BACKEND_INIT_STATE_COUNT);
186 // Before proceeding any further, we need to download the control types and
187 // purge any partial data (ie. data downloaded for a type that was on its way
188 // to being initially synced, but didn't quite make it.). The following
189 // configure cycle will take care of this. It depends on the registrar state
190 // which we initialize below to ensure that we don't perform any downloads if
191 // all control types have already completed their initial sync.
192 registrar_->SetInitialTypes(restored_types);
194 syncer::ConfigureReason reason =
195 restored_types.Empty() ?
196 syncer::CONFIGURE_REASON_NEW_CLIENT :
197 syncer::CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE;
199 syncer::ModelTypeSet new_control_types = registrar_->ConfigureDataTypes(
200 syncer::ControlTypes(), syncer::ModelTypeSet());
201 syncer::ModelSafeRoutingInfo routing_info;
202 registrar_->GetModelSafeRoutingInfo(&routing_info);
203 SDVLOG(1) << "Control Types "
204 << syncer::ModelTypeSetToString(new_control_types)
205 << " added; calling ConfigureSyncer";
207 syncer::ModelTypeSet types_to_purge =
208 syncer::Difference(syncer::ModelTypeSet::All(),
209 GetRoutingInfoTypes(routing_info));
211 sync_manager_->ConfigureSyncer(
212 reason,
213 new_control_types,
214 types_to_purge,
215 syncer::ModelTypeSet(),
216 syncer::ModelTypeSet(),
217 routing_info,
218 base::Bind(&SyncBackendHostCore::DoInitialProcessControlTypes,
219 weak_ptr_factory_.GetWeakPtr()),
220 base::Closure());
223 void SyncBackendHostCore::OnConnectionStatusChange(
224 syncer::ConnectionStatus status) {
225 if (!sync_loop_)
226 return;
227 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
228 host_.Call(
229 FROM_HERE,
230 &SyncBackendHostImpl::HandleConnectionStatusChangeOnFrontendLoop, status);
233 void SyncBackendHostCore::OnPassphraseRequired(
234 syncer::PassphraseRequiredReason reason,
235 const sync_pb::EncryptedData& pending_keys) {
236 if (!sync_loop_)
237 return;
238 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
239 host_.Call(
240 FROM_HERE,
241 &SyncBackendHostImpl::NotifyPassphraseRequired, reason, pending_keys);
244 void SyncBackendHostCore::OnPassphraseAccepted() {
245 if (!sync_loop_)
246 return;
247 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
248 host_.Call(
249 FROM_HERE,
250 &SyncBackendHostImpl::NotifyPassphraseAccepted);
253 void SyncBackendHostCore::OnBootstrapTokenUpdated(
254 const std::string& bootstrap_token,
255 syncer::BootstrapTokenType type) {
256 if (!sync_loop_)
257 return;
258 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
259 host_.Call(FROM_HERE,
260 &SyncBackendHostImpl::PersistEncryptionBootstrapToken,
261 bootstrap_token,
262 type);
265 void SyncBackendHostCore::OnEncryptedTypesChanged(
266 syncer::ModelTypeSet encrypted_types,
267 bool encrypt_everything) {
268 if (!sync_loop_)
269 return;
270 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
271 // NOTE: We're in a transaction.
272 host_.Call(
273 FROM_HERE,
274 &SyncBackendHostImpl::NotifyEncryptedTypesChanged,
275 encrypted_types, encrypt_everything);
278 void SyncBackendHostCore::OnEncryptionComplete() {
279 if (!sync_loop_)
280 return;
281 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
282 // NOTE: We're in a transaction.
283 host_.Call(
284 FROM_HERE,
285 &SyncBackendHostImpl::NotifyEncryptionComplete);
288 void SyncBackendHostCore::OnCryptographerStateChanged(
289 syncer::Cryptographer* cryptographer) {
290 // Do nothing.
293 void SyncBackendHostCore::OnPassphraseTypeChanged(
294 syncer::PassphraseType type, base::Time passphrase_time) {
295 host_.Call(
296 FROM_HERE,
297 &SyncBackendHostImpl::HandlePassphraseTypeChangedOnFrontendLoop,
298 type, passphrase_time);
301 void SyncBackendHostCore::OnCommitCountersUpdated(
302 syncer::ModelType type,
303 const syncer::CommitCounters& counters) {
304 host_.Call(
305 FROM_HERE,
306 &SyncBackendHostImpl::HandleDirectoryCommitCountersUpdatedOnFrontendLoop,
307 type, counters);
310 void SyncBackendHostCore::OnUpdateCountersUpdated(
311 syncer::ModelType type,
312 const syncer::UpdateCounters& counters) {
313 host_.Call(
314 FROM_HERE,
315 &SyncBackendHostImpl::HandleDirectoryUpdateCountersUpdatedOnFrontendLoop,
316 type, counters);
319 void SyncBackendHostCore::OnStatusCountersUpdated(
320 syncer::ModelType type,
321 const syncer::StatusCounters& counters) {
322 host_.Call(
323 FROM_HERE,
324 &SyncBackendHostImpl::HandleDirectoryStatusCountersUpdatedOnFrontendLoop,
325 type, counters);
328 void SyncBackendHostCore::OnActionableError(
329 const syncer::SyncProtocolError& sync_error) {
330 if (!sync_loop_)
331 return;
332 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
333 host_.Call(
334 FROM_HERE,
335 &SyncBackendHostImpl::HandleActionableErrorEventOnFrontendLoop,
336 sync_error);
339 void SyncBackendHostCore::OnMigrationRequested(syncer::ModelTypeSet types) {
340 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
341 host_.Call(
342 FROM_HERE,
343 &SyncBackendHostImpl::HandleMigrationRequestedOnFrontendLoop,
344 types);
347 void SyncBackendHostCore::OnProtocolEvent(
348 const syncer::ProtocolEvent& event) {
349 // TODO(rlarocque): Find a way to pass event_clone as a scoped_ptr.
350 if (forward_protocol_events_) {
351 scoped_ptr<syncer::ProtocolEvent> event_clone(event.Clone());
352 host_.Call(
353 FROM_HERE,
354 &SyncBackendHostImpl::HandleProtocolEventOnFrontendLoop,
355 event_clone.release());
359 void SyncBackendHostCore::DoOnInvalidatorStateChange(
360 syncer::InvalidatorState state) {
361 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
362 sync_manager_->SetInvalidatorEnabled(state == syncer::INVALIDATIONS_ENABLED);
365 void SyncBackendHostCore::DoOnIncomingInvalidation(
366 const syncer::ObjectIdInvalidationMap& invalidation_map) {
367 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
369 syncer::ObjectIdSet ids = invalidation_map.GetObjectIds();
370 for (syncer::ObjectIdSet::const_iterator ids_it = ids.begin();
371 ids_it != ids.end();
372 ++ids_it) {
373 syncer::ModelType type;
374 if (!NotificationTypeToRealModelType(ids_it->name(), &type)) {
375 DLOG(WARNING) << "Notification has invalid id: "
376 << syncer::ObjectIdToString(*ids_it);
377 } else {
378 syncer::SingleObjectInvalidationSet invalidation_set =
379 invalidation_map.ForObject(*ids_it);
380 for (syncer::SingleObjectInvalidationSet::const_iterator inv_it =
381 invalidation_set.begin();
382 inv_it != invalidation_set.end();
383 ++inv_it) {
384 scoped_ptr<syncer::InvalidationInterface> inv_adapter(
385 new InvalidationAdapter(*inv_it));
386 sync_manager_->OnIncomingInvalidation(type, inv_adapter.Pass());
392 void SyncBackendHostCore::DoInitialize(
393 scoped_ptr<DoInitializeOptions> options) {
394 DCHECK(!sync_loop_);
395 sync_loop_ = options->sync_loop;
396 DCHECK(sync_loop_);
398 // Finish initializing the HttpBridgeFactory. We do this here because
399 // building the user agent may block on some platforms.
400 chrome::VersionInfo version_info;
401 options->http_bridge_factory->Init(
402 LocalDeviceInfoProviderImpl::MakeUserAgentForSyncApi(version_info));
404 // Blow away the partial or corrupt sync data folder before doing any more
405 // initialization, if necessary.
406 if (options->delete_sync_data_folder) {
407 DeleteSyncDataFolder();
410 // Make sure that the directory exists before initializing the backend.
411 // If it already exists, this will do no harm.
412 if (!base::CreateDirectory(sync_data_folder_path_)) {
413 DLOG(FATAL) << "Sync Data directory creation failed.";
416 DCHECK(!registrar_);
417 registrar_ = options->registrar;
418 DCHECK(registrar_);
420 sync_manager_ = options->sync_manager_factory->CreateSyncManager(name_);
421 sync_manager_->AddObserver(this);
423 syncer::SyncManager::InitArgs args;
424 args.database_location = sync_data_folder_path_;
425 args.event_handler = options->event_handler;
426 args.service_url = options->service_url;
427 args.post_factory = options->http_bridge_factory.Pass();
428 args.workers = options->workers;
429 args.extensions_activity = options->extensions_activity.get();
430 args.change_delegate = options->registrar; // as SyncManager::ChangeDelegate
431 args.credentials = options->credentials;
432 args.invalidator_client_id = options->invalidator_client_id;
433 args.restored_key_for_bootstrapping = options->restored_key_for_bootstrapping;
434 args.restored_keystore_key_for_bootstrapping =
435 options->restored_keystore_key_for_bootstrapping;
436 args.internal_components_factory =
437 options->internal_components_factory.Pass();
438 args.encryptor = &encryptor_;
439 args.unrecoverable_error_handler =
440 options->unrecoverable_error_handler.Pass();
441 args.report_unrecoverable_error_function =
442 options->report_unrecoverable_error_function;
443 args.cancelation_signal = &stop_syncing_signal_;
444 sync_manager_->Init(&args);
447 void SyncBackendHostCore::DoUpdateCredentials(
448 const syncer::SyncCredentials& credentials) {
449 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
450 // UpdateCredentials can be called during backend initialization, possibly
451 // when backend initialization has failed but hasn't notified the UI thread
452 // yet. In that case, the sync manager may have been destroyed on the sync
453 // thread before this task was executed, so we do nothing.
454 if (sync_manager_) {
455 sync_manager_->UpdateCredentials(credentials);
459 void SyncBackendHostCore::DoStartSyncing(
460 const syncer::ModelSafeRoutingInfo& routing_info) {
461 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
462 sync_manager_->StartSyncingNormally(routing_info);
465 void SyncBackendHostCore::DoSetEncryptionPassphrase(
466 const std::string& passphrase,
467 bool is_explicit) {
468 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
469 sync_manager_->GetEncryptionHandler()->SetEncryptionPassphrase(
470 passphrase, is_explicit);
473 void SyncBackendHostCore::DoInitialProcessControlTypes() {
474 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
476 DVLOG(1) << "Initilalizing Control Types";
478 // Initialize encryption.
479 sync_manager_->GetEncryptionHandler()->Init();
481 // Note: experiments are currently handled via SBH::AddExperimentalTypes,
482 // which is called at the end of every sync cycle.
483 // TODO(zea): eventually add an experiment handler and initialize it here.
485 if (!sync_manager_->GetUserShare()) { // NULL in some tests.
486 DVLOG(1) << "Skipping initialization of DeviceInfo";
487 host_.Call(
488 FROM_HERE,
489 &SyncBackendHostImpl::HandleInitializationFailureOnFrontendLoop);
490 return;
493 if (!sync_manager_->InitialSyncEndedTypes().HasAll(syncer::ControlTypes())) {
494 LOG(ERROR) << "Failed to download control types";
495 host_.Call(
496 FROM_HERE,
497 &SyncBackendHostImpl::HandleInitializationFailureOnFrontendLoop);
498 return;
501 host_.Call(FROM_HERE,
502 &SyncBackendHostImpl::HandleInitializationSuccessOnFrontendLoop,
503 js_backend_,
504 debug_info_listener_,
505 sync_manager_->GetSyncContextProxy(),
506 sync_manager_->cache_guid());
508 js_backend_.Reset();
509 debug_info_listener_.Reset();
512 void SyncBackendHostCore::DoSetDecryptionPassphrase(
513 const std::string& passphrase) {
514 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
515 sync_manager_->GetEncryptionHandler()->SetDecryptionPassphrase(
516 passphrase);
519 void SyncBackendHostCore::DoEnableEncryptEverything() {
520 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
521 sync_manager_->GetEncryptionHandler()->EnableEncryptEverything();
524 void SyncBackendHostCore::ShutdownOnUIThread() {
525 // This will cut short any blocking network tasks, cut short any in-progress
526 // sync cycles, and prevent the creation of new blocking network tasks and new
527 // sync cycles. If there was an in-progress network request, it would have
528 // had a reference to the RequestContextGetter. This reference will be
529 // dropped by the time this function returns.
531 // It is safe to call this even if Sync's backend classes have not been
532 // initialized yet. Those classes will receive the message when the sync
533 // thread finally getes around to constructing them.
534 stop_syncing_signal_.Signal();
536 // This will drop the HttpBridgeFactory's reference to the
537 // RequestContextGetter. Once this has been called, the HttpBridgeFactory can
538 // no longer be used to create new HttpBridge instances. We can get away with
539 // this because the stop_syncing_signal_ has already been signalled, which
540 // guarantees that the ServerConnectionManager will no longer attempt to
541 // create new connections.
542 release_request_context_signal_.Signal();
545 void SyncBackendHostCore::DoShutdown(syncer::ShutdownReason reason) {
546 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
548 DoDestroySyncManager(reason);
550 registrar_ = NULL;
552 if (reason == syncer::DISABLE_SYNC)
553 DeleteSyncDataFolder();
555 host_.Reset();
556 weak_ptr_factory_.InvalidateWeakPtrs();
559 void SyncBackendHostCore::DoDestroySyncManager(syncer::ShutdownReason reason) {
560 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
561 if (sync_manager_) {
562 DisableDirectoryTypeDebugInfoForwarding();
563 save_changes_timer_.reset();
564 sync_manager_->RemoveObserver(this);
565 sync_manager_->ShutdownOnSyncThread(reason);
566 sync_manager_.reset();
570 void SyncBackendHostCore::DoConfigureSyncer(
571 syncer::ConfigureReason reason,
572 const DoConfigureSyncerTypes& config_types,
573 const syncer::ModelSafeRoutingInfo routing_info,
574 const base::Callback<void(syncer::ModelTypeSet,
575 syncer::ModelTypeSet)>& ready_task,
576 const base::Closure& retry_callback) {
577 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
578 DCHECK(!ready_task.is_null());
579 DCHECK(!retry_callback.is_null());
580 base::Closure chained_ready_task(
581 base::Bind(&SyncBackendHostCore::DoFinishConfigureDataTypes,
582 weak_ptr_factory_.GetWeakPtr(),
583 config_types.to_download,
584 ready_task));
585 base::Closure chained_retry_task(
586 base::Bind(&SyncBackendHostCore::DoRetryConfiguration,
587 weak_ptr_factory_.GetWeakPtr(),
588 retry_callback));
589 sync_manager_->ConfigureSyncer(reason,
590 config_types.to_download,
591 config_types.to_purge,
592 config_types.to_journal,
593 config_types.to_unapply,
594 routing_info,
595 chained_ready_task,
596 chained_retry_task);
599 void SyncBackendHostCore::DoFinishConfigureDataTypes(
600 syncer::ModelTypeSet types_to_config,
601 const base::Callback<void(syncer::ModelTypeSet,
602 syncer::ModelTypeSet)>& ready_task) {
603 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
605 // Update the enabled types for the bridge and sync manager.
606 syncer::ModelSafeRoutingInfo routing_info;
607 registrar_->GetModelSafeRoutingInfo(&routing_info);
608 syncer::ModelTypeSet enabled_types = GetRoutingInfoTypes(routing_info);
609 enabled_types.RemoveAll(syncer::ProxyTypes());
611 const syncer::ModelTypeSet failed_configuration_types =
612 Difference(types_to_config, sync_manager_->InitialSyncEndedTypes());
613 const syncer::ModelTypeSet succeeded_configuration_types =
614 Difference(types_to_config, failed_configuration_types);
615 host_.Call(FROM_HERE,
616 &SyncBackendHostImpl::FinishConfigureDataTypesOnFrontendLoop,
617 enabled_types,
618 succeeded_configuration_types,
619 failed_configuration_types,
620 ready_task);
623 void SyncBackendHostCore::DoRetryConfiguration(
624 const base::Closure& retry_callback) {
625 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
626 host_.Call(FROM_HERE,
627 &SyncBackendHostImpl::RetryConfigurationOnFrontendLoop,
628 retry_callback);
631 void SyncBackendHostCore::SendBufferedProtocolEventsAndEnableForwarding() {
632 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
633 forward_protocol_events_ = true;
635 if (sync_manager_) {
636 // Grab our own copy of the buffered events.
637 // The buffer is not modified by this operation.
638 std::vector<syncer::ProtocolEvent*> buffered_events;
639 sync_manager_->GetBufferedProtocolEvents().release(&buffered_events);
641 // Send them all over the fence to the host.
642 for (std::vector<syncer::ProtocolEvent*>::iterator it =
643 buffered_events.begin(); it != buffered_events.end(); ++it) {
644 // TODO(rlarocque): Make it explicit that host_ takes ownership.
645 host_.Call(
646 FROM_HERE,
647 &SyncBackendHostImpl::HandleProtocolEventOnFrontendLoop,
648 *it);
653 void SyncBackendHostCore::DisableProtocolEventForwarding() {
654 forward_protocol_events_ = false;
657 void SyncBackendHostCore::EnableDirectoryTypeDebugInfoForwarding() {
658 DCHECK(sync_manager_);
660 forward_type_info_ = true;
662 if (!sync_manager_->HasDirectoryTypeDebugInfoObserver(this))
663 sync_manager_->RegisterDirectoryTypeDebugInfoObserver(this);
664 sync_manager_->RequestEmitDebugInfo();
667 void SyncBackendHostCore::DisableDirectoryTypeDebugInfoForwarding() {
668 DCHECK(sync_manager_);
670 if (!forward_type_info_)
671 return;
673 forward_type_info_ = false;
675 if (sync_manager_->HasDirectoryTypeDebugInfoObserver(this))
676 sync_manager_->UnregisterDirectoryTypeDebugInfoObserver(this);
679 void SyncBackendHostCore::DeleteSyncDataFolder() {
680 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
681 if (base::DirectoryExists(sync_data_folder_path_)) {
682 if (!base::DeleteFile(sync_data_folder_path_, true))
683 SLOG(DFATAL) << "Could not delete the Sync Data folder.";
687 void SyncBackendHostCore::GetAllNodesForTypes(
688 syncer::ModelTypeSet types,
689 scoped_refptr<base::SequencedTaskRunner> task_runner,
690 base::Callback<void(const std::vector<syncer::ModelType>& type,
691 ScopedVector<base::ListValue>)> callback) {
692 std::vector<syncer::ModelType> types_vector;
693 ScopedVector<base::ListValue> node_lists;
695 syncer::ModelSafeRoutingInfo routes;
696 registrar_->GetModelSafeRoutingInfo(&routes);
697 syncer::ModelTypeSet enabled_types = GetRoutingInfoTypes(routes);
699 for (syncer::ModelTypeSet::Iterator it = types.First(); it.Good(); it.Inc()) {
700 types_vector.push_back(it.Get());
701 if (!enabled_types.Has(it.Get())) {
702 node_lists.push_back(new base::ListValue());
703 } else {
704 node_lists.push_back(
705 sync_manager_->GetAllNodesForType(it.Get()).release());
709 task_runner->PostTask(
710 FROM_HERE,
711 base::Bind(callback, types_vector, base::Passed(&node_lists)));
714 void SyncBackendHostCore::StartSavingChanges() {
715 // We may already be shut down.
716 if (!sync_loop_)
717 return;
718 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
719 DCHECK(!save_changes_timer_.get());
720 save_changes_timer_.reset(new base::RepeatingTimer<SyncBackendHostCore>());
721 save_changes_timer_->Start(FROM_HERE,
722 base::TimeDelta::FromSeconds(kSaveChangesIntervalSeconds),
723 this, &SyncBackendHostCore::SaveChanges);
726 void SyncBackendHostCore::SaveChanges() {
727 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
728 sync_manager_->SaveChanges();
731 } // namespace browser_sync