diff options
author | tim@chromium.org <tim@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-21 21:14:27 +0000 |
---|---|---|
committer | tim@chromium.org <tim@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-21 21:14:27 +0000 |
commit | e5e6e25f97934963c9e86c1a60e61b45621e59a3 (patch) | |
tree | 65659f03cceb06f0563df75c1384fc18f517ee9d | |
parent | 1fac55264aba1be9a3495488454e059e0c826778 (diff) | |
download | chromium_src-e5e6e25f97934963c9e86c1a60e61b45621e59a3.zip chromium_src-e5e6e25f97934963c9e86c1a60e61b45621e59a3.tar.gz chromium_src-e5e6e25f97934963c9e86c1a60e61b45621e59a3.tar.bz2 |
sync: add a bool to ConfigureDataTypes' ready_task to handle failure cases.
Plumbs failure on initialization and reconfigurations back to caller.
Converts to use base::Callback instead of Task, too.
BUG=
TEST=
Review URL: http://codereview.chromium.org/7472022
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@93472 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/sync/glue/data_type_manager_impl.cc | 22 | ||||
-rw-r--r-- | chrome/browser/sync/glue/data_type_manager_impl.h | 5 | ||||
-rw-r--r-- | chrome/browser/sync/glue/data_type_manager_impl_unittest.cc | 16 | ||||
-rw-r--r-- | chrome/browser/sync/glue/sync_backend_host.cc | 41 | ||||
-rw-r--r-- | chrome/browser/sync/glue/sync_backend_host.h | 16 | ||||
-rw-r--r-- | chrome/browser/sync/glue/sync_backend_host_mock.cc | 3 | ||||
-rw-r--r-- | chrome/browser/sync/glue/sync_backend_host_mock.h | 4 | ||||
-rw-r--r-- | chrome/browser/sync/glue/sync_backend_host_unittest.cc | 42 | ||||
-rw-r--r-- | chrome/browser/sync/profile_sync_service.cc | 9 | ||||
-rw-r--r-- | chrome/browser/sync/profile_sync_service.h | 2 | ||||
-rw-r--r-- | chrome/browser/sync/profile_sync_service_mock.h | 2 | ||||
-rw-r--r-- | chrome/browser/sync/profile_sync_service_startup_unittest.cc | 15 | ||||
-rw-r--r-- | chrome/browser/sync/test_profile_sync_service.cc | 89 | ||||
-rw-r--r-- | chrome/browser/sync/test_profile_sync_service.h | 12 |
14 files changed, 168 insertions, 110 deletions
diff --git a/chrome/browser/sync/glue/data_type_manager_impl.cc b/chrome/browser/sync/glue/data_type_manager_impl.cc index 8118fd63..ebafd82 100644 --- a/chrome/browser/sync/glue/data_type_manager_impl.cc +++ b/chrome/browser/sync/glue/data_type_manager_impl.cc @@ -7,6 +7,8 @@ #include <algorithm> #include <functional> +#include "base/bind.h" +#include "base/callback.h" #include "base/compiler_specific.h" #include "base/logging.h" #include "base/message_loop.h" @@ -68,7 +70,7 @@ DataTypeManagerImpl::DataTypeManagerImpl(SyncBackendHost* backend, state_(DataTypeManager::STOPPED), needs_reconfigure_(false), last_configure_reason_(sync_api::CONFIGURE_REASON_UNKNOWN), - method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { + weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { DCHECK(backend_); // Ensure all data type controllers are stopped. for (DataTypeController::TypeMap::const_iterator it = controllers_.begin(); @@ -210,13 +212,19 @@ void DataTypeManagerImpl::Restart(sync_api::ConfigureReason reason, controllers_, last_requested_types_, reason, - method_factory_.NewRunnableMethod(&DataTypeManagerImpl::DownloadReady), + base::Bind(&DataTypeManagerImpl::DownloadReady, + weak_ptr_factory_.GetWeakPtr()), enable_nigori); } -void DataTypeManagerImpl::DownloadReady() { +void DataTypeManagerImpl::DownloadReady(bool success) { DCHECK(state_ == DOWNLOAD_PENDING); + if (!success) { + NotifyDone(UNRECOVERABLE_ERROR, FROM_HERE); + return; + } + state_ = CONFIGURING; StartNextType(); } @@ -247,8 +255,10 @@ void DataTypeManagerImpl::StartNextType() { // Unwind the stack before executing configure. The method configure and its // callees are not re-entrant. MessageLoop::current()->PostTask(FROM_HERE, - method_factory_.NewRunnableMethod(&DataTypeManagerImpl::Configure, - last_requested_types_, last_configure_reason_)); + base::Bind(&DataTypeManagerImpl::Configure, + weak_ptr_factory_.GetWeakPtr(), + last_requested_types_, + last_configure_reason_)); needs_reconfigure_ = false; last_configure_reason_ = sync_api::CONFIGURE_REASON_UNKNOWN; @@ -357,7 +367,7 @@ void DataTypeManagerImpl::Stop() { if (download_pending) { // If Stop() is called while waiting for download, cancel all // outstanding tasks. - method_factory_.RevokeAll(); + weak_ptr_factory_.InvalidateWeakPtrs(); FinishStopAndNotify(ABORTED, FROM_HERE); return; } diff --git a/chrome/browser/sync/glue/data_type_manager_impl.h b/chrome/browser/sync/glue/data_type_manager_impl.h index 902bcf8..8e8076f 100644 --- a/chrome/browser/sync/glue/data_type_manager_impl.h +++ b/chrome/browser/sync/glue/data_type_manager_impl.h @@ -12,6 +12,7 @@ #include <vector> #include "base/basictypes.h" +#include "base/memory/weak_ptr.h" #include "base/task.h" #include "base/time.h" @@ -58,7 +59,7 @@ class DataTypeManagerImpl : public DataTypeManager { std::vector<DataTypeController*>* needs_start); void Restart(sync_api::ConfigureReason reason, bool enable_nigori); - void DownloadReady(); + void DownloadReady(bool success); void NotifyStart(); void NotifyDone(ConfigureResult result, const tracked_objects::Location& location); @@ -90,7 +91,7 @@ class DataTypeManagerImpl : public DataTypeManager { // valid value only if needs_reconfigure_ is set. sync_api::ConfigureReason last_configure_reason_; - ScopedRunnableMethodFactory<DataTypeManagerImpl> method_factory_; + base::WeakPtrFactory<DataTypeManagerImpl> weak_ptr_factory_; // The last time Restart() was called. base::Time last_restart_time_; diff --git a/chrome/browser/sync/glue/data_type_manager_impl_unittest.cc b/chrome/browser/sync/glue/data_type_manager_impl_unittest.cc index 32e6ce7..24dbe9c 100644 --- a/chrome/browser/sync/glue/data_type_manager_impl_unittest.cc +++ b/chrome/browser/sync/glue/data_type_manager_impl_unittest.cc @@ -9,7 +9,6 @@ #include "base/memory/scoped_ptr.h" #include "base/message_loop.h" #include "base/stl_util.h" -#include "base/task.h" #include "chrome/browser/sync/engine/configure_reason.h" #include "chrome/browser/sync/glue/data_type_controller.h" #include "chrome/browser/sync/glue/data_type_controller_mock.h" @@ -318,10 +317,9 @@ void DoConfigureDataTypes( const DataTypeController::TypeMap& data_type_controllers, const syncable::ModelTypeSet& types, sync_api::ConfigureReason reason, - CancelableTask* ready_task, + base::Callback<void(bool)> ready_task, bool enable_nigori) { - ready_task->Run(); - delete ready_task; + ready_task.Run(true); } void QuitMessageLoop() { @@ -465,7 +463,7 @@ TEST_F(DataTypeManagerImplTest, ConfigureWhileDownloadPending) { DataTypeManagerImpl dtm(&backend_, controllers_); SetConfigureStartExpectation(); SetConfigureDoneExpectation(DataTypeManager::OK); - CancelableTask* task; + base::Callback<void(bool)> task; // Grab the task the first time this is called so we can configure // before it is finished. EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _, _, _)). @@ -483,8 +481,7 @@ TEST_F(DataTypeManagerImplTest, ConfigureWhileDownloadPending) { // Running the task will queue a restart task to the message loop, and // eventually get us configured. - task->Run(); - delete task; + task.Run(true); MessageLoop::current()->RunAllPending(); EXPECT_EQ(DataTypeManager::CONFIGURED, dtm.state()); @@ -500,7 +497,7 @@ TEST_F(DataTypeManagerImplTest, StopWhileDownloadPending) { DataTypeManagerImpl dtm(&backend_, controllers_); SetConfigureStartExpectation(); SetConfigureDoneExpectation(DataTypeManager::ABORTED); - CancelableTask* task; + base::Callback<void(bool)> task; // Grab the task the first time this is called so we can stop // before it is finished. EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _, _, _)). @@ -517,6 +514,5 @@ TEST_F(DataTypeManagerImplTest, StopWhileDownloadPending) { // It should be perfectly safe to run this task even though the DTM // has been stopped. - task->Run(); - delete task; + task.Run(true); } diff --git a/chrome/browser/sync/glue/sync_backend_host.cc b/chrome/browser/sync/glue/sync_backend_host.cc index 1074328..9dc44f5 100644 --- a/chrome/browser/sync/glue/sync_backend_host.cc +++ b/chrome/browser/sync/glue/sync_backend_host.cc @@ -6,6 +6,7 @@ #include <algorithm> +#include "base/bind.h" #include "base/command_line.h" #include "base/compiler_specific.h" #include "base/file_util.h" @@ -289,7 +290,7 @@ SyncBackendHost::PendingConfigureDataTypesState* SyncBackendHost::MakePendingConfigModeState( const DataTypeController::TypeMap& data_type_controllers, const syncable::ModelTypeSet& types, - CancelableTask* ready_task, + base::Callback<void(bool)> ready_task, ModelSafeRoutingInfo* routing_info, sync_api::ConfigureReason reason, bool nigori_enabled) { @@ -327,7 +328,7 @@ SyncBackendHost::PendingConfigureDataTypesState* } } - state->ready_task.reset(ready_task); + state->ready_task = ready_task; state->initial_types = types; state->reason = reason; return state; @@ -337,7 +338,7 @@ void SyncBackendHost::ConfigureDataTypes( const DataTypeController::TypeMap& data_type_controllers, const syncable::ModelTypeSet& types, sync_api::ConfigureReason reason, - CancelableTask* ready_task, + base::Callback<void(bool)> ready_task, bool enable_nigori) { // Only one configure is allowed at a time. DCHECK(!pending_config_mode_state_.get()); @@ -409,7 +410,7 @@ void SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop() { VLOG(1) << "SyncBackendHost(" << this << "): No new types added. " << "Calling ready_task directly"; // No new types - just notify the caller that the types are available. - pending_config_mode_state_->ready_task->Run(); + pending_config_mode_state_->ready_task.Run(true); } else { pending_download_state_.reset(pending_config_mode_state_.release()); @@ -843,7 +844,6 @@ void SyncBackendHost::Core::OnChangesComplete( processor->CommitChangesFromSyncModel(); } - void SyncBackendHost::Core::OnSyncCycleCompleted( const SyncSessionSnapshot* snapshot) { host_->frontend_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, @@ -877,12 +877,9 @@ void SyncBackendHost::Core::HandleSyncCycleCompletedOnFrontendLoop( if (state->added_types.test(*it)) found_all_added &= snapshot->initial_sync_ended.test(*it); } - if (!found_all_added) { - DLOG(WARNING) << "Update didn't return updates for all types requested." - << "Possible connection failure?"; - } else { - state->ready_task->Run(); - } + state->ready_task.Run(found_all_added); + if (!found_all_added) + return; } if (host_->initialized()) @@ -898,22 +895,29 @@ void SyncBackendHost::Core::OnInitializationComplete() { // can definitely be null in here. host_->frontend_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, - &Core::HandleInitializationCompletedOnFrontendLoop)); + &Core::HandleInitializationCompletedOnFrontendLoop, + true)); // Initialization is complete, so we can schedule recurring SaveChanges. host_->sync_thread_.message_loop()->PostTask(FROM_HERE, NewRunnableMethod(this, &Core::StartSavingChanges)); } -void SyncBackendHost::Core::HandleInitializationCompletedOnFrontendLoop() { +void SyncBackendHost::Core::HandleInitializationCompletedOnFrontendLoop( + bool success) { if (!host_) return; - host_->HandleInitializationCompletedOnFrontendLoop(); + host_->HandleInitializationCompletedOnFrontendLoop(success); } -void SyncBackendHost::HandleInitializationCompletedOnFrontendLoop() { +void SyncBackendHost::HandleInitializationCompletedOnFrontendLoop( + bool success) { if (!frontend_) return; + if (!success) { + frontend_->OnBackendInitialized(false); + return; + } bool setup_completed = profile_->GetPrefs()->GetBoolean(prefs::kSyncHasSetupCompleted); @@ -925,7 +929,7 @@ void SyncBackendHost::HandleInitializationCompletedOnFrontendLoop() { if (setup_completed) core_->sync_manager()->RefreshEncryption(); initialization_state_ = INITIALIZED; - frontend_->OnBackendInitialized(); + frontend_->OnBackendInitialized(true); return; } @@ -934,8 +938,9 @@ void SyncBackendHost::HandleInitializationCompletedOnFrontendLoop() { DataTypeController::TypeMap(), syncable::ModelTypeSet(), sync_api::CONFIGURE_REASON_NEW_CLIENT, - NewRunnableMethod(core_.get(), - &SyncBackendHost::Core::HandleInitializationCompletedOnFrontendLoop), + base::Bind( + &SyncBackendHost::Core::HandleInitializationCompletedOnFrontendLoop, + core_.get()), true); } diff --git a/chrome/browser/sync/glue/sync_backend_host.h b/chrome/browser/sync/glue/sync_backend_host.h index c958890..ee3fd68 100644 --- a/chrome/browser/sync/glue/sync_backend_host.h +++ b/chrome/browser/sync/glue/sync_backend_host.h @@ -10,6 +10,7 @@ #include <string> #include <vector> +#include "base/callback.h" #include "base/compiler_specific.h" #include "base/file_path.h" #include "base/gtest_prod_util.h" @@ -60,8 +61,9 @@ class SyncFrontend { SyncFrontend() {} // The backend has completed initialization and it is now ready to accept and - // process changes. - virtual void OnBackendInitialized() = 0; + // process changes. If success is false, initialization wasn't able to be + // completed and should be retried. + virtual void OnBackendInitialized(bool success) = 0; // The backend queried the server recently and received some updates. virtual void OnSyncCycleCompleted() = 0; @@ -164,7 +166,7 @@ class SyncBackendHost : public browser_sync::ModelSafeWorkerRegistrar { const DataTypeController::TypeMap& data_type_controllers, const syncable::ModelTypeSet& types, sync_api::ConfigureReason reason, - CancelableTask* ready_task, + base::Callback<void(bool)> ready_task, bool enable_nigori); // Makes an asynchronous call to syncer to switch to config mode. When done @@ -407,7 +409,7 @@ class SyncBackendHost : public browser_sync::ModelSafeWorkerRegistrar { // Called to handle updating frontend thread components whenever we may // need to alert the frontend that the backend is intialized. - void HandleInitializationCompletedOnFrontendLoop(); + void HandleInitializationCompletedOnFrontendLoop(bool success); #if defined(UNIT_TEST) // Special form of initialization that does not try and authenticate the @@ -525,7 +527,7 @@ class SyncBackendHost : public browser_sync::ModelSafeWorkerRegistrar { // InitializationComplete passes through the SyncBackendHost to forward // on to |frontend_|, and so that tests can intercept here if they need to // set up initial conditions. - virtual void HandleInitializationCompletedOnFrontendLoop(); + virtual void HandleInitializationCompletedOnFrontendLoop(bool success); // Posts a nudge request on the sync thread. virtual void RequestNudge(const tracked_objects::Location& location); @@ -566,7 +568,7 @@ class SyncBackendHost : public browser_sync::ModelSafeWorkerRegistrar { // A task that should be called once data type configuration is // complete. - scoped_ptr<CancelableTask> ready_task; + base::Callback<void(bool)> ready_task; // The set of types that we are waiting to be initially synced in a // configuration cycle. @@ -585,7 +587,7 @@ class SyncBackendHost : public browser_sync::ModelSafeWorkerRegistrar { static PendingConfigureDataTypesState* MakePendingConfigModeState( const DataTypeController::TypeMap& data_type_controllers, const syncable::ModelTypeSet& types, - CancelableTask* ready_task, + base::Callback<void(bool)> ready_task, ModelSafeRoutingInfo* routing_info, sync_api::ConfigureReason reason, bool nigori_enabled); diff --git a/chrome/browser/sync/glue/sync_backend_host_mock.cc b/chrome/browser/sync/glue/sync_backend_host_mock.cc index fe7d9b3..ff661b7 100644 --- a/chrome/browser/sync/glue/sync_backend_host_mock.cc +++ b/chrome/browser/sync/glue/sync_backend_host_mock.cc @@ -7,8 +7,7 @@ namespace browser_sync { ACTION(InvokeTask) { - arg3->Run(); - delete arg3; + arg3.Run(true); } SyncBackendHostMock::SyncBackendHostMock() { diff --git a/chrome/browser/sync/glue/sync_backend_host_mock.h b/chrome/browser/sync/glue/sync_backend_host_mock.h index ad063e0..e63d778 100644 --- a/chrome/browser/sync/glue/sync_backend_host_mock.h +++ b/chrome/browser/sync/glue/sync_backend_host_mock.h @@ -8,7 +8,7 @@ #include <set> -#include "base/task.h" +#include "base/callback.h" #include "chrome/browser/sync/glue/sync_backend_host.h" #include "chrome/browser/sync/profile_sync_test_util.h" #include "content/common/content_notification_types.h" @@ -25,7 +25,7 @@ class SyncBackendHostMock : public SyncBackendHost { void(const DataTypeController::TypeMap&, const std::set<syncable::ModelType>&, sync_api::ConfigureReason, - CancelableTask*, + base::Callback<void(bool)>, bool)); MOCK_METHOD0(StartSyncingWithServer, void()); }; diff --git a/chrome/browser/sync/glue/sync_backend_host_unittest.cc b/chrome/browser/sync/glue/sync_backend_host_unittest.cc index ec6ca67..bee87a6 100644 --- a/chrome/browser/sync/glue/sync_backend_host_unittest.cc +++ b/chrome/browser/sync/glue/sync_backend_host_unittest.cc @@ -33,7 +33,7 @@ class MockSyncFrontend : public SyncFrontend { public: virtual ~MockSyncFrontend() {} - MOCK_METHOD0(OnBackendInitialized, void()); + MOCK_METHOD1(OnBackendInitialized, void(bool)); MOCK_METHOD0(OnSyncCycleCompleted, void()); MOCK_METHOD0(OnAuthError, void()); MOCK_METHOD0(OnStopSyncingPermanently, void()); @@ -119,10 +119,11 @@ TEST_F(SyncBackendHostTest, MakePendingConfigModeState) { scoped_ptr<SyncBackendHost::PendingConfigureDataTypesState> state(SyncBackendHost::MakePendingConfigModeState( - data_type_controllers, types, NULL, &routing_info, - sync_api::CONFIGURE_REASON_RECONFIGURATION, false)); + data_type_controllers, types, base::Callback<void(bool)>(), + &routing_info, sync_api::CONFIGURE_REASON_RECONFIGURATION, + false)); EXPECT_TRUE(routing_info.empty()); - EXPECT_FALSE(state->ready_task.get()); + EXPECT_TRUE(state->ready_task.is_null()); EXPECT_EQ(types, state->initial_types); EXPECT_FALSE(state->deleted_type); EXPECT_TRUE(state->added_types.none()); @@ -138,10 +139,10 @@ TEST_F(SyncBackendHostTest, MakePendingConfigModeState) { types.insert(syncable::NIGORI); scoped_ptr<SyncBackendHost::PendingConfigureDataTypesState> state(SyncBackendHost::MakePendingConfigModeState( - data_type_controllers, types, NULL, + data_type_controllers, types, base::Callback<void(bool)>(), &routing_info, sync_api::CONFIGURE_REASON_RECONFIGURATION, true)); EXPECT_TRUE(routing_info.empty()); - EXPECT_FALSE(state->ready_task.get()); + EXPECT_TRUE(state->ready_task.is_null()); EXPECT_EQ(types, state->initial_types); EXPECT_TRUE(state->deleted_type); EXPECT_TRUE(state->added_types.none()); @@ -158,13 +159,14 @@ TEST_F(SyncBackendHostTest, MakePendingConfigModeState) { scoped_ptr<SyncBackendHost::PendingConfigureDataTypesState> state(SyncBackendHost::MakePendingConfigModeState( - data_type_controllers, types, NULL, &routing_info, + data_type_controllers, types, base::Callback<void(bool)>(), + &routing_info, sync_api::CONFIGURE_REASON_RECONFIGURATION, true)); ModelSafeRoutingInfo expected_routing_info; expected_routing_info[syncable::BOOKMARKS] = GROUP_PASSIVE; EXPECT_EQ(expected_routing_info, routing_info); - EXPECT_FALSE(state->ready_task.get()); + EXPECT_TRUE(state->ready_task.is_null()); EXPECT_EQ(types, state->initial_types); EXPECT_FALSE(state->deleted_type); @@ -186,11 +188,11 @@ TEST_F(SyncBackendHostTest, MakePendingConfigModeState) { scoped_ptr<SyncBackendHost::PendingConfigureDataTypesState> state(SyncBackendHost::MakePendingConfigModeState( - data_type_controllers, types, NULL, &routing_info, - sync_api::CONFIGURE_REASON_RECONFIGURATION, true)); + data_type_controllers, types, base::Callback<void(bool)>(), + &routing_info, sync_api::CONFIGURE_REASON_RECONFIGURATION, true)); EXPECT_EQ(expected_routing_info, routing_info); - EXPECT_FALSE(state->ready_task.get()); + EXPECT_TRUE(state->ready_task.is_null()); EXPECT_EQ(types, state->initial_types); EXPECT_FALSE(state->deleted_type); EXPECT_TRUE(state->added_types.none()); @@ -207,12 +209,12 @@ TEST_F(SyncBackendHostTest, MakePendingConfigModeState) { scoped_ptr<SyncBackendHost::PendingConfigureDataTypesState> state(SyncBackendHost::MakePendingConfigModeState( - data_type_controllers, types, NULL, &routing_info, - sync_api::CONFIGURE_REASON_RECONFIGURATION, true)); + data_type_controllers, types, base::Callback<void(bool)>(), + &routing_info, sync_api::CONFIGURE_REASON_RECONFIGURATION, true)); ModelSafeRoutingInfo expected_routing_info; EXPECT_EQ(expected_routing_info, routing_info); - EXPECT_FALSE(state->ready_task.get()); + EXPECT_TRUE(state->ready_task.is_null()); EXPECT_EQ(types, state->initial_types); EXPECT_TRUE(state->deleted_type); EXPECT_TRUE(state->added_types.none()); @@ -227,13 +229,13 @@ TEST_F(SyncBackendHostTest, MakePendingConfigModeState) { scoped_ptr<SyncBackendHost::PendingConfigureDataTypesState> state(SyncBackendHost::MakePendingConfigModeState( - data_type_controllers, types, NULL, &routing_info, - sync_api::CONFIGURE_REASON_RECONFIGURATION, false)); + data_type_controllers, types, base::Callback<void(bool)>(), + &routing_info, sync_api::CONFIGURE_REASON_RECONFIGURATION, false)); ModelSafeRoutingInfo expected_routing_info; expected_routing_info[syncable::NIGORI] = GROUP_PASSIVE; EXPECT_EQ(expected_routing_info, routing_info); - EXPECT_FALSE(state->ready_task.get()); + EXPECT_TRUE(state->ready_task.is_null()); EXPECT_EQ(types, state->initial_types); EXPECT_FALSE(state->deleted_type); @@ -251,12 +253,12 @@ TEST_F(SyncBackendHostTest, MakePendingConfigModeState) { scoped_ptr<SyncBackendHost::PendingConfigureDataTypesState> state(SyncBackendHost::MakePendingConfigModeState( - data_type_controllers, types, NULL, &routing_info, - sync_api::CONFIGURE_REASON_RECONFIGURATION, true)); + data_type_controllers, types, base::Callback<void(bool)>(), + &routing_info, sync_api::CONFIGURE_REASON_RECONFIGURATION, true)); ModelSafeRoutingInfo expected_routing_info; EXPECT_EQ(expected_routing_info, routing_info); - EXPECT_FALSE(state->ready_task.get()); + EXPECT_TRUE(state->ready_task.is_null()); EXPECT_EQ(types, state->initial_types); EXPECT_TRUE(state->deleted_type); diff --git a/chrome/browser/sync/profile_sync_service.cc b/chrome/browser/sync/profile_sync_service.cc index 0cd4727..6aea12a 100644 --- a/chrome/browser/sync/profile_sync_service.cc +++ b/chrome/browser/sync/profile_sync_service.cc @@ -553,7 +553,14 @@ void ProfileSyncService::OnUnrecoverableError( &ProfileSyncService::Shutdown, true)); } -void ProfileSyncService::OnBackendInitialized() { +void ProfileSyncService::OnBackendInitialized(bool success) { + if (!success) { + // If backend initialization failed, abort. We only want to blow away + // state (DBs, etc) if this was a first-time scenario that failed. + Shutdown(!HasSyncSetupCompleted()); + return; + } + backend_initialized_ = true; js_event_handlers_.SetBackend(backend_->GetJsBackend()); diff --git a/chrome/browser/sync/profile_sync_service.h b/chrome/browser/sync/profile_sync_service.h index 51c12fe..cbee0a23 100644 --- a/chrome/browser/sync/profile_sync_service.h +++ b/chrome/browser/sync/profile_sync_service.h @@ -188,7 +188,7 @@ class ProfileSyncService : public browser_sync::SyncFrontend, virtual void SetSyncSetupCompleted(); // SyncFrontend implementation. - virtual void OnBackendInitialized(); + virtual void OnBackendInitialized(bool success); virtual void OnSyncCycleCompleted(); virtual void OnAuthError(); virtual void OnStopSyncingPermanently(); diff --git a/chrome/browser/sync/profile_sync_service_mock.h b/chrome/browser/sync/profile_sync_service_mock.h index 5237897..4464c3f 100644 --- a/chrome/browser/sync/profile_sync_service_mock.h +++ b/chrome/browser/sync/profile_sync_service_mock.h @@ -21,7 +21,7 @@ class ProfileSyncServiceMock : public ProfileSyncService { virtual ~ProfileSyncServiceMock(); MOCK_METHOD0(DisableForUser, void()); - MOCK_METHOD0(OnBackendInitialized, void()); + MOCK_METHOD1(OnBackendInitialized, void(bool)); MOCK_METHOD0(OnSyncCycleCompleted, void()); MOCK_METHOD0(OnAuthError, void()); MOCK_METHOD4(OnUserSubmittedAuth, diff --git a/chrome/browser/sync/profile_sync_service_startup_unittest.cc b/chrome/browser/sync/profile_sync_service_startup_unittest.cc index ce5feec..16bf87d 100644 --- a/chrome/browser/sync/profile_sync_service_startup_unittest.cc +++ b/chrome/browser/sync/profile_sync_service_startup_unittest.cc @@ -267,3 +267,18 @@ TEST_F(ProfileSyncServiceStartupTest, SKIP_MACOSX(StartFailure)) { service_->Initialize(); EXPECT_TRUE(service_->unrecoverable_error_detected()); } + +TEST_F(ProfileSyncServiceStartupTest, StartDownloadFailed) { + profile_.GetPrefs()->ClearPref(prefs::kSyncHasSetupCompleted); + + EXPECT_CALL(observer_, OnStateChanged()).Times(AnyNumber()); + + // Preload the tokens. + profile_.GetTokenService()->IssueAuthTokenForTest( + GaiaConstants::kSyncService, "sync_token"); + service_->fail_initial_download(); + + service_->Initialize(); + EXPECT_FALSE(service_->sync_initialized()); + EXPECT_FALSE(service_->GetBackendForTest()); +} diff --git a/chrome/browser/sync/test_profile_sync_service.cc b/chrome/browser/sync/test_profile_sync_service.cc index 1436a21..f12291c 100644 --- a/chrome/browser/sync/test_profile_sync_service.cc +++ b/chrome/browser/sync/test_profile_sync_service.cc @@ -31,9 +31,11 @@ using ::testing::_; SyncBackendHostForProfileSyncTest::SyncBackendHostForProfileSyncTest( Profile* profile, bool set_initial_sync_ended_on_init, - bool synchronous_init) + bool synchronous_init, + bool fail_initial_download) : browser_sync::SyncBackendHost(profile), - synchronous_init_(synchronous_init) { + synchronous_init_(synchronous_init), + fail_initial_download_(fail_initial_download) { ON_CALL(*this, RequestNudge(_)).WillByDefault( testing::Invoke(this, &SyncBackendHostForProfileSyncTest:: @@ -47,7 +49,7 @@ void SyncBackendHostForProfileSyncTest::ConfigureDataTypes( const DataTypeController::TypeMap& data_type_controllers, const syncable::ModelTypeSet& types, sync_api::ConfigureReason reason, - CancelableTask* ready_task, + base::Callback<void(bool)> ready_task, bool nigori_enabled) { SyncBackendHost::ConfigureDataTypes(data_type_controllers, types, reason, ready_task, nigori_enabled); @@ -64,6 +66,10 @@ void SyncBackendHostForProfileSyncTest:: i != enabled_types.end(); ++i) { sync_ended.set(i->first); } + + if (fail_initial_download_) + sync_ended.reset(); + core_->HandleSyncCycleCompletedOnFrontendLoop(new SyncSessionSnapshot( SyncerStatus(), ErrorCounters(), 0, false, sync_ended, download_progress_markers, false, false, 0, 0, 0, false, @@ -135,7 +141,9 @@ void SyncBackendHostForProfileSyncTest::StartConfiguration( SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop(); if (initialization_state_ == DOWNLOADING_NIGORI) { syncable::ModelTypeBitSet sync_ended; - sync_ended.set(syncable::NIGORI); + + if (!fail_initial_download_) + sync_ended.set(syncable::NIGORI); std::string download_progress_markers[syncable::MODEL_TYPE_COUNT]; core_->HandleSyncCycleCompletedOnFrontendLoop(new SyncSessionSnapshot( SyncerStatus(), ErrorCounters(), 0, false, @@ -179,7 +187,8 @@ TestProfileSyncService::TestProfileSyncService( synchronous_backend_initialization), synchronous_sync_configuration_(false), initial_condition_setup_task_(initial_condition_setup_task), - set_initial_sync_ended_on_init_(true) { + set_initial_sync_ended_on_init_(true), + fail_initial_download_(false) { RegisterPreferences(); SetSyncSetupCompleted(); } @@ -202,42 +211,44 @@ void TestProfileSyncService::SetInitialSyncEndedForEnabledTypes() { } } -void TestProfileSyncService::OnBackendInitialized() { - // Set this so below code can access GetUserShare(). - backend_initialized_ = true; - - // Set up any nodes the test wants around before model association. - if (initial_condition_setup_task_) { - initial_condition_setup_task_->Run(); - initial_condition_setup_task_ = NULL; - } - - // Pretend we downloaded initial updates and set initial sync ended bits - // if we were asked to. +void TestProfileSyncService::OnBackendInitialized(bool success) { bool send_passphrase_required = false; - if (set_initial_sync_ended_on_init_) { - UserShare* user_share = GetUserShare(); - DirectoryManager* dir_manager = user_share->dir_manager.get(); - - ScopedDirLookup dir(dir_manager, user_share->name); - if (!dir.good()) - FAIL(); - - if (!dir->initial_sync_ended_for_type(syncable::NIGORI)) { - ProfileSyncServiceTestHelper::CreateRoot( - syncable::NIGORI, GetUserShare(), - id_factory()); - - // A side effect of adding the NIGORI mode (normally done by the syncer) - // is a decryption attempt, which will fail the first time. - send_passphrase_required = true; + if (success) { + // Set this so below code can access GetUserShare(). + backend_initialized_ = true; + + // Set up any nodes the test wants around before model association. + if (initial_condition_setup_task_) { + initial_condition_setup_task_->Run(); + initial_condition_setup_task_ = NULL; } - SetInitialSyncEndedForEnabledTypes(); + // Pretend we downloaded initial updates and set initial sync ended bits + // if we were asked to. + if (set_initial_sync_ended_on_init_) { + UserShare* user_share = GetUserShare(); + DirectoryManager* dir_manager = user_share->dir_manager.get(); + + ScopedDirLookup dir(dir_manager, user_share->name); + if (!dir.good()) + FAIL(); + + if (!dir->initial_sync_ended_for_type(syncable::NIGORI)) { + ProfileSyncServiceTestHelper::CreateRoot( + syncable::NIGORI, GetUserShare(), + id_factory()); + + // A side effect of adding the NIGORI mode (normally done by the + // syncer) is a decryption attempt, which will fail the first time. + send_passphrase_required = true; + } + + SetInitialSyncEndedForEnabledTypes(); + } } - ProfileSyncService::OnBackendInitialized(); - if (send_passphrase_required) + ProfileSyncService::OnBackendInitialized(success); + if (success && send_passphrase_required) OnPassphraseRequired(sync_api::REASON_DECRYPTION); // TODO(akalin): Figure out a better way to do this. @@ -262,12 +273,16 @@ void TestProfileSyncService::dont_set_initial_sync_ended_on_init() { void TestProfileSyncService::set_synchronous_sync_configuration() { synchronous_sync_configuration_ = true; } +void TestProfileSyncService::fail_initial_download() { + fail_initial_download_ = true; +} void TestProfileSyncService::CreateBackend() { backend_.reset(new browser_sync::SyncBackendHostForProfileSyncTest( profile(), set_initial_sync_ended_on_init_, - synchronous_backend_initialization_)); + synchronous_backend_initialization_, + fail_initial_download_)); } std::string TestProfileSyncService::GetLsidForAuthBootstraping() { diff --git a/chrome/browser/sync/test_profile_sync_service.h b/chrome/browser/sync/test_profile_sync_service.h index 86ca121..a243e7a 100644 --- a/chrome/browser/sync/test_profile_sync_service.h +++ b/chrome/browser/sync/test_profile_sync_service.h @@ -38,7 +38,8 @@ class SyncBackendHostForProfileSyncTest SyncBackendHostForProfileSyncTest( Profile* profile, bool set_initial_sync_ended_on_init, - bool synchronous_init); + bool synchronous_init, + bool fail_initial_download); virtual ~SyncBackendHostForProfileSyncTest(); MOCK_METHOD1(RequestNudge, void(const tracked_objects::Location&)); @@ -47,7 +48,7 @@ class SyncBackendHostForProfileSyncTest const DataTypeController::TypeMap& data_type_controllers, const syncable::ModelTypeSet& types, sync_api::ConfigureReason reason, - CancelableTask* ready_task, + base::Callback<void(bool)> ready_task, bool nigori_enabled); // Called when a nudge comes in. @@ -79,6 +80,7 @@ class SyncBackendHostForProfileSyncTest private: bool synchronous_init_; + bool fail_initial_download_; }; } // namespace browser_sync @@ -97,7 +99,7 @@ class TestProfileSyncService : public ProfileSyncService { void SetInitialSyncEndedForEnabledTypes(); - virtual void OnBackendInitialized(); + virtual void OnBackendInitialized(bool success); virtual void Observe(int type, const NotificationSource& source, @@ -108,6 +110,8 @@ class TestProfileSyncService : public ProfileSyncService { void dont_set_initial_sync_ended_on_init(); void set_synchronous_sync_configuration(); + void fail_initial_download(); + browser_sync::TestIdFactory* id_factory(); // Override of ProfileSyncService::GetBackendForTest() with a more @@ -135,6 +139,8 @@ class TestProfileSyncService : public ProfileSyncService { Task* initial_condition_setup_task_; bool set_initial_sync_ended_on_init_; + + bool fail_initial_download_; }; |