| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "build/build_config.h" | 5 #include "build/build_config.h" |
| 6 | 6 |
| 7 #include "chrome/browser/sync/glue/sync_backend_host.h" | 7 #include "chrome/browser/sync/glue/sync_backend_host.h" |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <map> | 10 #include <map> |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 |
| 129 // Called to set the passphrase for encryption. | 133 // Called to set the passphrase for encryption. |
| 130 void DoSetEncryptionPassphrase(const std::string& passphrase, | 134 void DoSetEncryptionPassphrase(const std::string& passphrase, |
| 131 bool is_explicit); | 135 bool is_explicit); |
| 132 | 136 |
| 133 // Called to decrypt the pending keys. | 137 // Called to decrypt the pending keys. |
| 134 void DoSetDecryptionPassphrase(const std::string& passphrase); | 138 void DoSetDecryptionPassphrase(const std::string& passphrase); |
| 135 | 139 |
| 136 // Called to turn on encryption of all sync data as well as | 140 // Called to turn on encryption of all sync data as well as |
| 137 // reencrypt everything. | 141 // reencrypt everything. |
| 138 void DoEnableEncryptEverything(); | 142 void DoEnableEncryptEverything(); |
| 139 | 143 |
| 140 // Called to refresh encryption with the most recent passphrase | 144 // Called to refresh encryption with the most recent passphrase |
| 141 // and set of encrypted types. Also adds device information to the nigori | 145 // and set of encrypted types. Also adds device information to the nigori |
| 142 // node. |done_callback| is called on the sync thread. | 146 // node. |done_callback| is called on the sync thread. |
| 143 void DoRefreshNigori(const base::Closure& done_callback); | 147 void DoRefreshNigori(const base::Closure& done_callback); |
| 144 | 148 |
| 145 // The shutdown order is a bit complicated: | 149 // The shutdown order is a bit complicated: |
| 146 // 1) From |sync_thread_|, invoke the syncapi Shutdown call to do | 150 // 1) From |sync_thread_|, invoke the syncapi Shutdown call to do |
| 147 // a final SaveChanges, and close sqlite handles. | 151 // a final SaveChanges, and close sqlite handles. |
| 148 // 2) Then, from |frontend_loop_|, halt the sync_thread_ (which is | 152 // 2) Then, from |frontend_loop_|, halt the sync_thread_ (which is |
| 149 // a blocking call). This causes syncapi thread-exit handlers | 153 // a blocking call). This causes syncapi thread-exit handlers |
| 150 // to run and make use of cached pointers to various components | 154 // to run and make use of cached pointers to various components |
| 151 // owned implicitly by us. | 155 // owned implicitly by us. |
| 152 // 3) Destroy this Core. That will delete syncapi components in a | 156 // 3) Destroy this Core. That will delete syncapi components in a |
| 153 // safe order because the thread that was using them has exited | 157 // safe order because the thread that was using them has exited |
| 154 // (in step 2). | 158 // (in step 2). |
| 155 void DoStopSyncManagerForShutdown(const base::Closure& closure); | 159 void DoStopSyncManagerForShutdown(const base::Closure& closure); |
| 156 void DoShutdown(bool stopping_sync); | 160 void DoShutdown(bool stopping_sync); |
| 157 | 161 |
| 158 // Configuration methods that must execute on sync loop. | 162 virtual void DoRequestConfig( |
| 159 void DoConfigureSyncer( | 163 const syncer::ModelSafeRoutingInfo& routing_info, |
| 160 syncer::ConfigureReason reason, | |
| 161 syncer::ModelTypeSet types_to_config, | 164 syncer::ModelTypeSet types_to_config, |
| 162 const syncer::ModelSafeRoutingInfo routing_info, | 165 syncer::ConfigureReason reason); |
| 163 const base::Callback<void(syncer::ModelTypeSet)>& ready_task, | 166 |
| 164 const base::Closure& retry_callback); | 167 // Start the configuration mode. |callback| is called on the sync |
| 165 void DoFinishConfigureDataTypes( | 168 // thread. |
| 166 syncer::ModelTypeSet types_to_config, | 169 virtual void DoStartConfiguration(const base::Closure& callback); |
| 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 |
| 182 private: | 185 private: |
| 183 friend class base::RefCountedThreadSafe<SyncBackendHost::Core>; | 186 friend class base::RefCountedThreadSafe<SyncBackendHost::Core>; |
| 184 friend class SyncBackendHostForProfileSyncTest; | 187 friend class SyncBackendHostForProfileSyncTest; |
| 185 | 188 |
| 186 virtual ~Core(); | 189 virtual ~Core(); |
| 187 | 190 |
| 188 // Invoked when initialization of syncapi is complete and we can start | 191 // Invoked when initialization of syncapi is complete and we can start |
| 189 // our timer. | 192 // our timer. |
| 190 // This must be called from the thread on which SaveChanges is intended to | 193 // This must be called from the thread on which SaveChanges is intended to |
| 191 // be run on; the host's |sync_thread_|. | 194 // be run on; the host's |sync_thread_|. |
| (...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 579 registrar_.reset(); | 582 registrar_.reset(); |
| 580 frontend_ = NULL; | 583 frontend_ = NULL; |
| 581 core_ = NULL; // Releases reference to core_. | 584 core_ = NULL; // Releases reference to core_. |
| 582 } | 585 } |
| 583 | 586 |
| 584 void SyncBackendHost::ConfigureDataTypes( | 587 void SyncBackendHost::ConfigureDataTypes( |
| 585 syncer::ConfigureReason reason, | 588 syncer::ConfigureReason reason, |
| 586 syncer::ModelTypeSet types_to_add, | 589 syncer::ModelTypeSet types_to_add, |
| 587 syncer::ModelTypeSet types_to_remove, | 590 syncer::ModelTypeSet types_to_remove, |
| 588 NigoriState nigori_state, | 591 NigoriState nigori_state, |
| 589 const base::Callback<void(syncer::ModelTypeSet)>& ready_task, | 592 base::Callback<void(syncer::ModelTypeSet)> ready_task, |
| 590 const base::Callback<void()>& retry_callback) { | 593 base::Callback<void()> retry_callback) { |
| 591 syncer::ModelTypeSet types_to_add_with_nigori = types_to_add; | 594 syncer::ModelTypeSet types_to_add_with_nigori = types_to_add; |
| 592 syncer::ModelTypeSet types_to_remove_with_nigori = types_to_remove; | 595 syncer::ModelTypeSet types_to_remove_with_nigori = types_to_remove; |
| 593 if (nigori_state == WITH_NIGORI) { | 596 if (nigori_state == WITH_NIGORI) { |
| 594 types_to_add_with_nigori.Put(syncer::NIGORI); | 597 types_to_add_with_nigori.Put(syncer::NIGORI); |
| 595 types_to_remove_with_nigori.Remove(syncer::NIGORI); | 598 types_to_remove_with_nigori.Remove(syncer::NIGORI); |
| 596 } else { | 599 } else { |
| 597 types_to_add_with_nigori.Remove(syncer::NIGORI); | 600 types_to_add_with_nigori.Remove(syncer::NIGORI); |
| 598 types_to_remove_with_nigori.Put(syncer::NIGORI); | 601 types_to_remove_with_nigori.Put(syncer::NIGORI); |
| 599 } | 602 } |
| 600 // Only one configure is allowed at a time (DataTypeManager handles user | 603 // Only one configure is allowed at a time. |
| 601 // changes that happen while the syncer is reconfiguraing, and will only | 604 DCHECK(!pending_config_mode_state_.get()); |
| 602 // trigger another call to ConfigureDataTypes once the current reconfiguration | 605 DCHECK(!pending_download_state_.get()); |
| 603 // completes). | |
| 604 DCHECK_GT(initialization_state_, NOT_INITIALIZED); | 606 DCHECK_GT(initialization_state_, NOT_INITIALIZED); |
| 605 | 607 |
| 606 // The new set of enabled types is types_to_add_with_nigori + the | 608 pending_config_mode_state_.reset(new PendingConfigureDataTypesState()); |
| 607 // previously enabled types (on restart, the preferred types are already | 609 pending_config_mode_state_->ready_task = ready_task; |
| 608 // enabled) - types_to_remove_with_nigori. After reconfiguring the registrar, | 610 pending_config_mode_state_->types_to_add = types_to_add_with_nigori; |
| 609 // the new routing info will reflect the set of enabled types. | 611 pending_config_mode_state_->added_types = |
| 610 syncer::ModelSafeRoutingInfo routing_info; | 612 registrar_->ConfigureDataTypes(types_to_add_with_nigori, |
| 611 registrar_->ConfigureDataTypes(types_to_add_with_nigori, | 613 types_to_remove_with_nigori); |
| 612 types_to_remove_with_nigori); | 614 pending_config_mode_state_->reason = reason; |
| 613 registrar_->GetModelSafeRoutingInfo(&routing_info); | 615 pending_config_mode_state_->retry_callback = retry_callback; |
| 614 const syncer::ModelTypeSet enabled_types = | |
| 615 GetRoutingInfoTypes(routing_info); | |
| 616 | 616 |
| 617 // Figure out which types need to actually be downloaded. We pass those on | 617 // Cleanup disabled types before starting configuration so that |
| 618 // to the syncer while it's in configuration mode so that they can be | 618 // callers can assume that the data types are cleaned up once |
| 619 // downloaded before we perform association. Once we switch to normal mode | 619 // configuration is done. |
| 620 // downloads will get applied normally and hit the datatype's change | 620 if (!types_to_remove_with_nigori.Empty()) { |
| 621 // processor. | 621 syncer::ModelSafeRoutingInfo routing_info; |
| 622 // A datatype is in need of downloading if any of the following are true: | 622 registrar_->GetModelSafeRoutingInfo(&routing_info); |
| 623 // 1. it's enabled and initial_sync_ended is false (initial_sync_ended is | 623 sync_thread_.message_loop()->PostTask( |
| 624 // set after applying updates, and hence is a more conservative measure | 624 FROM_HERE, |
| 625 // than having a non-empty progress marker, which is set during | 625 base::Bind(&SyncBackendHost::Core::DoRequestCleanupDisabledTypes, |
| 626 // StoreTimestamps). | 626 core_.get(), |
| 627 // 2. the type is NIGORI, and any other datatype is being downloaded (nigori | 627 routing_info)); |
| 628 // is always included if we download a datatype). | 628 } |
| 629 // TODO(sync): consider moving this logic onto the sync thread (perhaps | |
| 630 // as part of SyncManager::ConfigureSyncer). | |
| 631 syncer::ModelTypeSet initial_sync_ended_types = | |
| 632 core_->sync_manager()->InitialSyncEndedTypes(); | |
| 633 initial_sync_ended_types.RetainAll(enabled_types); | |
| 634 syncer::ModelTypeSet types_to_config = | |
| 635 Difference(enabled_types, initial_sync_ended_types); | |
| 636 if (!types_to_config.Empty() && enabled_types.Has(syncer::NIGORI)) | |
| 637 types_to_config.Put(syncer::NIGORI); | |
| 638 | 629 |
| 639 SDVLOG(1) << "Types " | 630 StartConfiguration( |
| 640 << syncer::ModelTypeSetToString(types_to_config) | 631 base::Bind(&SyncBackendHost::Core::FinishConfigureDataTypes, |
| 641 << " added; calling DoConfigureSyncer"; | 632 core_.get())); |
| 642 // TODO(zea): figure out how to bypass this call if no types are being | 633 } |
| 643 // configured and GetKey is not needed. For now we rely on determining the | 634 |
| 644 // need for GetKey as part of the SyncManager::ConfigureSyncer logic. | 635 void SyncBackendHost::StartConfiguration(const base::Closure& callback) { |
| 645 RequestConfigureSyncer(reason, | 636 // Put syncer in the config mode. DTM will put us in normal mode once it is |
| 646 types_to_config, | 637 // done. This is to ensure we dont do a normal sync when we are doing model |
| 647 routing_info, | 638 // association. |
| 648 ready_task, | 639 sync_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
| 649 retry_callback); | 640 &SyncBackendHost::Core::DoStartConfiguration, core_.get(), callback)); |
| 650 } | 641 } |
| 651 | 642 |
| 652 void SyncBackendHost::EnableEncryptEverything() { | 643 void SyncBackendHost::EnableEncryptEverything() { |
| 653 sync_thread_.message_loop()->PostTask(FROM_HERE, | 644 sync_thread_.message_loop()->PostTask(FROM_HERE, |
| 654 base::Bind(&SyncBackendHost::Core::DoEnableEncryptEverything, | 645 base::Bind(&SyncBackendHost::Core::DoEnableEncryptEverything, |
| 655 core_.get())); | 646 core_.get())); |
| 656 } | 647 } |
| 657 | 648 |
| 658 void SyncBackendHost::ActivateDataType( | 649 void SyncBackendHost::ActivateDataType( |
| 659 syncer::ModelType type, syncer::ModelSafeGroup group, | 650 syncer::ModelType type, syncer::ModelSafeGroup group, |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 710 } else { | 701 } else { |
| 711 NOTREACHED(); | 702 NOTREACHED(); |
| 712 } | 703 } |
| 713 } | 704 } |
| 714 | 705 |
| 715 void SyncBackendHost::InitCore(const DoInitializeOptions& options) { | 706 void SyncBackendHost::InitCore(const DoInitializeOptions& options) { |
| 716 sync_thread_.message_loop()->PostTask(FROM_HERE, | 707 sync_thread_.message_loop()->PostTask(FROM_HERE, |
| 717 base::Bind(&SyncBackendHost::Core::DoInitialize, core_.get(), options)); | 708 base::Bind(&SyncBackendHost::Core::DoInitialize, core_.get(), options)); |
| 718 } | 709 } |
| 719 | 710 |
| 720 void SyncBackendHost::RequestConfigureSyncer( | 711 void SyncBackendHost::HandleSyncCycleCompletedOnFrontendLoop( |
| 721 syncer::ConfigureReason reason, | 712 const SyncSessionSnapshot& snapshot) { |
| 722 syncer::ModelTypeSet types_to_config, | 713 if (!frontend_) |
| 723 const syncer::ModelSafeRoutingInfo& routing_info, | 714 return; |
| 724 const base::Callback<void(syncer::ModelTypeSet)>& ready_task, | 715 DCHECK_EQ(MessageLoop::current(), frontend_loop_); |
| 725 const base::Closure& retry_callback) { | 716 |
| 726 sync_thread_.message_loop()->PostTask(FROM_HERE, | 717 last_snapshot_ = snapshot; |
| 727 base::Bind(&SyncBackendHost::Core::DoConfigureSyncer, | 718 |
| 728 core_.get(), | 719 SDVLOG(1) << "Got snapshot " << snapshot.ToString(); |
| 729 reason, | 720 |
| 730 types_to_config, | 721 const syncer::ModelTypeSet to_migrate = |
| 731 routing_info, | 722 snapshot.model_neutral_state().types_needing_local_migration; |
| 732 ready_task, | 723 if (!to_migrate.Empty()) |
| 733 retry_callback)); | 724 frontend_->OnMigrationNeededForTypes(to_migrate); |
| 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(); |
| 734 } | 775 } |
| 735 | 776 |
| 736 void SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop( | 777 void SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop() { |
| 737 syncer::ModelTypeSet types_to_configure, | 778 DCHECK_EQ(MessageLoop::current(), frontend_loop_); |
| 738 syncer::ModelTypeSet configured_types, | 779 // Nudge the syncer. This is necessary for both datatype addition/deletion. |
| 739 const base::Callback<void(syncer::ModelTypeSet)>& ready_task) { | 780 // |
| 740 const syncer::ModelTypeSet failed_configuration_types = | 781 // Deletions need a nudge in order to ensure the deletion occurs in a timely |
| 741 Difference(types_to_configure, configured_types); | 782 // manner (see issue 56416). |
| 742 SDVLOG(1) | 783 // |
| 743 << "Added types: " | 784 // In the case of additions, on the next sync cycle, the syncer should |
| 744 << syncer::ModelTypeSetToString(types_to_configure) | 785 // notice that the routing info has changed and start the process of |
| 745 << ", configured types: " | 786 // downloading updates for newly added data types. Once this is |
| 746 << syncer::ModelTypeSetToString(configured_types) | 787 // complete, the configure_state_.ready_task_ is run via an |
| 747 << ", failed configuration types: " | 788 // OnInitializationComplete notification. |
| 748 << syncer::ModelTypeSetToString(failed_configuration_types); | 789 |
| 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); |
| 749 | 796 |
| 750 // Update |chrome_sync_notification_bridge_|'s enabled types here as it has | 797 // Update |chrome_sync_notification_bridge_|'s enabled types here as it has |
| 751 // to happen on the UI thread. | 798 // to happen on the UI thread. |
| 752 chrome_sync_notification_bridge_.UpdateEnabledTypes(configured_types); | 799 chrome_sync_notification_bridge_.UpdateEnabledTypes(enabled_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(); |
| 753 | 850 |
| 754 // Notify SyncManager (especially the notification listener) about new types. | 851 // Notify SyncManager (especially the notification listener) about new types. |
| 755 sync_thread_.message_loop()->PostTask(FROM_HERE, | 852 sync_thread_.message_loop()->PostTask(FROM_HERE, |
| 756 base::Bind(&SyncBackendHost::Core::DoUpdateEnabledTypes, core_.get(), | 853 base::Bind(&SyncBackendHost::Core::DoUpdateEnabledTypes, core_.get(), |
| 757 configured_types)); | 854 enabled_types)); |
| 855 } |
| 758 | 856 |
| 759 if (!ready_task.is_null()) | 857 bool SyncBackendHost::IsDownloadingNigoriForTest() const { |
| 760 ready_task.Run(failed_configuration_types); | 858 return initialization_state_ == DOWNLOADING_NIGORI; |
| 761 } | 859 } |
| 762 | 860 |
| 763 SyncBackendHost::DoInitializeOptions::DoInitializeOptions( | 861 SyncBackendHost::DoInitializeOptions::DoInitializeOptions( |
| 764 MessageLoop* sync_loop, | 862 MessageLoop* sync_loop, |
| 765 SyncBackendRegistrar* registrar, | 863 SyncBackendRegistrar* registrar, |
| 766 const syncer::ModelSafeRoutingInfo& routing_info, | 864 const syncer::ModelSafeRoutingInfo& routing_info, |
| 767 const std::vector<syncer::ModelSafeWorker*>& workers, | 865 const std::vector<syncer::ModelSafeWorker*>& workers, |
| 768 syncer::ExtensionsActivityMonitor* extensions_activity_monitor, | 866 syncer::ExtensionsActivityMonitor* extensions_activity_monitor, |
| 769 const syncer::WeakHandle<syncer::JsEventHandler>& event_handler, | 867 const syncer::WeakHandle<syncer::JsEventHandler>& event_handler, |
| 770 const GURL& service_url, | 868 const GURL& service_url, |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 808 sync_loop_(NULL), | 906 sync_loop_(NULL), |
| 809 registrar_(NULL) { | 907 registrar_(NULL) { |
| 810 DCHECK(backend.get()); | 908 DCHECK(backend.get()); |
| 811 } | 909 } |
| 812 | 910 |
| 813 SyncBackendHost::Core::~Core() { | 911 SyncBackendHost::Core::~Core() { |
| 814 DCHECK(!sync_manager_.get()); | 912 DCHECK(!sync_manager_.get()); |
| 815 DCHECK(!sync_loop_); | 913 DCHECK(!sync_loop_); |
| 816 } | 914 } |
| 817 | 915 |
| 916 SyncBackendHost::PendingConfigureDataTypesState:: |
| 917 PendingConfigureDataTypesState() |
| 918 : reason(syncer::CONFIGURE_REASON_UNKNOWN), |
| 919 retry_in_progress(false) {} |
| 920 |
| 921 SyncBackendHost::PendingConfigureDataTypesState:: |
| 922 ~PendingConfigureDataTypesState() {} |
| 923 |
| 818 void SyncBackendHost::Core::OnSyncCycleCompleted( | 924 void SyncBackendHost::Core::OnSyncCycleCompleted( |
| 819 const SyncSessionSnapshot& snapshot) { | 925 const SyncSessionSnapshot& snapshot) { |
| 820 if (!sync_loop_) | 926 if (!sync_loop_) |
| 821 return; | 927 return; |
| 822 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 928 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 823 host_.Call( | 929 host_.Call( |
| 824 FROM_HERE, | 930 FROM_HERE, |
| 825 &SyncBackendHost::HandleSyncCycleCompletedOnFrontendLoop, | 931 &SyncBackendHost::HandleSyncCycleCompletedOnFrontendLoop, |
| 826 snapshot); | 932 snapshot); |
| 827 } | 933 } |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1003 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1109 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 1004 sync_manager_->UpdateEnabledTypes(enabled_types); | 1110 sync_manager_->UpdateEnabledTypes(enabled_types); |
| 1005 } | 1111 } |
| 1006 | 1112 |
| 1007 void SyncBackendHost::Core::DoStartSyncing( | 1113 void SyncBackendHost::Core::DoStartSyncing( |
| 1008 const syncer::ModelSafeRoutingInfo& routing_info) { | 1114 const syncer::ModelSafeRoutingInfo& routing_info) { |
| 1009 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1115 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 1010 sync_manager_->StartSyncingNormally(routing_info); | 1116 sync_manager_->StartSyncingNormally(routing_info); |
| 1011 } | 1117 } |
| 1012 | 1118 |
| 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 |
| 1013 void SyncBackendHost::Core::DoSetEncryptionPassphrase( | 1125 void SyncBackendHost::Core::DoSetEncryptionPassphrase( |
| 1014 const std::string& passphrase, | 1126 const std::string& passphrase, |
| 1015 bool is_explicit) { | 1127 bool is_explicit) { |
| 1016 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1128 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 1017 sync_manager_->SetEncryptionPassphrase(passphrase, is_explicit); | 1129 sync_manager_->SetEncryptionPassphrase(passphrase, is_explicit); |
| 1018 } | 1130 } |
| 1019 | 1131 |
| 1020 void SyncBackendHost::Core::DoSetDecryptionPassphrase( | 1132 void SyncBackendHost::Core::DoSetDecryptionPassphrase( |
| 1021 const std::string& passphrase) { | 1133 const std::string& passphrase) { |
| 1022 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1134 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1054 registrar_ = NULL; | 1166 registrar_ = NULL; |
| 1055 | 1167 |
| 1056 if (sync_disabled) | 1168 if (sync_disabled) |
| 1057 DeleteSyncDataFolder(); | 1169 DeleteSyncDataFolder(); |
| 1058 | 1170 |
| 1059 sync_loop_ = NULL; | 1171 sync_loop_ = NULL; |
| 1060 | 1172 |
| 1061 host_.Reset(); | 1173 host_.Reset(); |
| 1062 } | 1174 } |
| 1063 | 1175 |
| 1064 void SyncBackendHost::Core::DoConfigureSyncer( | 1176 void SyncBackendHost::Core::DoRequestConfig( |
| 1065 syncer::ConfigureReason reason, | 1177 const syncer::ModelSafeRoutingInfo& routing_info, |
| 1066 syncer::ModelTypeSet types_to_config, | 1178 syncer::ModelTypeSet types_to_config, |
| 1067 const syncer::ModelSafeRoutingInfo routing_info, | 1179 syncer::ConfigureReason reason) { |
| 1068 const base::Callback<void(syncer::ModelTypeSet)>& ready_task, | |
| 1069 const base::Closure& retry_callback) { | |
| 1070 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1180 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 1071 sync_manager_->ConfigureSyncer( | 1181 sync_manager_->RequestConfig(routing_info, types_to_config, reason); |
| 1072 reason, | |
| 1073 types_to_config, | |
| 1074 routing_info, | |
| 1075 base::Bind(&SyncBackendHost::Core::DoFinishConfigureDataTypes, | |
| 1076 this, | |
| 1077 types_to_config, | |
| 1078 ready_task), | |
| 1079 base::Bind(&SyncBackendHost::Core::DoRetryConfiguration, | |
| 1080 this, | |
| 1081 retry_callback)); | |
| 1082 } | 1182 } |
| 1083 | 1183 |
| 1084 void SyncBackendHost::Core::DoFinishConfigureDataTypes( | 1184 void SyncBackendHost::Core::DoStartConfiguration( |
| 1085 syncer::ModelTypeSet types_to_config, | 1185 const base::Closure& callback) { |
| 1086 const base::Callback<void(syncer::ModelTypeSet)>& ready_task) { | |
| 1087 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1186 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 1088 syncer::ModelTypeSet configured_types = | 1187 sync_manager_->StartConfigurationMode(callback); |
| 1089 sync_manager_->InitialSyncEndedTypes(); | |
| 1090 configured_types.RetainAll(types_to_config); | |
| 1091 host_.Call(FROM_HERE, | |
| 1092 &SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop, | |
| 1093 types_to_config, | |
| 1094 configured_types, | |
| 1095 ready_task); | |
| 1096 } | |
| 1097 | |
| 1098 void SyncBackendHost::Core::DoRetryConfiguration( | |
| 1099 const base::Closure& retry_callback) { | |
| 1100 DCHECK_EQ(MessageLoop::current(), sync_loop_); | |
| 1101 host_.Call(FROM_HERE, | |
| 1102 &SyncBackendHost::RetryConfigurationOnFrontendLoop, | |
| 1103 retry_callback); | |
| 1104 } | 1188 } |
| 1105 | 1189 |
| 1106 void SyncBackendHost::Core::DeleteSyncDataFolder() { | 1190 void SyncBackendHost::Core::DeleteSyncDataFolder() { |
| 1107 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1191 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 1108 if (file_util::DirectoryExists(sync_data_folder_path_)) { | 1192 if (file_util::DirectoryExists(sync_data_folder_path_)) { |
| 1109 if (!file_util::Delete(sync_data_folder_path_, true)) | 1193 if (!file_util::Delete(sync_data_folder_path_, true)) |
| 1110 SLOG(DFATAL) << "Could not delete the Sync Data folder."; | 1194 SLOG(DFATAL) << "Could not delete the Sync Data folder."; |
| 1111 } | 1195 } |
| 1112 } | 1196 } |
| 1113 | 1197 |
| 1198 void SyncBackendHost::Core::FinishConfigureDataTypes() { |
| 1199 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 1200 host_.Call( |
| 1201 FROM_HERE, |
| 1202 &SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop); |
| 1203 } |
| 1204 |
| 1114 void SyncBackendHost::Core::StartSavingChanges() { | 1205 void SyncBackendHost::Core::StartSavingChanges() { |
| 1115 // We may already be shut down. | 1206 // We may already be shut down. |
| 1116 if (!sync_loop_) | 1207 if (!sync_loop_) |
| 1117 return; | 1208 return; |
| 1118 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1209 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 1119 DCHECK(!save_changes_timer_.get()); | 1210 DCHECK(!save_changes_timer_.get()); |
| 1120 save_changes_timer_.reset(new base::RepeatingTimer<Core>()); | 1211 save_changes_timer_.reset(new base::RepeatingTimer<Core>()); |
| 1121 save_changes_timer_->Start(FROM_HERE, | 1212 save_changes_timer_->Start(FROM_HERE, |
| 1122 base::TimeDelta::FromSeconds(kSaveChangesIntervalSeconds), | 1213 base::TimeDelta::FromSeconds(kSaveChangesIntervalSeconds), |
| 1123 this, &Core::SaveChanges); | 1214 this, &Core::SaveChanges); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1155 initialization_state_ = NOT_INITIALIZED; | 1246 initialization_state_ = NOT_INITIALIZED; |
| 1156 | 1247 |
| 1157 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | 1248 DCHECK_EQ(MessageLoop::current(), frontend_loop_); |
| 1158 if (!success) { | 1249 if (!success) { |
| 1159 initialization_state_ = NOT_INITIALIZED; | 1250 initialization_state_ = NOT_INITIALIZED; |
| 1160 frontend_->OnBackendInitialized( | 1251 frontend_->OnBackendInitialized( |
| 1161 syncer::WeakHandle<syncer::JsBackend>(), false); | 1252 syncer::WeakHandle<syncer::JsBackend>(), false); |
| 1162 return; | 1253 return; |
| 1163 } | 1254 } |
| 1164 | 1255 |
| 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 |
| 1165 // Run initialization state machine. | 1264 // Run initialization state machine. |
| 1166 switch (initialization_state_) { | 1265 switch (initialization_state_) { |
| 1167 case NOT_INITIALIZED: | 1266 case NOT_INITIALIZED: |
| 1168 initialization_state_ = DOWNLOADING_NIGORI; | 1267 initialization_state_ = DOWNLOADING_NIGORI; |
| 1169 ConfigureDataTypes( | 1268 ConfigureDataTypes( |
| 1170 syncer::CONFIGURE_REASON_NEW_CLIENT, | 1269 syncer::CONFIGURE_REASON_NEW_CLIENT, |
| 1171 syncer::ModelTypeSet(), | 1270 syncer::ModelTypeSet(), |
| 1172 syncer::ModelTypeSet(), | 1271 syncer::ModelTypeSet(), |
| 1173 WITH_NIGORI, | 1272 WITH_NIGORI, |
| 1174 // Calls back into this function. | 1273 // Calls back into this function. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1195 // experimental types to enable. This should be done before we inform | 1294 // experimental types to enable. This should be done before we inform |
| 1196 // the frontend to ensure they're visible in the customize screen. | 1295 // the frontend to ensure they're visible in the customize screen. |
| 1197 AddExperimentalTypes(); | 1296 AddExperimentalTypes(); |
| 1198 frontend_->OnBackendInitialized(js_backend, true); | 1297 frontend_->OnBackendInitialized(js_backend, true); |
| 1199 break; | 1298 break; |
| 1200 default: | 1299 default: |
| 1201 NOTREACHED(); | 1300 NOTREACHED(); |
| 1202 } | 1301 } |
| 1203 } | 1302 } |
| 1204 | 1303 |
| 1205 void SyncBackendHost::HandleSyncCycleCompletedOnFrontendLoop( | |
| 1206 const SyncSessionSnapshot& snapshot) { | |
| 1207 if (!frontend_) | |
| 1208 return; | |
| 1209 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | |
| 1210 | |
| 1211 last_snapshot_ = snapshot; | |
| 1212 | |
| 1213 SDVLOG(1) << "Got snapshot " << snapshot.ToString(); | |
| 1214 | |
| 1215 const syncer::ModelTypeSet to_migrate = | |
| 1216 snapshot.model_neutral_state().types_needing_local_migration; | |
| 1217 if (!to_migrate.Empty()) | |
| 1218 frontend_->OnMigrationNeededForTypes(to_migrate); | |
| 1219 | |
| 1220 // Process any changes to the datatypes we're syncing. | |
| 1221 // TODO(sync): add support for removing types. | |
| 1222 if (initialized()) | |
| 1223 AddExperimentalTypes(); | |
| 1224 | |
| 1225 if (initialized()) | |
| 1226 frontend_->OnSyncCycleCompleted(); | |
| 1227 } | |
| 1228 | |
| 1229 void SyncBackendHost::RetryConfigurationOnFrontendLoop( | |
| 1230 const base::Closure& retry_callback) { | |
| 1231 SDVLOG(1) << "Failed to complete configuration, informing of retry."; | |
| 1232 retry_callback.Run(); | |
| 1233 } | |
| 1234 | |
| 1235 void SyncBackendHost::PersistEncryptionBootstrapToken( | 1304 void SyncBackendHost::PersistEncryptionBootstrapToken( |
| 1236 const std::string& token) { | 1305 const std::string& token) { |
| 1237 CHECK(sync_prefs_.get()); | 1306 CHECK(sync_prefs_.get()); |
| 1238 sync_prefs_->SetEncryptionBootstrapToken(token); | 1307 sync_prefs_->SetEncryptionBootstrapToken(token); |
| 1239 } | 1308 } |
| 1240 | 1309 |
| 1241 void SyncBackendHost::HandleActionableErrorEventOnFrontendLoop( | 1310 void SyncBackendHost::HandleActionableErrorEventOnFrontendLoop( |
| 1242 const syncer::SyncProtocolError& sync_error) { | 1311 const syncer::SyncProtocolError& sync_error) { |
| 1243 if (!frontend_) | 1312 if (!frontend_) |
| 1244 return; | 1313 return; |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1353 FROM_HERE, | 1422 FROM_HERE, |
| 1354 base::Bind(&SyncBackendHost::Core::DoRefreshNigori, | 1423 base::Bind(&SyncBackendHost::Core::DoRefreshNigori, |
| 1355 core_.get(), sync_thread_done_callback)); | 1424 core_.get(), sync_thread_done_callback)); |
| 1356 } | 1425 } |
| 1357 | 1426 |
| 1358 #undef SDVLOG | 1427 #undef SDVLOG |
| 1359 | 1428 |
| 1360 #undef SLOG | 1429 #undef SLOG |
| 1361 | 1430 |
| 1362 } // namespace browser_sync | 1431 } // namespace browser_sync |
| OLD | NEW |