OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "build/build_config.h" | 5 #include "build/build_config.h" |
6 | 6 |
7 #include "chrome/browser/sync/glue/sync_backend_host.h" | 7 #include "chrome/browser/sync/glue/sync_backend_host.h" |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <map> | 10 #include <map> |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
53 // Helper macros to log with the syncer thread name; useful when there | 53 // Helper macros to log with the syncer thread name; useful when there |
54 // are multiple syncers involved. | 54 // are multiple syncers involved. |
55 | 55 |
56 #define SLOG(severity) LOG(severity) << name_ << ": " | 56 #define SLOG(severity) LOG(severity) << name_ << ": " |
57 | 57 |
58 #define SDVLOG(verbose_level) DVLOG(verbose_level) << name_ << ": " | 58 #define SDVLOG(verbose_level) DVLOG(verbose_level) << name_ << ": " |
59 | 59 |
60 SyncBackendHost::SyncBackendHost(const std::string& name, | 60 SyncBackendHost::SyncBackendHost(const std::string& name, |
61 Profile* profile, | 61 Profile* profile, |
62 const base::WeakPtr<SyncPrefs>& sync_prefs) | 62 const base::WeakPtr<SyncPrefs>& sync_prefs) |
63 : core_(new Core(name, ALLOW_THIS_IN_INITIALIZER_LIST(this))), | 63 : initialization_state_(NOT_ATTEMPTED), |
64 initialization_state_(NOT_ATTEMPTED), | 64 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
65 sync_thread_("Chrome_SyncThread"), | 65 sync_thread_("Chrome_SyncThread"), |
66 frontend_loop_(MessageLoop::current()), | 66 frontend_loop_(MessageLoop::current()), |
67 profile_(profile), | 67 profile_(profile), |
68 name_(name), | |
69 core_(new Core(name, profile_->GetPath().Append(kSyncDataFolderName), | |
70 weak_ptr_factory_.GetWeakPtr())), | |
68 sync_prefs_(sync_prefs), | 71 sync_prefs_(sync_prefs), |
69 name_(name), | |
70 sync_notifier_factory_( | 72 sync_notifier_factory_( |
71 content::GetUserAgent(GURL()), | 73 content::GetUserAgent(GURL()), |
72 profile_->GetRequestContext(), | 74 profile_->GetRequestContext(), |
73 sync_prefs, | 75 sync_prefs, |
74 *CommandLine::ForCurrentProcess()), | 76 *CommandLine::ForCurrentProcess()), |
75 frontend_(NULL), | 77 frontend_(NULL), |
76 sync_data_folder_path_( | |
77 profile_->GetPath().Append(kSyncDataFolderName)), | |
78 last_auth_error_(AuthError::None()) { | 78 last_auth_error_(AuthError::None()) { |
79 } | 79 } |
80 | 80 |
81 SyncBackendHost::SyncBackendHost() | 81 SyncBackendHost::SyncBackendHost() |
82 : initialization_state_(NOT_ATTEMPTED), | 82 : initialization_state_(NOT_ATTEMPTED), |
83 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | |
83 sync_thread_("Chrome_SyncThread"), | 84 sync_thread_("Chrome_SyncThread"), |
84 frontend_loop_(MessageLoop::current()), | 85 frontend_loop_(MessageLoop::current()), |
85 profile_(NULL), | 86 profile_(NULL), |
86 name_("Unknown"), | 87 name_("Unknown"), |
87 sync_notifier_factory_( | 88 sync_notifier_factory_( |
88 content::GetUserAgent(GURL()), | 89 content::GetUserAgent(GURL()), |
89 NULL, | 90 NULL, |
90 base::WeakPtr<sync_notifier::InvalidationVersionTracker>(), | 91 base::WeakPtr<sync_notifier::InvalidationVersionTracker>(), |
91 *CommandLine::ForCurrentProcess()), | 92 *CommandLine::ForCurrentProcess()), |
92 frontend_(NULL), | 93 frontend_(NULL), |
93 last_auth_error_(AuthError::None()) { | 94 last_auth_error_(AuthError::None()) { |
94 } | 95 } |
95 | 96 |
96 SyncBackendHost::~SyncBackendHost() { | 97 SyncBackendHost::~SyncBackendHost() { |
97 DCHECK(!core_ && !frontend_) << "Must call Shutdown before destructor."; | 98 DCHECK(!core_ && !frontend_) << "Must call Shutdown before destructor."; |
98 DCHECK(!registrar_.get()); | 99 DCHECK(!registrar_.get()); |
99 } | 100 } |
100 | 101 |
102 namespace { | |
103 | |
104 sync_api::HttpPostProviderFactory* MakeHttpBridgeFactory( | |
105 const scoped_refptr<net::URLRequestContextGetter>& getter) { | |
106 return new HttpBridgeFactory(getter); | |
107 } | |
108 | |
109 } // namespace | |
110 | |
101 void SyncBackendHost::Initialize( | 111 void SyncBackendHost::Initialize( |
102 SyncFrontend* frontend, | 112 SyncFrontend* frontend, |
103 const WeakHandle<JsEventHandler>& event_handler, | 113 const WeakHandle<JsEventHandler>& event_handler, |
104 const GURL& sync_service_url, | 114 const GURL& sync_service_url, |
105 syncable::ModelTypeSet initial_types, | 115 syncable::ModelTypeSet initial_types, |
106 const SyncCredentials& credentials, | 116 const SyncCredentials& credentials, |
107 bool delete_sync_data_folder) { | 117 bool delete_sync_data_folder) { |
108 if (!sync_thread_.Start()) | 118 if (!sync_thread_.Start()) |
109 return; | 119 return; |
110 | 120 |
111 frontend_ = frontend; | 121 frontend_ = frontend; |
112 DCHECK(frontend); | 122 DCHECK(frontend); |
113 | 123 |
114 syncable::ModelTypeSet initial_types_with_nigori(initial_types); | 124 syncable::ModelTypeSet initial_types_with_nigori(initial_types); |
115 CHECK(sync_prefs_.get()); | 125 CHECK(sync_prefs_.get()); |
116 if (sync_prefs_->HasSyncSetupCompleted()) { | 126 if (sync_prefs_->HasSyncSetupCompleted()) { |
117 initial_types_with_nigori.Put(syncable::NIGORI); | 127 initial_types_with_nigori.Put(syncable::NIGORI); |
118 } | 128 } |
119 | 129 |
120 registrar_.reset(new SyncBackendRegistrar(initial_types_with_nigori, | 130 registrar_.reset(new SyncBackendRegistrar(initial_types_with_nigori, |
121 name_, | 131 name_, |
122 profile_, | 132 profile_, |
123 sync_thread_.message_loop())); | 133 sync_thread_.message_loop())); |
124 initialization_state_ = CREATING_SYNC_MANAGER; | 134 initialization_state_ = CREATING_SYNC_MANAGER; |
125 InitCore(Core::DoInitializeOptions( | 135 InitCore(DoInitializeOptions( |
126 sync_thread_.message_loop(), | 136 sync_thread_.message_loop(), |
127 registrar_.get(), | 137 registrar_.get(), |
128 event_handler, | 138 event_handler, |
129 sync_service_url, | 139 sync_service_url, |
130 profile_->GetRequestContext(), | 140 base::Bind(&MakeHttpBridgeFactory, |
Nicolas Zea
2011/12/14 20:37:25
Since MakeHttpBridgeFactory is now an anon functio
akalin
2011/12/15 01:21:05
Yeah. Added comment in header file saying the clo
| |
141 make_scoped_refptr(profile_->GetRequestContext())), | |
131 credentials, | 142 credentials, |
143 &sync_notifier_factory_, | |
132 delete_sync_data_folder, | 144 delete_sync_data_folder, |
133 sync_prefs_->GetEncryptionBootstrapToken(), | 145 sync_prefs_->GetEncryptionBootstrapToken(), |
134 false)); | 146 false)); |
135 } | 147 } |
136 | 148 |
137 void SyncBackendHost::InitCore(const Core::DoInitializeOptions& options) { | |
138 sync_thread_.message_loop()->PostTask(FROM_HERE, | |
139 base::Bind(&SyncBackendHost::Core::DoInitialize, core_.get(),options)); | |
140 } | |
141 | |
142 void SyncBackendHost::UpdateCredentials(const SyncCredentials& credentials) { | 149 void SyncBackendHost::UpdateCredentials(const SyncCredentials& credentials) { |
143 sync_thread_.message_loop()->PostTask(FROM_HERE, | 150 sync_thread_.message_loop()->PostTask(FROM_HERE, |
144 base::Bind(&SyncBackendHost::Core::DoUpdateCredentials, core_.get(), | 151 base::Bind(&SyncBackendHost::Core::DoUpdateCredentials, core_.get(), |
145 credentials)); | 152 credentials)); |
146 } | 153 } |
147 | 154 |
148 void SyncBackendHost::StartSyncingWithServer() { | 155 void SyncBackendHost::StartSyncingWithServer() { |
149 SDVLOG(1) << "SyncBackendHost::StartSyncingWithServer called."; | 156 SDVLOG(1) << "SyncBackendHost::StartSyncingWithServer called."; |
150 sync_thread_.message_loop()->PostTask(FROM_HERE, | 157 sync_thread_.message_loop()->PostTask(FROM_HERE, |
151 base::Bind(&SyncBackendHost::Core::DoStartSyncing, core_.get())); | 158 base::Bind(&SyncBackendHost::Core::DoStartSyncing, core_.get())); |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
373 void SyncBackendHost::GetModelSafeRoutingInfo( | 380 void SyncBackendHost::GetModelSafeRoutingInfo( |
374 ModelSafeRoutingInfo* out) const { | 381 ModelSafeRoutingInfo* out) const { |
375 if (initialized()) { | 382 if (initialized()) { |
376 CHECK(registrar_.get()); | 383 CHECK(registrar_.get()); |
377 registrar_->GetModelSafeRoutingInfo(out); | 384 registrar_->GetModelSafeRoutingInfo(out); |
378 } else { | 385 } else { |
379 NOTREACHED(); | 386 NOTREACHED(); |
380 } | 387 } |
381 } | 388 } |
382 | 389 |
390 void SyncBackendHost::InitCore(const DoInitializeOptions& options) { | |
391 sync_thread_.message_loop()->PostTask(FROM_HERE, | |
392 base::Bind(&SyncBackendHost::Core::DoInitialize, core_.get(),options)); | |
393 } | |
394 | |
395 void SyncBackendHost::HandleSyncCycleCompletedOnFrontendLoop( | |
396 SyncSessionSnapshot* snapshot) { | |
397 if (!frontend_) | |
398 return; | |
399 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | |
400 | |
401 last_snapshot_.reset(snapshot); | |
402 | |
403 SDVLOG(1) << "Got snapshot " << snapshot->ToString(); | |
404 | |
405 const syncable::ModelTypeSet to_migrate = | |
406 snapshot->syncer_status.types_needing_local_migration; | |
407 if (!to_migrate.Empty()) | |
408 frontend_->OnMigrationNeededForTypes(to_migrate); | |
409 | |
410 // Process any changes to the datatypes we're syncing. | |
411 // TODO(sync): add support for removing types. | |
412 if (initialized()) | |
413 AddExperimentalTypes(); | |
414 | |
415 // If we are waiting for a configuration change, check here to see | |
416 // if this sync cycle has initialized all of the types we've been | |
417 // waiting for. | |
418 if (pending_download_state_.get()) { | |
419 scoped_ptr<PendingConfigureDataTypesState> state( | |
420 pending_download_state_.release()); | |
421 const syncable::ModelTypeSet types_to_add = state->types_to_add; | |
422 const syncable::ModelTypeSet added_types = state->added_types; | |
423 DCHECK(types_to_add.HasAll(added_types)); | |
424 const syncable::ModelTypeSet initial_sync_ended = | |
425 snapshot->initial_sync_ended; | |
426 const syncable::ModelTypeSet failed_configuration_types = | |
427 Difference(added_types, initial_sync_ended); | |
428 SDVLOG(1) | |
429 << "Added types: " | |
430 << syncable::ModelTypeSetToString(added_types) | |
431 << ", configured types: " | |
432 << syncable::ModelTypeSetToString(initial_sync_ended) | |
433 << ", failed configuration types: " | |
434 << syncable::ModelTypeSetToString(failed_configuration_types); | |
435 state->ready_task.Run(failed_configuration_types); | |
436 if (!failed_configuration_types.Empty()) | |
437 return; | |
438 } | |
439 | |
440 if (initialized()) | |
441 frontend_->OnSyncCycleCompleted(); | |
442 } | |
443 | |
444 void SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop() { | |
445 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | |
446 // Nudge the syncer. This is necessary for both datatype addition/deletion. | |
447 // | |
448 // Deletions need a nudge in order to ensure the deletion occurs in a timely | |
449 // manner (see issue 56416). | |
450 // | |
451 // In the case of additions, on the next sync cycle, the syncer should | |
452 // notice that the routing info has changed and start the process of | |
453 // downloading updates for newly added data types. Once this is | |
454 // complete, the configure_state_.ready_task_ is run via an | |
455 // OnInitializationComplete notification. | |
456 | |
457 SDVLOG(1) << "Syncer in config mode. SBH executing " | |
458 << "FinishConfigureDataTypesOnFrontendLoop"; | |
459 | |
460 if (pending_config_mode_state_->added_types.Empty() && | |
461 !core_->sync_manager()->InitialSyncEndedForAllEnabledTypes()) { | |
462 | |
463 syncable::ModelTypeSet enabled_types; | |
464 ModelSafeRoutingInfo routing_info; | |
465 registrar_->GetModelSafeRoutingInfo(&routing_info); | |
466 for (ModelSafeRoutingInfo::const_iterator i = routing_info.begin(); | |
467 i != routing_info.end(); ++i) { | |
468 enabled_types.Put(i->first); | |
469 } | |
470 | |
471 // TODO(tim): Log / UMA / count this somehow? | |
472 // Add only the types with empty progress markers. Note: it is possible | |
473 // that some types have their initial_sync_ended be false but with non | |
474 // empty progress marker. Which is ok as the rest of the changes would | |
475 // be downloaded on a regular nudge and initial_sync_ended should be set | |
476 // to true. However this is a very corner case. So it is not explicitly | |
477 // handled. | |
478 pending_config_mode_state_->added_types = | |
479 sync_api::GetTypesWithEmptyProgressMarkerToken(enabled_types, | |
480 GetUserShare()); | |
481 } | |
482 | |
483 // If we've added types, we always want to request a nudge/config (even if | |
484 // the initial sync is ended), in case we could not decrypt the data. | |
485 if (pending_config_mode_state_->added_types.Empty()) { | |
486 SDVLOG(1) << "No new types added; calling ready_task directly"; | |
487 // No new types - just notify the caller that the types are available. | |
488 const syncable::ModelTypeSet failed_configuration_types; | |
489 pending_config_mode_state_->ready_task.Run(failed_configuration_types); | |
490 } else { | |
491 pending_download_state_.reset(pending_config_mode_state_.release()); | |
492 | |
493 // Always configure nigori if it's enabled. | |
494 syncable::ModelTypeSet types_to_config = | |
495 pending_download_state_->added_types; | |
496 if (IsNigoriEnabled()) { | |
497 // Note: Nigori is the only type that gets added with a nonempty | |
498 // progress marker during config. If the server returns a migration | |
499 // error then we will go into unrecoverable error. We dont handle it | |
500 // explicitly because server might help us out here by not sending a | |
501 // migraiton error for nigori during config. | |
502 types_to_config.Put(syncable::NIGORI); | |
503 } | |
504 SDVLOG(1) << "Types " | |
505 << syncable::ModelTypeSetToString(types_to_config) | |
506 << " added; calling DoRequestConfig"; | |
507 sync_thread_.message_loop()->PostTask(FROM_HERE, | |
508 base::Bind(&SyncBackendHost::Core::DoRequestConfig, | |
509 core_.get(), | |
510 types_to_config, | |
511 pending_download_state_->reason)); | |
512 } | |
513 | |
514 pending_config_mode_state_.reset(); | |
515 | |
516 // Notify the SyncManager about the new types. | |
517 sync_thread_.message_loop()->PostTask(FROM_HERE, | |
518 base::Bind(&SyncBackendHost::Core::DoUpdateEnabledTypes, core_.get())); | |
519 } | |
520 | |
521 SyncBackendHost::DoInitializeOptions::DoInitializeOptions( | |
522 MessageLoop* sync_loop, | |
523 SyncBackendRegistrar* registrar, | |
524 const WeakHandle<JsEventHandler>& event_handler, | |
525 const GURL& service_url, | |
526 MakeHttpBridgeFactoryFn make_http_bridge_factory_fn, | |
527 const sync_api::SyncCredentials& credentials, | |
528 sync_notifier::SyncNotifierFactory* sync_notifier_factory, | |
529 bool delete_sync_data_folder, | |
530 const std::string& restored_key_for_bootstrapping, | |
531 bool setup_for_test_mode) | |
532 : sync_loop(sync_loop), | |
533 registrar(registrar), | |
534 event_handler(event_handler), | |
535 service_url(service_url), | |
536 make_http_bridge_factory_fn(make_http_bridge_factory_fn), | |
537 credentials(credentials), | |
538 sync_notifier_factory(sync_notifier_factory), | |
539 delete_sync_data_folder(delete_sync_data_folder), | |
540 restored_key_for_bootstrapping(restored_key_for_bootstrapping), | |
541 setup_for_test_mode(setup_for_test_mode) { | |
542 } | |
543 | |
544 SyncBackendHost::DoInitializeOptions::~DoInitializeOptions() {} | |
545 | |
383 SyncBackendHost::Core::Core(const std::string& name, | 546 SyncBackendHost::Core::Core(const std::string& name, |
384 SyncBackendHost* backend) | 547 const FilePath& sync_data_folder_path, |
548 const base::WeakPtr<SyncBackendHost>& backend) | |
385 : name_(name), | 549 : name_(name), |
550 sync_data_folder_path_(sync_data_folder_path), | |
386 host_(backend), | 551 host_(backend), |
387 sync_loop_(NULL), | 552 sync_loop_(NULL), |
388 registrar_(NULL) { | 553 registrar_(NULL) { |
389 DCHECK(host_); | 554 DCHECK(backend.get()); |
390 } | 555 } |
391 | 556 |
392 SyncBackendHost::Core::~Core() { | 557 SyncBackendHost::Core::~Core() { |
393 DCHECK(!sync_manager_.get()); | 558 DCHECK(!sync_manager_.get()); |
394 DCHECK(!sync_loop_); | 559 DCHECK(!sync_loop_); |
395 } | 560 } |
396 | 561 |
562 SyncBackendHost::PendingConfigureDataTypesState:: | |
563 PendingConfigureDataTypesState() | |
564 : reason(sync_api::CONFIGURE_REASON_UNKNOWN) {} | |
565 | |
566 SyncBackendHost::PendingConfigureDataTypesState:: | |
567 ~PendingConfigureDataTypesState() {} | |
568 | |
397 void SyncBackendHost::Core::OnSyncCycleCompleted( | 569 void SyncBackendHost::Core::OnSyncCycleCompleted( |
398 const SyncSessionSnapshot* snapshot) { | 570 const SyncSessionSnapshot* snapshot) { |
399 if (!sync_loop_) | 571 if (!sync_loop_) |
400 return; | 572 return; |
401 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 573 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
402 host_->frontend_loop_->PostTask(FROM_HERE, base::Bind( | 574 host_.Call( |
403 &Core::HandleSyncCycleCompletedOnFrontendLoop, | 575 FROM_HERE, |
404 this, | 576 &SyncBackendHost::HandleSyncCycleCompletedOnFrontendLoop, |
405 new SyncSessionSnapshot(*snapshot))); | 577 new SyncSessionSnapshot(*snapshot)); |
406 } | 578 } |
407 | 579 |
408 | 580 |
409 void SyncBackendHost::Core::OnInitializationComplete( | 581 void SyncBackendHost::Core::OnInitializationComplete( |
410 const WeakHandle<JsBackend>& js_backend, | 582 const WeakHandle<JsBackend>& js_backend, |
411 bool success) { | 583 bool success) { |
412 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 584 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
413 | 585 host_.Call( |
414 host_->frontend_loop_->PostTask(FROM_HERE, | 586 FROM_HERE, |
415 base::Bind(&Core::HandleInitializationCompletedOnFrontendLoop, this, | 587 &SyncBackendHost::HandleInitializationCompletedOnFrontendLoop, |
416 js_backend, success)); | 588 js_backend, success); |
417 | 589 |
418 if (success) { | 590 if (success) { |
419 // Initialization is complete, so we can schedule recurring SaveChanges. | 591 // Initialization is complete, so we can schedule recurring SaveChanges. |
420 sync_loop_->PostTask(FROM_HERE, | 592 sync_loop_->PostTask(FROM_HERE, |
421 base::Bind(&Core::StartSavingChanges, this)); | 593 base::Bind(&Core::StartSavingChanges, this)); |
422 } | 594 } |
423 } | 595 } |
424 | 596 |
425 void SyncBackendHost::Core::OnAuthError(const AuthError& auth_error) { | 597 void SyncBackendHost::Core::OnAuthError(const AuthError& auth_error) { |
426 if (!sync_loop_) | 598 if (!sync_loop_) |
427 return; | 599 return; |
428 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 600 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
429 // Post to our core loop so we can modify state. Could be on another thread. | 601 host_.Call( |
430 host_->frontend_loop_->PostTask(FROM_HERE, | 602 FROM_HERE, |
431 base::Bind(&Core::HandleAuthErrorEventOnFrontendLoop, this, auth_error)); | 603 &SyncBackendHost::HandleAuthErrorEventOnFrontendLoop, auth_error); |
432 } | 604 } |
433 | 605 |
434 void SyncBackendHost::Core::OnPassphraseRequired( | 606 void SyncBackendHost::Core::OnPassphraseRequired( |
435 sync_api::PassphraseRequiredReason reason) { | 607 sync_api::PassphraseRequiredReason reason) { |
436 if (!sync_loop_) | 608 if (!sync_loop_) |
437 return; | 609 return; |
438 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 610 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
439 host_->frontend_loop_->PostTask(FROM_HERE, | 611 host_.Call( |
440 base::Bind(&Core::NotifyPassphraseRequired, this, reason)); | 612 FROM_HERE, |
613 &SyncBackendHost::NotifyPassphraseRequired, reason); | |
441 } | 614 } |
442 | 615 |
443 void SyncBackendHost::Core::OnPassphraseAccepted( | 616 void SyncBackendHost::Core::OnPassphraseAccepted( |
444 const std::string& bootstrap_token) { | 617 const std::string& bootstrap_token) { |
445 if (!sync_loop_) | 618 if (!sync_loop_) |
446 return; | 619 return; |
447 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 620 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
448 host_->frontend_loop_->PostTask(FROM_HERE, | 621 host_.Call( |
449 base::Bind(&Core::NotifyPassphraseAccepted, this, bootstrap_token)); | 622 FROM_HERE, |
623 &SyncBackendHost::NotifyPassphraseAccepted, bootstrap_token); | |
450 } | 624 } |
451 | 625 |
452 void SyncBackendHost::Core::OnStopSyncingPermanently() { | 626 void SyncBackendHost::Core::OnStopSyncingPermanently() { |
453 if (!sync_loop_) | 627 if (!sync_loop_) |
454 return; | 628 return; |
455 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 629 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
456 host_->frontend_loop_->PostTask(FROM_HERE, base::Bind( | 630 host_.Call( |
457 &Core::HandleStopSyncingPermanentlyOnFrontendLoop, this)); | 631 FROM_HERE, |
632 &SyncBackendHost::HandleStopSyncingPermanentlyOnFrontendLoop); | |
458 } | 633 } |
459 | 634 |
460 void SyncBackendHost::Core::OnUpdatedToken(const std::string& token) { | 635 void SyncBackendHost::Core::OnUpdatedToken(const std::string& token) { |
461 if (!sync_loop_) | 636 if (!sync_loop_) |
462 return; | 637 return; |
463 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 638 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
464 host_->frontend_loop_->PostTask(FROM_HERE, base::Bind( | 639 host_.Call( |
465 &Core::NotifyUpdatedToken, this, token)); | 640 FROM_HERE, |
641 &SyncBackendHost::NotifyUpdatedToken, token); | |
466 } | 642 } |
467 | 643 |
468 void SyncBackendHost::Core::OnClearServerDataFailed() { | 644 void SyncBackendHost::Core::OnClearServerDataFailed() { |
469 if (!sync_loop_) | 645 if (!sync_loop_) |
470 return; | 646 return; |
471 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 647 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
472 host_->frontend_loop_->PostTask(FROM_HERE, base::Bind( | 648 host_.Call( |
473 &Core::HandleClearServerDataFailedOnFrontendLoop, this)); | 649 FROM_HERE, |
650 &SyncBackendHost::HandleClearServerDataFailedOnFrontendLoop); | |
474 } | 651 } |
475 | 652 |
476 void SyncBackendHost::Core::OnClearServerDataSucceeded() { | 653 void SyncBackendHost::Core::OnClearServerDataSucceeded() { |
477 if (!sync_loop_) | 654 if (!sync_loop_) |
478 return; | 655 return; |
479 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 656 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
480 host_->frontend_loop_->PostTask(FROM_HERE, base::Bind( | 657 host_.Call( |
481 &Core::HandleClearServerDataSucceededOnFrontendLoop, this)); | 658 FROM_HERE, |
659 &SyncBackendHost::HandleClearServerDataSucceededOnFrontendLoop); | |
482 } | 660 } |
483 | 661 |
484 void SyncBackendHost::Core::OnEncryptedTypesChanged( | 662 void SyncBackendHost::Core::OnEncryptedTypesChanged( |
485 syncable::ModelTypeSet encrypted_types, | 663 syncable::ModelTypeSet encrypted_types, |
486 bool encrypt_everything) { | 664 bool encrypt_everything) { |
487 if (!sync_loop_) | 665 if (!sync_loop_) |
488 return; | 666 return; |
489 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 667 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
490 // NOTE: We're in a transaction. | 668 // NOTE: We're in a transaction. |
491 host_->frontend_loop_->PostTask( | 669 host_.Call( |
492 FROM_HERE, | 670 FROM_HERE, |
493 base::Bind(&Core::NotifyEncryptedTypesChanged, this, | 671 &SyncBackendHost::NotifyEncryptedTypesChanged, |
494 encrypted_types, encrypt_everything)); | 672 encrypted_types, encrypt_everything); |
495 } | 673 } |
496 | 674 |
497 void SyncBackendHost::Core::OnEncryptionComplete() { | 675 void SyncBackendHost::Core::OnEncryptionComplete() { |
498 if (!sync_loop_) | 676 if (!sync_loop_) |
499 return; | 677 return; |
500 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 678 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
501 // NOTE: We're in a transaction. | 679 // NOTE: We're in a transaction. |
502 host_->frontend_loop_->PostTask( | 680 host_.Call( |
503 FROM_HERE, | 681 FROM_HERE, |
504 base::Bind(&Core::NotifyEncryptionComplete, this)); | 682 &SyncBackendHost::NotifyEncryptionComplete); |
505 } | 683 } |
506 | 684 |
507 void SyncBackendHost::Core::OnActionableError( | 685 void SyncBackendHost::Core::OnActionableError( |
508 const browser_sync::SyncProtocolError& sync_error) { | 686 const browser_sync::SyncProtocolError& sync_error) { |
509 if (!sync_loop_) | 687 if (!sync_loop_) |
510 return; | 688 return; |
511 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 689 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
512 host_->frontend_loop_->PostTask( | 690 host_.Call( |
513 FROM_HERE, | 691 FROM_HERE, |
514 base::Bind(&Core::HandleActionableErrorEventOnFrontendLoop, this, | 692 &SyncBackendHost::HandleActionableErrorEventOnFrontendLoop, |
515 sync_error)); | 693 sync_error); |
516 } | 694 } |
517 | 695 |
518 SyncBackendHost::Core::DoInitializeOptions::DoInitializeOptions( | |
519 MessageLoop* sync_loop, | |
520 SyncBackendRegistrar* registrar, | |
521 const WeakHandle<JsEventHandler>& event_handler, | |
522 const GURL& service_url, | |
523 const scoped_refptr<net::URLRequestContextGetter>& | |
524 request_context_getter, | |
525 const sync_api::SyncCredentials& credentials, | |
526 bool delete_sync_data_folder, | |
527 const std::string& restored_key_for_bootstrapping, | |
528 bool setup_for_test_mode) | |
529 : sync_loop(sync_loop), | |
530 registrar(registrar), | |
531 event_handler(event_handler), | |
532 service_url(service_url), | |
533 request_context_getter(request_context_getter), | |
534 credentials(credentials), | |
535 delete_sync_data_folder(delete_sync_data_folder), | |
536 restored_key_for_bootstrapping(restored_key_for_bootstrapping), | |
537 setup_for_test_mode(setup_for_test_mode) { | |
538 } | |
539 | |
540 SyncBackendHost::Core::DoInitializeOptions::~DoInitializeOptions() {} | |
541 | |
542 // Helper to construct a user agent string (ASCII) suitable for use by | 696 // Helper to construct a user agent string (ASCII) suitable for use by |
543 // the syncapi for any HTTP communication. This string is used by the sync | 697 // the syncapi for any HTTP communication. This string is used by the sync |
544 // backend for classifying client types when calculating statistics. | 698 // backend for classifying client types when calculating statistics. |
545 std::string MakeUserAgentForSyncApi() { | 699 std::string MakeUserAgentForSyncApi() { |
546 std::string user_agent; | 700 std::string user_agent; |
547 user_agent = "Chrome "; | 701 user_agent = "Chrome "; |
548 #if defined(OS_WIN) | 702 #if defined(OS_WIN) |
549 user_agent += "WIN "; | 703 user_agent += "WIN "; |
550 #elif defined(OS_LINUX) | 704 #elif defined(OS_LINUX) |
551 user_agent += "LINUX "; | 705 user_agent += "LINUX "; |
(...skipping 23 matching lines...) Expand all Loading... | |
575 DCHECK(sync_loop_); | 729 DCHECK(sync_loop_); |
576 | 730 |
577 // Blow away the partial or corrupt sync data folder before doing any more | 731 // Blow away the partial or corrupt sync data folder before doing any more |
578 // initialization, if necessary. | 732 // initialization, if necessary. |
579 if (options.delete_sync_data_folder) { | 733 if (options.delete_sync_data_folder) { |
580 DeleteSyncDataFolder(); | 734 DeleteSyncDataFolder(); |
581 } | 735 } |
582 | 736 |
583 // Make sure that the directory exists before initializing the backend. | 737 // Make sure that the directory exists before initializing the backend. |
584 // If it already exists, this will do no harm. | 738 // If it already exists, this will do no harm. |
585 bool success = file_util::CreateDirectory(host_->sync_data_folder_path()); | 739 bool success = file_util::CreateDirectory(sync_data_folder_path_); |
586 DCHECK(success); | 740 DCHECK(success); |
587 | 741 |
588 DCHECK(!registrar_); | 742 DCHECK(!registrar_); |
589 registrar_ = options.registrar; | 743 registrar_ = options.registrar; |
590 DCHECK(registrar_); | 744 DCHECK(registrar_); |
591 | 745 |
592 sync_manager_.reset(new sync_api::SyncManager(name_)); | 746 sync_manager_.reset(new sync_api::SyncManager(name_)); |
593 sync_manager_->AddObserver(this); | 747 sync_manager_->AddObserver(this); |
594 const FilePath& path_str = host_->sync_data_folder_path(); | |
595 success = sync_manager_->Init( | 748 success = sync_manager_->Init( |
596 path_str, | 749 sync_data_folder_path_, |
597 options.event_handler, | 750 options.event_handler, |
598 options.service_url.host() + options.service_url.path(), | 751 options.service_url.host() + options.service_url.path(), |
599 options.service_url.EffectiveIntPort(), | 752 options.service_url.EffectiveIntPort(), |
600 options.service_url.SchemeIsSecure(), | 753 options.service_url.SchemeIsSecure(), |
601 host_->MakeHttpBridgeFactory(options.request_context_getter), | 754 options.make_http_bridge_factory_fn.Run(), |
602 options.registrar /* as ModelSafeWorkerRegistrar */, | 755 options.registrar /* as ModelSafeWorkerRegistrar */, |
603 options.registrar /* as SyncManager::ChangeDelegate */, | 756 options.registrar /* as SyncManager::ChangeDelegate */, |
604 MakeUserAgentForSyncApi(), | 757 MakeUserAgentForSyncApi(), |
605 options.credentials, | 758 options.credentials, |
606 host_->sync_notifier_factory_.CreateSyncNotifier(), | 759 options.sync_notifier_factory->CreateSyncNotifier(), |
607 options.restored_key_for_bootstrapping, | 760 options.restored_key_for_bootstrapping, |
608 options.setup_for_test_mode); | 761 options.setup_for_test_mode); |
609 LOG_IF(ERROR, !success) << "Syncapi initialization failed!"; | 762 LOG_IF(ERROR, !success) << "Syncapi initialization failed!"; |
610 } | 763 } |
611 | 764 |
612 void SyncBackendHost::Core::DoCheckServerReachable() { | 765 void SyncBackendHost::Core::DoCheckServerReachable() { |
613 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 766 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
614 sync_manager_->CheckServerReachable(); | 767 sync_manager_->CheckServerReachable(); |
615 } | 768 } |
616 | 769 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
673 sync_manager_->ShutdownOnSyncThread(); | 826 sync_manager_->ShutdownOnSyncThread(); |
674 sync_manager_->RemoveObserver(this); | 827 sync_manager_->RemoveObserver(this); |
675 sync_manager_.reset(); | 828 sync_manager_.reset(); |
676 registrar_ = NULL; | 829 registrar_ = NULL; |
677 | 830 |
678 if (sync_disabled) | 831 if (sync_disabled) |
679 DeleteSyncDataFolder(); | 832 DeleteSyncDataFolder(); |
680 | 833 |
681 sync_loop_ = NULL; | 834 sync_loop_ = NULL; |
682 | 835 |
683 host_ = NULL; | 836 host_.Reset(); |
684 } | 837 } |
685 | 838 |
686 void SyncBackendHost::Core::DoRequestConfig( | 839 void SyncBackendHost::Core::DoRequestConfig( |
687 syncable::ModelTypeSet types_to_config, | 840 syncable::ModelTypeSet types_to_config, |
688 sync_api::ConfigureReason reason) { | 841 sync_api::ConfigureReason reason) { |
689 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 842 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
690 sync_manager_->RequestConfig(types_to_config, reason); | 843 sync_manager_->RequestConfig(types_to_config, reason); |
691 } | 844 } |
692 | 845 |
693 void SyncBackendHost::Core::DoStartConfiguration( | 846 void SyncBackendHost::Core::DoStartConfiguration( |
694 const base::Closure& callback) { | 847 const base::Closure& callback) { |
695 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 848 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
696 sync_manager_->StartConfigurationMode(callback); | 849 sync_manager_->StartConfigurationMode(callback); |
697 } | 850 } |
698 | 851 |
699 void SyncBackendHost::Core::DeleteSyncDataFolder() { | 852 void SyncBackendHost::Core::DeleteSyncDataFolder() { |
700 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 853 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
701 if (file_util::DirectoryExists(host_->sync_data_folder_path())) { | 854 if (file_util::DirectoryExists(sync_data_folder_path_)) { |
702 if (!file_util::Delete(host_->sync_data_folder_path(), true)) | 855 if (!file_util::Delete(sync_data_folder_path_, true)) |
703 SLOG(DFATAL) << "Could not delete the Sync Data folder."; | 856 SLOG(DFATAL) << "Could not delete the Sync Data folder."; |
704 } | 857 } |
705 } | 858 } |
706 | 859 |
707 void SyncBackendHost::Core::FinishConfigureDataTypes() { | 860 void SyncBackendHost::Core::FinishConfigureDataTypes() { |
708 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 861 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
709 host_->frontend_loop_->PostTask(FROM_HERE, base::Bind( | 862 host_.Call( |
710 &SyncBackendHost::Core::FinishConfigureDataTypesOnFrontendLoop, this)); | 863 FROM_HERE, |
711 } | 864 &SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop); |
712 | |
713 void SyncBackendHost::Core::HandleInitializationCompletedOnFrontendLoop( | |
714 const WeakHandle<JsBackend>& js_backend, | |
715 bool success) { | |
716 if (!host_) | |
717 return; | |
718 host_->HandleInitializationCompletedOnFrontendLoop(js_backend, success); | |
719 } | |
720 | |
721 void SyncBackendHost::Core::HandleNigoriConfigurationCompletedOnFrontendLoop( | |
722 const WeakHandle<JsBackend>& js_backend, | |
723 const syncable::ModelTypeSet failed_configuration_types) { | |
724 if (!host_) | |
725 return; | |
726 host_->HandleInitializationCompletedOnFrontendLoop( | |
727 js_backend, failed_configuration_types.Empty()); | |
728 } | 865 } |
729 | 866 |
730 void SyncBackendHost::Core::StartSavingChanges() { | 867 void SyncBackendHost::Core::StartSavingChanges() { |
731 // We may already be shut down. | 868 // We may already be shut down. |
732 if (!sync_loop_) | 869 if (!sync_loop_) |
733 return; | 870 return; |
734 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 871 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
735 save_changes_timer_.Start(FROM_HERE, | 872 save_changes_timer_.Start(FROM_HERE, |
736 base::TimeDelta::FromSeconds(kSaveChangesIntervalSeconds), | 873 base::TimeDelta::FromSeconds(kSaveChangesIntervalSeconds), |
737 this, &Core::SaveChanges); | 874 this, &Core::SaveChanges); |
738 } | 875 } |
739 | 876 |
740 void SyncBackendHost::Core::SaveChanges() { | 877 void SyncBackendHost::Core::SaveChanges() { |
741 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 878 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
742 sync_manager_->SaveChanges(); | 879 sync_manager_->SaveChanges(); |
743 } | 880 } |
744 | 881 |
745 void SyncBackendHost::Core::HandleActionableErrorEventOnFrontendLoop( | |
746 const browser_sync::SyncProtocolError& sync_error) { | |
747 if (!host_ || !host_->frontend_) | |
748 return; | |
749 DCHECK_EQ(MessageLoop::current(), host_->frontend_loop_); | |
750 host_->frontend_->OnActionableError(sync_error); | |
751 } | |
752 | |
753 void SyncBackendHost::Core::HandleAuthErrorEventOnFrontendLoop( | |
754 const GoogleServiceAuthError& new_auth_error) { | |
755 if (!host_ || !host_->frontend_) | |
756 return; | |
757 | |
758 DCHECK_EQ(MessageLoop::current(), host_->frontend_loop_); | |
759 | |
760 host_->last_auth_error_ = new_auth_error; | |
761 host_->frontend_->OnAuthError(); | |
762 } | |
763 | |
764 void SyncBackendHost::Core::NotifyPassphraseRequired( | |
765 sync_api::PassphraseRequiredReason reason) { | |
766 if (!host_ || !host_->frontend_) | |
767 return; | |
768 | |
769 DCHECK_EQ(MessageLoop::current(), host_->frontend_loop_); | |
770 | |
771 host_->frontend_->OnPassphraseRequired(reason); | |
772 } | |
773 | |
774 void SyncBackendHost::Core::NotifyPassphraseAccepted( | |
775 const std::string& bootstrap_token) { | |
776 if (!host_ || !host_->frontend_) | |
777 return; | |
778 | |
779 DCHECK_EQ(MessageLoop::current(), host_->frontend_loop_); | |
780 | |
781 host_->PersistEncryptionBootstrapToken(bootstrap_token); | |
782 host_->frontend_->OnPassphraseAccepted(); | |
783 } | |
784 | |
785 void SyncBackendHost::Core::NotifyUpdatedToken(const std::string& token) { | |
786 if (!host_) | |
787 return; | |
788 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
789 TokenAvailableDetails details(GaiaConstants::kSyncService, token); | |
790 content::NotificationService::current()->Notify( | |
791 chrome::NOTIFICATION_TOKEN_UPDATED, | |
792 content::Source<Profile>(host_->profile_), | |
793 content::Details<const TokenAvailableDetails>(&details)); | |
794 } | |
795 | |
796 void SyncBackendHost::Core::NotifyEncryptedTypesChanged( | |
797 syncable::ModelTypeSet encrypted_types, | |
798 bool encrypt_everything) { | |
799 if (!host_) | |
800 return; | |
801 DCHECK_EQ(MessageLoop::current(), host_->frontend_loop_); | |
802 host_->frontend_->OnEncryptedTypesChanged( | |
803 encrypted_types, encrypt_everything); | |
804 } | |
805 | |
806 void SyncBackendHost::Core::NotifyEncryptionComplete() { | |
807 if (!host_) | |
808 return; | |
809 DCHECK_EQ(MessageLoop::current(), host_->frontend_loop_); | |
810 host_->frontend_->OnEncryptionComplete(); | |
811 } | |
812 | |
813 void SyncBackendHost::Core::HandleSyncCycleCompletedOnFrontendLoop( | |
814 SyncSessionSnapshot* snapshot) { | |
815 if (!host_ || !host_->frontend_) | |
816 return; | |
817 DCHECK_EQ(MessageLoop::current(), host_->frontend_loop_); | |
818 | |
819 host_->last_snapshot_.reset(snapshot); | |
820 | |
821 SDVLOG(1) << "Got snapshot " << snapshot->ToString(); | |
822 | |
823 const syncable::ModelTypeSet to_migrate = | |
824 snapshot->syncer_status.types_needing_local_migration; | |
825 if (!to_migrate.Empty()) | |
826 host_->frontend_->OnMigrationNeededForTypes(to_migrate); | |
827 | |
828 // Process any changes to the datatypes we're syncing. | |
829 // TODO(sync): add support for removing types. | |
830 if (host_->initialized()) | |
831 host_->AddExperimentalTypes(); | |
832 | |
833 // If we are waiting for a configuration change, check here to see | |
834 // if this sync cycle has initialized all of the types we've been | |
835 // waiting for. | |
836 if (host_->pending_download_state_.get()) { | |
837 scoped_ptr<PendingConfigureDataTypesState> state( | |
838 host_->pending_download_state_.release()); | |
839 const syncable::ModelTypeSet types_to_add = state->types_to_add; | |
840 const syncable::ModelTypeSet added_types = state->added_types; | |
841 DCHECK(types_to_add.HasAll(added_types)); | |
842 const syncable::ModelTypeSet initial_sync_ended = | |
843 snapshot->initial_sync_ended; | |
844 const syncable::ModelTypeSet failed_configuration_types = | |
845 Difference(added_types, initial_sync_ended); | |
846 SDVLOG(1) | |
847 << "Added types: " | |
848 << syncable::ModelTypeSetToString(added_types) | |
849 << ", configured types: " | |
850 << syncable::ModelTypeSetToString(initial_sync_ended) | |
851 << ", failed configuration types: " | |
852 << syncable::ModelTypeSetToString(failed_configuration_types); | |
853 state->ready_task.Run(failed_configuration_types); | |
854 if (!failed_configuration_types.Empty()) | |
855 return; | |
856 } | |
857 | |
858 if (host_->initialized()) | |
859 host_->frontend_->OnSyncCycleCompleted(); | |
860 } | |
861 | |
862 void SyncBackendHost::Core::HandleStopSyncingPermanentlyOnFrontendLoop() { | |
863 if (!host_ || !host_->frontend_) | |
864 return; | |
865 host_->frontend_->OnStopSyncingPermanently(); | |
866 } | |
867 | |
868 void SyncBackendHost::Core::HandleClearServerDataSucceededOnFrontendLoop() { | |
869 if (!host_ || !host_->frontend_) | |
870 return; | |
871 host_->frontend_->OnClearServerDataSucceeded(); | |
872 } | |
873 | |
874 void SyncBackendHost::Core::HandleClearServerDataFailedOnFrontendLoop() { | |
875 if (!host_ || !host_->frontend_) | |
876 return; | |
877 host_->frontend_->OnClearServerDataFailed(); | |
878 } | |
879 | |
880 void SyncBackendHost::Core::FinishConfigureDataTypesOnFrontendLoop() { | |
881 host_->FinishConfigureDataTypesOnFrontendLoop(); | |
882 } | |
883 | |
884 void SyncBackendHost::AddExperimentalTypes() { | 882 void SyncBackendHost::AddExperimentalTypes() { |
885 CHECK(initialized()); | 883 CHECK(initialized()); |
886 syncable::ModelTypeSet to_add; | 884 syncable::ModelTypeSet to_add; |
887 if (core_->sync_manager()->ReceivedExperimentalTypes(&to_add)) | 885 if (core_->sync_manager()->ReceivedExperimentalTypes(&to_add)) |
888 frontend_->OnDataTypesChanged(to_add); | 886 frontend_->OnDataTypesChanged(to_add); |
889 } | 887 } |
890 | 888 |
891 void SyncBackendHost::HandleInitializationCompletedOnFrontendLoop( | 889 void SyncBackendHost::HandleInitializationCompletedOnFrontendLoop( |
892 const WeakHandle<JsBackend>& js_backend, bool success) { | 890 const WeakHandle<JsBackend>& js_backend, bool success) { |
893 DCHECK_NE(NOT_ATTEMPTED, initialization_state_); | 891 DCHECK_NE(NOT_ATTEMPTED, initialization_state_); |
(...skipping 23 matching lines...) Expand all Loading... | |
917 // Run initialization state machine. | 915 // Run initialization state machine. |
918 switch (initialization_state_) { | 916 switch (initialization_state_) { |
919 case NOT_INITIALIZED: | 917 case NOT_INITIALIZED: |
920 initialization_state_ = DOWNLOADING_NIGORI; | 918 initialization_state_ = DOWNLOADING_NIGORI; |
921 ConfigureDataTypes( | 919 ConfigureDataTypes( |
922 syncable::ModelTypeSet(), | 920 syncable::ModelTypeSet(), |
923 syncable::ModelTypeSet(), | 921 syncable::ModelTypeSet(), |
924 sync_api::CONFIGURE_REASON_NEW_CLIENT, | 922 sync_api::CONFIGURE_REASON_NEW_CLIENT, |
925 // Calls back into this function. | 923 // Calls back into this function. |
926 base::Bind( | 924 base::Bind( |
927 &SyncBackendHost::Core:: | 925 &SyncBackendHost:: |
928 HandleNigoriConfigurationCompletedOnFrontendLoop, | 926 HandleNigoriConfigurationCompletedOnFrontendLoop, |
929 core_.get(), js_backend), | 927 weak_ptr_factory_.GetWeakPtr(), js_backend), |
930 true); | 928 true); |
931 break; | 929 break; |
932 case DOWNLOADING_NIGORI: | 930 case DOWNLOADING_NIGORI: |
933 initialization_state_ = REFRESHING_ENCRYPTION; | 931 initialization_state_ = REFRESHING_ENCRYPTION; |
934 // Triggers OnEncryptedTypesChanged() and OnEncryptionComplete() | 932 // Triggers OnEncryptedTypesChanged() and OnEncryptionComplete() |
935 // if necessary. | 933 // if necessary. |
936 RefreshEncryption( | 934 RefreshEncryption( |
937 base::Bind( | 935 base::Bind( |
938 &SyncBackendHost::Core:: | 936 &SyncBackendHost:: |
939 HandleInitializationCompletedOnFrontendLoop, | 937 HandleInitializationCompletedOnFrontendLoop, |
940 core_.get(), js_backend, true)); | 938 weak_ptr_factory_.GetWeakPtr(), js_backend, true)); |
941 break; | 939 break; |
942 case REFRESHING_ENCRYPTION: | 940 case REFRESHING_ENCRYPTION: |
943 initialization_state_ = INITIALIZED; | 941 initialization_state_ = INITIALIZED; |
944 // Now that we've downloaded the nigori node, we can see if there are any | 942 // Now that we've downloaded the nigori node, we can see if there are any |
945 // experimental types to enable. This should be done before we inform | 943 // experimental types to enable. This should be done before we inform |
946 // the frontend to ensure they're visible in the customize screen. | 944 // the frontend to ensure they're visible in the customize screen. |
947 AddExperimentalTypes(); | 945 AddExperimentalTypes(); |
948 frontend_->OnBackendInitialized(js_backend, true); | 946 frontend_->OnBackendInitialized(js_backend, true); |
949 // Now that we're fully initialized, kick off a server | 947 // Now that we're fully initialized, kick off a server |
950 // reachability check. | 948 // reachability check. |
951 sync_thread_.message_loop()->PostTask( | 949 sync_thread_.message_loop()->PostTask( |
952 FROM_HERE, | 950 FROM_HERE, |
953 base::Bind(&SyncBackendHost::Core::DoCheckServerReachable, | 951 base::Bind(&SyncBackendHost::Core::DoCheckServerReachable, |
954 core_.get())); | 952 core_.get())); |
955 break; | 953 break; |
956 default: | 954 default: |
957 NOTREACHED(); | 955 NOTREACHED(); |
958 } | 956 } |
959 } | 957 } |
960 | 958 |
961 void SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop() { | |
962 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | |
963 // Nudge the syncer. This is necessary for both datatype addition/deletion. | |
964 // | |
965 // Deletions need a nudge in order to ensure the deletion occurs in a timely | |
966 // manner (see issue 56416). | |
967 // | |
968 // In the case of additions, on the next sync cycle, the syncer should | |
969 // notice that the routing info has changed and start the process of | |
970 // downloading updates for newly added data types. Once this is | |
971 // complete, the configure_state_.ready_task_ is run via an | |
972 // OnInitializationComplete notification. | |
973 | |
974 SDVLOG(1) << "Syncer in config mode. SBH executing " | |
975 << "FinishConfigureDataTypesOnFrontendLoop"; | |
976 | |
977 if (pending_config_mode_state_->added_types.Empty() && | |
978 !core_->sync_manager()->InitialSyncEndedForAllEnabledTypes()) { | |
979 | |
980 syncable::ModelTypeSet enabled_types; | |
981 ModelSafeRoutingInfo routing_info; | |
982 registrar_->GetModelSafeRoutingInfo(&routing_info); | |
983 for (ModelSafeRoutingInfo::const_iterator i = routing_info.begin(); | |
984 i != routing_info.end(); ++i) { | |
985 enabled_types.Put(i->first); | |
986 } | |
987 | |
988 // TODO(tim): Log / UMA / count this somehow? | |
989 // Add only the types with empty progress markers. Note: it is possible | |
990 // that some types have their initial_sync_ended be false but with non | |
991 // empty progress marker. Which is ok as the rest of the changes would | |
992 // be downloaded on a regular nudge and initial_sync_ended should be set | |
993 // to true. However this is a very corner case. So it is not explicitly | |
994 // handled. | |
995 pending_config_mode_state_->added_types = | |
996 sync_api::GetTypesWithEmptyProgressMarkerToken(enabled_types, | |
997 GetUserShare()); | |
998 } | |
999 | |
1000 // If we've added types, we always want to request a nudge/config (even if | |
1001 // the initial sync is ended), in case we could not decrypt the data. | |
1002 if (pending_config_mode_state_->added_types.Empty()) { | |
1003 SDVLOG(1) << "No new types added; calling ready_task directly"; | |
1004 // No new types - just notify the caller that the types are available. | |
1005 const syncable::ModelTypeSet failed_configuration_types; | |
1006 pending_config_mode_state_->ready_task.Run(failed_configuration_types); | |
1007 } else { | |
1008 pending_download_state_.reset(pending_config_mode_state_.release()); | |
1009 | |
1010 // Always configure nigori if it's enabled. | |
1011 syncable::ModelTypeSet types_to_config = | |
1012 pending_download_state_->added_types; | |
1013 if (IsNigoriEnabled()) { | |
1014 // Note: Nigori is the only type that gets added with a nonempty | |
1015 // progress marker during config. If the server returns a migration | |
1016 // error then we will go into unrecoverable error. We dont handle it | |
1017 // explicitly because server might help us out here by not sending a | |
1018 // migraiton error for nigori during config. | |
1019 types_to_config.Put(syncable::NIGORI); | |
1020 } | |
1021 SDVLOG(1) << "Types " << syncable::ModelTypeSetToString(types_to_config) | |
1022 << " added; calling DoRequestConfig"; | |
1023 sync_thread_.message_loop()->PostTask(FROM_HERE, | |
1024 base::Bind(&SyncBackendHost::Core::DoRequestConfig, | |
1025 core_.get(), | |
1026 types_to_config, | |
1027 pending_download_state_->reason)); | |
1028 } | |
1029 | |
1030 pending_config_mode_state_.reset(); | |
1031 | |
1032 // Notify the SyncManager about the new types. | |
1033 sync_thread_.message_loop()->PostTask(FROM_HERE, | |
1034 base::Bind(&SyncBackendHost::Core::DoUpdateEnabledTypes, core_.get())); | |
1035 } | |
1036 | |
1037 sync_api::HttpPostProviderFactory* SyncBackendHost::MakeHttpBridgeFactory( | |
1038 const scoped_refptr<net::URLRequestContextGetter>& getter) { | |
1039 return new HttpBridgeFactory(getter); | |
1040 } | |
1041 | |
1042 void SyncBackendHost::PersistEncryptionBootstrapToken( | 959 void SyncBackendHost::PersistEncryptionBootstrapToken( |
1043 const std::string& token) { | 960 const std::string& token) { |
1044 CHECK(sync_prefs_.get()); | 961 CHECK(sync_prefs_.get()); |
1045 sync_prefs_->SetEncryptionBootstrapToken(token); | 962 sync_prefs_->SetEncryptionBootstrapToken(token); |
1046 } | 963 } |
1047 | 964 |
1048 SyncBackendHost::PendingConfigureDataTypesState:: | 965 void SyncBackendHost::HandleActionableErrorEventOnFrontendLoop( |
1049 PendingConfigureDataTypesState() | 966 const browser_sync::SyncProtocolError& sync_error) { |
1050 : reason(sync_api::CONFIGURE_REASON_UNKNOWN) {} | 967 if (!frontend_) |
968 return; | |
969 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | |
970 frontend_->OnActionableError(sync_error); | |
971 } | |
1051 | 972 |
1052 SyncBackendHost::PendingConfigureDataTypesState:: | 973 void SyncBackendHost::NotifyPassphraseRequired( |
1053 ~PendingConfigureDataTypesState() {} | 974 sync_api::PassphraseRequiredReason reason) { |
975 if (!frontend_) | |
976 return; | |
977 | |
978 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | |
979 | |
980 frontend_->OnPassphraseRequired(reason); | |
981 } | |
982 | |
983 void SyncBackendHost::NotifyPassphraseAccepted( | |
984 const std::string& bootstrap_token) { | |
985 if (!frontend_) | |
986 return; | |
987 | |
988 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | |
989 | |
990 PersistEncryptionBootstrapToken(bootstrap_token); | |
991 frontend_->OnPassphraseAccepted(); | |
992 } | |
993 | |
994 void SyncBackendHost::NotifyUpdatedToken(const std::string& token) { | |
995 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
996 TokenAvailableDetails details(GaiaConstants::kSyncService, token); | |
997 content::NotificationService::current()->Notify( | |
998 chrome::NOTIFICATION_TOKEN_UPDATED, | |
999 content::Source<Profile>(profile_), | |
1000 content::Details<const TokenAvailableDetails>(&details)); | |
1001 } | |
1002 | |
1003 void SyncBackendHost::NotifyEncryptedTypesChanged( | |
1004 syncable::ModelTypeSet encrypted_types, | |
1005 bool encrypt_everything) { | |
1006 if (!frontend_) | |
1007 return; | |
1008 | |
1009 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | |
1010 frontend_->OnEncryptedTypesChanged( | |
1011 encrypted_types, encrypt_everything); | |
1012 } | |
1013 | |
1014 void SyncBackendHost::NotifyEncryptionComplete() { | |
1015 if (!frontend_) | |
1016 return; | |
1017 | |
1018 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | |
1019 frontend_->OnEncryptionComplete(); | |
1020 } | |
1021 | |
1022 void SyncBackendHost::HandleStopSyncingPermanentlyOnFrontendLoop() { | |
1023 if (!frontend_) | |
1024 return; | |
1025 frontend_->OnStopSyncingPermanently(); | |
1026 } | |
1027 | |
1028 void SyncBackendHost::HandleClearServerDataSucceededOnFrontendLoop() { | |
1029 if (!frontend_) | |
1030 return; | |
1031 frontend_->OnClearServerDataSucceeded(); | |
1032 } | |
1033 | |
1034 void SyncBackendHost::HandleClearServerDataFailedOnFrontendLoop() { | |
1035 if (!frontend_) | |
1036 return; | |
1037 frontend_->OnClearServerDataFailed(); | |
1038 } | |
1039 | |
1040 void SyncBackendHost::HandleAuthErrorEventOnFrontendLoop( | |
1041 const GoogleServiceAuthError& new_auth_error) { | |
1042 if (!frontend_) | |
1043 return; | |
1044 | |
1045 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | |
1046 | |
1047 last_auth_error_ = new_auth_error; | |
1048 frontend_->OnAuthError(); | |
1049 } | |
1050 | |
1051 void SyncBackendHost::HandleNigoriConfigurationCompletedOnFrontendLoop( | |
1052 const WeakHandle<JsBackend>& js_backend, | |
1053 const syncable::ModelTypeSet failed_configuration_types) { | |
1054 HandleInitializationCompletedOnFrontendLoop( | |
1055 js_backend, failed_configuration_types.Empty()); | |
1056 } | |
1054 | 1057 |
1055 namespace { | 1058 namespace { |
1056 | 1059 |
1057 // Needed because MessageLoop::PostTask is overloaded. | 1060 // Needed because MessageLoop::PostTask is overloaded. |
1058 void PostClosure(MessageLoop* message_loop, | 1061 void PostClosure(MessageLoop* message_loop, |
1059 const tracked_objects::Location& from_here, | 1062 const tracked_objects::Location& from_here, |
1060 const base::Closure& callback) { | 1063 const base::Closure& callback) { |
1061 message_loop->PostTask(from_here, callback); | 1064 message_loop->PostTask(from_here, callback); |
1062 } | 1065 } |
1063 | 1066 |
1064 } // namespace | 1067 } // namespace |
1065 | 1068 |
1066 void SyncBackendHost::RefreshEncryption(const base::Closure& done_callback) { | 1069 void SyncBackendHost::RefreshEncryption(const base::Closure& done_callback) { |
1067 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | 1070 DCHECK_EQ(MessageLoop::current(), frontend_loop_); |
1068 base::Closure sync_thread_done_callback = | 1071 base::Closure sync_thread_done_callback = |
1069 base::Bind(&PostClosure, | 1072 base::Bind(&PostClosure, |
1070 MessageLoop::current(), FROM_HERE, done_callback); | 1073 MessageLoop::current(), FROM_HERE, done_callback); |
1071 sync_thread_.message_loop()->PostTask( | 1074 sync_thread_.message_loop()->PostTask( |
1072 FROM_HERE, | 1075 FROM_HERE, |
1073 base::Bind(&SyncBackendHost::Core::DoRefreshEncryption, | 1076 base::Bind(&SyncBackendHost::Core::DoRefreshEncryption, |
1074 core_.get(), sync_thread_done_callback)); | 1077 core_.get(), sync_thread_done_callback)); |
1075 } | 1078 } |
1076 | 1079 |
1077 #undef SDVLOG | 1080 #undef SDVLOG |
1078 | 1081 |
1079 #undef SLOG | 1082 #undef SLOG |
1080 | 1083 |
1081 } // namespace browser_sync | 1084 } // namespace browser_sync |
OLD | NEW |