summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortim@chromium.org <tim@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-21 21:14:27 +0000
committertim@chromium.org <tim@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-21 21:14:27 +0000
commite5e6e25f97934963c9e86c1a60e61b45621e59a3 (patch)
tree65659f03cceb06f0563df75c1384fc18f517ee9d
parent1fac55264aba1be9a3495488454e059e0c826778 (diff)
downloadchromium_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.cc22
-rw-r--r--chrome/browser/sync/glue/data_type_manager_impl.h5
-rw-r--r--chrome/browser/sync/glue/data_type_manager_impl_unittest.cc16
-rw-r--r--chrome/browser/sync/glue/sync_backend_host.cc41
-rw-r--r--chrome/browser/sync/glue/sync_backend_host.h16
-rw-r--r--chrome/browser/sync/glue/sync_backend_host_mock.cc3
-rw-r--r--chrome/browser/sync/glue/sync_backend_host_mock.h4
-rw-r--r--chrome/browser/sync/glue/sync_backend_host_unittest.cc42
-rw-r--r--chrome/browser/sync/profile_sync_service.cc9
-rw-r--r--chrome/browser/sync/profile_sync_service.h2
-rw-r--r--chrome/browser/sync/profile_sync_service_mock.h2
-rw-r--r--chrome/browser/sync/profile_sync_service_startup_unittest.cc15
-rw-r--r--chrome/browser/sync/test_profile_sync_service.cc89
-rw-r--r--chrome/browser/sync/test_profile_sync_service.h12
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_;
};