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

Side by Side Diff: chrome/browser/sync/glue/sync_backend_host_core.cc

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

Powered by Google App Engine
This is Rietveld 408576698