Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "build/build_config.h" | 5 #include "build/build_config.h" |
| 6 | 6 |
| 7 #include "chrome/browser/sync/glue/sync_backend_host.h" | 7 #include "chrome/browser/sync/glue/sync_backend_host.h" |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <map> | 10 #include <map> |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 124 // Called when the user disables or enables a sync type. | 124 // Called when the user disables or enables a sync type. |
| 125 void DoUpdateEnabledTypes(const syncable::ModelTypeSet& enabled_types); | 125 void DoUpdateEnabledTypes(const syncable::ModelTypeSet& enabled_types); |
| 126 | 126 |
| 127 // Called to tell the syncapi to start syncing (generally after | 127 // Called to tell the syncapi to start syncing (generally after |
| 128 // initialization and authentication). | 128 // initialization and authentication). |
| 129 void DoStartSyncing(const ModelSafeRoutingInfo& routing_info); | 129 void DoStartSyncing(const ModelSafeRoutingInfo& routing_info); |
| 130 | 130 |
| 131 // Called to clear server data. | 131 // Called to clear server data. |
| 132 void DoRequestClearServerData(); | 132 void DoRequestClearServerData(); |
| 133 | 133 |
| 134 // Called to cleanup disabled types. | |
| 135 void DoRequestCleanupDisabledTypes( | |
| 136 const browser_sync::ModelSafeRoutingInfo& routing_info); | |
| 137 | |
| 138 // Called to set the passphrase for encryption. | 134 // Called to set the passphrase for encryption. |
| 139 void DoSetEncryptionPassphrase(const std::string& passphrase, | 135 void DoSetEncryptionPassphrase(const std::string& passphrase, |
| 140 bool is_explicit); | 136 bool is_explicit); |
| 141 | 137 |
| 142 // Called to decrypt the pending keys. | 138 // Called to decrypt the pending keys. |
| 143 void DoSetDecryptionPassphrase(const std::string& passphrase); | 139 void DoSetDecryptionPassphrase(const std::string& passphrase); |
| 144 | 140 |
| 145 // Called to turn on encryption of all sync data as well as | 141 // Called to turn on encryption of all sync data as well as |
| 146 // reencrypt everything. | 142 // reencrypt everything. |
| 147 void DoEnableEncryptEverything(); | 143 void DoEnableEncryptEverything(); |
| 148 | 144 |
| 149 // Called to refresh encryption with the most recent passphrase | 145 // Called to refresh encryption with the most recent passphrase |
| 150 // and set of encrypted types. Also adds device information to the nigori | 146 // and set of encrypted types. Also adds device information to the nigori |
| 151 // node. |done_callback| is called on the sync thread. | 147 // node. |done_callback| is called on the sync thread. |
| 152 void DoRefreshNigori(const base::Closure& done_callback); | 148 void DoRefreshNigori(const base::Closure& done_callback); |
| 153 | 149 |
| 154 // The shutdown order is a bit complicated: | 150 // The shutdown order is a bit complicated: |
| 155 // 1) From |sync_thread_|, invoke the syncapi Shutdown call to do | 151 // 1) From |sync_thread_|, invoke the syncapi Shutdown call to do |
| 156 // a final SaveChanges, and close sqlite handles. | 152 // a final SaveChanges, and close sqlite handles. |
| 157 // 2) Then, from |frontend_loop_|, halt the sync_thread_ (which is | 153 // 2) Then, from |frontend_loop_|, halt the sync_thread_ (which is |
| 158 // a blocking call). This causes syncapi thread-exit handlers | 154 // a blocking call). This causes syncapi thread-exit handlers |
| 159 // to run and make use of cached pointers to various components | 155 // to run and make use of cached pointers to various components |
| 160 // owned implicitly by us. | 156 // owned implicitly by us. |
| 161 // 3) Destroy this Core. That will delete syncapi components in a | 157 // 3) Destroy this Core. That will delete syncapi components in a |
| 162 // safe order because the thread that was using them has exited | 158 // safe order because the thread that was using them has exited |
| 163 // (in step 2). | 159 // (in step 2). |
| 164 void DoStopSyncManagerForShutdown(const base::Closure& closure); | 160 void DoStopSyncManagerForShutdown(const base::Closure& closure); |
| 165 void DoShutdown(bool stopping_sync); | 161 void DoShutdown(bool stopping_sync); |
| 166 | 162 |
| 167 virtual void DoRequestConfig( | 163 // Configuration methods that must execute on sync loop. |
| 168 const browser_sync::ModelSafeRoutingInfo& routing_info, | 164 void DoConfigureSyncer( |
|
rlarocque
2012/06/09 01:44:35
Could we rename either this method or SBH::Request
Nicolas Zea
2012/06/11 23:05:20
I'm not sure what you mean? The whole Request/Do n
rlarocque
2012/06/12 17:45:13
I got confused between the old and new names of th
| |
| 165 sync_api::ConfigureReason reason, | |
| 169 syncable::ModelTypeSet types_to_config, | 166 syncable::ModelTypeSet types_to_config, |
| 170 sync_api::ConfigureReason reason); | 167 const browser_sync::ModelSafeRoutingInfo routing_info, |
| 171 | 168 const base::Callback<void(syncable::ModelTypeSet)>& ready_task, |
| 172 // Start the configuration mode. |callback| is called on the sync | 169 const base::Closure& retry_callback); |
| 173 // thread. | 170 void DoFinishConfigureDataTypes( |
| 174 virtual void DoStartConfiguration(const base::Closure& callback); | 171 syncable::ModelTypeSet types_to_config, |
| 172 const base::Callback<void(syncable::ModelTypeSet)>& ready_task); | |
| 173 void DoRetryConfiguration( | |
| 174 const base::Closure& retry_callback); | |
| 175 | 175 |
| 176 // Set the base request context to use when making HTTP calls. | 176 // Set the base request context to use when making HTTP calls. |
| 177 // This method will add a reference to the context to persist it | 177 // This method will add a reference to the context to persist it |
| 178 // on the IO thread. Must be removed from IO thread. | 178 // on the IO thread. Must be removed from IO thread. |
| 179 | 179 |
| 180 sync_api::SyncManager* sync_manager() { return sync_manager_.get(); } | 180 sync_api::SyncManager* sync_manager() { return sync_manager_.get(); } |
| 181 | 181 |
| 182 // Delete the sync data folder to cleanup backend data. Happens the first | 182 // Delete the sync data folder to cleanup backend data. Happens the first |
| 183 // time sync is enabled for a user (to prevent accidentally reusing old | 183 // time sync is enabled for a user (to prevent accidentally reusing old |
| 184 // sync databases), as well as shutdown when you're no longer syncing. | 184 // sync databases), as well as shutdown when you're no longer syncing. |
| 185 void DeleteSyncDataFolder(); | 185 void DeleteSyncDataFolder(); |
| 186 | 186 |
| 187 // A callback from the SyncerThread when it is safe to continue config. | |
| 188 void FinishConfigureDataTypes(); | |
| 189 | |
| 190 private: | 187 private: |
| 191 friend class base::RefCountedThreadSafe<SyncBackendHost::Core>; | 188 friend class base::RefCountedThreadSafe<SyncBackendHost::Core>; |
| 192 friend class SyncBackendHostForProfileSyncTest; | 189 friend class SyncBackendHostForProfileSyncTest; |
| 193 | 190 |
| 194 virtual ~Core(); | 191 virtual ~Core(); |
| 195 | 192 |
| 196 // Invoked when initialization of syncapi is complete and we can start | 193 // Invoked when initialization of syncapi is complete and we can start |
| 197 // our timer. | 194 // our timer. |
| 198 // This must be called from the thread on which SaveChanges is intended to | 195 // This must be called from the thread on which SaveChanges is intended to |
| 199 // be run on; the host's |sync_thread_|. | 196 // be run on; the host's |sync_thread_|. |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 550 stop_thread_start_time; | 547 stop_thread_start_time; |
| 551 UMA_HISTOGRAM_TIMES("Sync.Shutdown.StopSyncThreadTime", | 548 UMA_HISTOGRAM_TIMES("Sync.Shutdown.StopSyncThreadTime", |
| 552 stop_sync_thread_time); | 549 stop_sync_thread_time); |
| 553 | 550 |
| 554 registrar_.reset(); | 551 registrar_.reset(); |
| 555 frontend_ = NULL; | 552 frontend_ = NULL; |
| 556 core_ = NULL; // Releases reference to core_. | 553 core_ = NULL; // Releases reference to core_. |
| 557 } | 554 } |
| 558 | 555 |
| 559 void SyncBackendHost::ConfigureDataTypes( | 556 void SyncBackendHost::ConfigureDataTypes( |
| 560 sync_api::ConfigureReason reason, | 557 const sync_api::ConfigureReason& reason, |
| 561 syncable::ModelTypeSet types_to_add, | 558 const syncable::ModelTypeSet& desired_types, |
| 562 syncable::ModelTypeSet types_to_remove, | 559 const syncable::ModelTypeSet& disabled_types, |
|
rlarocque
2012/06/09 01:44:35
I think disabled_types is not like the other names
Nicolas Zea
2012/06/11 23:05:20
But that implies that it's a delta and not already
| |
| 563 NigoriState nigori_state, | 560 NigoriState nigori_state, |
| 564 base::Callback<void(syncable::ModelTypeSet)> ready_task, | 561 const base::Callback<void(syncable::ModelTypeSet)>& ready_task, |
| 565 base::Callback<void()> retry_callback) { | 562 const base::Callback<void()>& retry_callback) { |
| 566 syncable::ModelTypeSet types_to_add_with_nigori = types_to_add; | 563 syncable::ModelTypeSet desired_types_with_nigori = desired_types; |
| 567 syncable::ModelTypeSet types_to_remove_with_nigori = types_to_remove; | 564 syncable::ModelTypeSet disabled_types_with_nigori = disabled_types; |
| 568 if (nigori_state == WITH_NIGORI) { | 565 if (nigori_state == WITH_NIGORI) { |
| 569 types_to_add_with_nigori.Put(syncable::NIGORI); | 566 desired_types_with_nigori.Put(syncable::NIGORI); |
| 570 types_to_remove_with_nigori.Remove(syncable::NIGORI); | 567 disabled_types_with_nigori.Remove(syncable::NIGORI); |
| 571 } else { | 568 } else { |
| 572 types_to_add_with_nigori.Remove(syncable::NIGORI); | 569 desired_types_with_nigori.Remove(syncable::NIGORI); |
| 573 types_to_remove_with_nigori.Put(syncable::NIGORI); | 570 disabled_types_with_nigori.Put(syncable::NIGORI); |
| 574 } | 571 } |
| 575 // Only one configure is allowed at a time. | 572 // Only one configure is allowed at a time (DataTypeManager handles user |
| 576 DCHECK(!pending_config_mode_state_.get()); | 573 // changes that happen while the syncer is reconfiguraing, and will only |
| 577 DCHECK(!pending_download_state_.get()); | 574 // trigger another call to ConfigureDataTypes once the current reconfiguration |
| 575 // completes). | |
| 578 DCHECK_GT(initialization_state_, NOT_INITIALIZED); | 576 DCHECK_GT(initialization_state_, NOT_INITIALIZED); |
| 579 | 577 |
| 580 pending_config_mode_state_.reset(new PendingConfigureDataTypesState()); | 578 // enabled_types \setunion disabled_types gives the set of all registered |
| 581 pending_config_mode_state_->ready_task = ready_task; | 579 // types (i.e. types with datatype controllers registered). |
| 582 pending_config_mode_state_->types_to_add = types_to_add_with_nigori; | 580 ModelSafeRoutingInfo routing_info; |
| 583 pending_config_mode_state_->added_types = | 581 registrar_->ConfigureDataTypes(desired_types_with_nigori, |
| 584 registrar_->ConfigureDataTypes(types_to_add_with_nigori, | 582 disabled_types_with_nigori); |
| 585 types_to_remove_with_nigori); | 583 registrar_->GetModelSafeRoutingInfo(&routing_info); |
| 586 pending_config_mode_state_->reason = reason; | |
| 587 pending_config_mode_state_->retry_callback = retry_callback; | |
| 588 | 584 |
| 589 // Cleanup disabled types before starting configuration so that | 585 // |enabled_types| is desired_types_with_nigori \setintersect types with |
| 590 // callers can assume that the data types are cleaned up once | 586 // model safe workers (e.g. the password store may fail to start up, in which |
| 591 // configuration is done. | 587 // case we have no model safe worker for it and should not enable it). |
| 592 if (!types_to_remove_with_nigori.Empty()) { | 588 // TODO(sync): This shouldn't be necessary. We should do whatever filtering |
| 593 ModelSafeRoutingInfo routing_info; | 589 // we need beforehand as part of ProfileSyncComponentsFactory's |
| 594 registrar_->GetModelSafeRoutingInfo(&routing_info); | 590 // RegisterDataTypes. |
| 595 sync_thread_.message_loop()->PostTask( | 591 const syncable::ModelTypeSet enabled_types = |
| 596 FROM_HERE, | 592 GetRoutingInfoTypes(routing_info); |
| 597 base::Bind(&SyncBackendHost::Core::DoRequestCleanupDisabledTypes, | |
| 598 core_.get(), | |
| 599 routing_info)); | |
| 600 } | |
| 601 | 593 |
| 602 StartConfiguration( | 594 // Figure out which types need to actually be downloaded. We pass those on |
| 603 base::Bind(&SyncBackendHost::Core::FinishConfigureDataTypes, | 595 // to the syncer while it's in configuration mode so that they can be |
| 604 core_.get())); | 596 // downloaded before we perform association. Once we switch to normal mode |
| 605 } | 597 // downloads will get applied normally and hit the datatype's change |
| 598 // processor. | |
| 599 // A datatype is in need of downloading if any of the following are true: | |
| 600 // 1. it's enabled and initial_sync_ended is false (initial_sync_ended is | |
| 601 // set after applying updates, and hence is a more conservative measure | |
| 602 // than having a non-empty progress marker, which is set during | |
| 603 // StoreTimestamps). | |
| 604 // 2. the type is NIGORI, and any other datatype is being configured (nigori | |
| 605 // is always included if we do a configuration). | |
| 606 // TODO(sync): consider moving this logic onto the sync thread (perhaps | |
| 607 // as part of SyncManager::ConfigureSyncer). | |
| 608 syncable::ModelTypeSet initial_sync_ended_types = | |
| 609 core_->sync_manager()->InitialSyncEndedTypes(); | |
| 610 initial_sync_ended_types.RetainAll(enabled_types); | |
| 611 syncable::ModelTypeSet types_to_config = | |
| 612 Difference(enabled_types, initial_sync_ended_types); | |
| 613 if (types_to_config.Size() > 1 && enabled_types.Has(syncable::NIGORI)) | |
| 614 types_to_config.Put(syncable::NIGORI); | |
| 606 | 615 |
| 607 void SyncBackendHost::StartConfiguration(const base::Closure& callback) { | 616 SDVLOG(1) << "Types " |
| 608 // Put syncer in the config mode. DTM will put us in normal mode once it is | 617 << syncable::ModelTypeSetToString(types_to_config) |
| 609 // done. This is to ensure we dont do a normal sync when we are doing model | 618 << " added; calling DoConfigureSyncer"; |
| 610 // association. | 619 // TODO(zea): figure out how to bypass this call if no types are being |
| 611 sync_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | 620 // configured and GetKey is not needed. For now we rely on determining the |
| 612 &SyncBackendHost::Core::DoStartConfiguration, core_.get(), callback)); | 621 // need for GetKey as part of the SyncManager::ConfigureSyncer logic. |
| 622 RequestConfigureSyncer(reason, | |
| 623 types_to_config, | |
| 624 routing_info, | |
| 625 ready_task, | |
| 626 retry_callback); | |
| 613 } | 627 } |
| 614 | 628 |
| 615 void SyncBackendHost::EnableEncryptEverything() { | 629 void SyncBackendHost::EnableEncryptEverything() { |
| 616 sync_thread_.message_loop()->PostTask(FROM_HERE, | 630 sync_thread_.message_loop()->PostTask(FROM_HERE, |
| 617 base::Bind(&SyncBackendHost::Core::DoEnableEncryptEverything, | 631 base::Bind(&SyncBackendHost::Core::DoEnableEncryptEverything, |
| 618 core_.get())); | 632 core_.get())); |
| 619 } | 633 } |
| 620 | 634 |
| 621 void SyncBackendHost::ActivateDataType( | 635 void SyncBackendHost::ActivateDataType( |
| 622 syncable::ModelType type, ModelSafeGroup group, | 636 syncable::ModelType type, ModelSafeGroup group, |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 680 } else { | 694 } else { |
| 681 NOTREACHED(); | 695 NOTREACHED(); |
| 682 } | 696 } |
| 683 } | 697 } |
| 684 | 698 |
| 685 void SyncBackendHost::InitCore(const DoInitializeOptions& options) { | 699 void SyncBackendHost::InitCore(const DoInitializeOptions& options) { |
| 686 sync_thread_.message_loop()->PostTask(FROM_HERE, | 700 sync_thread_.message_loop()->PostTask(FROM_HERE, |
| 687 base::Bind(&SyncBackendHost::Core::DoInitialize, core_.get(), options)); | 701 base::Bind(&SyncBackendHost::Core::DoInitialize, core_.get(), options)); |
| 688 } | 702 } |
| 689 | 703 |
| 690 void SyncBackendHost::HandleSyncCycleCompletedOnFrontendLoop( | 704 void SyncBackendHost::RequestConfigureSyncer( |
| 691 const SyncSessionSnapshot& snapshot) { | 705 sync_api::ConfigureReason reason, |
| 692 if (!frontend_) | 706 syncable::ModelTypeSet types_to_config, |
| 693 return; | 707 const browser_sync::ModelSafeRoutingInfo routing_info, |
| 694 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | 708 const base::Callback<void(syncable::ModelTypeSet)>& ready_task, |
| 695 | 709 const base::Closure& retry_callback) { |
| 696 last_snapshot_ = snapshot; | 710 sync_thread_.message_loop()->PostTask(FROM_HERE, |
| 697 | 711 base::Bind(&SyncBackendHost::Core::DoConfigureSyncer, |
| 698 SDVLOG(1) << "Got snapshot " << snapshot.ToString(); | 712 core_.get(), |
| 699 | 713 reason, |
| 700 const syncable::ModelTypeSet to_migrate = | 714 types_to_config, |
| 701 snapshot.syncer_status().types_needing_local_migration; | 715 routing_info, |
| 702 if (!to_migrate.Empty()) | 716 ready_task, |
| 703 frontend_->OnMigrationNeededForTypes(to_migrate); | 717 retry_callback)); |
| 704 | |
| 705 // Process any changes to the datatypes we're syncing. | |
| 706 // TODO(sync): add support for removing types. | |
| 707 if (initialized()) | |
| 708 AddExperimentalTypes(); | |
| 709 | |
| 710 // If we are waiting for a configuration change, check here to see | |
| 711 // if this sync cycle has initialized all of the types we've been | |
| 712 // waiting for. | |
| 713 if (pending_download_state_.get()) { | |
| 714 const syncable::ModelTypeSet types_to_add = | |
| 715 pending_download_state_->types_to_add; | |
| 716 const syncable::ModelTypeSet added_types = | |
| 717 pending_download_state_->added_types; | |
| 718 DCHECK(types_to_add.HasAll(added_types)); | |
| 719 const syncable::ModelTypeSet initial_sync_ended = | |
| 720 snapshot.initial_sync_ended(); | |
| 721 const syncable::ModelTypeSet failed_configuration_types = | |
| 722 Difference(added_types, initial_sync_ended); | |
| 723 SDVLOG(1) | |
| 724 << "Added types: " | |
| 725 << syncable::ModelTypeSetToString(added_types) | |
| 726 << ", configured types: " | |
| 727 << syncable::ModelTypeSetToString(initial_sync_ended) | |
| 728 << ", failed configuration types: " | |
| 729 << syncable::ModelTypeSetToString(failed_configuration_types); | |
| 730 | |
| 731 if (!failed_configuration_types.Empty() && | |
| 732 snapshot.retry_scheduled()) { | |
| 733 // Inform the caller that download failed but we are retrying. | |
| 734 if (!pending_download_state_->retry_in_progress) { | |
| 735 pending_download_state_->retry_callback.Run(); | |
| 736 pending_download_state_->retry_in_progress = true; | |
| 737 } | |
| 738 // Nothing more to do. | |
| 739 return; | |
| 740 } | |
| 741 | |
| 742 scoped_ptr<PendingConfigureDataTypesState> state( | |
| 743 pending_download_state_.release()); | |
| 744 state->ready_task.Run(failed_configuration_types); | |
| 745 | |
| 746 // Syncer did not report an error but did not download everything | |
| 747 // we requested either. So abort. The caller of the config will cleanup. | |
| 748 if (!failed_configuration_types.Empty()) | |
| 749 return; | |
| 750 } | |
| 751 | |
| 752 if (initialized()) | |
| 753 frontend_->OnSyncCycleCompleted(); | |
| 754 } | 718 } |
| 755 | 719 |
| 756 void SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop() { | 720 void SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop( |
| 757 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | 721 const syncable::ModelTypeSet& types_to_configure, |
| 758 // Nudge the syncer. This is necessary for both datatype addition/deletion. | 722 const syncable::ModelTypeSet& configured_types, |
| 759 // | 723 const base::Callback<void(syncable::ModelTypeSet)>& ready_task) { |
| 760 // Deletions need a nudge in order to ensure the deletion occurs in a timely | 724 const syncable::ModelTypeSet failed_configuration_types = |
| 761 // manner (see issue 56416). | 725 Difference(types_to_configure, configured_types); |
| 762 // | 726 SDVLOG(1) |
| 763 // In the case of additions, on the next sync cycle, the syncer should | 727 << "Added types: " |
| 764 // notice that the routing info has changed and start the process of | 728 << syncable::ModelTypeSetToString(types_to_configure) |
| 765 // downloading updates for newly added data types. Once this is | 729 << ", configured types: " |
| 766 // complete, the configure_state_.ready_task_ is run via an | 730 << syncable::ModelTypeSetToString(configured_types) |
| 767 // OnInitializationComplete notification. | 731 << ", failed configuration types: " |
| 768 | 732 << syncable::ModelTypeSetToString(failed_configuration_types); |
| 769 SDVLOG(1) << "Syncer in config mode. SBH executing " | |
| 770 << "FinishConfigureDataTypesOnFrontendLoop"; | |
| 771 | |
| 772 | |
| 773 ModelSafeRoutingInfo routing_info; | |
| 774 registrar_->GetModelSafeRoutingInfo(&routing_info); | |
| 775 const syncable::ModelTypeSet enabled_types = | |
| 776 GetRoutingInfoTypes(routing_info); | |
| 777 | 733 |
| 778 // Update |chrome_sync_notification_bridge_|'s enabled types here as it has | 734 // Update |chrome_sync_notification_bridge_|'s enabled types here as it has |
| 779 // to happen on the UI thread. | 735 // to happen on the UI thread. |
| 780 chrome_sync_notification_bridge_.UpdateEnabledTypes(enabled_types); | 736 chrome_sync_notification_bridge_.UpdateEnabledTypes(configured_types); |
| 781 | |
| 782 if (pending_config_mode_state_->added_types.Empty() && | |
| 783 !core_->sync_manager()->InitialSyncEndedTypes().HasAll(enabled_types)) { | |
| 784 | |
| 785 // TODO(tim): Log / UMA / count this somehow? | |
| 786 // Add only the types with empty progress markers. Note: it is possible | |
| 787 // that some types have their initial_sync_ended be false but with non | |
| 788 // empty progress marker. Which is ok as the rest of the changes would | |
| 789 // be downloaded on a regular nudge and initial_sync_ended should be set | |
| 790 // to true. However this is a very corner case. So it is not explicitly | |
| 791 // handled. | |
| 792 pending_config_mode_state_->added_types = | |
| 793 sync_api::GetTypesWithEmptyProgressMarkerToken(enabled_types, | |
| 794 GetUserShare()); | |
| 795 } | |
| 796 | |
| 797 // If we've added types, we always want to request a nudge/config (even if | |
| 798 // the initial sync is ended), in case we could not decrypt the data. | |
| 799 if (pending_config_mode_state_->added_types.Empty()) { | |
| 800 SDVLOG(1) << "No new types added; calling ready_task directly"; | |
| 801 // No new types - just notify the caller that the types are available. | |
| 802 const syncable::ModelTypeSet failed_configuration_types; | |
| 803 pending_config_mode_state_->ready_task.Run(failed_configuration_types); | |
| 804 } else { | |
| 805 pending_download_state_.reset(pending_config_mode_state_.release()); | |
| 806 | |
| 807 // Always configure nigori if it's enabled. | |
| 808 syncable::ModelTypeSet types_to_config = | |
| 809 pending_download_state_->added_types; | |
| 810 if (IsNigoriEnabled()) { | |
| 811 // Note: Nigori is the only type that gets added with a nonempty | |
| 812 // progress marker during config. If the server returns a migration | |
| 813 // error then we will go into unrecoverable error. We dont handle it | |
| 814 // explicitly because server might help us out here by not sending a | |
| 815 // migraiton error for nigori during config. | |
| 816 types_to_config.Put(syncable::NIGORI); | |
| 817 } | |
| 818 SDVLOG(1) << "Types " | |
| 819 << syncable::ModelTypeSetToString(types_to_config) | |
| 820 << " added; calling DoRequestConfig"; | |
| 821 ModelSafeRoutingInfo routing_info; | |
| 822 registrar_->GetModelSafeRoutingInfo(&routing_info); | |
| 823 sync_thread_.message_loop()->PostTask(FROM_HERE, | |
| 824 base::Bind(&SyncBackendHost::Core::DoRequestConfig, | |
| 825 core_.get(), | |
| 826 routing_info, | |
| 827 types_to_config, | |
| 828 pending_download_state_->reason)); | |
| 829 } | |
| 830 | |
| 831 pending_config_mode_state_.reset(); | |
| 832 | 737 |
| 833 // Notify SyncManager (especially the notification listener) about new types. | 738 // Notify SyncManager (especially the notification listener) about new types. |
| 834 sync_thread_.message_loop()->PostTask(FROM_HERE, | 739 sync_thread_.message_loop()->PostTask(FROM_HERE, |
| 835 base::Bind(&SyncBackendHost::Core::DoUpdateEnabledTypes, core_.get(), | 740 base::Bind(&SyncBackendHost::Core::DoUpdateEnabledTypes, core_.get(), |
| 836 enabled_types)); | 741 configured_types)); |
| 837 } | |
| 838 | 742 |
| 839 bool SyncBackendHost::IsDownloadingNigoriForTest() const { | 743 if (!ready_task.is_null()) |
| 840 return initialization_state_ == DOWNLOADING_NIGORI; | 744 ready_task.Run(failed_configuration_types); |
| 841 } | 745 } |
| 842 | 746 |
| 843 SyncBackendHost::DoInitializeOptions::DoInitializeOptions( | 747 SyncBackendHost::DoInitializeOptions::DoInitializeOptions( |
| 844 MessageLoop* sync_loop, | 748 MessageLoop* sync_loop, |
| 845 SyncBackendRegistrar* registrar, | 749 SyncBackendRegistrar* registrar, |
| 846 const ModelSafeRoutingInfo& routing_info, | 750 const ModelSafeRoutingInfo& routing_info, |
| 847 const std::vector<ModelSafeWorker*>& workers, | 751 const std::vector<ModelSafeWorker*>& workers, |
| 848 ExtensionsActivityMonitor* extensions_activity_monitor, | 752 ExtensionsActivityMonitor* extensions_activity_monitor, |
| 849 const WeakHandle<JsEventHandler>& event_handler, | 753 const WeakHandle<JsEventHandler>& event_handler, |
| 850 const GURL& service_url, | 754 const GURL& service_url, |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 887 sync_loop_(NULL), | 791 sync_loop_(NULL), |
| 888 registrar_(NULL) { | 792 registrar_(NULL) { |
| 889 DCHECK(backend.get()); | 793 DCHECK(backend.get()); |
| 890 } | 794 } |
| 891 | 795 |
| 892 SyncBackendHost::Core::~Core() { | 796 SyncBackendHost::Core::~Core() { |
| 893 DCHECK(!sync_manager_.get()); | 797 DCHECK(!sync_manager_.get()); |
| 894 DCHECK(!sync_loop_); | 798 DCHECK(!sync_loop_); |
| 895 } | 799 } |
| 896 | 800 |
| 897 SyncBackendHost::PendingConfigureDataTypesState:: | |
| 898 PendingConfigureDataTypesState() | |
| 899 : reason(sync_api::CONFIGURE_REASON_UNKNOWN), | |
| 900 retry_in_progress(false) {} | |
| 901 | |
| 902 SyncBackendHost::PendingConfigureDataTypesState:: | |
| 903 ~PendingConfigureDataTypesState() {} | |
| 904 | |
| 905 void SyncBackendHost::Core::OnSyncCycleCompleted( | 801 void SyncBackendHost::Core::OnSyncCycleCompleted( |
| 906 const SyncSessionSnapshot& snapshot) { | 802 const SyncSessionSnapshot& snapshot) { |
| 907 if (!sync_loop_) | 803 if (!sync_loop_) |
| 908 return; | 804 return; |
| 909 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 805 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 910 host_.Call( | 806 host_.Call( |
| 911 FROM_HERE, | 807 FROM_HERE, |
| 912 &SyncBackendHost::HandleSyncCycleCompletedOnFrontendLoop, | 808 &SyncBackendHost::HandleSyncCycleCompletedOnFrontendLoop, |
| 913 snapshot); | 809 snapshot); |
| 914 } | 810 } |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1146 const ModelSafeRoutingInfo& routing_info) { | 1042 const ModelSafeRoutingInfo& routing_info) { |
| 1147 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1043 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 1148 sync_manager_->StartSyncingNormally(routing_info); | 1044 sync_manager_->StartSyncingNormally(routing_info); |
| 1149 } | 1045 } |
| 1150 | 1046 |
| 1151 void SyncBackendHost::Core::DoRequestClearServerData() { | 1047 void SyncBackendHost::Core::DoRequestClearServerData() { |
| 1152 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1048 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 1153 sync_manager_->RequestClearServerData(); | 1049 sync_manager_->RequestClearServerData(); |
| 1154 } | 1050 } |
| 1155 | 1051 |
| 1156 void SyncBackendHost::Core::DoRequestCleanupDisabledTypes( | |
| 1157 const browser_sync::ModelSafeRoutingInfo& routing_info) { | |
| 1158 DCHECK_EQ(MessageLoop::current(), sync_loop_); | |
| 1159 sync_manager_->RequestCleanupDisabledTypes(routing_info); | |
| 1160 } | |
| 1161 | |
| 1162 void SyncBackendHost::Core::DoSetEncryptionPassphrase( | 1052 void SyncBackendHost::Core::DoSetEncryptionPassphrase( |
| 1163 const std::string& passphrase, | 1053 const std::string& passphrase, |
| 1164 bool is_explicit) { | 1054 bool is_explicit) { |
| 1165 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1055 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 1166 sync_manager_->SetEncryptionPassphrase(passphrase, is_explicit); | 1056 sync_manager_->SetEncryptionPassphrase(passphrase, is_explicit); |
| 1167 } | 1057 } |
| 1168 | 1058 |
| 1169 void SyncBackendHost::Core::DoSetDecryptionPassphrase( | 1059 void SyncBackendHost::Core::DoSetDecryptionPassphrase( |
| 1170 const std::string& passphrase) { | 1060 const std::string& passphrase) { |
| 1171 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1061 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1203 registrar_ = NULL; | 1093 registrar_ = NULL; |
| 1204 | 1094 |
| 1205 if (sync_disabled) | 1095 if (sync_disabled) |
| 1206 DeleteSyncDataFolder(); | 1096 DeleteSyncDataFolder(); |
| 1207 | 1097 |
| 1208 sync_loop_ = NULL; | 1098 sync_loop_ = NULL; |
| 1209 | 1099 |
| 1210 host_.Reset(); | 1100 host_.Reset(); |
| 1211 } | 1101 } |
| 1212 | 1102 |
| 1213 void SyncBackendHost::Core::DoRequestConfig( | 1103 void SyncBackendHost::Core::DoConfigureSyncer( |
| 1214 const browser_sync::ModelSafeRoutingInfo& routing_info, | 1104 sync_api::ConfigureReason reason, |
| 1215 syncable::ModelTypeSet types_to_config, | 1105 syncable::ModelTypeSet types_to_config, |
| 1216 sync_api::ConfigureReason reason) { | 1106 const browser_sync::ModelSafeRoutingInfo routing_info, |
| 1107 const base::Callback<void(syncable::ModelTypeSet)>& ready_task, | |
| 1108 const base::Closure& retry_callback) { | |
| 1217 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1109 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 1218 sync_manager_->RequestConfig(routing_info, types_to_config, reason); | 1110 sync_manager_->ConfigureSyncer( |
| 1111 reason, | |
| 1112 types_to_config, | |
| 1113 routing_info, | |
| 1114 base::Bind(&SyncBackendHost::Core::DoFinishConfigureDataTypes, | |
| 1115 this, | |
| 1116 types_to_config, | |
| 1117 ready_task), | |
| 1118 base::Bind(&SyncBackendHost::Core::DoRetryConfiguration, | |
| 1119 this, | |
| 1120 retry_callback)); | |
| 1219 } | 1121 } |
| 1220 | 1122 |
| 1221 void SyncBackendHost::Core::DoStartConfiguration( | 1123 void SyncBackendHost::Core::DoFinishConfigureDataTypes( |
| 1222 const base::Closure& callback) { | 1124 syncable::ModelTypeSet types_to_config, |
| 1125 const base::Callback<void(syncable::ModelTypeSet)>& ready_task) { | |
| 1223 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1126 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 1224 sync_manager_->StartConfigurationMode(callback); | 1127 syncable::ModelTypeSet configured_types = |
| 1128 sync_manager_->InitialSyncEndedTypes(); | |
| 1129 configured_types.RetainAll(types_to_config); | |
| 1130 host_.Call(FROM_HERE, | |
| 1131 &SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop, | |
| 1132 types_to_config, | |
| 1133 configured_types, | |
| 1134 ready_task); | |
| 1135 } | |
| 1136 | |
| 1137 void SyncBackendHost::Core::DoRetryConfiguration( | |
| 1138 const base::Closure& retry_callback) { | |
| 1139 DCHECK_EQ(MessageLoop::current(), sync_loop_); | |
| 1140 host_.Call(FROM_HERE, | |
| 1141 &SyncBackendHost::RetryConfigurationOnFrontendLoop, | |
| 1142 retry_callback); | |
| 1225 } | 1143 } |
| 1226 | 1144 |
| 1227 void SyncBackendHost::Core::DeleteSyncDataFolder() { | 1145 void SyncBackendHost::Core::DeleteSyncDataFolder() { |
| 1228 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1146 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 1229 if (file_util::DirectoryExists(sync_data_folder_path_)) { | 1147 if (file_util::DirectoryExists(sync_data_folder_path_)) { |
| 1230 if (!file_util::Delete(sync_data_folder_path_, true)) | 1148 if (!file_util::Delete(sync_data_folder_path_, true)) |
| 1231 SLOG(DFATAL) << "Could not delete the Sync Data folder."; | 1149 SLOG(DFATAL) << "Could not delete the Sync Data folder."; |
| 1232 } | 1150 } |
| 1233 } | 1151 } |
| 1234 | 1152 |
| 1235 void SyncBackendHost::Core::FinishConfigureDataTypes() { | |
| 1236 DCHECK_EQ(MessageLoop::current(), sync_loop_); | |
| 1237 host_.Call( | |
| 1238 FROM_HERE, | |
| 1239 &SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop); | |
| 1240 } | |
| 1241 | |
| 1242 void SyncBackendHost::Core::StartSavingChanges() { | 1153 void SyncBackendHost::Core::StartSavingChanges() { |
| 1243 // We may already be shut down. | 1154 // We may already be shut down. |
| 1244 if (!sync_loop_) | 1155 if (!sync_loop_) |
| 1245 return; | 1156 return; |
| 1246 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1157 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 1247 DCHECK(!save_changes_timer_.get()); | 1158 DCHECK(!save_changes_timer_.get()); |
| 1248 save_changes_timer_.reset(new base::RepeatingTimer<Core>()); | 1159 save_changes_timer_.reset(new base::RepeatingTimer<Core>()); |
| 1249 save_changes_timer_->Start(FROM_HERE, | 1160 save_changes_timer_->Start(FROM_HERE, |
| 1250 base::TimeDelta::FromSeconds(kSaveChangesIntervalSeconds), | 1161 base::TimeDelta::FromSeconds(kSaveChangesIntervalSeconds), |
| 1251 this, &Core::SaveChanges); | 1162 this, &Core::SaveChanges); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1285 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | 1196 DCHECK_EQ(MessageLoop::current(), frontend_loop_); |
| 1286 if (!success) { | 1197 if (!success) { |
| 1287 initialization_state_ = NOT_INITIALIZED; | 1198 initialization_state_ = NOT_INITIALIZED; |
| 1288 frontend_->OnBackendInitialized(WeakHandle<JsBackend>(), false); | 1199 frontend_->OnBackendInitialized(WeakHandle<JsBackend>(), false); |
| 1289 return; | 1200 return; |
| 1290 } | 1201 } |
| 1291 | 1202 |
| 1292 // If setup has completed, start off in DOWNLOADING_NIGORI so that | 1203 // If setup has completed, start off in DOWNLOADING_NIGORI so that |
| 1293 // we start off by refreshing nigori. | 1204 // we start off by refreshing nigori. |
| 1294 CHECK(sync_prefs_.get()); | 1205 CHECK(sync_prefs_.get()); |
| 1295 if (sync_prefs_->HasSyncSetupCompleted() && | 1206 if (sync_prefs_->HasSyncSetupCompleted() && |
|
rlarocque
2012/06/09 01:44:35
Because you check the initial_sync_ended bit for N
Nicolas Zea
2012/06/11 23:05:20
Done.
| |
| 1296 initialization_state_ < DOWNLOADING_NIGORI) { | 1207 initialization_state_ < DOWNLOADING_NIGORI) { |
| 1297 initialization_state_ = DOWNLOADING_NIGORI; | 1208 initialization_state_ = DOWNLOADING_NIGORI; |
| 1298 } | 1209 } |
| 1299 | 1210 |
| 1300 // Run initialization state machine. | 1211 // Run initialization state machine. |
| 1301 switch (initialization_state_) { | 1212 switch (initialization_state_) { |
| 1302 case NOT_INITIALIZED: | 1213 case NOT_INITIALIZED: |
| 1303 initialization_state_ = DOWNLOADING_NIGORI; | 1214 initialization_state_ = DOWNLOADING_NIGORI; |
| 1304 ConfigureDataTypes( | 1215 ConfigureDataTypes( |
| 1305 sync_api::CONFIGURE_REASON_NEW_CLIENT, | 1216 sync_api::CONFIGURE_REASON_NEW_CLIENT, |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 1330 // experimental types to enable. This should be done before we inform | 1241 // experimental types to enable. This should be done before we inform |
| 1331 // the frontend to ensure they're visible in the customize screen. | 1242 // the frontend to ensure they're visible in the customize screen. |
| 1332 AddExperimentalTypes(); | 1243 AddExperimentalTypes(); |
| 1333 frontend_->OnBackendInitialized(js_backend, true); | 1244 frontend_->OnBackendInitialized(js_backend, true); |
| 1334 break; | 1245 break; |
| 1335 default: | 1246 default: |
| 1336 NOTREACHED(); | 1247 NOTREACHED(); |
| 1337 } | 1248 } |
| 1338 } | 1249 } |
| 1339 | 1250 |
| 1251 void SyncBackendHost::HandleSyncCycleCompletedOnFrontendLoop( | |
| 1252 const SyncSessionSnapshot& snapshot) { | |
| 1253 if (!frontend_) | |
| 1254 return; | |
| 1255 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | |
| 1256 | |
| 1257 last_snapshot_ = snapshot; | |
| 1258 | |
| 1259 SDVLOG(1) << "Got snapshot " << snapshot.ToString(); | |
| 1260 | |
| 1261 const syncable::ModelTypeSet to_migrate = | |
| 1262 snapshot.syncer_status().types_needing_local_migration; | |
| 1263 if (!to_migrate.Empty()) | |
| 1264 frontend_->OnMigrationNeededForTypes(to_migrate); | |
| 1265 | |
| 1266 // Process any changes to the datatypes we're syncing. | |
| 1267 // TODO(sync): add support for removing types. | |
| 1268 if (initialized()) | |
| 1269 AddExperimentalTypes(); | |
| 1270 | |
| 1271 if (initialized()) | |
| 1272 frontend_->OnSyncCycleCompleted(); | |
| 1273 } | |
| 1274 | |
| 1275 void SyncBackendHost::RetryConfigurationOnFrontendLoop( | |
| 1276 const base::Closure& retry_callback) { | |
| 1277 SDVLOG(1) << "Failed to complete configuration, informing of retry."; | |
| 1278 retry_callback.Run(); | |
| 1279 } | |
| 1280 | |
| 1340 void SyncBackendHost::PersistEncryptionBootstrapToken( | 1281 void SyncBackendHost::PersistEncryptionBootstrapToken( |
| 1341 const std::string& token) { | 1282 const std::string& token) { |
| 1342 CHECK(sync_prefs_.get()); | 1283 CHECK(sync_prefs_.get()); |
| 1343 sync_prefs_->SetEncryptionBootstrapToken(token); | 1284 sync_prefs_->SetEncryptionBootstrapToken(token); |
| 1344 } | 1285 } |
| 1345 | 1286 |
| 1346 void SyncBackendHost::HandleActionableErrorEventOnFrontendLoop( | 1287 void SyncBackendHost::HandleActionableErrorEventOnFrontendLoop( |
| 1347 const browser_sync::SyncProtocolError& sync_error) { | 1288 const browser_sync::SyncProtocolError& sync_error) { |
| 1348 if (!frontend_) | 1289 if (!frontend_) |
| 1349 return; | 1290 return; |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1470 FROM_HERE, | 1411 FROM_HERE, |
| 1471 base::Bind(&SyncBackendHost::Core::DoRefreshNigori, | 1412 base::Bind(&SyncBackendHost::Core::DoRefreshNigori, |
| 1472 core_.get(), sync_thread_done_callback)); | 1413 core_.get(), sync_thread_done_callback)); |
| 1473 } | 1414 } |
| 1474 | 1415 |
| 1475 #undef SDVLOG | 1416 #undef SDVLOG |
| 1476 | 1417 |
| 1477 #undef SLOG | 1418 #undef SLOG |
| 1478 | 1419 |
| 1479 } // namespace browser_sync | 1420 } // namespace browser_sync |
| OLD | NEW |