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

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: SetBool -> CallbackCounter 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(
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
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.
tim (not reviewing) 2012/06/14 00:26:53 I originally wrote it that way, but I think some f
Nicolas Zea 2012/06/14 22:35:52 Well, previously we had to rely on having the set
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 configured (nigori
607 // is always included if we do a configuration).
tim (not reviewing) 2012/06/14 00:26:53 This (and the logic below) seems a bit convoluted?
Nicolas Zea 2012/06/14 22:35:52 I disagree that it's not already special cased :-)
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.Size() > 1 && enabled_types.Has(syncable::NIGORI))
tim (not reviewing) 2012/06/14 00:26:53 Your comment above says "any other data type is be
Nicolas Zea 2012/06/14 22:35:52 Good catch, the logic was slightly different in a
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698