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

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

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

Powered by Google App Engine
This is Rietveld 408576698