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

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

Issue 10483015: [Sync] Refactor sync configuration logic. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698