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( |
rlarocque
2012/06/09 01:44:35
Could we rename either this method or SBH::Request
Nicolas Zea
2012/06/11 23:05:20
I'm not sure what you mean? The whole Request/Do n
rlarocque
2012/06/12 17:45:13
I got confused between the old and new names of th
| |
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 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 |
559 void SyncBackendHost::ConfigureDataTypes( | 556 void SyncBackendHost::ConfigureDataTypes( |
560 sync_api::ConfigureReason reason, | 557 const sync_api::ConfigureReason& reason, |
561 syncable::ModelTypeSet types_to_add, | 558 const syncable::ModelTypeSet& desired_types, |
562 syncable::ModelTypeSet types_to_remove, | 559 const syncable::ModelTypeSet& disabled_types, |
rlarocque
2012/06/09 01:44:35
I think disabled_types is not like the other names
Nicolas Zea
2012/06/11 23:05:20
But that implies that it's a delta and not already
| |
563 NigoriState nigori_state, | 560 NigoriState nigori_state, |
564 base::Callback<void(syncable::ModelTypeSet)> ready_task, | 561 const base::Callback<void(syncable::ModelTypeSet)>& ready_task, |
565 base::Callback<void()> retry_callback) { | 562 const base::Callback<void()>& retry_callback) { |
566 syncable::ModelTypeSet types_to_add_with_nigori = types_to_add; | 563 syncable::ModelTypeSet desired_types_with_nigori = desired_types; |
567 syncable::ModelTypeSet types_to_remove_with_nigori = types_to_remove; | 564 syncable::ModelTypeSet disabled_types_with_nigori = disabled_types; |
568 if (nigori_state == WITH_NIGORI) { | 565 if (nigori_state == WITH_NIGORI) { |
569 types_to_add_with_nigori.Put(syncable::NIGORI); | 566 desired_types_with_nigori.Put(syncable::NIGORI); |
570 types_to_remove_with_nigori.Remove(syncable::NIGORI); | 567 disabled_types_with_nigori.Remove(syncable::NIGORI); |
571 } else { | 568 } else { |
572 types_to_add_with_nigori.Remove(syncable::NIGORI); | 569 desired_types_with_nigori.Remove(syncable::NIGORI); |
573 types_to_remove_with_nigori.Put(syncable::NIGORI); | 570 disabled_types_with_nigori.Put(syncable::NIGORI); |
574 } | 571 } |
575 // Only one configure is allowed at a time. | 572 // Only one configure is allowed at a time (DataTypeManager handles user |
576 DCHECK(!pending_config_mode_state_.get()); | 573 // changes that happen while the syncer is reconfiguraing, and will only |
577 DCHECK(!pending_download_state_.get()); | 574 // trigger another call to ConfigureDataTypes once the current reconfiguration |
575 // completes). | |
578 DCHECK_GT(initialization_state_, NOT_INITIALIZED); | 576 DCHECK_GT(initialization_state_, NOT_INITIALIZED); |
579 | 577 |
580 pending_config_mode_state_.reset(new PendingConfigureDataTypesState()); | 578 // enabled_types \setunion disabled_types gives the set of all registered |
581 pending_config_mode_state_->ready_task = ready_task; | 579 // types (i.e. types with datatype controllers registered). |
582 pending_config_mode_state_->types_to_add = types_to_add_with_nigori; | 580 ModelSafeRoutingInfo routing_info; |
583 pending_config_mode_state_->added_types = | 581 registrar_->ConfigureDataTypes(desired_types_with_nigori, |
584 registrar_->ConfigureDataTypes(types_to_add_with_nigori, | 582 disabled_types_with_nigori); |
585 types_to_remove_with_nigori); | 583 registrar_->GetModelSafeRoutingInfo(&routing_info); |
586 pending_config_mode_state_->reason = reason; | |
587 pending_config_mode_state_->retry_callback = retry_callback; | |
588 | 584 |
589 // Cleanup disabled types before starting configuration so that | 585 // |enabled_types| is desired_types_with_nigori \setintersect types with |
590 // callers can assume that the data types are cleaned up once | 586 // model safe workers (e.g. the password store may fail to start up, in which |
591 // configuration is done. | 587 // case we have no model safe worker for it and should not enable it). |
592 if (!types_to_remove_with_nigori.Empty()) { | 588 // TODO(sync): This shouldn't be necessary. We should do whatever filtering |
593 ModelSafeRoutingInfo routing_info; | 589 // we need beforehand as part of ProfileSyncComponentsFactory's |
594 registrar_->GetModelSafeRoutingInfo(&routing_info); | 590 // RegisterDataTypes. |
595 sync_thread_.message_loop()->PostTask( | 591 const syncable::ModelTypeSet enabled_types = |
596 FROM_HERE, | 592 GetRoutingInfoTypes(routing_info); |
597 base::Bind(&SyncBackendHost::Core::DoRequestCleanupDisabledTypes, | |
598 core_.get(), | |
599 routing_info)); | |
600 } | |
601 | 593 |
602 StartConfiguration( | 594 // Figure out which types need to actually be downloaded. We pass those on |
603 base::Bind(&SyncBackendHost::Core::FinishConfigureDataTypes, | 595 // to the syncer while it's in configuration mode so that they can be |
604 core_.get())); | 596 // downloaded before we perform association. Once we switch to normal mode |
605 } | 597 // downloads will get applied normally and hit the datatype's change |
598 // processor. | |
599 // A datatype is in need of downloading if any of the following are true: | |
600 // 1. it's enabled and initial_sync_ended is false (initial_sync_ended is | |
601 // set after applying updates, and hence is a more conservative measure | |
602 // than having a non-empty progress marker, which is set during | |
603 // StoreTimestamps). | |
604 // 2. the type is NIGORI, and any other datatype is being configured (nigori | |
605 // is always included if we do a configuration). | |
606 // TODO(sync): consider moving this logic onto the sync thread (perhaps | |
607 // as part of SyncManager::ConfigureSyncer). | |
608 syncable::ModelTypeSet initial_sync_ended_types = | |
609 core_->sync_manager()->InitialSyncEndedTypes(); | |
610 initial_sync_ended_types.RetainAll(enabled_types); | |
611 syncable::ModelTypeSet types_to_config = | |
612 Difference(enabled_types, initial_sync_ended_types); | |
613 if (types_to_config.Size() > 1 && enabled_types.Has(syncable::NIGORI)) | |
614 types_to_config.Put(syncable::NIGORI); | |
606 | 615 |
607 void SyncBackendHost::StartConfiguration(const base::Closure& callback) { | 616 SDVLOG(1) << "Types " |
608 // Put syncer in the config mode. DTM will put us in normal mode once it is | 617 << syncable::ModelTypeSetToString(types_to_config) |
609 // done. This is to ensure we dont do a normal sync when we are doing model | 618 << " added; calling DoConfigureSyncer"; |
610 // association. | 619 // TODO(zea): figure out how to bypass this call if no types are being |
611 sync_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | 620 // configured and GetKey is not needed. For now we rely on determining the |
612 &SyncBackendHost::Core::DoStartConfiguration, core_.get(), callback)); | 621 // need for GetKey as part of the SyncManager::ConfigureSyncer logic. |
622 RequestConfigureSyncer(reason, | |
623 types_to_config, | |
624 routing_info, | |
625 ready_task, | |
626 retry_callback); | |
613 } | 627 } |
614 | 628 |
615 void SyncBackendHost::EnableEncryptEverything() { | 629 void SyncBackendHost::EnableEncryptEverything() { |
616 sync_thread_.message_loop()->PostTask(FROM_HERE, | 630 sync_thread_.message_loop()->PostTask(FROM_HERE, |
617 base::Bind(&SyncBackendHost::Core::DoEnableEncryptEverything, | 631 base::Bind(&SyncBackendHost::Core::DoEnableEncryptEverything, |
618 core_.get())); | 632 core_.get())); |
619 } | 633 } |
620 | 634 |
621 void SyncBackendHost::ActivateDataType( | 635 void SyncBackendHost::ActivateDataType( |
622 syncable::ModelType type, ModelSafeGroup group, | 636 syncable::ModelType type, ModelSafeGroup group, |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
680 } else { | 694 } else { |
681 NOTREACHED(); | 695 NOTREACHED(); |
682 } | 696 } |
683 } | 697 } |
684 | 698 |
685 void SyncBackendHost::InitCore(const DoInitializeOptions& options) { | 699 void SyncBackendHost::InitCore(const DoInitializeOptions& options) { |
686 sync_thread_.message_loop()->PostTask(FROM_HERE, | 700 sync_thread_.message_loop()->PostTask(FROM_HERE, |
687 base::Bind(&SyncBackendHost::Core::DoInitialize, core_.get(), options)); | 701 base::Bind(&SyncBackendHost::Core::DoInitialize, core_.get(), options)); |
688 } | 702 } |
689 | 703 |
690 void SyncBackendHost::HandleSyncCycleCompletedOnFrontendLoop( | 704 void SyncBackendHost::RequestConfigureSyncer( |
691 const SyncSessionSnapshot& snapshot) { | 705 sync_api::ConfigureReason reason, |
692 if (!frontend_) | 706 syncable::ModelTypeSet types_to_config, |
693 return; | 707 const browser_sync::ModelSafeRoutingInfo routing_info, |
694 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | 708 const base::Callback<void(syncable::ModelTypeSet)>& ready_task, |
695 | 709 const base::Closure& retry_callback) { |
696 last_snapshot_ = snapshot; | 710 sync_thread_.message_loop()->PostTask(FROM_HERE, |
697 | 711 base::Bind(&SyncBackendHost::Core::DoConfigureSyncer, |
698 SDVLOG(1) << "Got snapshot " << snapshot.ToString(); | 712 core_.get(), |
699 | 713 reason, |
700 const syncable::ModelTypeSet to_migrate = | 714 types_to_config, |
701 snapshot.syncer_status().types_needing_local_migration; | 715 routing_info, |
702 if (!to_migrate.Empty()) | 716 ready_task, |
703 frontend_->OnMigrationNeededForTypes(to_migrate); | 717 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 } | 718 } |
755 | 719 |
756 void SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop() { | 720 void SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop( |
757 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | 721 const syncable::ModelTypeSet& types_to_configure, |
758 // Nudge the syncer. This is necessary for both datatype addition/deletion. | 722 const syncable::ModelTypeSet& configured_types, |
759 // | 723 const base::Callback<void(syncable::ModelTypeSet)>& ready_task) { |
760 // Deletions need a nudge in order to ensure the deletion occurs in a timely | 724 const syncable::ModelTypeSet failed_configuration_types = |
761 // manner (see issue 56416). | 725 Difference(types_to_configure, configured_types); |
762 // | 726 SDVLOG(1) |
763 // In the case of additions, on the next sync cycle, the syncer should | 727 << "Added types: " |
764 // notice that the routing info has changed and start the process of | 728 << syncable::ModelTypeSetToString(types_to_configure) |
765 // downloading updates for newly added data types. Once this is | 729 << ", configured types: " |
766 // complete, the configure_state_.ready_task_ is run via an | 730 << syncable::ModelTypeSetToString(configured_types) |
767 // OnInitializationComplete notification. | 731 << ", failed configuration types: " |
768 | 732 << 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 | 733 |
778 // Update |chrome_sync_notification_bridge_|'s enabled types here as it has | 734 // Update |chrome_sync_notification_bridge_|'s enabled types here as it has |
779 // to happen on the UI thread. | 735 // to happen on the UI thread. |
780 chrome_sync_notification_bridge_.UpdateEnabledTypes(enabled_types); | 736 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 | 737 |
833 // Notify SyncManager (especially the notification listener) about new types. | 738 // Notify SyncManager (especially the notification listener) about new types. |
834 sync_thread_.message_loop()->PostTask(FROM_HERE, | 739 sync_thread_.message_loop()->PostTask(FROM_HERE, |
835 base::Bind(&SyncBackendHost::Core::DoUpdateEnabledTypes, core_.get(), | 740 base::Bind(&SyncBackendHost::Core::DoUpdateEnabledTypes, core_.get(), |
836 enabled_types)); | 741 configured_types)); |
837 } | |
838 | 742 |
839 bool SyncBackendHost::IsDownloadingNigoriForTest() const { | 743 if (!ready_task.is_null()) |
840 return initialization_state_ == DOWNLOADING_NIGORI; | 744 ready_task.Run(failed_configuration_types); |
841 } | 745 } |
842 | 746 |
843 SyncBackendHost::DoInitializeOptions::DoInitializeOptions( | 747 SyncBackendHost::DoInitializeOptions::DoInitializeOptions( |
844 MessageLoop* sync_loop, | 748 MessageLoop* sync_loop, |
845 SyncBackendRegistrar* registrar, | 749 SyncBackendRegistrar* registrar, |
846 const ModelSafeRoutingInfo& routing_info, | 750 const ModelSafeRoutingInfo& routing_info, |
847 const std::vector<ModelSafeWorker*>& workers, | 751 const std::vector<ModelSafeWorker*>& workers, |
848 ExtensionsActivityMonitor* extensions_activity_monitor, | 752 ExtensionsActivityMonitor* extensions_activity_monitor, |
849 const WeakHandle<JsEventHandler>& event_handler, | 753 const WeakHandle<JsEventHandler>& event_handler, |
850 const GURL& service_url, | 754 const GURL& service_url, |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
887 sync_loop_(NULL), | 791 sync_loop_(NULL), |
888 registrar_(NULL) { | 792 registrar_(NULL) { |
889 DCHECK(backend.get()); | 793 DCHECK(backend.get()); |
890 } | 794 } |
891 | 795 |
892 SyncBackendHost::Core::~Core() { | 796 SyncBackendHost::Core::~Core() { |
893 DCHECK(!sync_manager_.get()); | 797 DCHECK(!sync_manager_.get()); |
894 DCHECK(!sync_loop_); | 798 DCHECK(!sync_loop_); |
895 } | 799 } |
896 | 800 |
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( | 801 void SyncBackendHost::Core::OnSyncCycleCompleted( |
906 const SyncSessionSnapshot& snapshot) { | 802 const SyncSessionSnapshot& snapshot) { |
907 if (!sync_loop_) | 803 if (!sync_loop_) |
908 return; | 804 return; |
909 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 805 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
910 host_.Call( | 806 host_.Call( |
911 FROM_HERE, | 807 FROM_HERE, |
912 &SyncBackendHost::HandleSyncCycleCompletedOnFrontendLoop, | 808 &SyncBackendHost::HandleSyncCycleCompletedOnFrontendLoop, |
913 snapshot); | 809 snapshot); |
914 } | 810 } |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1146 const ModelSafeRoutingInfo& routing_info) { | 1042 const ModelSafeRoutingInfo& routing_info) { |
1147 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1043 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
1148 sync_manager_->StartSyncingNormally(routing_info); | 1044 sync_manager_->StartSyncingNormally(routing_info); |
1149 } | 1045 } |
1150 | 1046 |
1151 void SyncBackendHost::Core::DoRequestClearServerData() { | 1047 void SyncBackendHost::Core::DoRequestClearServerData() { |
1152 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1048 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
1153 sync_manager_->RequestClearServerData(); | 1049 sync_manager_->RequestClearServerData(); |
1154 } | 1050 } |
1155 | 1051 |
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( | 1052 void SyncBackendHost::Core::DoSetEncryptionPassphrase( |
1163 const std::string& passphrase, | 1053 const std::string& passphrase, |
1164 bool is_explicit) { | 1054 bool is_explicit) { |
1165 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1055 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
1166 sync_manager_->SetEncryptionPassphrase(passphrase, is_explicit); | 1056 sync_manager_->SetEncryptionPassphrase(passphrase, is_explicit); |
1167 } | 1057 } |
1168 | 1058 |
1169 void SyncBackendHost::Core::DoSetDecryptionPassphrase( | 1059 void SyncBackendHost::Core::DoSetDecryptionPassphrase( |
1170 const std::string& passphrase) { | 1060 const std::string& passphrase) { |
1171 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1061 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1203 registrar_ = NULL; | 1093 registrar_ = NULL; |
1204 | 1094 |
1205 if (sync_disabled) | 1095 if (sync_disabled) |
1206 DeleteSyncDataFolder(); | 1096 DeleteSyncDataFolder(); |
1207 | 1097 |
1208 sync_loop_ = NULL; | 1098 sync_loop_ = NULL; |
1209 | 1099 |
1210 host_.Reset(); | 1100 host_.Reset(); |
1211 } | 1101 } |
1212 | 1102 |
1213 void SyncBackendHost::Core::DoRequestConfig( | 1103 void SyncBackendHost::Core::DoConfigureSyncer( |
1214 const browser_sync::ModelSafeRoutingInfo& routing_info, | 1104 sync_api::ConfigureReason reason, |
1215 syncable::ModelTypeSet types_to_config, | 1105 syncable::ModelTypeSet types_to_config, |
1216 sync_api::ConfigureReason reason) { | 1106 const browser_sync::ModelSafeRoutingInfo routing_info, |
1107 const base::Callback<void(syncable::ModelTypeSet)>& ready_task, | |
1108 const base::Closure& retry_callback) { | |
1217 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1109 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
1218 sync_manager_->RequestConfig(routing_info, types_to_config, reason); | 1110 sync_manager_->ConfigureSyncer( |
1111 reason, | |
1112 types_to_config, | |
1113 routing_info, | |
1114 base::Bind(&SyncBackendHost::Core::DoFinishConfigureDataTypes, | |
1115 this, | |
1116 types_to_config, | |
1117 ready_task), | |
1118 base::Bind(&SyncBackendHost::Core::DoRetryConfiguration, | |
1119 this, | |
1120 retry_callback)); | |
1219 } | 1121 } |
1220 | 1122 |
1221 void SyncBackendHost::Core::DoStartConfiguration( | 1123 void SyncBackendHost::Core::DoFinishConfigureDataTypes( |
1222 const base::Closure& callback) { | 1124 syncable::ModelTypeSet types_to_config, |
1125 const base::Callback<void(syncable::ModelTypeSet)>& ready_task) { | |
1223 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1126 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
1224 sync_manager_->StartConfigurationMode(callback); | 1127 syncable::ModelTypeSet configured_types = |
1128 sync_manager_->InitialSyncEndedTypes(); | |
1129 configured_types.RetainAll(types_to_config); | |
1130 host_.Call(FROM_HERE, | |
1131 &SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop, | |
1132 types_to_config, | |
1133 configured_types, | |
1134 ready_task); | |
1135 } | |
1136 | |
1137 void SyncBackendHost::Core::DoRetryConfiguration( | |
1138 const base::Closure& retry_callback) { | |
1139 DCHECK_EQ(MessageLoop::current(), sync_loop_); | |
1140 host_.Call(FROM_HERE, | |
1141 &SyncBackendHost::RetryConfigurationOnFrontendLoop, | |
1142 retry_callback); | |
1225 } | 1143 } |
1226 | 1144 |
1227 void SyncBackendHost::Core::DeleteSyncDataFolder() { | 1145 void SyncBackendHost::Core::DeleteSyncDataFolder() { |
1228 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1146 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
1229 if (file_util::DirectoryExists(sync_data_folder_path_)) { | 1147 if (file_util::DirectoryExists(sync_data_folder_path_)) { |
1230 if (!file_util::Delete(sync_data_folder_path_, true)) | 1148 if (!file_util::Delete(sync_data_folder_path_, true)) |
1231 SLOG(DFATAL) << "Could not delete the Sync Data folder."; | 1149 SLOG(DFATAL) << "Could not delete the Sync Data folder."; |
1232 } | 1150 } |
1233 } | 1151 } |
1234 | 1152 |
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() { | 1153 void SyncBackendHost::Core::StartSavingChanges() { |
1243 // We may already be shut down. | 1154 // We may already be shut down. |
1244 if (!sync_loop_) | 1155 if (!sync_loop_) |
1245 return; | 1156 return; |
1246 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1157 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
1247 DCHECK(!save_changes_timer_.get()); | 1158 DCHECK(!save_changes_timer_.get()); |
1248 save_changes_timer_.reset(new base::RepeatingTimer<Core>()); | 1159 save_changes_timer_.reset(new base::RepeatingTimer<Core>()); |
1249 save_changes_timer_->Start(FROM_HERE, | 1160 save_changes_timer_->Start(FROM_HERE, |
1250 base::TimeDelta::FromSeconds(kSaveChangesIntervalSeconds), | 1161 base::TimeDelta::FromSeconds(kSaveChangesIntervalSeconds), |
1251 this, &Core::SaveChanges); | 1162 this, &Core::SaveChanges); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1285 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | 1196 DCHECK_EQ(MessageLoop::current(), frontend_loop_); |
1286 if (!success) { | 1197 if (!success) { |
1287 initialization_state_ = NOT_INITIALIZED; | 1198 initialization_state_ = NOT_INITIALIZED; |
1288 frontend_->OnBackendInitialized(WeakHandle<JsBackend>(), false); | 1199 frontend_->OnBackendInitialized(WeakHandle<JsBackend>(), false); |
1289 return; | 1200 return; |
1290 } | 1201 } |
1291 | 1202 |
1292 // If setup has completed, start off in DOWNLOADING_NIGORI so that | 1203 // If setup has completed, start off in DOWNLOADING_NIGORI so that |
1293 // we start off by refreshing nigori. | 1204 // we start off by refreshing nigori. |
1294 CHECK(sync_prefs_.get()); | 1205 CHECK(sync_prefs_.get()); |
1295 if (sync_prefs_->HasSyncSetupCompleted() && | 1206 if (sync_prefs_->HasSyncSetupCompleted() && |
rlarocque
2012/06/09 01:44:35
Because you check the initial_sync_ended bit for N
Nicolas Zea
2012/06/11 23:05:20
Done.
| |
1296 initialization_state_ < DOWNLOADING_NIGORI) { | 1207 initialization_state_ < DOWNLOADING_NIGORI) { |
1297 initialization_state_ = DOWNLOADING_NIGORI; | 1208 initialization_state_ = DOWNLOADING_NIGORI; |
1298 } | 1209 } |
1299 | 1210 |
1300 // Run initialization state machine. | 1211 // Run initialization state machine. |
1301 switch (initialization_state_) { | 1212 switch (initialization_state_) { |
1302 case NOT_INITIALIZED: | 1213 case NOT_INITIALIZED: |
1303 initialization_state_ = DOWNLOADING_NIGORI; | 1214 initialization_state_ = DOWNLOADING_NIGORI; |
1304 ConfigureDataTypes( | 1215 ConfigureDataTypes( |
1305 sync_api::CONFIGURE_REASON_NEW_CLIENT, | 1216 sync_api::CONFIGURE_REASON_NEW_CLIENT, |
(...skipping 24 matching lines...) Expand all Loading... | |
1330 // experimental types to enable. This should be done before we inform | 1241 // experimental types to enable. This should be done before we inform |
1331 // the frontend to ensure they're visible in the customize screen. | 1242 // the frontend to ensure they're visible in the customize screen. |
1332 AddExperimentalTypes(); | 1243 AddExperimentalTypes(); |
1333 frontend_->OnBackendInitialized(js_backend, true); | 1244 frontend_->OnBackendInitialized(js_backend, true); |
1334 break; | 1245 break; |
1335 default: | 1246 default: |
1336 NOTREACHED(); | 1247 NOTREACHED(); |
1337 } | 1248 } |
1338 } | 1249 } |
1339 | 1250 |
1251 void SyncBackendHost::HandleSyncCycleCompletedOnFrontendLoop( | |
1252 const SyncSessionSnapshot& snapshot) { | |
1253 if (!frontend_) | |
1254 return; | |
1255 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | |
1256 | |
1257 last_snapshot_ = snapshot; | |
1258 | |
1259 SDVLOG(1) << "Got snapshot " << snapshot.ToString(); | |
1260 | |
1261 const syncable::ModelTypeSet to_migrate = | |
1262 snapshot.syncer_status().types_needing_local_migration; | |
1263 if (!to_migrate.Empty()) | |
1264 frontend_->OnMigrationNeededForTypes(to_migrate); | |
1265 | |
1266 // Process any changes to the datatypes we're syncing. | |
1267 // TODO(sync): add support for removing types. | |
1268 if (initialized()) | |
1269 AddExperimentalTypes(); | |
1270 | |
1271 if (initialized()) | |
1272 frontend_->OnSyncCycleCompleted(); | |
1273 } | |
1274 | |
1275 void SyncBackendHost::RetryConfigurationOnFrontendLoop( | |
1276 const base::Closure& retry_callback) { | |
1277 SDVLOG(1) << "Failed to complete configuration, informing of retry."; | |
1278 retry_callback.Run(); | |
1279 } | |
1280 | |
1340 void SyncBackendHost::PersistEncryptionBootstrapToken( | 1281 void SyncBackendHost::PersistEncryptionBootstrapToken( |
1341 const std::string& token) { | 1282 const std::string& token) { |
1342 CHECK(sync_prefs_.get()); | 1283 CHECK(sync_prefs_.get()); |
1343 sync_prefs_->SetEncryptionBootstrapToken(token); | 1284 sync_prefs_->SetEncryptionBootstrapToken(token); |
1344 } | 1285 } |
1345 | 1286 |
1346 void SyncBackendHost::HandleActionableErrorEventOnFrontendLoop( | 1287 void SyncBackendHost::HandleActionableErrorEventOnFrontendLoop( |
1347 const browser_sync::SyncProtocolError& sync_error) { | 1288 const browser_sync::SyncProtocolError& sync_error) { |
1348 if (!frontend_) | 1289 if (!frontend_) |
1349 return; | 1290 return; |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1470 FROM_HERE, | 1411 FROM_HERE, |
1471 base::Bind(&SyncBackendHost::Core::DoRefreshNigori, | 1412 base::Bind(&SyncBackendHost::Core::DoRefreshNigori, |
1472 core_.get(), sync_thread_done_callback)); | 1413 core_.get(), sync_thread_done_callback)); |
1473 } | 1414 } |
1474 | 1415 |
1475 #undef SDVLOG | 1416 #undef SDVLOG |
1476 | 1417 |
1477 #undef SLOG | 1418 #undef SLOG |
1478 | 1419 |
1479 } // namespace browser_sync | 1420 } // namespace browser_sync |
OLD | NEW |