OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 // SyncBackendHost::UpdateCredentials | 119 // SyncBackendHost::UpdateCredentials |
120 void DoUpdateCredentials(const syncer::SyncCredentials& credentials); | 120 void DoUpdateCredentials(const syncer::SyncCredentials& credentials); |
121 | 121 |
122 // Called when the user disables or enables a sync type. | 122 // Called when the user disables or enables a sync type. |
123 void DoUpdateEnabledTypes(const syncer::ModelTypeSet& enabled_types); | 123 void DoUpdateEnabledTypes(const syncer::ModelTypeSet& enabled_types); |
124 | 124 |
125 // Called to tell the syncapi to start syncing (generally after | 125 // Called to tell the syncapi to start syncing (generally after |
126 // initialization and authentication). | 126 // initialization and authentication). |
127 void DoStartSyncing(const syncer::ModelSafeRoutingInfo& routing_info); | 127 void DoStartSyncing(const syncer::ModelSafeRoutingInfo& routing_info); |
128 | 128 |
129 // Called to cleanup disabled types. | |
130 void DoRequestCleanupDisabledTypes( | |
131 const syncer::ModelSafeRoutingInfo& routing_info); | |
132 | |
133 // Called to set the passphrase for encryption. | 129 // Called to set the passphrase for encryption. |
134 void DoSetEncryptionPassphrase(const std::string& passphrase, | 130 void DoSetEncryptionPassphrase(const std::string& passphrase, |
135 bool is_explicit); | 131 bool is_explicit); |
136 | 132 |
137 // Called to decrypt the pending keys. | 133 // Called to decrypt the pending keys. |
138 void DoSetDecryptionPassphrase(const std::string& passphrase); | 134 void DoSetDecryptionPassphrase(const std::string& passphrase); |
139 | 135 |
140 // Called to turn on encryption of all sync data as well as | 136 // Called to turn on encryption of all sync data as well as |
141 // reencrypt everything. | 137 // reencrypt everything. |
142 void DoEnableEncryptEverything(); | 138 void DoEnableEncryptEverything(); |
143 | 139 |
144 // Called to refresh encryption with the most recent passphrase | 140 // Called to refresh encryption with the most recent passphrase |
145 // and set of encrypted types. Also adds device information to the nigori | 141 // and set of encrypted types. Also adds device information to the nigori |
146 // node. |done_callback| is called on the sync thread. | 142 // node. |done_callback| is called on the sync thread. |
147 void DoRefreshNigori(const base::Closure& done_callback); | 143 void DoRefreshNigori(const base::Closure& done_callback); |
148 | 144 |
149 // The shutdown order is a bit complicated: | 145 // The shutdown order is a bit complicated: |
150 // 1) From |sync_thread_|, invoke the syncapi Shutdown call to do | 146 // 1) From |sync_thread_|, invoke the syncapi Shutdown call to do |
151 // a final SaveChanges, and close sqlite handles. | 147 // a final SaveChanges, and close sqlite handles. |
152 // 2) Then, from |frontend_loop_|, halt the sync_thread_ (which is | 148 // 2) Then, from |frontend_loop_|, halt the sync_thread_ (which is |
153 // a blocking call). This causes syncapi thread-exit handlers | 149 // a blocking call). This causes syncapi thread-exit handlers |
154 // to run and make use of cached pointers to various components | 150 // to run and make use of cached pointers to various components |
155 // owned implicitly by us. | 151 // owned implicitly by us. |
156 // 3) Destroy this Core. That will delete syncapi components in a | 152 // 3) Destroy this Core. That will delete syncapi components in a |
157 // safe order because the thread that was using them has exited | 153 // safe order because the thread that was using them has exited |
158 // (in step 2). | 154 // (in step 2). |
159 void DoStopSyncManagerForShutdown(const base::Closure& closure); | 155 void DoStopSyncManagerForShutdown(const base::Closure& closure); |
160 void DoShutdown(bool stopping_sync); | 156 void DoShutdown(bool stopping_sync); |
161 | 157 |
162 virtual void DoRequestConfig( | 158 // Configuration methods that must execute on sync loop. |
163 const syncer::ModelSafeRoutingInfo& routing_info, | 159 void DoConfigureSyncer( |
| 160 syncer::ConfigureReason reason, |
164 syncer::ModelTypeSet types_to_config, | 161 syncer::ModelTypeSet types_to_config, |
165 syncer::ConfigureReason reason); | 162 const syncer::ModelSafeRoutingInfo routing_info, |
166 | 163 const base::Callback<void(syncer::ModelTypeSet)>& ready_task, |
167 // Start the configuration mode. |callback| is called on the sync | 164 const base::Closure& retry_callback); |
168 // thread. | 165 void DoFinishConfigureDataTypes( |
169 virtual void DoStartConfiguration(const base::Closure& callback); | 166 syncer::ModelTypeSet types_to_config, |
| 167 const base::Callback<void(syncer::ModelTypeSet)>& ready_task); |
| 168 void DoRetryConfiguration( |
| 169 const base::Closure& retry_callback); |
170 | 170 |
171 // Set the base request context to use when making HTTP calls. | 171 // Set the base request context to use when making HTTP calls. |
172 // This method will add a reference to the context to persist it | 172 // This method will add a reference to the context to persist it |
173 // on the IO thread. Must be removed from IO thread. | 173 // on the IO thread. Must be removed from IO thread. |
174 | 174 |
175 syncer::SyncManager* sync_manager() { return sync_manager_.get(); } | 175 syncer::SyncManager* sync_manager() { return sync_manager_.get(); } |
176 | 176 |
177 // Delete the sync data folder to cleanup backend data. Happens the first | 177 // Delete the sync data folder to cleanup backend data. Happens the first |
178 // time sync is enabled for a user (to prevent accidentally reusing old | 178 // time sync is enabled for a user (to prevent accidentally reusing old |
179 // sync databases), as well as shutdown when you're no longer syncing. | 179 // sync databases), as well as shutdown when you're no longer syncing. |
180 void DeleteSyncDataFolder(); | 180 void DeleteSyncDataFolder(); |
181 | 181 |
182 // A callback from the SyncerThread when it is safe to continue config. | |
183 void FinishConfigureDataTypes(); | |
184 | |
185 private: | 182 private: |
186 friend class base::RefCountedThreadSafe<SyncBackendHost::Core>; | 183 friend class base::RefCountedThreadSafe<SyncBackendHost::Core>; |
187 friend class SyncBackendHostForProfileSyncTest; | 184 friend class SyncBackendHostForProfileSyncTest; |
188 | 185 |
189 virtual ~Core(); | 186 virtual ~Core(); |
190 | 187 |
191 // Invoked when initialization of syncapi is complete and we can start | 188 // Invoked when initialization of syncapi is complete and we can start |
192 // our timer. | 189 // our timer. |
193 // This must be called from the thread on which SaveChanges is intended to | 190 // This must be called from the thread on which SaveChanges is intended to |
194 // be run on; the host's |sync_thread_|. | 191 // be run on; the host's |sync_thread_|. |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 return user_agent; | 345 return user_agent; |
349 } | 346 } |
350 | 347 |
351 user_agent += version_info.Version(); | 348 user_agent += version_info.Version(); |
352 user_agent += " (" + version_info.LastChange() + ")"; | 349 user_agent += " (" + version_info.LastChange() + ")"; |
353 if (!version_info.IsOfficialBuild()) | 350 if (!version_info.IsOfficialBuild()) |
354 user_agent += "-devel"; | 351 user_agent += "-devel"; |
355 return user_agent; | 352 return user_agent; |
356 } | 353 } |
357 | 354 |
358 syncer::HttpPostProviderFactory* MakeHttpBridgeFactory( | 355 scoped_ptr<syncer::HttpPostProviderFactory> MakeHttpBridgeFactory( |
359 const scoped_refptr<net::URLRequestContextGetter>& getter) { | 356 const scoped_refptr<net::URLRequestContextGetter>& getter) { |
360 return new syncer::HttpBridgeFactory(getter, MakeUserAgentForSyncApi()); | 357 return scoped_ptr<syncer::HttpPostProviderFactory>( |
| 358 new syncer::HttpBridgeFactory(getter, MakeUserAgentForSyncApi())); |
361 } | 359 } |
362 | 360 |
363 } // namespace | 361 } // namespace |
364 | 362 |
365 void SyncBackendHost::Initialize( | 363 void SyncBackendHost::Initialize( |
366 SyncFrontend* frontend, | 364 SyncFrontend* frontend, |
367 const syncer::WeakHandle<syncer::JsEventHandler>& event_handler, | 365 const syncer::WeakHandle<syncer::JsEventHandler>& event_handler, |
368 const GURL& sync_service_url, | 366 const GURL& sync_service_url, |
369 syncer::ModelTypeSet initial_types, | 367 syncer::ModelTypeSet initial_types, |
370 const SyncCredentials& credentials, | 368 const SyncCredentials& credentials, |
371 bool delete_sync_data_folder, | 369 bool delete_sync_data_folder, |
| 370 syncer::SyncManagerFactory* sync_manager_factory, |
372 syncer::UnrecoverableErrorHandler* unrecoverable_error_handler, | 371 syncer::UnrecoverableErrorHandler* unrecoverable_error_handler, |
373 syncer::ReportUnrecoverableErrorFunction | 372 syncer::ReportUnrecoverableErrorFunction |
374 report_unrecoverable_error_function) { | 373 report_unrecoverable_error_function) { |
375 if (!sync_thread_.Start()) | 374 if (!StartSyncThread()) |
376 return; | 375 return; |
377 | 376 |
378 frontend_ = frontend; | 377 frontend_ = frontend; |
379 DCHECK(frontend); | 378 DCHECK(frontend); |
380 | 379 |
381 syncer::ModelTypeSet initial_types_with_nigori(initial_types); | 380 syncer::ModelTypeSet initial_types_with_nigori(initial_types); |
382 CHECK(sync_prefs_.get()); | 381 CHECK(sync_prefs_.get()); |
383 if (sync_prefs_->HasSyncSetupCompleted()) { | 382 if (sync_prefs_->HasSyncSetupCompleted()) { |
384 initial_types_with_nigori.Put(syncer::NIGORI); | 383 initial_types_with_nigori.Put(syncer::NIGORI); |
385 } | 384 } |
(...skipping 14 matching lines...) Expand all Loading... |
400 routing_info, | 399 routing_info, |
401 workers, | 400 workers, |
402 &extensions_activity_monitor_, | 401 &extensions_activity_monitor_, |
403 event_handler, | 402 event_handler, |
404 sync_service_url, | 403 sync_service_url, |
405 base::Bind(&MakeHttpBridgeFactory, | 404 base::Bind(&MakeHttpBridgeFactory, |
406 make_scoped_refptr(profile_->GetRequestContext())), | 405 make_scoped_refptr(profile_->GetRequestContext())), |
407 credentials, | 406 credentials, |
408 &chrome_sync_notification_bridge_, | 407 &chrome_sync_notification_bridge_, |
409 &sync_notifier_factory_, | 408 &sync_notifier_factory_, |
| 409 sync_manager_factory, |
410 delete_sync_data_folder, | 410 delete_sync_data_folder, |
411 sync_prefs_->GetEncryptionBootstrapToken(), | 411 sync_prefs_->GetEncryptionBootstrapToken(), |
412 syncer::SyncManager::NON_TEST, | 412 syncer::SyncManager::NON_TEST, |
413 unrecoverable_error_handler, | 413 unrecoverable_error_handler, |
414 report_unrecoverable_error_function)); | 414 report_unrecoverable_error_function)); |
415 } | 415 } |
416 | 416 |
417 void SyncBackendHost::UpdateCredentials(const SyncCredentials& credentials) { | 417 void SyncBackendHost::UpdateCredentials(const SyncCredentials& credentials) { |
418 sync_thread_.message_loop()->PostTask(FROM_HERE, | 418 sync_thread_.message_loop()->PostTask(FROM_HERE, |
419 base::Bind(&SyncBackendHost::Core::DoUpdateCredentials, core_.get(), | 419 base::Bind(&SyncBackendHost::Core::DoUpdateCredentials, core_.get(), |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
582 registrar_.reset(); | 582 registrar_.reset(); |
583 frontend_ = NULL; | 583 frontend_ = NULL; |
584 core_ = NULL; // Releases reference to core_. | 584 core_ = NULL; // Releases reference to core_. |
585 } | 585 } |
586 | 586 |
587 void SyncBackendHost::ConfigureDataTypes( | 587 void SyncBackendHost::ConfigureDataTypes( |
588 syncer::ConfigureReason reason, | 588 syncer::ConfigureReason reason, |
589 syncer::ModelTypeSet types_to_add, | 589 syncer::ModelTypeSet types_to_add, |
590 syncer::ModelTypeSet types_to_remove, | 590 syncer::ModelTypeSet types_to_remove, |
591 NigoriState nigori_state, | 591 NigoriState nigori_state, |
592 base::Callback<void(syncer::ModelTypeSet)> ready_task, | 592 const base::Callback<void(syncer::ModelTypeSet)>& ready_task, |
593 base::Callback<void()> retry_callback) { | 593 const base::Callback<void()>& retry_callback) { |
594 syncer::ModelTypeSet types_to_add_with_nigori = types_to_add; | 594 syncer::ModelTypeSet types_to_add_with_nigori = types_to_add; |
595 syncer::ModelTypeSet types_to_remove_with_nigori = types_to_remove; | 595 syncer::ModelTypeSet types_to_remove_with_nigori = types_to_remove; |
596 if (nigori_state == WITH_NIGORI) { | 596 if (nigori_state == WITH_NIGORI) { |
597 types_to_add_with_nigori.Put(syncer::NIGORI); | 597 types_to_add_with_nigori.Put(syncer::NIGORI); |
598 types_to_remove_with_nigori.Remove(syncer::NIGORI); | 598 types_to_remove_with_nigori.Remove(syncer::NIGORI); |
599 } else { | 599 } else { |
600 types_to_add_with_nigori.Remove(syncer::NIGORI); | 600 types_to_add_with_nigori.Remove(syncer::NIGORI); |
601 types_to_remove_with_nigori.Put(syncer::NIGORI); | 601 types_to_remove_with_nigori.Put(syncer::NIGORI); |
602 } | 602 } |
603 // Only one configure is allowed at a time. | 603 // Only one configure is allowed at a time (DataTypeManager handles user |
604 DCHECK(!pending_config_mode_state_.get()); | 604 // changes that happen while the syncer is reconfiguring, and will only |
605 DCHECK(!pending_download_state_.get()); | 605 // trigger another call to ConfigureDataTypes once the current reconfiguration |
| 606 // completes). |
606 DCHECK_GT(initialization_state_, NOT_INITIALIZED); | 607 DCHECK_GT(initialization_state_, NOT_INITIALIZED); |
607 | 608 |
608 pending_config_mode_state_.reset(new PendingConfigureDataTypesState()); | 609 // The new set of enabled types is types_to_add_with_nigori + the |
609 pending_config_mode_state_->ready_task = ready_task; | 610 // previously enabled types (on restart, the preferred types are already |
610 pending_config_mode_state_->types_to_add = types_to_add_with_nigori; | 611 // enabled) - types_to_remove_with_nigori. After reconfiguring the registrar, |
611 pending_config_mode_state_->added_types = | 612 // the new routing info will reflect the set of enabled types. |
612 registrar_->ConfigureDataTypes(types_to_add_with_nigori, | 613 syncer::ModelSafeRoutingInfo routing_info; |
613 types_to_remove_with_nigori); | 614 registrar_->ConfigureDataTypes(types_to_add_with_nigori, |
614 pending_config_mode_state_->reason = reason; | 615 types_to_remove_with_nigori); |
615 pending_config_mode_state_->retry_callback = retry_callback; | 616 registrar_->GetModelSafeRoutingInfo(&routing_info); |
| 617 const syncer::ModelTypeSet enabled_types = |
| 618 GetRoutingInfoTypes(routing_info); |
616 | 619 |
617 // Cleanup disabled types before starting configuration so that | 620 // Figure out which types need to actually be downloaded. We pass those on |
618 // callers can assume that the data types are cleaned up once | 621 // to the syncer while it's in configuration mode so that they can be |
619 // configuration is done. | 622 // downloaded before we perform association. Once we switch to normal mode |
620 if (!types_to_remove_with_nigori.Empty()) { | 623 // downloads will get applied normally and hit the datatype's change |
621 syncer::ModelSafeRoutingInfo routing_info; | 624 // processor. |
622 registrar_->GetModelSafeRoutingInfo(&routing_info); | 625 // A datatype is in need of downloading if any of the following are true: |
623 sync_thread_.message_loop()->PostTask( | 626 // 1. it's enabled and initial_sync_ended is false (initial_sync_ended is |
624 FROM_HERE, | 627 // set after applying updates, and hence is a more conservative measure |
625 base::Bind(&SyncBackendHost::Core::DoRequestCleanupDisabledTypes, | 628 // than having a non-empty progress marker, which is set during |
626 core_.get(), | 629 // StoreTimestamps). |
627 routing_info)); | 630 // 2. the type is NIGORI, and any other datatype is being downloaded (nigori |
628 } | 631 // is always included if we download a datatype). |
| 632 // TODO(sync): consider moving this logic onto the sync thread (perhaps |
| 633 // as part of SyncManager::ConfigureSyncer). |
| 634 syncer::ModelTypeSet initial_sync_ended_types = |
| 635 core_->sync_manager()->InitialSyncEndedTypes(); |
| 636 initial_sync_ended_types.RetainAll(enabled_types); |
| 637 syncer::ModelTypeSet types_to_config = |
| 638 Difference(enabled_types, initial_sync_ended_types); |
| 639 if (!types_to_config.Empty() && enabled_types.Has(syncer::NIGORI)) |
| 640 types_to_config.Put(syncer::NIGORI); |
629 | 641 |
630 StartConfiguration( | 642 SDVLOG(1) << "Types " |
631 base::Bind(&SyncBackendHost::Core::FinishConfigureDataTypes, | 643 << syncer::ModelTypeSetToString(types_to_config) |
632 core_.get())); | 644 << " added; calling DoConfigureSyncer"; |
633 } | 645 // TODO(zea): figure out how to bypass this call if no types are being |
634 | 646 // configured and GetKey is not needed. For now we rely on determining the |
635 void SyncBackendHost::StartConfiguration(const base::Closure& callback) { | 647 // need for GetKey as part of the SyncManager::ConfigureSyncer logic. |
636 // Put syncer in the config mode. DTM will put us in normal mode once it is | 648 RequestConfigureSyncer(reason, |
637 // done. This is to ensure we dont do a normal sync when we are doing model | 649 types_to_config, |
638 // association. | 650 routing_info, |
639 sync_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | 651 ready_task, |
640 &SyncBackendHost::Core::DoStartConfiguration, core_.get(), callback)); | 652 retry_callback); |
641 } | 653 } |
642 | 654 |
643 void SyncBackendHost::EnableEncryptEverything() { | 655 void SyncBackendHost::EnableEncryptEverything() { |
644 sync_thread_.message_loop()->PostTask(FROM_HERE, | 656 sync_thread_.message_loop()->PostTask(FROM_HERE, |
645 base::Bind(&SyncBackendHost::Core::DoEnableEncryptEverything, | 657 base::Bind(&SyncBackendHost::Core::DoEnableEncryptEverything, |
646 core_.get())); | 658 core_.get())); |
647 } | 659 } |
648 | 660 |
649 void SyncBackendHost::ActivateDataType( | 661 void SyncBackendHost::ActivateDataType( |
650 syncer::ModelType type, syncer::ModelSafeGroup group, | 662 syncer::ModelType type, syncer::ModelSafeGroup group, |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
696 void SyncBackendHost::GetModelSafeRoutingInfo( | 708 void SyncBackendHost::GetModelSafeRoutingInfo( |
697 syncer::ModelSafeRoutingInfo* out) const { | 709 syncer::ModelSafeRoutingInfo* out) const { |
698 if (initialized()) { | 710 if (initialized()) { |
699 CHECK(registrar_.get()); | 711 CHECK(registrar_.get()); |
700 registrar_->GetModelSafeRoutingInfo(out); | 712 registrar_->GetModelSafeRoutingInfo(out); |
701 } else { | 713 } else { |
702 NOTREACHED(); | 714 NOTREACHED(); |
703 } | 715 } |
704 } | 716 } |
705 | 717 |
| 718 bool SyncBackendHost::StartSyncThread() { |
| 719 if (!sync_thread_.IsRunning()) |
| 720 return sync_thread_.Start(); |
| 721 return true; |
| 722 } |
| 723 |
706 void SyncBackendHost::InitCore(const DoInitializeOptions& options) { | 724 void SyncBackendHost::InitCore(const DoInitializeOptions& options) { |
707 sync_thread_.message_loop()->PostTask(FROM_HERE, | 725 sync_thread_.message_loop()->PostTask(FROM_HERE, |
708 base::Bind(&SyncBackendHost::Core::DoInitialize, core_.get(), options)); | 726 base::Bind(&SyncBackendHost::Core::DoInitialize, core_.get(), options)); |
709 } | 727 } |
710 | 728 |
711 void SyncBackendHost::HandleSyncCycleCompletedOnFrontendLoop( | 729 void SyncBackendHost::RequestConfigureSyncer( |
712 const SyncSessionSnapshot& snapshot) { | 730 syncer::ConfigureReason reason, |
713 if (!frontend_) | 731 syncer::ModelTypeSet types_to_config, |
714 return; | 732 const syncer::ModelSafeRoutingInfo& routing_info, |
715 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | 733 const base::Callback<void(syncer::ModelTypeSet)>& ready_task, |
716 | 734 const base::Closure& retry_callback) { |
717 last_snapshot_ = snapshot; | 735 sync_thread_.message_loop()->PostTask(FROM_HERE, |
718 | 736 base::Bind(&SyncBackendHost::Core::DoConfigureSyncer, |
719 SDVLOG(1) << "Got snapshot " << snapshot.ToString(); | 737 core_.get(), |
720 | 738 reason, |
721 const syncer::ModelTypeSet to_migrate = | 739 types_to_config, |
722 snapshot.model_neutral_state().types_needing_local_migration; | 740 routing_info, |
723 if (!to_migrate.Empty()) | 741 ready_task, |
724 frontend_->OnMigrationNeededForTypes(to_migrate); | 742 retry_callback)); |
725 | |
726 // Process any changes to the datatypes we're syncing. | |
727 // TODO(sync): add support for removing types. | |
728 if (initialized()) | |
729 AddExperimentalTypes(); | |
730 | |
731 // If we are waiting for a configuration change, check here to see | |
732 // if this sync cycle has initialized all of the types we've been | |
733 // waiting for. | |
734 if (pending_download_state_.get()) { | |
735 const syncer::ModelTypeSet types_to_add = | |
736 pending_download_state_->types_to_add; | |
737 const syncer::ModelTypeSet added_types = | |
738 pending_download_state_->added_types; | |
739 DCHECK(types_to_add.HasAll(added_types)); | |
740 const syncer::ModelTypeSet initial_sync_ended = | |
741 snapshot.initial_sync_ended(); | |
742 const syncer::ModelTypeSet failed_configuration_types = | |
743 Difference(added_types, initial_sync_ended); | |
744 SDVLOG(1) | |
745 << "Added types: " | |
746 << syncer::ModelTypeSetToString(added_types) | |
747 << ", configured types: " | |
748 << syncer::ModelTypeSetToString(initial_sync_ended) | |
749 << ", failed configuration types: " | |
750 << syncer::ModelTypeSetToString(failed_configuration_types); | |
751 | |
752 if (!failed_configuration_types.Empty() && | |
753 snapshot.retry_scheduled()) { | |
754 // Inform the caller that download failed but we are retrying. | |
755 if (!pending_download_state_->retry_in_progress) { | |
756 pending_download_state_->retry_callback.Run(); | |
757 pending_download_state_->retry_in_progress = true; | |
758 } | |
759 // Nothing more to do. | |
760 return; | |
761 } | |
762 | |
763 scoped_ptr<PendingConfigureDataTypesState> state( | |
764 pending_download_state_.release()); | |
765 state->ready_task.Run(failed_configuration_types); | |
766 | |
767 // Syncer did not report an error but did not download everything | |
768 // we requested either. So abort. The caller of the config will cleanup. | |
769 if (!failed_configuration_types.Empty()) | |
770 return; | |
771 } | |
772 | |
773 if (initialized()) | |
774 frontend_->OnSyncCycleCompleted(); | |
775 } | 743 } |
776 | 744 |
777 void SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop() { | 745 void SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop( |
778 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | 746 syncer::ModelTypeSet types_to_configure, |
779 // Nudge the syncer. This is necessary for both datatype addition/deletion. | 747 syncer::ModelTypeSet configured_types, |
780 // | 748 const base::Callback<void(syncer::ModelTypeSet)>& ready_task) { |
781 // Deletions need a nudge in order to ensure the deletion occurs in a timely | 749 const syncer::ModelTypeSet failed_configuration_types = |
782 // manner (see issue 56416). | 750 Difference(types_to_configure, configured_types); |
783 // | 751 SDVLOG(1) |
784 // In the case of additions, on the next sync cycle, the syncer should | 752 << "Added types: " |
785 // notice that the routing info has changed and start the process of | 753 << syncer::ModelTypeSetToString(types_to_configure) |
786 // downloading updates for newly added data types. Once this is | 754 << ", configured types: " |
787 // complete, the configure_state_.ready_task_ is run via an | 755 << syncer::ModelTypeSetToString(configured_types) |
788 // OnInitializationComplete notification. | 756 << ", failed configuration types: " |
789 | 757 << syncer::ModelTypeSetToString(failed_configuration_types); |
790 SDVLOG(1) << "Syncer in config mode. SBH executing " | |
791 << "FinishConfigureDataTypesOnFrontendLoop"; | |
792 | |
793 syncer::ModelSafeRoutingInfo routing_info; | |
794 registrar_->GetModelSafeRoutingInfo(&routing_info); | |
795 const syncer::ModelTypeSet enabled_types = GetRoutingInfoTypes(routing_info); | |
796 | 758 |
797 // Update |chrome_sync_notification_bridge_|'s enabled types here as it has | 759 // Update |chrome_sync_notification_bridge_|'s enabled types here as it has |
798 // to happen on the UI thread. | 760 // to happen on the UI thread. |
799 chrome_sync_notification_bridge_.UpdateEnabledTypes(enabled_types); | 761 chrome_sync_notification_bridge_.UpdateEnabledTypes(configured_types); |
800 | |
801 if (pending_config_mode_state_->added_types.Empty() && | |
802 !core_->sync_manager()->InitialSyncEndedTypes().HasAll(enabled_types)) { | |
803 | |
804 // TODO(tim): Log / UMA / count this somehow? | |
805 // Add only the types with empty progress markers. Note: it is possible | |
806 // that some types have their initial_sync_ended be false but with non | |
807 // empty progress marker. Which is ok as the rest of the changes would | |
808 // be downloaded on a regular nudge and initial_sync_ended should be set | |
809 // to true. However this is a very corner case. So it is not explicitly | |
810 // handled. | |
811 pending_config_mode_state_->added_types = | |
812 syncer::GetTypesWithEmptyProgressMarkerToken(enabled_types, | |
813 GetUserShare()); | |
814 } | |
815 | |
816 // If we've added types, we always want to request a nudge/config (even if | |
817 // the initial sync is ended), in case we could not decrypt the data. | |
818 if (pending_config_mode_state_->added_types.Empty()) { | |
819 SDVLOG(1) << "No new types added; calling ready_task directly"; | |
820 // No new types - just notify the caller that the types are available. | |
821 const syncer::ModelTypeSet failed_configuration_types; | |
822 pending_config_mode_state_->ready_task.Run(failed_configuration_types); | |
823 } else { | |
824 pending_download_state_.reset(pending_config_mode_state_.release()); | |
825 | |
826 // Always configure nigori if it's enabled. | |
827 syncer::ModelTypeSet types_to_config = pending_download_state_->added_types; | |
828 if (IsNigoriEnabled()) { | |
829 // Note: Nigori is the only type that gets added with a nonempty | |
830 // progress marker during config. If the server returns a migration | |
831 // error then we will go into unrecoverable error. We dont handle it | |
832 // explicitly because server might help us out here by not sending a | |
833 // migraiton error for nigori during config. | |
834 types_to_config.Put(syncer::NIGORI); | |
835 } | |
836 SDVLOG(1) << "Types " | |
837 << syncer::ModelTypeSetToString(types_to_config) | |
838 << " added; calling DoRequestConfig"; | |
839 syncer::ModelSafeRoutingInfo routing_info; | |
840 registrar_->GetModelSafeRoutingInfo(&routing_info); | |
841 sync_thread_.message_loop()->PostTask(FROM_HERE, | |
842 base::Bind(&SyncBackendHost::Core::DoRequestConfig, | |
843 core_.get(), | |
844 routing_info, | |
845 types_to_config, | |
846 pending_download_state_->reason)); | |
847 } | |
848 | |
849 pending_config_mode_state_.reset(); | |
850 | 762 |
851 // Notify SyncManager (especially the notification listener) about new types. | 763 // Notify SyncManager (especially the notification listener) about new types. |
852 sync_thread_.message_loop()->PostTask(FROM_HERE, | 764 sync_thread_.message_loop()->PostTask(FROM_HERE, |
853 base::Bind(&SyncBackendHost::Core::DoUpdateEnabledTypes, core_.get(), | 765 base::Bind(&SyncBackendHost::Core::DoUpdateEnabledTypes, core_.get(), |
854 enabled_types)); | 766 configured_types)); |
855 } | |
856 | 767 |
857 bool SyncBackendHost::IsDownloadingNigoriForTest() const { | 768 if (!ready_task.is_null()) |
858 return initialization_state_ == DOWNLOADING_NIGORI; | 769 ready_task.Run(failed_configuration_types); |
859 } | 770 } |
860 | 771 |
861 SyncBackendHost::DoInitializeOptions::DoInitializeOptions( | 772 SyncBackendHost::DoInitializeOptions::DoInitializeOptions( |
862 MessageLoop* sync_loop, | 773 MessageLoop* sync_loop, |
863 SyncBackendRegistrar* registrar, | 774 SyncBackendRegistrar* registrar, |
864 const syncer::ModelSafeRoutingInfo& routing_info, | 775 const syncer::ModelSafeRoutingInfo& routing_info, |
865 const std::vector<syncer::ModelSafeWorker*>& workers, | 776 const std::vector<syncer::ModelSafeWorker*>& workers, |
866 syncer::ExtensionsActivityMonitor* extensions_activity_monitor, | 777 syncer::ExtensionsActivityMonitor* extensions_activity_monitor, |
867 const syncer::WeakHandle<syncer::JsEventHandler>& event_handler, | 778 const syncer::WeakHandle<syncer::JsEventHandler>& event_handler, |
868 const GURL& service_url, | 779 const GURL& service_url, |
869 MakeHttpBridgeFactoryFn make_http_bridge_factory_fn, | 780 MakeHttpBridgeFactoryFn make_http_bridge_factory_fn, |
870 const syncer::SyncCredentials& credentials, | 781 const syncer::SyncCredentials& credentials, |
871 ChromeSyncNotificationBridge* chrome_sync_notification_bridge, | 782 ChromeSyncNotificationBridge* chrome_sync_notification_bridge, |
872 syncer::SyncNotifierFactory* sync_notifier_factory, | 783 syncer::SyncNotifierFactory* sync_notifier_factory, |
| 784 syncer::SyncManagerFactory* sync_manager_factory, |
873 bool delete_sync_data_folder, | 785 bool delete_sync_data_folder, |
874 const std::string& restored_key_for_bootstrapping, | 786 const std::string& restored_key_for_bootstrapping, |
875 syncer::SyncManager::TestingMode testing_mode, | 787 syncer::SyncManager::TestingMode testing_mode, |
876 syncer::UnrecoverableErrorHandler* unrecoverable_error_handler, | 788 syncer::UnrecoverableErrorHandler* unrecoverable_error_handler, |
877 syncer::ReportUnrecoverableErrorFunction | 789 syncer::ReportUnrecoverableErrorFunction |
878 report_unrecoverable_error_function) | 790 report_unrecoverable_error_function) |
879 : sync_loop(sync_loop), | 791 : sync_loop(sync_loop), |
880 registrar(registrar), | 792 registrar(registrar), |
881 routing_info(routing_info), | 793 routing_info(routing_info), |
882 workers(workers), | 794 workers(workers), |
883 extensions_activity_monitor(extensions_activity_monitor), | 795 extensions_activity_monitor(extensions_activity_monitor), |
884 event_handler(event_handler), | 796 event_handler(event_handler), |
885 service_url(service_url), | 797 service_url(service_url), |
886 make_http_bridge_factory_fn(make_http_bridge_factory_fn), | 798 make_http_bridge_factory_fn(make_http_bridge_factory_fn), |
887 credentials(credentials), | 799 credentials(credentials), |
888 chrome_sync_notification_bridge(chrome_sync_notification_bridge), | 800 chrome_sync_notification_bridge(chrome_sync_notification_bridge), |
889 sync_notifier_factory(sync_notifier_factory), | 801 sync_notifier_factory(sync_notifier_factory), |
| 802 sync_manager_factory(sync_manager_factory), |
890 delete_sync_data_folder(delete_sync_data_folder), | 803 delete_sync_data_folder(delete_sync_data_folder), |
891 restored_key_for_bootstrapping(restored_key_for_bootstrapping), | 804 restored_key_for_bootstrapping(restored_key_for_bootstrapping), |
892 testing_mode(testing_mode), | 805 testing_mode(testing_mode), |
893 unrecoverable_error_handler(unrecoverable_error_handler), | 806 unrecoverable_error_handler(unrecoverable_error_handler), |
894 report_unrecoverable_error_function( | 807 report_unrecoverable_error_function( |
895 report_unrecoverable_error_function) { | 808 report_unrecoverable_error_function) { |
896 } | 809 } |
897 | 810 |
898 SyncBackendHost::DoInitializeOptions::~DoInitializeOptions() {} | 811 SyncBackendHost::DoInitializeOptions::~DoInitializeOptions() {} |
899 | 812 |
900 SyncBackendHost::Core::Core(const std::string& name, | 813 SyncBackendHost::Core::Core(const std::string& name, |
901 const FilePath& sync_data_folder_path, | 814 const FilePath& sync_data_folder_path, |
902 const base::WeakPtr<SyncBackendHost>& backend) | 815 const base::WeakPtr<SyncBackendHost>& backend) |
903 : name_(name), | 816 : name_(name), |
904 sync_data_folder_path_(sync_data_folder_path), | 817 sync_data_folder_path_(sync_data_folder_path), |
905 host_(backend), | 818 host_(backend), |
906 sync_loop_(NULL), | 819 sync_loop_(NULL), |
907 registrar_(NULL) { | 820 registrar_(NULL) { |
908 DCHECK(backend.get()); | 821 DCHECK(backend.get()); |
909 } | 822 } |
910 | 823 |
911 SyncBackendHost::Core::~Core() { | 824 SyncBackendHost::Core::~Core() { |
912 DCHECK(!sync_manager_.get()); | 825 DCHECK(!sync_manager_.get()); |
913 DCHECK(!sync_loop_); | 826 DCHECK(!sync_loop_); |
914 } | 827 } |
915 | 828 |
916 SyncBackendHost::PendingConfigureDataTypesState:: | |
917 PendingConfigureDataTypesState() | |
918 : reason(syncer::CONFIGURE_REASON_UNKNOWN), | |
919 retry_in_progress(false) {} | |
920 | |
921 SyncBackendHost::PendingConfigureDataTypesState:: | |
922 ~PendingConfigureDataTypesState() {} | |
923 | |
924 void SyncBackendHost::Core::OnSyncCycleCompleted( | 829 void SyncBackendHost::Core::OnSyncCycleCompleted( |
925 const SyncSessionSnapshot& snapshot) { | 830 const SyncSessionSnapshot& snapshot) { |
926 if (!sync_loop_) | 831 if (!sync_loop_) |
927 return; | 832 return; |
928 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 833 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
929 host_.Call( | 834 host_.Call( |
930 FROM_HERE, | 835 FROM_HERE, |
931 &SyncBackendHost::HandleSyncCycleCompletedOnFrontendLoop, | 836 &SyncBackendHost::HandleSyncCycleCompletedOnFrontendLoop, |
932 snapshot); | 837 snapshot); |
933 } | 838 } |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1054 | 959 |
1055 // Make sure that the directory exists before initializing the backend. | 960 // Make sure that the directory exists before initializing the backend. |
1056 // If it already exists, this will do no harm. | 961 // If it already exists, this will do no harm. |
1057 bool success = file_util::CreateDirectory(sync_data_folder_path_); | 962 bool success = file_util::CreateDirectory(sync_data_folder_path_); |
1058 DCHECK(success); | 963 DCHECK(success); |
1059 | 964 |
1060 DCHECK(!registrar_); | 965 DCHECK(!registrar_); |
1061 registrar_ = options.registrar; | 966 registrar_ = options.registrar; |
1062 DCHECK(registrar_); | 967 DCHECK(registrar_); |
1063 | 968 |
1064 sync_manager_.reset(new syncer::SyncManager(name_)); | 969 sync_manager_ = options.sync_manager_factory->CreateSyncManager(name_); |
1065 sync_manager_->AddObserver(this); | 970 sync_manager_->AddObserver(this); |
1066 success = sync_manager_->Init( | 971 success = sync_manager_->Init( |
1067 sync_data_folder_path_, | 972 sync_data_folder_path_, |
1068 options.event_handler, | 973 options.event_handler, |
1069 options.service_url.host() + options.service_url.path(), | 974 options.service_url.host() + options.service_url.path(), |
1070 options.service_url.EffectiveIntPort(), | 975 options.service_url.EffectiveIntPort(), |
1071 options.service_url.SchemeIsSecure(), | 976 options.service_url.SchemeIsSecure(), |
1072 BrowserThread::GetBlockingPool(), | 977 BrowserThread::GetBlockingPool(), |
1073 options.make_http_bridge_factory_fn.Run(), | 978 options.make_http_bridge_factory_fn.Run().Pass(), |
1074 options.routing_info, | 979 options.routing_info, |
1075 options.workers, | 980 options.workers, |
1076 options.extensions_activity_monitor, | 981 options.extensions_activity_monitor, |
1077 options.registrar /* as SyncManager::ChangeDelegate */, | 982 options.registrar /* as SyncManager::ChangeDelegate */, |
1078 options.credentials, | 983 options.credentials, |
1079 new BridgedSyncNotifier( | 984 scoped_ptr<syncer::SyncNotifier>(new BridgedSyncNotifier( |
1080 options.chrome_sync_notification_bridge, | 985 options.chrome_sync_notification_bridge, |
1081 options.sync_notifier_factory->CreateSyncNotifier()), | 986 options.sync_notifier_factory->CreateSyncNotifier())), |
1082 options.restored_key_for_bootstrapping, | 987 options.restored_key_for_bootstrapping, |
1083 options.testing_mode, | 988 options.testing_mode, |
1084 &encryptor_, | 989 &encryptor_, |
1085 options.unrecoverable_error_handler, | 990 options.unrecoverable_error_handler, |
1086 options.report_unrecoverable_error_function); | 991 options.report_unrecoverable_error_function); |
1087 LOG_IF(ERROR, !success) << "Syncapi initialization failed!"; | 992 LOG_IF(ERROR, !success) << "Syncapi initialization failed!"; |
1088 | 993 |
1089 // Now check the command line to see if we need to simulate an | 994 // Now check the command line to see if we need to simulate an |
1090 // unrecoverable error for testing purpose. Note the error is thrown | 995 // unrecoverable error for testing purpose. Note the error is thrown |
1091 // only if the initialization succeeded. Also it makes sense to use this | 996 // only if the initialization succeeded. Also it makes sense to use this |
(...skipping 17 matching lines...) Expand all Loading... |
1109 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1014 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
1110 sync_manager_->UpdateEnabledTypes(enabled_types); | 1015 sync_manager_->UpdateEnabledTypes(enabled_types); |
1111 } | 1016 } |
1112 | 1017 |
1113 void SyncBackendHost::Core::DoStartSyncing( | 1018 void SyncBackendHost::Core::DoStartSyncing( |
1114 const syncer::ModelSafeRoutingInfo& routing_info) { | 1019 const syncer::ModelSafeRoutingInfo& routing_info) { |
1115 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1020 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
1116 sync_manager_->StartSyncingNormally(routing_info); | 1021 sync_manager_->StartSyncingNormally(routing_info); |
1117 } | 1022 } |
1118 | 1023 |
1119 void SyncBackendHost::Core::DoRequestCleanupDisabledTypes( | |
1120 const syncer::ModelSafeRoutingInfo& routing_info) { | |
1121 DCHECK_EQ(MessageLoop::current(), sync_loop_); | |
1122 sync_manager_->RequestCleanupDisabledTypes(routing_info); | |
1123 } | |
1124 | |
1125 void SyncBackendHost::Core::DoSetEncryptionPassphrase( | 1024 void SyncBackendHost::Core::DoSetEncryptionPassphrase( |
1126 const std::string& passphrase, | 1025 const std::string& passphrase, |
1127 bool is_explicit) { | 1026 bool is_explicit) { |
1128 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1027 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
1129 sync_manager_->SetEncryptionPassphrase(passphrase, is_explicit); | 1028 sync_manager_->SetEncryptionPassphrase(passphrase, is_explicit); |
1130 } | 1029 } |
1131 | 1030 |
1132 void SyncBackendHost::Core::DoSetDecryptionPassphrase( | 1031 void SyncBackendHost::Core::DoSetDecryptionPassphrase( |
1133 const std::string& passphrase) { | 1032 const std::string& passphrase) { |
1134 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1033 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1166 registrar_ = NULL; | 1065 registrar_ = NULL; |
1167 | 1066 |
1168 if (sync_disabled) | 1067 if (sync_disabled) |
1169 DeleteSyncDataFolder(); | 1068 DeleteSyncDataFolder(); |
1170 | 1069 |
1171 sync_loop_ = NULL; | 1070 sync_loop_ = NULL; |
1172 | 1071 |
1173 host_.Reset(); | 1072 host_.Reset(); |
1174 } | 1073 } |
1175 | 1074 |
1176 void SyncBackendHost::Core::DoRequestConfig( | 1075 void SyncBackendHost::Core::DoConfigureSyncer( |
1177 const syncer::ModelSafeRoutingInfo& routing_info, | 1076 syncer::ConfigureReason reason, |
1178 syncer::ModelTypeSet types_to_config, | 1077 syncer::ModelTypeSet types_to_config, |
1179 syncer::ConfigureReason reason) { | 1078 const syncer::ModelSafeRoutingInfo routing_info, |
| 1079 const base::Callback<void(syncer::ModelTypeSet)>& ready_task, |
| 1080 const base::Closure& retry_callback) { |
1180 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1081 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
1181 sync_manager_->RequestConfig(routing_info, types_to_config, reason); | 1082 sync_manager_->ConfigureSyncer( |
| 1083 reason, |
| 1084 types_to_config, |
| 1085 routing_info, |
| 1086 base::Bind(&SyncBackendHost::Core::DoFinishConfigureDataTypes, |
| 1087 this, |
| 1088 types_to_config, |
| 1089 ready_task), |
| 1090 base::Bind(&SyncBackendHost::Core::DoRetryConfiguration, |
| 1091 this, |
| 1092 retry_callback)); |
1182 } | 1093 } |
1183 | 1094 |
1184 void SyncBackendHost::Core::DoStartConfiguration( | 1095 void SyncBackendHost::Core::DoFinishConfigureDataTypes( |
1185 const base::Closure& callback) { | 1096 syncer::ModelTypeSet types_to_config, |
| 1097 const base::Callback<void(syncer::ModelTypeSet)>& ready_task) { |
1186 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1098 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
1187 sync_manager_->StartConfigurationMode(callback); | 1099 syncer::ModelTypeSet configured_types = |
| 1100 sync_manager_->InitialSyncEndedTypes(); |
| 1101 configured_types.RetainAll(types_to_config); |
| 1102 host_.Call(FROM_HERE, |
| 1103 &SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop, |
| 1104 types_to_config, |
| 1105 configured_types, |
| 1106 ready_task); |
| 1107 } |
| 1108 |
| 1109 void SyncBackendHost::Core::DoRetryConfiguration( |
| 1110 const base::Closure& retry_callback) { |
| 1111 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 1112 host_.Call(FROM_HERE, |
| 1113 &SyncBackendHost::RetryConfigurationOnFrontendLoop, |
| 1114 retry_callback); |
1188 } | 1115 } |
1189 | 1116 |
1190 void SyncBackendHost::Core::DeleteSyncDataFolder() { | 1117 void SyncBackendHost::Core::DeleteSyncDataFolder() { |
1191 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1118 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
1192 if (file_util::DirectoryExists(sync_data_folder_path_)) { | 1119 if (file_util::DirectoryExists(sync_data_folder_path_)) { |
1193 if (!file_util::Delete(sync_data_folder_path_, true)) | 1120 if (!file_util::Delete(sync_data_folder_path_, true)) |
1194 SLOG(DFATAL) << "Could not delete the Sync Data folder."; | 1121 SLOG(DFATAL) << "Could not delete the Sync Data folder."; |
1195 } | 1122 } |
1196 } | 1123 } |
1197 | 1124 |
1198 void SyncBackendHost::Core::FinishConfigureDataTypes() { | |
1199 DCHECK_EQ(MessageLoop::current(), sync_loop_); | |
1200 host_.Call( | |
1201 FROM_HERE, | |
1202 &SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop); | |
1203 } | |
1204 | |
1205 void SyncBackendHost::Core::StartSavingChanges() { | 1125 void SyncBackendHost::Core::StartSavingChanges() { |
1206 // We may already be shut down. | 1126 // We may already be shut down. |
1207 if (!sync_loop_) | 1127 if (!sync_loop_) |
1208 return; | 1128 return; |
1209 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1129 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
1210 DCHECK(!save_changes_timer_.get()); | 1130 DCHECK(!save_changes_timer_.get()); |
1211 save_changes_timer_.reset(new base::RepeatingTimer<Core>()); | 1131 save_changes_timer_.reset(new base::RepeatingTimer<Core>()); |
1212 save_changes_timer_->Start(FROM_HERE, | 1132 save_changes_timer_->Start(FROM_HERE, |
1213 base::TimeDelta::FromSeconds(kSaveChangesIntervalSeconds), | 1133 base::TimeDelta::FromSeconds(kSaveChangesIntervalSeconds), |
1214 this, &Core::SaveChanges); | 1134 this, &Core::SaveChanges); |
(...skipping 12 matching lines...) Expand all Loading... |
1227 } | 1147 } |
1228 | 1148 |
1229 void SyncBackendHost::OnNigoriDownloadRetry() { | 1149 void SyncBackendHost::OnNigoriDownloadRetry() { |
1230 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | 1150 DCHECK_EQ(MessageLoop::current(), frontend_loop_); |
1231 if (!frontend_) | 1151 if (!frontend_) |
1232 return; | 1152 return; |
1233 | 1153 |
1234 frontend_->OnSyncConfigureRetry(); | 1154 frontend_->OnSyncConfigureRetry(); |
1235 } | 1155 } |
1236 | 1156 |
| 1157 namespace { |
| 1158 |
| 1159 syncer::ModelTypeSet GetPartiallySyncedTypes( |
| 1160 syncer::SyncManager* sync_manager) { |
| 1161 syncer::ModelTypeSet partially_synced_types = |
| 1162 syncer::ModelTypeSet::All(); |
| 1163 partially_synced_types.RemoveAll(sync_manager->InitialSyncEndedTypes()); |
| 1164 partially_synced_types.RemoveAll( |
| 1165 sync_manager->GetTypesWithEmptyProgressMarkerToken( |
| 1166 syncer::ModelTypeSet::All())); |
| 1167 return partially_synced_types; |
| 1168 } |
| 1169 |
| 1170 } // namespace |
| 1171 |
1237 void SyncBackendHost::HandleInitializationCompletedOnFrontendLoop( | 1172 void SyncBackendHost::HandleInitializationCompletedOnFrontendLoop( |
1238 const syncer::WeakHandle<syncer::JsBackend>& js_backend, bool success) { | 1173 const syncer::WeakHandle<syncer::JsBackend>& js_backend, bool success) { |
1239 DCHECK_NE(NOT_ATTEMPTED, initialization_state_); | 1174 DCHECK_NE(NOT_ATTEMPTED, initialization_state_); |
1240 if (!frontend_) | 1175 if (!frontend_) |
1241 return; | 1176 return; |
1242 | 1177 |
1243 // We've at least created the sync manager at this point, but if that is all | 1178 // We've at least created the sync manager at this point, but if that is all |
1244 // we've done we're just beginning the initialization process. | 1179 // we've done we're just beginning the initialization process. |
1245 if (initialization_state_ == CREATING_SYNC_MANAGER) | 1180 if (initialization_state_ == CREATING_SYNC_MANAGER) |
1246 initialization_state_ = NOT_INITIALIZED; | 1181 initialization_state_ = NOT_INITIALIZED; |
1247 | 1182 |
1248 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | 1183 DCHECK_EQ(MessageLoop::current(), frontend_loop_); |
1249 if (!success) { | 1184 if (!success) { |
1250 initialization_state_ = NOT_INITIALIZED; | 1185 initialization_state_ = NOT_INITIALIZED; |
1251 frontend_->OnBackendInitialized( | 1186 frontend_->OnBackendInitialized( |
1252 syncer::WeakHandle<syncer::JsBackend>(), false); | 1187 syncer::WeakHandle<syncer::JsBackend>(), false); |
1253 return; | 1188 return; |
1254 } | 1189 } |
1255 | 1190 |
1256 // If setup has completed, start off in DOWNLOADING_NIGORI so that | |
1257 // we start off by refreshing nigori. | |
1258 CHECK(sync_prefs_.get()); | |
1259 if (sync_prefs_->HasSyncSetupCompleted() && | |
1260 initialization_state_ < DOWNLOADING_NIGORI) { | |
1261 initialization_state_ = DOWNLOADING_NIGORI; | |
1262 } | |
1263 | |
1264 // Run initialization state machine. | 1191 // Run initialization state machine. |
1265 switch (initialization_state_) { | 1192 switch (initialization_state_) { |
1266 case NOT_INITIALIZED: | 1193 case NOT_INITIALIZED: { |
| 1194 NigoriState nigori_state; |
| 1195 syncer::ModelTypeSet partially_synced_types = GetPartiallySyncedTypes( |
| 1196 core_->sync_manager()); |
| 1197 |
| 1198 // Although it's possible for any type to be in a partially downloaded |
| 1199 // state, we only care about nigori as it's the only one we download |
| 1200 // before the backend is fully initialized. Other types will be |
| 1201 // re-downloaded at configuration time, at which point we can handle |
| 1202 // migrations and other events. |
| 1203 UMA_HISTOGRAM_COUNTS("Sync.PartiallySyncedTypes", |
| 1204 partially_synced_types.Size()); |
| 1205 |
| 1206 if (partially_synced_types.Has(syncer::NIGORI)) { |
| 1207 // Configure without nigori to force it to be cleaned ( |
| 1208 // SyncBackendRegistrar will remove nigori from routing info as part |
| 1209 // of the configuration). |
| 1210 nigori_state = WITHOUT_NIGORI; |
| 1211 initialization_state_ = CLEANING_NIGORI; |
| 1212 } else { |
| 1213 // Normal configuration. Will do nothing if the nigori is already |
| 1214 // downloaded and applied. |
| 1215 nigori_state = WITH_NIGORI; |
| 1216 initialization_state_ = DOWNLOADING_NIGORI; |
| 1217 } |
| 1218 ConfigureDataTypes( |
| 1219 syncer::CONFIGURE_REASON_NEW_CLIENT, |
| 1220 syncer::ModelTypeSet(), |
| 1221 syncer::ModelTypeSet(), |
| 1222 nigori_state, |
| 1223 // Calls back into this function. |
| 1224 base::Bind( |
| 1225 &SyncBackendHost:: |
| 1226 HandleNigoriConfigurationCompletedOnFrontendLoop, |
| 1227 weak_ptr_factory_.GetWeakPtr(), js_backend), |
| 1228 base::Bind(&SyncBackendHost::OnNigoriDownloadRetry, |
| 1229 weak_ptr_factory_.GetWeakPtr())); |
| 1230 break; |
| 1231 } |
| 1232 case CLEANING_NIGORI: { |
| 1233 syncer::ModelTypeSet partially_synced_types = GetPartiallySyncedTypes( |
| 1234 core_->sync_manager()); |
| 1235 if (partially_synced_types.Has(syncer::NIGORI)) { |
| 1236 // We apparently failed to clean the nigori somehow. Attempting |
| 1237 // to continue could lead to crashes (see bug 133219), so we fail |
| 1238 // gracefully instead by triggering an unrecoverable error. |
| 1239 LOG(ERROR) << "Failed to cleanup partial nigori."; |
| 1240 initialization_state_ = NOT_INITIALIZED; |
| 1241 frontend_->OnBackendInitialized( |
| 1242 syncer::WeakHandle<syncer::JsBackend>(), false); |
| 1243 return; |
| 1244 } |
| 1245 |
1267 initialization_state_ = DOWNLOADING_NIGORI; | 1246 initialization_state_ = DOWNLOADING_NIGORI; |
1268 ConfigureDataTypes( | 1247 ConfigureDataTypes( |
1269 syncer::CONFIGURE_REASON_NEW_CLIENT, | 1248 syncer::CONFIGURE_REASON_NEW_CLIENT, |
1270 syncer::ModelTypeSet(), | 1249 syncer::ModelTypeSet(), |
1271 syncer::ModelTypeSet(), | 1250 syncer::ModelTypeSet(), |
1272 WITH_NIGORI, | 1251 WITH_NIGORI, |
1273 // Calls back into this function. | 1252 // Calls back into this function. |
1274 base::Bind( | 1253 base::Bind( |
1275 &SyncBackendHost:: | 1254 &SyncBackendHost:: |
1276 HandleNigoriConfigurationCompletedOnFrontendLoop, | 1255 HandleNigoriConfigurationCompletedOnFrontendLoop, |
1277 weak_ptr_factory_.GetWeakPtr(), js_backend), | 1256 weak_ptr_factory_.GetWeakPtr(), js_backend), |
1278 base::Bind(&SyncBackendHost::OnNigoriDownloadRetry, | 1257 base::Bind(&SyncBackendHost::OnNigoriDownloadRetry, |
1279 weak_ptr_factory_.GetWeakPtr())); | 1258 weak_ptr_factory_.GetWeakPtr())); |
1280 break; | 1259 break; |
| 1260 } |
1281 case DOWNLOADING_NIGORI: | 1261 case DOWNLOADING_NIGORI: |
1282 initialization_state_ = REFRESHING_NIGORI; | 1262 initialization_state_ = REFRESHING_NIGORI; |
1283 // Triggers OnEncryptedTypesChanged() and OnEncryptionComplete() | 1263 // Triggers OnEncryptedTypesChanged() and OnEncryptionComplete() |
1284 // if necessary. | 1264 // if necessary. |
1285 RefreshNigori( | 1265 RefreshNigori( |
1286 base::Bind( | 1266 base::Bind( |
1287 &SyncBackendHost:: | 1267 &SyncBackendHost:: |
1288 HandleInitializationCompletedOnFrontendLoop, | 1268 HandleInitializationCompletedOnFrontendLoop, |
1289 weak_ptr_factory_.GetWeakPtr(), js_backend, true)); | 1269 weak_ptr_factory_.GetWeakPtr(), js_backend, true)); |
1290 break; | 1270 break; |
1291 case REFRESHING_NIGORI: | 1271 case REFRESHING_NIGORI: |
1292 initialization_state_ = INITIALIZED; | 1272 initialization_state_ = INITIALIZED; |
1293 // Now that we've downloaded the nigori node, we can see if there are any | 1273 // Now that we've downloaded the nigori node, we can see if there are any |
1294 // experimental types to enable. This should be done before we inform | 1274 // experimental types to enable. This should be done before we inform |
1295 // the frontend to ensure they're visible in the customize screen. | 1275 // the frontend to ensure they're visible in the customize screen. |
1296 AddExperimentalTypes(); | 1276 AddExperimentalTypes(); |
1297 frontend_->OnBackendInitialized(js_backend, true); | 1277 frontend_->OnBackendInitialized(js_backend, true); |
1298 break; | 1278 break; |
1299 default: | 1279 default: |
1300 NOTREACHED(); | 1280 NOTREACHED(); |
1301 } | 1281 } |
1302 } | 1282 } |
1303 | 1283 |
| 1284 void SyncBackendHost::HandleSyncCycleCompletedOnFrontendLoop( |
| 1285 const SyncSessionSnapshot& snapshot) { |
| 1286 if (!frontend_) |
| 1287 return; |
| 1288 DCHECK_EQ(MessageLoop::current(), frontend_loop_); |
| 1289 |
| 1290 last_snapshot_ = snapshot; |
| 1291 |
| 1292 SDVLOG(1) << "Got snapshot " << snapshot.ToString(); |
| 1293 |
| 1294 const syncer::ModelTypeSet to_migrate = |
| 1295 snapshot.model_neutral_state().types_needing_local_migration; |
| 1296 if (!to_migrate.Empty()) |
| 1297 frontend_->OnMigrationNeededForTypes(to_migrate); |
| 1298 |
| 1299 // Process any changes to the datatypes we're syncing. |
| 1300 // TODO(sync): add support for removing types. |
| 1301 if (initialized()) |
| 1302 AddExperimentalTypes(); |
| 1303 |
| 1304 if (initialized()) |
| 1305 frontend_->OnSyncCycleCompleted(); |
| 1306 } |
| 1307 |
| 1308 void SyncBackendHost::RetryConfigurationOnFrontendLoop( |
| 1309 const base::Closure& retry_callback) { |
| 1310 SDVLOG(1) << "Failed to complete configuration, informing of retry."; |
| 1311 retry_callback.Run(); |
| 1312 } |
| 1313 |
1304 void SyncBackendHost::PersistEncryptionBootstrapToken( | 1314 void SyncBackendHost::PersistEncryptionBootstrapToken( |
1305 const std::string& token) { | 1315 const std::string& token) { |
1306 CHECK(sync_prefs_.get()); | 1316 CHECK(sync_prefs_.get()); |
1307 sync_prefs_->SetEncryptionBootstrapToken(token); | 1317 sync_prefs_->SetEncryptionBootstrapToken(token); |
1308 } | 1318 } |
1309 | 1319 |
1310 void SyncBackendHost::HandleActionableErrorEventOnFrontendLoop( | 1320 void SyncBackendHost::HandleActionableErrorEventOnFrontendLoop( |
1311 const syncer::SyncProtocolError& sync_error) { | 1321 const syncer::SyncProtocolError& sync_error) { |
1312 if (!frontend_) | 1322 if (!frontend_) |
1313 return; | 1323 return; |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1422 FROM_HERE, | 1432 FROM_HERE, |
1423 base::Bind(&SyncBackendHost::Core::DoRefreshNigori, | 1433 base::Bind(&SyncBackendHost::Core::DoRefreshNigori, |
1424 core_.get(), sync_thread_done_callback)); | 1434 core_.get(), sync_thread_done_callback)); |
1425 } | 1435 } |
1426 | 1436 |
1427 #undef SDVLOG | 1437 #undef SDVLOG |
1428 | 1438 |
1429 #undef SLOG | 1439 #undef SLOG |
1430 | 1440 |
1431 } // namespace browser_sync | 1441 } // namespace browser_sync |
OLD | NEW |