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 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 // Called when the user disables or enables a sync type. | 124 // Called when the user disables or enables a sync type. |
125 void DoUpdateEnabledTypes(const syncable::ModelTypeSet& enabled_types); | 125 void DoUpdateEnabledTypes(const syncable::ModelTypeSet& enabled_types); |
126 | 126 |
127 // Called to tell the syncapi to start syncing (generally after | 127 // Called to tell the syncapi to start syncing (generally after |
128 // initialization and authentication). | 128 // initialization and authentication). |
129 void DoStartSyncing(const ModelSafeRoutingInfo& routing_info); | 129 void DoStartSyncing(const ModelSafeRoutingInfo& routing_info); |
130 | 130 |
131 // Called to clear server data. | 131 // Called to clear server data. |
132 void DoRequestClearServerData(); | 132 void DoRequestClearServerData(); |
133 | 133 |
134 // Called to cleanup disabled types. | |
135 void DoRequestCleanupDisabledTypes( | |
136 const browser_sync::ModelSafeRoutingInfo& routing_info); | |
137 | |
138 // Called to set the passphrase for encryption. | 134 // Called to set the passphrase for encryption. |
139 void DoSetEncryptionPassphrase(const std::string& passphrase, | 135 void DoSetEncryptionPassphrase(const std::string& passphrase, |
140 bool is_explicit); | 136 bool is_explicit); |
141 | 137 |
142 // Called to decrypt the pending keys. | 138 // Called to decrypt the pending keys. |
143 void DoSetDecryptionPassphrase(const std::string& passphrase); | 139 void DoSetDecryptionPassphrase(const std::string& passphrase); |
144 | 140 |
145 // Called to turn on encryption of all sync data as well as | 141 // Called to turn on encryption of all sync data as well as |
146 // reencrypt everything. | 142 // reencrypt everything. |
147 void DoEnableEncryptEverything(); | 143 void DoEnableEncryptEverything(); |
148 | 144 |
149 // Called to refresh encryption with the most recent passphrase | 145 // Called to refresh encryption with the most recent passphrase |
150 // and set of encrypted types. Also adds device information to the nigori | 146 // and set of encrypted types. Also adds device information to the nigori |
151 // node. |done_callback| is called on the sync thread. | 147 // node. |done_callback| is called on the sync thread. |
152 void DoRefreshNigori(const base::Closure& done_callback); | 148 void DoRefreshNigori(const base::Closure& done_callback); |
153 | 149 |
154 // The shutdown order is a bit complicated: | 150 // The shutdown order is a bit complicated: |
155 // 1) From |sync_thread_|, invoke the syncapi Shutdown call to do | 151 // 1) From |sync_thread_|, invoke the syncapi Shutdown call to do |
156 // a final SaveChanges, and close sqlite handles. | 152 // a final SaveChanges, and close sqlite handles. |
157 // 2) Then, from |frontend_loop_|, halt the sync_thread_ (which is | 153 // 2) Then, from |frontend_loop_|, halt the sync_thread_ (which is |
158 // a blocking call). This causes syncapi thread-exit handlers | 154 // a blocking call). This causes syncapi thread-exit handlers |
159 // to run and make use of cached pointers to various components | 155 // to run and make use of cached pointers to various components |
160 // owned implicitly by us. | 156 // owned implicitly by us. |
161 // 3) Destroy this Core. That will delete syncapi components in a | 157 // 3) Destroy this Core. That will delete syncapi components in a |
162 // safe order because the thread that was using them has exited | 158 // safe order because the thread that was using them has exited |
163 // (in step 2). | 159 // (in step 2). |
164 void DoStopSyncManagerForShutdown(const base::Closure& closure); | 160 void DoStopSyncManagerForShutdown(const base::Closure& closure); |
165 void DoShutdown(bool stopping_sync); | 161 void DoShutdown(bool stopping_sync); |
166 | 162 |
167 virtual void DoRequestConfig( | 163 // Configuration methods that must execute on sync loop. |
168 const browser_sync::ModelSafeRoutingInfo& routing_info, | 164 void DoConfigureSyncer( |
| 165 sync_api::ConfigureReason reason, |
169 syncable::ModelTypeSet types_to_config, | 166 syncable::ModelTypeSet types_to_config, |
170 sync_api::ConfigureReason reason); | 167 const browser_sync::ModelSafeRoutingInfo routing_info, |
171 | 168 const base::Callback<void(syncable::ModelTypeSet)>& ready_task, |
172 // Start the configuration mode. |callback| is called on the sync | 169 const base::Closure& retry_callback); |
173 // thread. | 170 void DoFinishConfigureDataTypes( |
174 virtual void DoStartConfiguration(const base::Closure& callback); | 171 syncable::ModelTypeSet types_to_config, |
| 172 const base::Callback<void(syncable::ModelTypeSet)>& ready_task); |
| 173 void DoRetryConfiguration( |
| 174 const base::Closure& retry_callback); |
175 | 175 |
176 // Set the base request context to use when making HTTP calls. | 176 // Set the base request context to use when making HTTP calls. |
177 // This method will add a reference to the context to persist it | 177 // This method will add a reference to the context to persist it |
178 // on the IO thread. Must be removed from IO thread. | 178 // on the IO thread. Must be removed from IO thread. |
179 | 179 |
180 sync_api::SyncManager* sync_manager() { return sync_manager_.get(); } | 180 sync_api::SyncManager* sync_manager() { return sync_manager_.get(); } |
181 | 181 |
182 // Delete the sync data folder to cleanup backend data. Happens the first | 182 // Delete the sync data folder to cleanup backend data. Happens the first |
183 // time sync is enabled for a user (to prevent accidentally reusing old | 183 // time sync is enabled for a user (to prevent accidentally reusing old |
184 // sync databases), as well as shutdown when you're no longer syncing. | 184 // sync databases), as well as shutdown when you're no longer syncing. |
185 void DeleteSyncDataFolder(); | 185 void DeleteSyncDataFolder(); |
186 | 186 |
187 // A callback from the SyncerThread when it is safe to continue config. | |
188 void FinishConfigureDataTypes(); | |
189 | |
190 private: | 187 private: |
191 friend class base::RefCountedThreadSafe<SyncBackendHost::Core>; | 188 friend class base::RefCountedThreadSafe<SyncBackendHost::Core>; |
192 friend class SyncBackendHostForProfileSyncTest; | 189 friend class SyncBackendHostForProfileSyncTest; |
193 | 190 |
194 virtual ~Core(); | 191 virtual ~Core(); |
195 | 192 |
196 // Invoked when initialization of syncapi is complete and we can start | 193 // Invoked when initialization of syncapi is complete and we can start |
197 // our timer. | 194 // our timer. |
198 // This must be called from the thread on which SaveChanges is intended to | 195 // This must be called from the thread on which SaveChanges is intended to |
199 // be run on; the host's |sync_thread_|. | 196 // be run on; the host's |sync_thread_|. |
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
549 base::TimeDelta stop_sync_thread_time = base::Time::Now() - | 546 base::TimeDelta stop_sync_thread_time = base::Time::Now() - |
550 stop_thread_start_time; | 547 stop_thread_start_time; |
551 UMA_HISTOGRAM_TIMES("Sync.Shutdown.StopSyncThreadTime", | 548 UMA_HISTOGRAM_TIMES("Sync.Shutdown.StopSyncThreadTime", |
552 stop_sync_thread_time); | 549 stop_sync_thread_time); |
553 | 550 |
554 registrar_.reset(); | 551 registrar_.reset(); |
555 frontend_ = NULL; | 552 frontend_ = NULL; |
556 core_ = NULL; // Releases reference to core_. | 553 core_ = NULL; // Releases reference to core_. |
557 } | 554 } |
558 | 555 |
| 556 // TODO(sync): remove |disabled_types| completely, as it's just the set of |
| 557 // registered types - the set of desired types. |
559 void SyncBackendHost::ConfigureDataTypes( | 558 void SyncBackendHost::ConfigureDataTypes( |
560 sync_api::ConfigureReason reason, | 559 sync_api::ConfigureReason reason, |
561 syncable::ModelTypeSet types_to_add, | 560 const syncable::ModelTypeSet& desired_types, |
562 syncable::ModelTypeSet types_to_remove, | 561 const syncable::ModelTypeSet& disabled_types, |
563 NigoriState nigori_state, | 562 NigoriState nigori_state, |
564 base::Callback<void(syncable::ModelTypeSet)> ready_task, | 563 const base::Callback<void(syncable::ModelTypeSet)>& ready_task, |
565 base::Callback<void()> retry_callback) { | 564 const base::Callback<void()>& retry_callback) { |
566 syncable::ModelTypeSet types_to_add_with_nigori = types_to_add; | 565 syncable::ModelTypeSet desired_types_with_nigori = desired_types; |
567 syncable::ModelTypeSet types_to_remove_with_nigori = types_to_remove; | 566 syncable::ModelTypeSet disabled_types_with_nigori = disabled_types; |
568 if (nigori_state == WITH_NIGORI) { | 567 if (nigori_state == WITH_NIGORI) { |
569 types_to_add_with_nigori.Put(syncable::NIGORI); | 568 desired_types_with_nigori.Put(syncable::NIGORI); |
570 types_to_remove_with_nigori.Remove(syncable::NIGORI); | 569 disabled_types_with_nigori.Remove(syncable::NIGORI); |
571 } else { | 570 } else { |
572 types_to_add_with_nigori.Remove(syncable::NIGORI); | 571 desired_types_with_nigori.Remove(syncable::NIGORI); |
573 types_to_remove_with_nigori.Put(syncable::NIGORI); | 572 disabled_types_with_nigori.Put(syncable::NIGORI); |
574 } | 573 } |
575 // Only one configure is allowed at a time. | 574 // Only one configure is allowed at a time (DataTypeManager handles user |
576 DCHECK(!pending_config_mode_state_.get()); | 575 // changes that happen while the syncer is reconfiguraing, and will only |
577 DCHECK(!pending_download_state_.get()); | 576 // trigger another call to ConfigureDataTypes once the current reconfiguration |
| 577 // completes). |
578 DCHECK_GT(initialization_state_, NOT_INITIALIZED); | 578 DCHECK_GT(initialization_state_, NOT_INITIALIZED); |
579 | 579 |
580 pending_config_mode_state_.reset(new PendingConfigureDataTypesState()); | 580 // enabled_types \setunion disabled_types gives the set of all registered |
581 pending_config_mode_state_->ready_task = ready_task; | 581 // types (i.e. types with datatype controllers registered). |
582 pending_config_mode_state_->types_to_add = types_to_add_with_nigori; | 582 ModelSafeRoutingInfo routing_info; |
583 pending_config_mode_state_->added_types = | 583 registrar_->ConfigureDataTypes(desired_types_with_nigori, |
584 registrar_->ConfigureDataTypes(types_to_add_with_nigori, | 584 disabled_types_with_nigori); |
585 types_to_remove_with_nigori); | 585 registrar_->GetModelSafeRoutingInfo(&routing_info); |
586 pending_config_mode_state_->reason = reason; | |
587 pending_config_mode_state_->retry_callback = retry_callback; | |
588 | 586 |
589 // Cleanup disabled types before starting configuration so that | 587 // |enabled_types| is desired_types_with_nigori \setintersect types with |
590 // callers can assume that the data types are cleaned up once | 588 // model safe workers (e.g. the password store may fail to start up, in which |
591 // configuration is done. | 589 // case we have no model safe worker for it and should not enable it). |
592 if (!types_to_remove_with_nigori.Empty()) { | 590 // TODO(sync): This shouldn't be necessary. We should do whatever filtering |
593 ModelSafeRoutingInfo routing_info; | 591 // we need beforehand as part of ProfileSyncComponentsFactory's |
594 registrar_->GetModelSafeRoutingInfo(&routing_info); | 592 // RegisterDataTypes. |
595 sync_thread_.message_loop()->PostTask( | 593 const syncable::ModelTypeSet enabled_types = |
596 FROM_HERE, | 594 GetRoutingInfoTypes(routing_info); |
597 base::Bind(&SyncBackendHost::Core::DoRequestCleanupDisabledTypes, | |
598 core_.get(), | |
599 routing_info)); | |
600 } | |
601 | 595 |
602 StartConfiguration( | 596 // Figure out which types need to actually be downloaded. We pass those on |
603 base::Bind(&SyncBackendHost::Core::FinishConfigureDataTypes, | 597 // to the syncer while it's in configuration mode so that they can be |
604 core_.get())); | 598 // downloaded before we perform association. Once we switch to normal mode |
605 } | 599 // downloads will get applied normally and hit the datatype's change |
| 600 // processor. |
| 601 // A datatype is in need of downloading if any of the following are true: |
| 602 // 1. it's enabled and initial_sync_ended is false (initial_sync_ended is |
| 603 // set after applying updates, and hence is a more conservative measure |
| 604 // than having a non-empty progress marker, which is set during |
| 605 // StoreTimestamps). |
| 606 // 2. the type is NIGORI, and any other datatype is being downloaded (nigori |
| 607 // is always included if we download a datatype). |
| 608 // TODO(sync): consider moving this logic onto the sync thread (perhaps |
| 609 // as part of SyncManager::ConfigureSyncer). |
| 610 syncable::ModelTypeSet initial_sync_ended_types = |
| 611 core_->sync_manager()->InitialSyncEndedTypes(); |
| 612 initial_sync_ended_types.RetainAll(enabled_types); |
| 613 syncable::ModelTypeSet types_to_config = |
| 614 Difference(enabled_types, initial_sync_ended_types); |
| 615 if (!types_to_config.Empty() && enabled_types.Has(syncable::NIGORI)) |
| 616 types_to_config.Put(syncable::NIGORI); |
606 | 617 |
607 void SyncBackendHost::StartConfiguration(const base::Closure& callback) { | 618 SDVLOG(1) << "Types " |
608 // Put syncer in the config mode. DTM will put us in normal mode once it is | 619 << syncable::ModelTypeSetToString(types_to_config) |
609 // done. This is to ensure we dont do a normal sync when we are doing model | 620 << " added; calling DoConfigureSyncer"; |
610 // association. | 621 // TODO(zea): figure out how to bypass this call if no types are being |
611 sync_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | 622 // configured and GetKey is not needed. For now we rely on determining the |
612 &SyncBackendHost::Core::DoStartConfiguration, core_.get(), callback)); | 623 // need for GetKey as part of the SyncManager::ConfigureSyncer logic. |
| 624 RequestConfigureSyncer(reason, |
| 625 types_to_config, |
| 626 routing_info, |
| 627 ready_task, |
| 628 retry_callback); |
613 } | 629 } |
614 | 630 |
615 void SyncBackendHost::EnableEncryptEverything() { | 631 void SyncBackendHost::EnableEncryptEverything() { |
616 sync_thread_.message_loop()->PostTask(FROM_HERE, | 632 sync_thread_.message_loop()->PostTask(FROM_HERE, |
617 base::Bind(&SyncBackendHost::Core::DoEnableEncryptEverything, | 633 base::Bind(&SyncBackendHost::Core::DoEnableEncryptEverything, |
618 core_.get())); | 634 core_.get())); |
619 } | 635 } |
620 | 636 |
621 void SyncBackendHost::ActivateDataType( | 637 void SyncBackendHost::ActivateDataType( |
622 syncable::ModelType type, ModelSafeGroup group, | 638 syncable::ModelType type, ModelSafeGroup group, |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
680 } else { | 696 } else { |
681 NOTREACHED(); | 697 NOTREACHED(); |
682 } | 698 } |
683 } | 699 } |
684 | 700 |
685 void SyncBackendHost::InitCore(const DoInitializeOptions& options) { | 701 void SyncBackendHost::InitCore(const DoInitializeOptions& options) { |
686 sync_thread_.message_loop()->PostTask(FROM_HERE, | 702 sync_thread_.message_loop()->PostTask(FROM_HERE, |
687 base::Bind(&SyncBackendHost::Core::DoInitialize, core_.get(), options)); | 703 base::Bind(&SyncBackendHost::Core::DoInitialize, core_.get(), options)); |
688 } | 704 } |
689 | 705 |
690 void SyncBackendHost::HandleSyncCycleCompletedOnFrontendLoop( | 706 void SyncBackendHost::RequestConfigureSyncer( |
691 const SyncSessionSnapshot& snapshot) { | 707 sync_api::ConfigureReason reason, |
692 if (!frontend_) | 708 syncable::ModelTypeSet types_to_config, |
693 return; | 709 const browser_sync::ModelSafeRoutingInfo& routing_info, |
694 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | 710 const base::Callback<void(syncable::ModelTypeSet)>& ready_task, |
695 | 711 const base::Closure& retry_callback) { |
696 last_snapshot_ = snapshot; | 712 sync_thread_.message_loop()->PostTask(FROM_HERE, |
697 | 713 base::Bind(&SyncBackendHost::Core::DoConfigureSyncer, |
698 SDVLOG(1) << "Got snapshot " << snapshot.ToString(); | 714 core_.get(), |
699 | 715 reason, |
700 const syncable::ModelTypeSet to_migrate = | 716 types_to_config, |
701 snapshot.syncer_status().types_needing_local_migration; | 717 routing_info, |
702 if (!to_migrate.Empty()) | 718 ready_task, |
703 frontend_->OnMigrationNeededForTypes(to_migrate); | 719 retry_callback)); |
704 | |
705 // Process any changes to the datatypes we're syncing. | |
706 // TODO(sync): add support for removing types. | |
707 if (initialized()) | |
708 AddExperimentalTypes(); | |
709 | |
710 // If we are waiting for a configuration change, check here to see | |
711 // if this sync cycle has initialized all of the types we've been | |
712 // waiting for. | |
713 if (pending_download_state_.get()) { | |
714 const syncable::ModelTypeSet types_to_add = | |
715 pending_download_state_->types_to_add; | |
716 const syncable::ModelTypeSet added_types = | |
717 pending_download_state_->added_types; | |
718 DCHECK(types_to_add.HasAll(added_types)); | |
719 const syncable::ModelTypeSet initial_sync_ended = | |
720 snapshot.initial_sync_ended(); | |
721 const syncable::ModelTypeSet failed_configuration_types = | |
722 Difference(added_types, initial_sync_ended); | |
723 SDVLOG(1) | |
724 << "Added types: " | |
725 << syncable::ModelTypeSetToString(added_types) | |
726 << ", configured types: " | |
727 << syncable::ModelTypeSetToString(initial_sync_ended) | |
728 << ", failed configuration types: " | |
729 << syncable::ModelTypeSetToString(failed_configuration_types); | |
730 | |
731 if (!failed_configuration_types.Empty() && | |
732 snapshot.retry_scheduled()) { | |
733 // Inform the caller that download failed but we are retrying. | |
734 if (!pending_download_state_->retry_in_progress) { | |
735 pending_download_state_->retry_callback.Run(); | |
736 pending_download_state_->retry_in_progress = true; | |
737 } | |
738 // Nothing more to do. | |
739 return; | |
740 } | |
741 | |
742 scoped_ptr<PendingConfigureDataTypesState> state( | |
743 pending_download_state_.release()); | |
744 state->ready_task.Run(failed_configuration_types); | |
745 | |
746 // Syncer did not report an error but did not download everything | |
747 // we requested either. So abort. The caller of the config will cleanup. | |
748 if (!failed_configuration_types.Empty()) | |
749 return; | |
750 } | |
751 | |
752 if (initialized()) | |
753 frontend_->OnSyncCycleCompleted(); | |
754 } | 720 } |
755 | 721 |
756 void SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop() { | 722 void SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop( |
757 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | 723 const syncable::ModelTypeSet& types_to_configure, |
758 // Nudge the syncer. This is necessary for both datatype addition/deletion. | 724 const syncable::ModelTypeSet& configured_types, |
759 // | 725 const base::Callback<void(syncable::ModelTypeSet)>& ready_task) { |
760 // Deletions need a nudge in order to ensure the deletion occurs in a timely | 726 const syncable::ModelTypeSet failed_configuration_types = |
761 // manner (see issue 56416). | 727 Difference(types_to_configure, configured_types); |
762 // | 728 SDVLOG(1) |
763 // In the case of additions, on the next sync cycle, the syncer should | 729 << "Added types: " |
764 // notice that the routing info has changed and start the process of | 730 << syncable::ModelTypeSetToString(types_to_configure) |
765 // downloading updates for newly added data types. Once this is | 731 << ", configured types: " |
766 // complete, the configure_state_.ready_task_ is run via an | 732 << syncable::ModelTypeSetToString(configured_types) |
767 // OnInitializationComplete notification. | 733 << ", failed configuration types: " |
768 | 734 << syncable::ModelTypeSetToString(failed_configuration_types); |
769 SDVLOG(1) << "Syncer in config mode. SBH executing " | |
770 << "FinishConfigureDataTypesOnFrontendLoop"; | |
771 | |
772 | |
773 ModelSafeRoutingInfo routing_info; | |
774 registrar_->GetModelSafeRoutingInfo(&routing_info); | |
775 const syncable::ModelTypeSet enabled_types = | |
776 GetRoutingInfoTypes(routing_info); | |
777 | 735 |
778 // Update |chrome_sync_notification_bridge_|'s enabled types here as it has | 736 // Update |chrome_sync_notification_bridge_|'s enabled types here as it has |
779 // to happen on the UI thread. | 737 // to happen on the UI thread. |
780 chrome_sync_notification_bridge_.UpdateEnabledTypes(enabled_types); | 738 chrome_sync_notification_bridge_.UpdateEnabledTypes(configured_types); |
781 | |
782 if (pending_config_mode_state_->added_types.Empty() && | |
783 !core_->sync_manager()->InitialSyncEndedTypes().HasAll(enabled_types)) { | |
784 | |
785 // TODO(tim): Log / UMA / count this somehow? | |
786 // Add only the types with empty progress markers. Note: it is possible | |
787 // that some types have their initial_sync_ended be false but with non | |
788 // empty progress marker. Which is ok as the rest of the changes would | |
789 // be downloaded on a regular nudge and initial_sync_ended should be set | |
790 // to true. However this is a very corner case. So it is not explicitly | |
791 // handled. | |
792 pending_config_mode_state_->added_types = | |
793 sync_api::GetTypesWithEmptyProgressMarkerToken(enabled_types, | |
794 GetUserShare()); | |
795 } | |
796 | |
797 // If we've added types, we always want to request a nudge/config (even if | |
798 // the initial sync is ended), in case we could not decrypt the data. | |
799 if (pending_config_mode_state_->added_types.Empty()) { | |
800 SDVLOG(1) << "No new types added; calling ready_task directly"; | |
801 // No new types - just notify the caller that the types are available. | |
802 const syncable::ModelTypeSet failed_configuration_types; | |
803 pending_config_mode_state_->ready_task.Run(failed_configuration_types); | |
804 } else { | |
805 pending_download_state_.reset(pending_config_mode_state_.release()); | |
806 | |
807 // Always configure nigori if it's enabled. | |
808 syncable::ModelTypeSet types_to_config = | |
809 pending_download_state_->added_types; | |
810 if (IsNigoriEnabled()) { | |
811 // Note: Nigori is the only type that gets added with a nonempty | |
812 // progress marker during config. If the server returns a migration | |
813 // error then we will go into unrecoverable error. We dont handle it | |
814 // explicitly because server might help us out here by not sending a | |
815 // migraiton error for nigori during config. | |
816 types_to_config.Put(syncable::NIGORI); | |
817 } | |
818 SDVLOG(1) << "Types " | |
819 << syncable::ModelTypeSetToString(types_to_config) | |
820 << " added; calling DoRequestConfig"; | |
821 ModelSafeRoutingInfo routing_info; | |
822 registrar_->GetModelSafeRoutingInfo(&routing_info); | |
823 sync_thread_.message_loop()->PostTask(FROM_HERE, | |
824 base::Bind(&SyncBackendHost::Core::DoRequestConfig, | |
825 core_.get(), | |
826 routing_info, | |
827 types_to_config, | |
828 pending_download_state_->reason)); | |
829 } | |
830 | |
831 pending_config_mode_state_.reset(); | |
832 | 739 |
833 // Notify SyncManager (especially the notification listener) about new types. | 740 // Notify SyncManager (especially the notification listener) about new types. |
834 sync_thread_.message_loop()->PostTask(FROM_HERE, | 741 sync_thread_.message_loop()->PostTask(FROM_HERE, |
835 base::Bind(&SyncBackendHost::Core::DoUpdateEnabledTypes, core_.get(), | 742 base::Bind(&SyncBackendHost::Core::DoUpdateEnabledTypes, core_.get(), |
836 enabled_types)); | 743 configured_types)); |
837 } | |
838 | 744 |
839 bool SyncBackendHost::IsDownloadingNigoriForTest() const { | 745 if (!ready_task.is_null()) |
840 return initialization_state_ == DOWNLOADING_NIGORI; | 746 ready_task.Run(failed_configuration_types); |
841 } | 747 } |
842 | 748 |
843 SyncBackendHost::DoInitializeOptions::DoInitializeOptions( | 749 SyncBackendHost::DoInitializeOptions::DoInitializeOptions( |
844 MessageLoop* sync_loop, | 750 MessageLoop* sync_loop, |
845 SyncBackendRegistrar* registrar, | 751 SyncBackendRegistrar* registrar, |
846 const ModelSafeRoutingInfo& routing_info, | 752 const ModelSafeRoutingInfo& routing_info, |
847 const std::vector<ModelSafeWorker*>& workers, | 753 const std::vector<ModelSafeWorker*>& workers, |
848 ExtensionsActivityMonitor* extensions_activity_monitor, | 754 ExtensionsActivityMonitor* extensions_activity_monitor, |
849 const WeakHandle<JsEventHandler>& event_handler, | 755 const WeakHandle<JsEventHandler>& event_handler, |
850 const GURL& service_url, | 756 const GURL& service_url, |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
887 sync_loop_(NULL), | 793 sync_loop_(NULL), |
888 registrar_(NULL) { | 794 registrar_(NULL) { |
889 DCHECK(backend.get()); | 795 DCHECK(backend.get()); |
890 } | 796 } |
891 | 797 |
892 SyncBackendHost::Core::~Core() { | 798 SyncBackendHost::Core::~Core() { |
893 DCHECK(!sync_manager_.get()); | 799 DCHECK(!sync_manager_.get()); |
894 DCHECK(!sync_loop_); | 800 DCHECK(!sync_loop_); |
895 } | 801 } |
896 | 802 |
897 SyncBackendHost::PendingConfigureDataTypesState:: | |
898 PendingConfigureDataTypesState() | |
899 : reason(sync_api::CONFIGURE_REASON_UNKNOWN), | |
900 retry_in_progress(false) {} | |
901 | |
902 SyncBackendHost::PendingConfigureDataTypesState:: | |
903 ~PendingConfigureDataTypesState() {} | |
904 | |
905 void SyncBackendHost::Core::OnSyncCycleCompleted( | 803 void SyncBackendHost::Core::OnSyncCycleCompleted( |
906 const SyncSessionSnapshot& snapshot) { | 804 const SyncSessionSnapshot& snapshot) { |
907 if (!sync_loop_) | 805 if (!sync_loop_) |
908 return; | 806 return; |
909 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 807 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
910 host_.Call( | 808 host_.Call( |
911 FROM_HERE, | 809 FROM_HERE, |
912 &SyncBackendHost::HandleSyncCycleCompletedOnFrontendLoop, | 810 &SyncBackendHost::HandleSyncCycleCompletedOnFrontendLoop, |
913 snapshot); | 811 snapshot); |
914 } | 812 } |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1146 const ModelSafeRoutingInfo& routing_info) { | 1044 const ModelSafeRoutingInfo& routing_info) { |
1147 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1045 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
1148 sync_manager_->StartSyncingNormally(routing_info); | 1046 sync_manager_->StartSyncingNormally(routing_info); |
1149 } | 1047 } |
1150 | 1048 |
1151 void SyncBackendHost::Core::DoRequestClearServerData() { | 1049 void SyncBackendHost::Core::DoRequestClearServerData() { |
1152 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1050 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
1153 sync_manager_->RequestClearServerData(); | 1051 sync_manager_->RequestClearServerData(); |
1154 } | 1052 } |
1155 | 1053 |
1156 void SyncBackendHost::Core::DoRequestCleanupDisabledTypes( | |
1157 const browser_sync::ModelSafeRoutingInfo& routing_info) { | |
1158 DCHECK_EQ(MessageLoop::current(), sync_loop_); | |
1159 sync_manager_->RequestCleanupDisabledTypes(routing_info); | |
1160 } | |
1161 | |
1162 void SyncBackendHost::Core::DoSetEncryptionPassphrase( | 1054 void SyncBackendHost::Core::DoSetEncryptionPassphrase( |
1163 const std::string& passphrase, | 1055 const std::string& passphrase, |
1164 bool is_explicit) { | 1056 bool is_explicit) { |
1165 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1057 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
1166 sync_manager_->SetEncryptionPassphrase(passphrase, is_explicit); | 1058 sync_manager_->SetEncryptionPassphrase(passphrase, is_explicit); |
1167 } | 1059 } |
1168 | 1060 |
1169 void SyncBackendHost::Core::DoSetDecryptionPassphrase( | 1061 void SyncBackendHost::Core::DoSetDecryptionPassphrase( |
1170 const std::string& passphrase) { | 1062 const std::string& passphrase) { |
1171 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1063 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1203 registrar_ = NULL; | 1095 registrar_ = NULL; |
1204 | 1096 |
1205 if (sync_disabled) | 1097 if (sync_disabled) |
1206 DeleteSyncDataFolder(); | 1098 DeleteSyncDataFolder(); |
1207 | 1099 |
1208 sync_loop_ = NULL; | 1100 sync_loop_ = NULL; |
1209 | 1101 |
1210 host_.Reset(); | 1102 host_.Reset(); |
1211 } | 1103 } |
1212 | 1104 |
1213 void SyncBackendHost::Core::DoRequestConfig( | 1105 void SyncBackendHost::Core::DoConfigureSyncer( |
1214 const browser_sync::ModelSafeRoutingInfo& routing_info, | 1106 sync_api::ConfigureReason reason, |
1215 syncable::ModelTypeSet types_to_config, | 1107 syncable::ModelTypeSet types_to_config, |
1216 sync_api::ConfigureReason reason) { | 1108 const browser_sync::ModelSafeRoutingInfo routing_info, |
| 1109 const base::Callback<void(syncable::ModelTypeSet)>& ready_task, |
| 1110 const base::Closure& retry_callback) { |
1217 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1111 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
1218 sync_manager_->RequestConfig(routing_info, types_to_config, reason); | 1112 sync_manager_->ConfigureSyncer( |
| 1113 reason, |
| 1114 types_to_config, |
| 1115 routing_info, |
| 1116 base::Bind(&SyncBackendHost::Core::DoFinishConfigureDataTypes, |
| 1117 this, |
| 1118 types_to_config, |
| 1119 ready_task), |
| 1120 base::Bind(&SyncBackendHost::Core::DoRetryConfiguration, |
| 1121 this, |
| 1122 retry_callback)); |
1219 } | 1123 } |
1220 | 1124 |
1221 void SyncBackendHost::Core::DoStartConfiguration( | 1125 void SyncBackendHost::Core::DoFinishConfigureDataTypes( |
1222 const base::Closure& callback) { | 1126 syncable::ModelTypeSet types_to_config, |
| 1127 const base::Callback<void(syncable::ModelTypeSet)>& ready_task) { |
1223 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1128 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
1224 sync_manager_->StartConfigurationMode(callback); | 1129 syncable::ModelTypeSet configured_types = |
| 1130 sync_manager_->InitialSyncEndedTypes(); |
| 1131 configured_types.RetainAll(types_to_config); |
| 1132 host_.Call(FROM_HERE, |
| 1133 &SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop, |
| 1134 types_to_config, |
| 1135 configured_types, |
| 1136 ready_task); |
| 1137 } |
| 1138 |
| 1139 void SyncBackendHost::Core::DoRetryConfiguration( |
| 1140 const base::Closure& retry_callback) { |
| 1141 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 1142 host_.Call(FROM_HERE, |
| 1143 &SyncBackendHost::RetryConfigurationOnFrontendLoop, |
| 1144 retry_callback); |
1225 } | 1145 } |
1226 | 1146 |
1227 void SyncBackendHost::Core::DeleteSyncDataFolder() { | 1147 void SyncBackendHost::Core::DeleteSyncDataFolder() { |
1228 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1148 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
1229 if (file_util::DirectoryExists(sync_data_folder_path_)) { | 1149 if (file_util::DirectoryExists(sync_data_folder_path_)) { |
1230 if (!file_util::Delete(sync_data_folder_path_, true)) | 1150 if (!file_util::Delete(sync_data_folder_path_, true)) |
1231 SLOG(DFATAL) << "Could not delete the Sync Data folder."; | 1151 SLOG(DFATAL) << "Could not delete the Sync Data folder."; |
1232 } | 1152 } |
1233 } | 1153 } |
1234 | 1154 |
1235 void SyncBackendHost::Core::FinishConfigureDataTypes() { | |
1236 DCHECK_EQ(MessageLoop::current(), sync_loop_); | |
1237 host_.Call( | |
1238 FROM_HERE, | |
1239 &SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop); | |
1240 } | |
1241 | |
1242 void SyncBackendHost::Core::StartSavingChanges() { | 1155 void SyncBackendHost::Core::StartSavingChanges() { |
1243 // We may already be shut down. | 1156 // We may already be shut down. |
1244 if (!sync_loop_) | 1157 if (!sync_loop_) |
1245 return; | 1158 return; |
1246 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1159 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
1247 DCHECK(!save_changes_timer_.get()); | 1160 DCHECK(!save_changes_timer_.get()); |
1248 save_changes_timer_.reset(new base::RepeatingTimer<Core>()); | 1161 save_changes_timer_.reset(new base::RepeatingTimer<Core>()); |
1249 save_changes_timer_->Start(FROM_HERE, | 1162 save_changes_timer_->Start(FROM_HERE, |
1250 base::TimeDelta::FromSeconds(kSaveChangesIntervalSeconds), | 1163 base::TimeDelta::FromSeconds(kSaveChangesIntervalSeconds), |
1251 this, &Core::SaveChanges); | 1164 this, &Core::SaveChanges); |
(...skipping 30 matching lines...) Expand all Loading... |
1282 if (initialization_state_ == CREATING_SYNC_MANAGER) | 1195 if (initialization_state_ == CREATING_SYNC_MANAGER) |
1283 initialization_state_ = NOT_INITIALIZED; | 1196 initialization_state_ = NOT_INITIALIZED; |
1284 | 1197 |
1285 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | 1198 DCHECK_EQ(MessageLoop::current(), frontend_loop_); |
1286 if (!success) { | 1199 if (!success) { |
1287 initialization_state_ = NOT_INITIALIZED; | 1200 initialization_state_ = NOT_INITIALIZED; |
1288 frontend_->OnBackendInitialized(WeakHandle<JsBackend>(), false); | 1201 frontend_->OnBackendInitialized(WeakHandle<JsBackend>(), false); |
1289 return; | 1202 return; |
1290 } | 1203 } |
1291 | 1204 |
1292 // If setup has completed, start off in DOWNLOADING_NIGORI so that | |
1293 // we start off by refreshing nigori. | |
1294 CHECK(sync_prefs_.get()); | |
1295 if (sync_prefs_->HasSyncSetupCompleted() && | |
1296 initialization_state_ < DOWNLOADING_NIGORI) { | |
1297 initialization_state_ = DOWNLOADING_NIGORI; | |
1298 } | |
1299 | |
1300 // Run initialization state machine. | 1205 // Run initialization state machine. |
1301 switch (initialization_state_) { | 1206 switch (initialization_state_) { |
1302 case NOT_INITIALIZED: | 1207 case NOT_INITIALIZED: |
1303 initialization_state_ = DOWNLOADING_NIGORI; | 1208 initialization_state_ = DOWNLOADING_NIGORI; |
1304 ConfigureDataTypes( | 1209 ConfigureDataTypes( |
1305 sync_api::CONFIGURE_REASON_NEW_CLIENT, | 1210 sync_api::CONFIGURE_REASON_NEW_CLIENT, |
1306 syncable::ModelTypeSet(), | 1211 syncable::ModelTypeSet(), |
1307 syncable::ModelTypeSet(), | 1212 syncable::ModelTypeSet(), |
1308 WITH_NIGORI, | 1213 WITH_NIGORI, |
1309 // Calls back into this function. | 1214 // Calls back into this function. |
(...skipping 20 matching lines...) Expand all Loading... |
1330 // experimental types to enable. This should be done before we inform | 1235 // experimental types to enable. This should be done before we inform |
1331 // the frontend to ensure they're visible in the customize screen. | 1236 // the frontend to ensure they're visible in the customize screen. |
1332 AddExperimentalTypes(); | 1237 AddExperimentalTypes(); |
1333 frontend_->OnBackendInitialized(js_backend, true); | 1238 frontend_->OnBackendInitialized(js_backend, true); |
1334 break; | 1239 break; |
1335 default: | 1240 default: |
1336 NOTREACHED(); | 1241 NOTREACHED(); |
1337 } | 1242 } |
1338 } | 1243 } |
1339 | 1244 |
| 1245 void SyncBackendHost::HandleSyncCycleCompletedOnFrontendLoop( |
| 1246 const SyncSessionSnapshot& snapshot) { |
| 1247 if (!frontend_) |
| 1248 return; |
| 1249 DCHECK_EQ(MessageLoop::current(), frontend_loop_); |
| 1250 |
| 1251 last_snapshot_ = snapshot; |
| 1252 |
| 1253 SDVLOG(1) << "Got snapshot " << snapshot.ToString(); |
| 1254 |
| 1255 const syncable::ModelTypeSet to_migrate = |
| 1256 snapshot.syncer_status().types_needing_local_migration; |
| 1257 if (!to_migrate.Empty()) |
| 1258 frontend_->OnMigrationNeededForTypes(to_migrate); |
| 1259 |
| 1260 // Process any changes to the datatypes we're syncing. |
| 1261 // TODO(sync): add support for removing types. |
| 1262 if (initialized()) |
| 1263 AddExperimentalTypes(); |
| 1264 |
| 1265 if (initialized()) |
| 1266 frontend_->OnSyncCycleCompleted(); |
| 1267 } |
| 1268 |
| 1269 void SyncBackendHost::RetryConfigurationOnFrontendLoop( |
| 1270 const base::Closure& retry_callback) { |
| 1271 SDVLOG(1) << "Failed to complete configuration, informing of retry."; |
| 1272 retry_callback.Run(); |
| 1273 } |
| 1274 |
1340 void SyncBackendHost::PersistEncryptionBootstrapToken( | 1275 void SyncBackendHost::PersistEncryptionBootstrapToken( |
1341 const std::string& token) { | 1276 const std::string& token) { |
1342 CHECK(sync_prefs_.get()); | 1277 CHECK(sync_prefs_.get()); |
1343 sync_prefs_->SetEncryptionBootstrapToken(token); | 1278 sync_prefs_->SetEncryptionBootstrapToken(token); |
1344 } | 1279 } |
1345 | 1280 |
1346 void SyncBackendHost::HandleActionableErrorEventOnFrontendLoop( | 1281 void SyncBackendHost::HandleActionableErrorEventOnFrontendLoop( |
1347 const browser_sync::SyncProtocolError& sync_error) { | 1282 const browser_sync::SyncProtocolError& sync_error) { |
1348 if (!frontend_) | 1283 if (!frontend_) |
1349 return; | 1284 return; |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1470 FROM_HERE, | 1405 FROM_HERE, |
1471 base::Bind(&SyncBackendHost::Core::DoRefreshNigori, | 1406 base::Bind(&SyncBackendHost::Core::DoRefreshNigori, |
1472 core_.get(), sync_thread_done_callback)); | 1407 core_.get(), sync_thread_done_callback)); |
1473 } | 1408 } |
1474 | 1409 |
1475 #undef SDVLOG | 1410 #undef SDVLOG |
1476 | 1411 |
1477 #undef SLOG | 1412 #undef SLOG |
1478 | 1413 |
1479 } // namespace browser_sync | 1414 } // namespace browser_sync |
OLD | NEW |