summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoroshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-08-12 23:29:10 +0000
committeroshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-08-12 23:31:52 +0000
commitf5de7a00d48ef86eeb126652d9f68ac00ac6db23 (patch)
treee46b13ae2e4c8ea820091cef6e3b5523f21047a8
parent209d521c49a8cae194ea5f1458a2ecbbba2bcc78 (diff)
downloadchromium_src-f5de7a00d48ef86eeb126652d9f68ac00ac6db23.zip
chromium_src-f5de7a00d48ef86eeb126652d9f68ac00ac6db23.tar.gz
chromium_src-f5de7a00d48ef86eeb126652d9f68ac00ac6db23.tar.bz2
Revert 288557 "[Sync] Use OnSingleDataTypeUnrecoverableError for..."
Reason for revert: see crbug.com/403098 > [Sync] Use OnSingleDataTypeUnrecoverableError for all errors > > This removes the disable callback from all datatype controllers as well > as the DisableDataType method from the PSS, in favor of > OnSingleDataTypeUnrecoverable error (which now accepts a SyncError). > > BUG=368834,403098 > TBR=bauerb@chromium.org > > Review URL: https://codereview.chromium.org/436733002 TBR=zea@chromium.org Review URL: https://codereview.chromium.org/465113002 Cr-Commit-Position: refs/heads/master@{#289113} git-svn-id: svn://svn.chromium.org/chrome/trunk/src@289113 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/supervised_user/supervised_user_sync_data_type_controller.cc2
-rw-r--r--chrome/browser/supervised_user/supervised_user_sync_data_type_controller.h1
-rw-r--r--chrome/browser/sync/glue/autofill_data_type_controller.cc4
-rw-r--r--chrome/browser/sync/glue/autofill_data_type_controller.h3
-rw-r--r--chrome/browser/sync/glue/autofill_data_type_controller_unittest.cc3
-rw-r--r--chrome/browser/sync/glue/autofill_profile_data_type_controller.cc4
-rw-r--r--chrome/browser/sync/glue/autofill_profile_data_type_controller.h3
-rw-r--r--chrome/browser/sync/glue/bookmark_change_processor.cc70
-rw-r--r--chrome/browser/sync/glue/bookmark_data_type_controller_unittest.cc18
-rw-r--r--chrome/browser/sync/glue/bookmark_model_associator.cc7
-rw-r--r--chrome/browser/sync/glue/device_info_data_type_controller.cc4
-rw-r--r--chrome/browser/sync/glue/device_info_data_type_controller.h3
-rw-r--r--chrome/browser/sync/glue/device_info_data_type_controller_unittest.cc3
-rw-r--r--chrome/browser/sync/glue/extension_backed_data_type_controller.cc16
-rw-r--r--chrome/browser/sync/glue/extension_backed_data_type_controller.h1
-rw-r--r--chrome/browser/sync/glue/extension_data_type_controller.cc4
-rw-r--r--chrome/browser/sync/glue/extension_data_type_controller.h3
-rw-r--r--chrome/browser/sync/glue/extension_setting_data_type_controller.cc4
-rw-r--r--chrome/browser/sync/glue/extension_setting_data_type_controller.h3
-rw-r--r--chrome/browser/sync/glue/frontend_data_type_controller.cc34
-rw-r--r--chrome/browser/sync/glue/frontend_data_type_controller.h5
-rw-r--r--chrome/browser/sync/glue/frontend_data_type_controller_unittest.cc18
-rw-r--r--chrome/browser/sync/glue/non_frontend_data_type_controller.cc48
-rw-r--r--chrome/browser/sync/glue/non_frontend_data_type_controller.h8
-rw-r--r--chrome/browser/sync/glue/non_frontend_data_type_controller_unittest.cc11
-rw-r--r--chrome/browser/sync/glue/password_data_type_controller.cc4
-rw-r--r--chrome/browser/sync/glue/password_data_type_controller.h3
-rw-r--r--chrome/browser/sync/glue/search_engine_data_type_controller.cc4
-rw-r--r--chrome/browser/sync/glue/search_engine_data_type_controller.h3
-rw-r--r--chrome/browser/sync/glue/search_engine_data_type_controller_unittest.cc3
-rw-r--r--chrome/browser/sync/glue/theme_data_type_controller.cc4
-rw-r--r--chrome/browser/sync/glue/theme_data_type_controller.h3
-rw-r--r--chrome/browser/sync/glue/typed_url_change_processor.cc76
-rw-r--r--chrome/browser/sync/glue/typed_url_data_type_controller.cc2
-rw-r--r--chrome/browser/sync/profile_sync_components_factory_impl.cc81
-rw-r--r--chrome/browser/sync/profile_sync_service.cc27
-rw-r--r--chrome/browser/sync/profile_sync_service.h5
-rw-r--r--chrome/browser/sync/profile_sync_service_autofill_unittest.cc10
-rw-r--r--chrome/browser/sync/profile_sync_service_bookmark_unittest.cc2
-rw-r--r--chrome/browser/sync/sessions/session_data_type_controller.cc4
-rw-r--r--chrome/browser/sync/sessions/session_data_type_controller.h3
-rw-r--r--chrome/browser/sync/sessions/session_data_type_controller_unittest.cc3
-rw-r--r--components/sync_driver/change_processor_mock.h5
-rw-r--r--components/sync_driver/data_type_controller.cc9
-rw-r--r--components/sync_driver/data_type_controller.h7
-rw-r--r--components/sync_driver/data_type_error_handler.h5
-rw-r--r--components/sync_driver/data_type_error_handler_mock.h4
-rw-r--r--components/sync_driver/fake_data_type_controller.cc10
-rw-r--r--components/sync_driver/fake_data_type_controller.h5
-rw-r--r--components/sync_driver/generic_change_processor.cc83
-rw-r--r--components/sync_driver/model_association_manager_unittest.cc6
-rw-r--r--components/sync_driver/non_ui_data_type_controller.cc21
-rw-r--r--components/sync_driver/non_ui_data_type_controller.h9
-rw-r--r--components/sync_driver/non_ui_data_type_controller_mock.h5
-rw-r--r--components/sync_driver/non_ui_data_type_controller_unittest.cc28
-rw-r--r--components/sync_driver/proxy_data_type_controller.cc6
-rw-r--r--components/sync_driver/proxy_data_type_controller.h5
-rw-r--r--components/sync_driver/ui_data_type_controller.cc16
-rw-r--r--components/sync_driver/ui_data_type_controller.h6
-rw-r--r--components/sync_driver/ui_data_type_controller_unittest.cc20
60 files changed, 482 insertions, 285 deletions
diff --git a/chrome/browser/supervised_user/supervised_user_sync_data_type_controller.cc b/chrome/browser/supervised_user/supervised_user_sync_data_type_controller.cc
index 8c23834..8e42c4e 100644
--- a/chrome/browser/supervised_user/supervised_user_sync_data_type_controller.cc
+++ b/chrome/browser/supervised_user/supervised_user_sync_data_type_controller.cc
@@ -9,6 +9,7 @@
#include "content/public/browser/browser_thread.h"
SupervisedUserSyncDataTypeController::SupervisedUserSyncDataTypeController(
+ const DisableTypeCallback& disable_callback,
syncer::ModelType type,
sync_driver::SyncApiComponentFactory* sync_factory,
Profile* profile)
@@ -16,6 +17,7 @@ SupervisedUserSyncDataTypeController::SupervisedUserSyncDataTypeController(
content::BrowserThread::GetMessageLoopProxyForThread(
content::BrowserThread::UI),
base::Bind(&browser_sync::ChromeReportUnrecoverableError),
+ disable_callback,
type,
sync_factory),
profile_(profile) {
diff --git a/chrome/browser/supervised_user/supervised_user_sync_data_type_controller.h b/chrome/browser/supervised_user/supervised_user_sync_data_type_controller.h
index a2818a9..5b7b1af 100644
--- a/chrome/browser/supervised_user/supervised_user_sync_data_type_controller.h
+++ b/chrome/browser/supervised_user/supervised_user_sync_data_type_controller.h
@@ -22,6 +22,7 @@ class SupervisedUserSyncDataTypeController
: public sync_driver::UIDataTypeController {
public:
SupervisedUserSyncDataTypeController(
+ const DisableTypeCallback& disable_callback,
syncer::ModelType type,
sync_driver::SyncApiComponentFactory* sync_factory,
Profile* profile);
diff --git a/chrome/browser/sync/glue/autofill_data_type_controller.cc b/chrome/browser/sync/glue/autofill_data_type_controller.cc
index 8225b24..48dec09 100644
--- a/chrome/browser/sync/glue/autofill_data_type_controller.cc
+++ b/chrome/browser/sync/glue/autofill_data_type_controller.cc
@@ -23,10 +23,12 @@ namespace browser_sync {
AutofillDataTypeController::AutofillDataTypeController(
ProfileSyncComponentsFactory* profile_sync_factory,
- Profile* profile)
+ Profile* profile,
+ const DisableTypeCallback& disable_callback)
: NonUIDataTypeController(
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
base::Bind(&ChromeReportUnrecoverableError),
+ disable_callback,
profile_sync_factory),
profile_(profile) {
}
diff --git a/chrome/browser/sync/glue/autofill_data_type_controller.h b/chrome/browser/sync/glue/autofill_data_type_controller.h
index a213d12..1f4c126 100644
--- a/chrome/browser/sync/glue/autofill_data_type_controller.h
+++ b/chrome/browser/sync/glue/autofill_data_type_controller.h
@@ -27,7 +27,8 @@ class AutofillDataTypeController
public:
AutofillDataTypeController(
ProfileSyncComponentsFactory* profile_sync_factory,
- Profile* profile);
+ Profile* profile,
+ const DisableTypeCallback& disable_callback);
// NonUIDataTypeController implementation.
virtual syncer::ModelType type() const OVERRIDE;
diff --git a/chrome/browser/sync/glue/autofill_data_type_controller_unittest.cc b/chrome/browser/sync/glue/autofill_data_type_controller_unittest.cc
index fcdd0e7..6107331 100644
--- a/chrome/browser/sync/glue/autofill_data_type_controller_unittest.cc
+++ b/chrome/browser/sync/glue/autofill_data_type_controller_unittest.cc
@@ -153,7 +153,8 @@ class SyncAutofillDataTypeControllerTest : public testing::Test {
autofill_dtc_ =
new AutofillDataTypeController(
- &profile_sync_factory_, &profile_);
+ &profile_sync_factory_, &profile_,
+ sync_driver::DataTypeController::DisableTypeCallback());
}
// Passed to AutofillDTC::Start().
diff --git a/chrome/browser/sync/glue/autofill_profile_data_type_controller.cc b/chrome/browser/sync/glue/autofill_profile_data_type_controller.cc
index 9907386..f8edcd7 100644
--- a/chrome/browser/sync/glue/autofill_profile_data_type_controller.cc
+++ b/chrome/browser/sync/glue/autofill_profile_data_type_controller.cc
@@ -24,10 +24,12 @@ namespace browser_sync {
AutofillProfileDataTypeController::AutofillProfileDataTypeController(
ProfileSyncComponentsFactory* profile_sync_factory,
- Profile* profile)
+ Profile* profile,
+ const DisableTypeCallback& disable_callback)
: NonUIDataTypeController(
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
base::Bind(&ChromeReportUnrecoverableError),
+ disable_callback,
profile_sync_factory),
profile_(profile),
personal_data_(NULL),
diff --git a/chrome/browser/sync/glue/autofill_profile_data_type_controller.h b/chrome/browser/sync/glue/autofill_profile_data_type_controller.h
index 9641c67..9b1b4fd 100644
--- a/chrome/browser/sync/glue/autofill_profile_data_type_controller.h
+++ b/chrome/browser/sync/glue/autofill_profile_data_type_controller.h
@@ -26,7 +26,8 @@ class AutofillProfileDataTypeController
public:
AutofillProfileDataTypeController(
ProfileSyncComponentsFactory* profile_sync_factory,
- Profile* profile);
+ Profile* profile,
+ const DisableTypeCallback& disable_callback);
// NonUIDataTypeController implementation.
virtual syncer::ModelType type() const OVERRIDE;
diff --git a/chrome/browser/sync/glue/bookmark_change_processor.cc b/chrome/browser/sync/glue/bookmark_change_processor.cc
index d6c4d6a..8e31f92 100644
--- a/chrome/browser/sync/glue/bookmark_change_processor.cc
+++ b/chrome/browser/sync/glue/bookmark_change_processor.cc
@@ -120,11 +120,8 @@ void BookmarkChangeProcessor::RemoveSyncNodeHierarchy(
syncer::WriteNode topmost_sync_node(&trans);
if (!model_associator_->InitSyncNodeFromChromeId(topmost->id(),
&topmost_sync_node)) {
- syncer::SyncError error(FROM_HERE,
- syncer::SyncError::DATATYPE_ERROR,
- "Failed to init sync node from chrome node",
- syncer::BOOKMARKS);
- error_handler()->OnSingleDataTypeUnrecoverableError(error);
+ error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ std::string());
return;
}
// Check that |topmost| has been unlinked.
@@ -166,11 +163,8 @@ void BookmarkChangeProcessor::RemoveAllChildNodes(
syncer::WriteNode topmost_node(trans);
if (!model_associator_->InitSyncNodeFromChromeId(topmost_node_id,
&topmost_node)) {
- syncer::SyncError error(FROM_HERE,
- syncer::SyncError::DATATYPE_ERROR,
- "Failed to init sync node from chrome node",
- syncer::BOOKMARKS);
- error_handler()->OnSingleDataTypeUnrecoverableError(error);
+ error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ std::string());
return;
}
const int64 topmost_sync_id = topmost_node.GetId();
@@ -278,11 +272,8 @@ int64 BookmarkChangeProcessor::CreateSyncNode(const BookmarkNode* parent,
// Actually create the node with the appropriate initial position.
if (!PlaceSyncNode(CREATE, parent, index, trans, &sync_child, associator)) {
- syncer::SyncError error(FROM_HERE,
- syncer::SyncError::DATATYPE_ERROR,
- "Failed ot creat sync node.",
- syncer::BOOKMARKS);
- error_handler->OnSingleDataTypeUnrecoverableError(error);
+ error_handler->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ "Sync node creation failed; recovery unlikely");
return syncer::kInvalidId;
}
@@ -330,11 +321,8 @@ int64 BookmarkChangeProcessor::UpdateSyncNode(
// Lookup the sync node that's associated with |node|.
syncer::WriteNode sync_node(trans);
if (!associator->InitSyncNodeFromChromeId(node->id(), &sync_node)) {
- syncer::SyncError error(FROM_HERE,
- syncer::SyncError::DATATYPE_ERROR,
- "Failed to init sync node from chrome node",
- syncer::BOOKMARKS);
- error_handler->OnSingleDataTypeUnrecoverableError(error);
+ error_handler->OnSingleDatatypeUnrecoverableError(
+ FROM_HERE, "Could not load bookmark node on update.");
return syncer::kInvalidId;
}
UpdateSyncNodeProperties(node, model, &sync_node);
@@ -368,21 +356,15 @@ void BookmarkChangeProcessor::BookmarkNodeMoved(BookmarkModel* model,
// Lookup the sync node that's associated with |child|.
syncer::WriteNode sync_node(&trans);
if (!model_associator_->InitSyncNodeFromChromeId(child->id(), &sync_node)) {
- syncer::SyncError error(FROM_HERE,
- syncer::SyncError::DATATYPE_ERROR,
- "Failed to init sync node from chrome node",
- syncer::BOOKMARKS);
- error_handler()->OnSingleDataTypeUnrecoverableError(error);
+ error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ std::string());
return;
}
if (!PlaceSyncNode(MOVE, new_parent, new_index, &trans, &sync_node,
model_associator_)) {
- syncer::SyncError error(FROM_HERE,
- syncer::SyncError::DATATYPE_ERROR,
- "Failed to place sync node",
- syncer::BOOKMARKS);
- error_handler()->OnSingleDataTypeUnrecoverableError(error);
+ error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ std::string());
return;
}
}
@@ -414,11 +396,8 @@ void BookmarkChangeProcessor::BookmarkNodeChildrenReordered(
syncer::WriteNode sync_child(&trans);
if (!model_associator_->InitSyncNodeFromChromeId(child->id(),
&sync_child)) {
- syncer::SyncError error(FROM_HERE,
- syncer::SyncError::DATATYPE_ERROR,
- "Failed to init sync node from chrome node",
- syncer::BOOKMARKS);
- error_handler()->OnSingleDataTypeUnrecoverableError(error);
+ error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ std::string());
return;
}
DCHECK_EQ(sync_child.GetParentId(),
@@ -426,11 +405,8 @@ void BookmarkChangeProcessor::BookmarkNodeChildrenReordered(
if (!PlaceSyncNode(MOVE, node, i, &trans, &sync_child,
model_associator_)) {
- syncer::SyncError error(FROM_HERE,
- syncer::SyncError::DATATYPE_ERROR,
- "Failed to place sync node",
- syncer::BOOKMARKS);
- error_handler()->OnSingleDataTypeUnrecoverableError(error);
+ error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ std::string());
return;
}
}
@@ -552,11 +528,8 @@ void BookmarkChangeProcessor::ApplyChangesFromSyncModel(
model->other_node()->child_count(),
base::string16());
if (!foster_parent) {
- syncer::SyncError error(FROM_HERE,
- syncer::SyncError::DATATYPE_ERROR,
- "Failed to create foster parent",
- syncer::BOOKMARKS);
- error_handler()->OnSingleDataTypeUnrecoverableError(error);
+ error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ "Failed to create foster parent.");
return;
}
}
@@ -613,11 +586,8 @@ void BookmarkChangeProcessor::ApplyChangesFromSyncModel(
syncer::ReadNode src(trans);
if (src.InitByIdLookup(it->id) != syncer::BaseNode::INIT_OK) {
- syncer::SyncError error(FROM_HERE,
- syncer::SyncError::DATATYPE_ERROR,
- "Failed to load sync node",
- syncer::BOOKMARKS);
- error_handler()->OnSingleDataTypeUnrecoverableError(error);
+ error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ "ApplyModelChanges was passed a bad ID");
return;
}
diff --git a/chrome/browser/sync/glue/bookmark_data_type_controller_unittest.cc b/chrome/browser/sync/glue/bookmark_data_type_controller_unittest.cc
index 3c00de5..d8b7ead 100644
--- a/chrome/browser/sync/glue/bookmark_data_type_controller_unittest.cc
+++ b/chrome/browser/sync/glue/bookmark_data_type_controller_unittest.cc
@@ -335,3 +335,21 @@ TEST_F(SyncBookmarkDataTypeControllerTest, Stop) {
bookmark_dtc_->Stop();
EXPECT_EQ(DataTypeController::NOT_RUNNING, bookmark_dtc_->state());
}
+
+TEST_F(SyncBookmarkDataTypeControllerTest, OnSingleDatatypeUnrecoverableError) {
+ CreateBookmarkModel(LOAD_MODEL);
+ SetStartExpectations();
+ SetAssociateExpectations();
+ EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_)).
+ WillRepeatedly(DoAll(SetArgumentPointee<0>(true), Return(true)));
+ EXPECT_CALL(service_, DisableDatatype(_)).
+ WillOnce(InvokeWithoutArgs(bookmark_dtc_.get(),
+ &BookmarkDataTypeController::Stop));
+ SetStopExpectations();
+
+ EXPECT_CALL(start_callback_, Run(DataTypeController::OK, _, _));
+ Start();
+ // This should cause bookmark_dtc_->Stop() to be called.
+ bookmark_dtc_->OnSingleDatatypeUnrecoverableError(FROM_HERE, "Test");
+ base::RunLoop().RunUntilIdle();
+}
diff --git a/chrome/browser/sync/glue/bookmark_model_associator.cc b/chrome/browser/sync/glue/bookmark_model_associator.cc
index c77bf96..4ea6b9c 100644
--- a/chrome/browser/sync/glue/bookmark_model_associator.cc
+++ b/chrome/browser/sync/glue/bookmark_model_associator.cc
@@ -730,12 +730,9 @@ void BookmarkModelAssociator::PersistAssociations() {
int64 sync_id = *iter;
syncer::WriteNode sync_node(&trans);
if (sync_node.InitByIdLookup(sync_id) != syncer::BaseNode::INIT_OK) {
- syncer::SyncError error(
+ unrecoverable_error_handler_->OnSingleDatatypeUnrecoverableError(
FROM_HERE,
- syncer::SyncError::DATATYPE_ERROR,
- "Could not lookup bookmark node for ID persistence.",
- syncer::BOOKMARKS);
- unrecoverable_error_handler_->OnSingleDataTypeUnrecoverableError(error);
+ "Could not lookup bookmark node for ID persistence.");
return;
}
const BookmarkNode* node = GetChromeNodeFromSyncId(sync_id);
diff --git a/chrome/browser/sync/glue/device_info_data_type_controller.cc b/chrome/browser/sync/glue/device_info_data_type_controller.cc
index 81d0fa8..a8deb06 100644
--- a/chrome/browser/sync/glue/device_info_data_type_controller.cc
+++ b/chrome/browser/sync/glue/device_info_data_type_controller.cc
@@ -14,10 +14,12 @@ namespace browser_sync {
DeviceInfoDataTypeController::DeviceInfoDataTypeController(
sync_driver::SyncApiComponentFactory* sync_factory,
- LocalDeviceInfoProvider* local_device_info_provider)
+ LocalDeviceInfoProvider* local_device_info_provider,
+ const DisableTypeCallback& disable_callback)
: UIDataTypeController(
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
base::Bind(&ChromeReportUnrecoverableError),
+ disable_callback,
syncer::DEVICE_INFO,
sync_factory),
local_device_info_provider_(local_device_info_provider) {
diff --git a/chrome/browser/sync/glue/device_info_data_type_controller.h b/chrome/browser/sync/glue/device_info_data_type_controller.h
index 38c7b45..979536f 100644
--- a/chrome/browser/sync/glue/device_info_data_type_controller.h
+++ b/chrome/browser/sync/glue/device_info_data_type_controller.h
@@ -16,7 +16,8 @@ class DeviceInfoDataTypeController : public sync_driver::UIDataTypeController {
public:
DeviceInfoDataTypeController(
sync_driver::SyncApiComponentFactory* sync_factory,
- LocalDeviceInfoProvider* local_device_info_provider);
+ LocalDeviceInfoProvider* local_device_info_provider,
+ const DisableTypeCallback& disable_callback);
private:
virtual ~DeviceInfoDataTypeController();
diff --git a/chrome/browser/sync/glue/device_info_data_type_controller_unittest.cc b/chrome/browser/sync/glue/device_info_data_type_controller_unittest.cc
index 0f0a2b9..92a94a9 100644
--- a/chrome/browser/sync/glue/device_info_data_type_controller_unittest.cc
+++ b/chrome/browser/sync/glue/device_info_data_type_controller_unittest.cc
@@ -38,7 +38,8 @@ class DeviceInfoDataTypeControllerTest : public testing::Test {
controller_ = new DeviceInfoDataTypeController(
&profile_sync_factory_,
- local_device_.get());
+ local_device_.get(),
+ DataTypeController::DisableTypeCallback());
load_finished_ = false;
last_type_ = syncer::UNSPECIFIED;
diff --git a/chrome/browser/sync/glue/extension_backed_data_type_controller.cc b/chrome/browser/sync/glue/extension_backed_data_type_controller.cc
index 7de4d7e..b06f6df 100644
--- a/chrome/browser/sync/glue/extension_backed_data_type_controller.cc
+++ b/chrome/browser/sync/glue/extension_backed_data_type_controller.cc
@@ -30,6 +30,7 @@ std::string IdToHash(const std::string extension_id) {
} // namespace
ExtensionBackedDataTypeController::ExtensionBackedDataTypeController(
+ const DisableTypeCallback& disable_callback,
syncer::ModelType type,
const std::string& extension_hash,
sync_driver::SyncApiComponentFactory* sync_factory,
@@ -37,6 +38,7 @@ ExtensionBackedDataTypeController::ExtensionBackedDataTypeController(
: UIDataTypeController(
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
base::Bind(&ChromeReportUnrecoverableError),
+ disable_callback,
type,
sync_factory),
extension_hash_(extension_hash),
@@ -73,16 +75,20 @@ void ExtensionBackedDataTypeController::OnExtensionUnloaded(
const extensions::Extension* extension,
extensions::UnloadedExtensionInfo::Reason reason) {
if (DoesExtensionMatch(*extension)) {
+ ProfileSyncService* sync_service =
+ ProfileSyncServiceFactory::GetForProfile(profile_);
+
// This will trigger purging the datatype from the sync directory. This
// may not always be the right choice, especially in the face of transient
// unloads (e.g. for permission changes). If that becomes a large enough
// issue, we should consider using the extension unload reason to just
// trigger a reconfiguration without disabling (type will be unready).
- syncer::SyncError error(FROM_HERE,
- syncer::SyncError::DATATYPE_POLICY_ERROR,
- "Extension unloaded",
- type());
- OnSingleDataTypeUnrecoverableError(error);
+ syncer::SyncError error(
+ FROM_HERE,
+ syncer::SyncError::DATATYPE_ERROR,
+ "Extension unloaded",
+ type());
+ sync_service->DisableDatatype(error);
}
}
diff --git a/chrome/browser/sync/glue/extension_backed_data_type_controller.h b/chrome/browser/sync/glue/extension_backed_data_type_controller.h
index d5c6df8..9d438d2 100644
--- a/chrome/browser/sync/glue/extension_backed_data_type_controller.h
+++ b/chrome/browser/sync/glue/extension_backed_data_type_controller.h
@@ -22,6 +22,7 @@ class ExtensionBackedDataTypeController
public extensions::ExtensionRegistryObserver {
public:
ExtensionBackedDataTypeController(
+ const DisableTypeCallback& disable_callback,
syncer::ModelType type,
const std::string& extension_hash,
sync_driver::SyncApiComponentFactory* sync_factory,
diff --git a/chrome/browser/sync/glue/extension_data_type_controller.cc b/chrome/browser/sync/glue/extension_data_type_controller.cc
index cdeead6..7f3e258 100644
--- a/chrome/browser/sync/glue/extension_data_type_controller.cc
+++ b/chrome/browser/sync/glue/extension_data_type_controller.cc
@@ -17,10 +17,12 @@ namespace browser_sync {
ExtensionDataTypeController::ExtensionDataTypeController(
syncer::ModelType type,
sync_driver::SyncApiComponentFactory* sync_factory,
- Profile* profile)
+ Profile* profile,
+ const DisableTypeCallback& disable_callback)
: UIDataTypeController(
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
base::Bind(&ChromeReportUnrecoverableError),
+ disable_callback,
type,
sync_factory),
profile_(profile) {
diff --git a/chrome/browser/sync/glue/extension_data_type_controller.h b/chrome/browser/sync/glue/extension_data_type_controller.h
index 0904d35..4cb1113 100644
--- a/chrome/browser/sync/glue/extension_data_type_controller.h
+++ b/chrome/browser/sync/glue/extension_data_type_controller.h
@@ -22,7 +22,8 @@ class ExtensionDataTypeController : public sync_driver::UIDataTypeController {
ExtensionDataTypeController(
syncer::ModelType type, // Either EXTENSIONS or APPS.
sync_driver::SyncApiComponentFactory* sync_factory,
- Profile* profile);
+ Profile* profile,
+ const DisableTypeCallback& disable_callback);
private:
virtual ~ExtensionDataTypeController();
diff --git a/chrome/browser/sync/glue/extension_setting_data_type_controller.cc b/chrome/browser/sync/glue/extension_setting_data_type_controller.cc
index 9e015d9..dc9e29e 100644
--- a/chrome/browser/sync/glue/extension_setting_data_type_controller.cc
+++ b/chrome/browser/sync/glue/extension_setting_data_type_controller.cc
@@ -22,10 +22,12 @@ namespace browser_sync {
ExtensionSettingDataTypeController::ExtensionSettingDataTypeController(
syncer::ModelType type,
ProfileSyncComponentsFactory* profile_sync_factory,
- Profile* profile)
+ Profile* profile,
+ const DisableTypeCallback& disable_callback)
: NonUIDataTypeController(
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
base::Bind(&ChromeReportUnrecoverableError),
+ disable_callback,
profile_sync_factory),
type_(type),
profile_(profile) {
diff --git a/chrome/browser/sync/glue/extension_setting_data_type_controller.h b/chrome/browser/sync/glue/extension_setting_data_type_controller.h
index a7215b0..d53e9bf 100644
--- a/chrome/browser/sync/glue/extension_setting_data_type_controller.h
+++ b/chrome/browser/sync/glue/extension_setting_data_type_controller.h
@@ -30,7 +30,8 @@ class ExtensionSettingDataTypeController
// Either EXTENSION_SETTINGS or APP_SETTINGS.
syncer::ModelType type,
ProfileSyncComponentsFactory* profile_sync_factory,
- Profile* profile);
+ Profile* profile,
+ const DisableTypeCallback& disable_callback);
// NonFrontendDataTypeController implementation
virtual syncer::ModelType type() const OVERRIDE;
diff --git a/chrome/browser/sync/glue/frontend_data_type_controller.cc b/chrome/browser/sync/glue/frontend_data_type_controller.cc
index eaa6ea5..38435a8 100644
--- a/chrome/browser/sync/glue/frontend_data_type_controller.cc
+++ b/chrome/browser/sync/glue/frontend_data_type_controller.cc
@@ -30,7 +30,7 @@ FrontendDataTypeController::FrontendDataTypeController(
ProfileSyncComponentsFactory* profile_sync_factory,
Profile* profile,
ProfileSyncService* sync_service)
- : DataTypeController(ui_thread, error_callback),
+ : DataTypeController(ui_thread, error_callback, DisableTypeCallback()),
profile_sync_factory_(profile_sync_factory),
profile_(profile),
sync_service_(sync_service),
@@ -85,6 +85,7 @@ void FrontendDataTypeController::StartAssociating(
const StartCallback& start_callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK(!start_callback.is_null());
+ DCHECK(start_callback_.is_null());
DCHECK_EQ(state_, MODEL_LOADED);
start_callback_ = start_callback;
@@ -101,9 +102,6 @@ void FrontendDataTypeController::StartAssociating(
void FrontendDataTypeController::Stop() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (state_ == NOT_RUNNING)
- return;
-
State prev_state = state_;
state_ = STOPPING;
@@ -115,6 +113,7 @@ void FrontendDataTypeController::Stop() {
// still in MODEL_STARTING.
return;
}
+ DCHECK(start_callback_.is_null());
CleanUpState();
@@ -146,21 +145,17 @@ sync_driver::DataTypeController::State FrontendDataTypeController::state()
return state_;
}
-void FrontendDataTypeController::OnSingleDataTypeUnrecoverableError(
- const syncer::SyncError& error) {
- DCHECK_EQ(type(), error.model_type());
- RecordUnrecoverableError(error.location(), error.message());
- if (!start_callback_.is_null()) {
- syncer::SyncMergeResult local_merge_result(type());
- local_merge_result.set_error(error);
- start_callback_.Run(RUNTIME_ERROR,
- local_merge_result,
- syncer::SyncMergeResult(type()));
- }
+void FrontendDataTypeController::OnSingleDatatypeUnrecoverableError(
+ const tracked_objects::Location& from_here, const std::string& message) {
+ RecordUnrecoverableError(from_here, message);
+ syncer::SyncError error(
+ from_here, syncer::SyncError::DATATYPE_ERROR, message, type());
+ sync_service_->DisableDatatype(error);
}
FrontendDataTypeController::FrontendDataTypeController()
- : DataTypeController(base::MessageLoopProxy::current(), base::Closure()),
+ : DataTypeController(base::MessageLoopProxy::current(), base::Closure(),
+ DisableTypeCallback()),
profile_sync_factory_(NULL),
profile_(NULL),
sync_service_(NULL),
@@ -284,7 +279,12 @@ void FrontendDataTypeController::StartDone(
RecordStartFailure(start_result);
}
- start_callback_.Run(start_result, local_merge_result, syncer_merge_result);
+ // We have to release the callback before we call it, since it's possible
+ // invoking the callback will trigger a call to STOP(), which will get
+ // confused by the non-NULL start_callback_.
+ StartCallback callback = start_callback_;
+ start_callback_.Reset();
+ callback.Run(start_result, local_merge_result, syncer_merge_result);
}
void FrontendDataTypeController::RecordAssociationTime(base::TimeDelta time) {
diff --git a/chrome/browser/sync/glue/frontend_data_type_controller.h b/chrome/browser/sync/glue/frontend_data_type_controller.h
index dcc24c2..ab85db4 100644
--- a/chrome/browser/sync/glue/frontend_data_type_controller.h
+++ b/chrome/browser/sync/glue/frontend_data_type_controller.h
@@ -62,8 +62,9 @@ class FrontendDataTypeController : public sync_driver::DataTypeController {
virtual State state() const OVERRIDE;
// DataTypeErrorHandler interface.
- virtual void OnSingleDataTypeUnrecoverableError(
- const syncer::SyncError& error) OVERRIDE;
+ virtual void OnSingleDatatypeUnrecoverableError(
+ const tracked_objects::Location& from_here,
+ const std::string& message) OVERRIDE;
protected:
friend class FrontendDataTypeControllerMock;
diff --git a/chrome/browser/sync/glue/frontend_data_type_controller_unittest.cc b/chrome/browser/sync/glue/frontend_data_type_controller_unittest.cc
index 6f0b9bd..88fd3fd 100644
--- a/chrome/browser/sync/glue/frontend_data_type_controller_unittest.cc
+++ b/chrome/browser/sync/glue/frontend_data_type_controller_unittest.cc
@@ -255,3 +255,21 @@ TEST_F(SyncFrontendDataTypeControllerTest, Stop) {
frontend_dtc_->Stop();
EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state());
}
+
+TEST_F(SyncFrontendDataTypeControllerTest, OnSingleDatatypeUnrecoverableError) {
+ SetStartExpectations();
+ SetAssociateExpectations();
+ SetActivateExpectations(DataTypeController::OK);
+ EXPECT_CALL(*dtc_mock_.get(), RecordUnrecoverableError(_, "Test"));
+ EXPECT_CALL(service_, DisableDatatype(_))
+ .WillOnce(InvokeWithoutArgs(frontend_dtc_.get(),
+ &FrontendDataTypeController::Stop));
+ SetStopExpectations();
+ EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state());
+ Start();
+ EXPECT_EQ(DataTypeController::RUNNING, frontend_dtc_->state());
+ // This should cause frontend_dtc_->Stop() to be called.
+ frontend_dtc_->OnSingleDatatypeUnrecoverableError(FROM_HERE, "Test");
+ PumpLoop();
+ EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state());
+}
diff --git a/chrome/browser/sync/glue/non_frontend_data_type_controller.cc b/chrome/browser/sync/glue/non_frontend_data_type_controller.cc
index ea9d144..5b83a8e 100644
--- a/chrome/browser/sync/glue/non_frontend_data_type_controller.cc
+++ b/chrome/browser/sync/glue/non_frontend_data_type_controller.cc
@@ -157,15 +157,16 @@ NonFrontendDataTypeController::AssociationResult::AssociationResult(
NonFrontendDataTypeController::AssociationResult::~AssociationResult() {}
// TODO(tim): Legacy controllers are being left behind in componentization
-// effort for now, hence still having a dependency on ProfileSyncService.
-// That dep can probably be removed without too much work.
+// effort for now, hence passing null DisableTypeCallback and still having
+// a dependency on ProfileSyncService. That dep can probably be removed
+// without too much work.
NonFrontendDataTypeController::NonFrontendDataTypeController(
scoped_refptr<base::MessageLoopProxy> ui_thread,
const base::Closure& error_callback,
ProfileSyncComponentsFactory* profile_sync_factory,
Profile* profile,
ProfileSyncService* sync_service)
- : DataTypeController(ui_thread, error_callback),
+ : DataTypeController(ui_thread, error_callback, DisableTypeCallback()),
state_(NOT_RUNNING),
profile_sync_factory_(profile_sync_factory),
profile_(profile),
@@ -252,9 +253,7 @@ void DestroyComponentsInBackend(
void NonFrontendDataTypeController::Stop() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- if (state_ == NOT_RUNNING)
- return;
+ DCHECK_NE(state_, NOT_RUNNING);
// Deactivate the date type on the UI thread first to stop processing
// sync server changes. This needs to happen before posting task to destroy
@@ -298,19 +297,21 @@ sync_driver::DataTypeController::State NonFrontendDataTypeController::state()
return state_;
}
-void NonFrontendDataTypeController::OnSingleDataTypeUnrecoverableError(
- const syncer::SyncError& error) {
+void NonFrontendDataTypeController::OnSingleDatatypeUnrecoverableError(
+ const tracked_objects::Location& from_here,
+ const std::string& message) {
DCHECK(IsOnBackendThread());
- DCHECK_EQ(type(), error.model_type());
- RecordUnrecoverableError(error.location(), error.message());
- BrowserThread::PostTask(BrowserThread::UI, error.location(),
+ RecordUnrecoverableError(from_here, message);
+ BrowserThread::PostTask(BrowserThread::UI, from_here,
base::Bind(&NonFrontendDataTypeController::DisableImpl,
this,
- error));
+ from_here,
+ message));
}
NonFrontendDataTypeController::NonFrontendDataTypeController()
- : DataTypeController(base::MessageLoopProxy::current(), base::Closure()),
+ : DataTypeController(base::MessageLoopProxy::current(), base::Closure(),
+ DisableTypeCallback()),
state_(NOT_RUNNING),
profile_sync_factory_(NULL),
profile_(NULL),
@@ -370,19 +371,22 @@ void NonFrontendDataTypeController::StartDoneImpl(
RecordStartFailure(start_result);
}
- start_callback_.Run(start_result, local_merge_result, syncer_merge_result);
+ DCHECK(!start_callback_.is_null());
+ // We have to release the callback before we call it, since it's possible
+ // invoking the callback will trigger a call to STOP(), which will get
+ // confused by the non-NULL start_callback_.
+ StartCallback callback = start_callback_;
+ start_callback_.Reset();
+ callback.Run(start_result, local_merge_result, syncer_merge_result);
}
void NonFrontendDataTypeController::DisableImpl(
- const syncer::SyncError& error) {
+ const tracked_objects::Location& from_here,
+ const std::string& message) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (!start_callback_.is_null()) {
- syncer::SyncMergeResult local_merge_result(type());
- local_merge_result.set_error(error);
- start_callback_.Run(RUNTIME_ERROR,
- local_merge_result,
- syncer::SyncMergeResult(type()));
- }
+ syncer::SyncError error(
+ from_here, syncer::SyncError::DATATYPE_ERROR, message, type());
+ profile_sync_service_->DisableDatatype(error);
}
void NonFrontendDataTypeController::RecordAssociationTime(
diff --git a/chrome/browser/sync/glue/non_frontend_data_type_controller.h b/chrome/browser/sync/glue/non_frontend_data_type_controller.h
index e2e5043..41f3fcf 100644
--- a/chrome/browser/sync/glue/non_frontend_data_type_controller.h
+++ b/chrome/browser/sync/glue/non_frontend_data_type_controller.h
@@ -68,8 +68,9 @@ class NonFrontendDataTypeController : public sync_driver::DataTypeController {
// DataTypeErrorHandler interface.
// Note: this is performed on the datatype's thread.
- virtual void OnSingleDataTypeUnrecoverableError(
- const syncer::SyncError& error) OVERRIDE;
+ virtual void OnSingleDatatypeUnrecoverableError(
+ const tracked_objects::Location& from_here,
+ const std::string& message) OVERRIDE;
// Callback to receive background association results.
struct AssociationResult {
@@ -146,7 +147,8 @@ class NonFrontendDataTypeController : public sync_driver::DataTypeController {
// The actual implementation of Disabling the datatype. This happens
// on the UI thread.
- virtual void DisableImpl(const syncer::SyncError& error);
+ virtual void DisableImpl(const tracked_objects::Location& from_here,
+ const std::string& message);
// Record association time. Called on Datatype's thread.
virtual void RecordAssociationTime(base::TimeDelta time);
diff --git a/chrome/browser/sync/glue/non_frontend_data_type_controller_unittest.cc b/chrome/browser/sync/glue/non_frontend_data_type_controller_unittest.cc
index 605313b..a383e14 100644
--- a/chrome/browser/sync/glue/non_frontend_data_type_controller_unittest.cc
+++ b/chrome/browser/sync/glue/non_frontend_data_type_controller_unittest.cc
@@ -373,7 +373,7 @@ TEST_F(SyncNonFrontendDataTypeControllerTest, Stop) {
// Disabled due to http://crbug.com/388367
TEST_F(SyncNonFrontendDataTypeControllerTest,
- DISABLED_OnSingleDataTypeUnrecoverableError) {
+ DISABLED_OnSingleDatatypeUnrecoverableError) {
SetStartExpectations();
SetAssociateExpectations();
SetActivateExpectations(DataTypeController::OK);
@@ -387,14 +387,11 @@ TEST_F(SyncNonFrontendDataTypeControllerTest,
WaitForDTC();
EXPECT_EQ(DataTypeController::RUNNING, non_frontend_dtc_->state());
// This should cause non_frontend_dtc_->Stop() to be called.
- syncer::SyncError error(FROM_HERE,
- syncer::SyncError::DATATYPE_ERROR,
- "error",
- non_frontend_dtc_->type());
BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, base::Bind(
- &NonFrontendDataTypeControllerFake::OnSingleDataTypeUnrecoverableError,
+ &NonFrontendDataTypeControllerFake::OnSingleDatatypeUnrecoverableError,
non_frontend_dtc_.get(),
- error));
+ FROM_HERE,
+ std::string("Test")));
WaitForDTC();
EXPECT_EQ(DataTypeController::NOT_RUNNING, non_frontend_dtc_->state());
}
diff --git a/chrome/browser/sync/glue/password_data_type_controller.cc b/chrome/browser/sync/glue/password_data_type_controller.cc
index 3681b04..2ff1b37 100644
--- a/chrome/browser/sync/glue/password_data_type_controller.cc
+++ b/chrome/browser/sync/glue/password_data_type_controller.cc
@@ -19,10 +19,12 @@ namespace browser_sync {
PasswordDataTypeController::PasswordDataTypeController(
ProfileSyncComponentsFactory* profile_sync_factory,
- Profile* profile)
+ Profile* profile,
+ const DisableTypeCallback& disable_callback)
: NonUIDataTypeController(
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
base::Bind(&ChromeReportUnrecoverableError),
+ disable_callback,
profile_sync_factory),
profile_(profile) {
}
diff --git a/chrome/browser/sync/glue/password_data_type_controller.h b/chrome/browser/sync/glue/password_data_type_controller.h
index e701a89..7394f0b 100644
--- a/chrome/browser/sync/glue/password_data_type_controller.h
+++ b/chrome/browser/sync/glue/password_data_type_controller.h
@@ -24,7 +24,8 @@ class PasswordDataTypeController : public sync_driver::NonUIDataTypeController {
public:
PasswordDataTypeController(
ProfileSyncComponentsFactory* profile_sync_factory,
- Profile* profile);
+ Profile* profile,
+ const DisableTypeCallback& disable_callback);
// NonFrontendDataTypeController implementation
virtual syncer::ModelType type() const OVERRIDE;
diff --git a/chrome/browser/sync/glue/search_engine_data_type_controller.cc b/chrome/browser/sync/glue/search_engine_data_type_controller.cc
index 5ac663a..7a596aa 100644
--- a/chrome/browser/sync/glue/search_engine_data_type_controller.cc
+++ b/chrome/browser/sync/glue/search_engine_data_type_controller.cc
@@ -18,10 +18,12 @@ namespace browser_sync {
SearchEngineDataTypeController::SearchEngineDataTypeController(
sync_driver::SyncApiComponentFactory* sync_factory,
- Profile* profile)
+ Profile* profile,
+ const DisableTypeCallback& disable_callback)
: UIDataTypeController(
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
base::Bind(&ChromeReportUnrecoverableError),
+ disable_callback,
syncer::SEARCH_ENGINES,
sync_factory),
profile_(profile) {
diff --git a/chrome/browser/sync/glue/search_engine_data_type_controller.h b/chrome/browser/sync/glue/search_engine_data_type_controller.h
index f40a6fa..b55dafc 100644
--- a/chrome/browser/sync/glue/search_engine_data_type_controller.h
+++ b/chrome/browser/sync/glue/search_engine_data_type_controller.h
@@ -24,7 +24,8 @@ class SearchEngineDataTypeController
public:
SearchEngineDataTypeController(
sync_driver::SyncApiComponentFactory* profile_sync_factory,
- Profile* profile);
+ Profile* profile,
+ const DisableTypeCallback& disable_callback);
TemplateURLService::Subscription* GetSubscriptionForTesting();
diff --git a/chrome/browser/sync/glue/search_engine_data_type_controller_unittest.cc b/chrome/browser/sync/glue/search_engine_data_type_controller_unittest.cc
index 470c11a..e8952c5 100644
--- a/chrome/browser/sync/glue/search_engine_data_type_controller_unittest.cc
+++ b/chrome/browser/sync/glue/search_engine_data_type_controller_unittest.cc
@@ -39,7 +39,8 @@ class SyncSearchEngineDataTypeControllerTest : public testing::Test {
// Feed the DTC the profile so it is reused later.
// This allows us to control the associated TemplateURLService.
search_engine_dtc_ = new SearchEngineDataTypeController(
- profile_sync_factory_.get(), &profile_);
+ profile_sync_factory_.get(), &profile_,
+ sync_driver::DataTypeController::DisableTypeCallback());
}
virtual void TearDown() {
diff --git a/chrome/browser/sync/glue/theme_data_type_controller.cc b/chrome/browser/sync/glue/theme_data_type_controller.cc
index 6e9852e..162d9f6 100644
--- a/chrome/browser/sync/glue/theme_data_type_controller.cc
+++ b/chrome/browser/sync/glue/theme_data_type_controller.cc
@@ -15,10 +15,12 @@ namespace browser_sync {
ThemeDataTypeController::ThemeDataTypeController(
sync_driver::SyncApiComponentFactory* sync_factory,
- Profile* profile)
+ Profile* profile,
+ const DisableTypeCallback& disable_callback)
: UIDataTypeController(
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
base::Bind(&ChromeReportUnrecoverableError),
+ disable_callback,
syncer::THEMES,
sync_factory),
profile_(profile) {
diff --git a/chrome/browser/sync/glue/theme_data_type_controller.h b/chrome/browser/sync/glue/theme_data_type_controller.h
index 47e24f8..086ef00 100644
--- a/chrome/browser/sync/glue/theme_data_type_controller.h
+++ b/chrome/browser/sync/glue/theme_data_type_controller.h
@@ -15,7 +15,8 @@ class ThemeDataTypeController : public sync_driver::UIDataTypeController {
public:
ThemeDataTypeController(
sync_driver::SyncApiComponentFactory* sync_factory,
- Profile* profile);
+ Profile* profile,
+ const DisableTypeCallback& disable_callback);
private:
virtual ~ThemeDataTypeController();
diff --git a/chrome/browser/sync/glue/typed_url_change_processor.cc b/chrome/browser/sync/glue/typed_url_change_processor.cc
index ae25e4f..0ef8f7d 100644
--- a/chrome/browser/sync/glue/typed_url_change_processor.cc
+++ b/chrome/browser/sync/glue/typed_url_change_processor.cc
@@ -113,11 +113,9 @@ bool TypedUrlChangeProcessor::CreateOrUpdateSyncNode(
syncer::ReadNode typed_url_root(trans);
if (typed_url_root.InitTypeRoot(syncer::TYPED_URLS) !=
syncer::BaseNode::INIT_OK) {
- syncer::SyncError error(FROM_HERE,
- syncer::SyncError::DATATYPE_ERROR,
- "No top level folder",
- syncer::TYPED_URLS);
- error_handler()->OnSingleDataTypeUnrecoverableError(error);
+ error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ "Server did not create the top-level typed_url node. We "
+ "might be running against an out-of-date server.");
return false;
}
@@ -132,24 +130,47 @@ bool TypedUrlChangeProcessor::CreateOrUpdateSyncNode(
if (result == syncer::BaseNode::INIT_OK) {
model_associator_->WriteToSyncNode(url, visit_vector, &update_node);
} else if (result == syncer::BaseNode::INIT_FAILED_DECRYPT_IF_NECESSARY) {
- syncer::SyncError error(FROM_HERE,
- syncer::SyncError::DATATYPE_ERROR,
- "Failed to decrypt.",
- syncer::TYPED_URLS);
- error_handler()->OnSingleDataTypeUnrecoverableError(error);
- return false;
+ // TODO(tim): Investigating bug 121587.
+ syncer::Cryptographer* crypto = trans->GetCryptographer();
+ syncer::ModelTypeSet encrypted_types(trans->GetEncryptedTypes());
+ const sync_pb::EntitySpecifics& specifics =
+ update_node.GetEntry()->GetSpecifics();
+ CHECK(specifics.has_encrypted());
+ const bool can_decrypt = crypto->CanDecrypt(specifics.encrypted());
+ const bool agreement = encrypted_types.Has(syncer::TYPED_URLS);
+ if (!agreement && !can_decrypt) {
+ error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ "Could not InitByIdLookup in CreateOrUpdateSyncNode, "
+ " Cryptographer thinks typed urls not encrypted, and CanDecrypt"
+ " failed.");
+ LOG(ERROR) << "Case 1.";
+ } else if (agreement && can_decrypt) {
+ error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ "Could not InitByIdLookup on CreateOrUpdateSyncNode, "
+ " Cryptographer thinks typed urls are encrypted, and CanDecrypt"
+ " succeeded (?!), but DecryptIfNecessary failed.");
+ LOG(ERROR) << "Case 2.";
+ } else if (agreement) {
+ error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ "Could not InitByIdLookup on CreateOrUpdateSyncNode, "
+ " Cryptographer thinks typed urls are encrypted, but CanDecrypt"
+ " failed.");
+ LOG(ERROR) << "Case 3.";
+ } else {
+ error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ "Could not InitByIdLookup on CreateOrUpdateSyncNode, "
+ " Cryptographer thinks typed urls not encrypted, but CanDecrypt"
+ " succeeded (super weird, btw)");
+ LOG(ERROR) << "Case 4.";
+ }
} else {
syncer::WriteNode create_node(trans);
syncer::WriteNode::InitUniqueByCreationResult result =
create_node.InitUniqueByCreation(syncer::TYPED_URLS,
typed_url_root, tag);
if (result != syncer::WriteNode::INIT_SUCCESS) {
-
- syncer::SyncError error(FROM_HERE,
- syncer::SyncError::DATATYPE_ERROR,
- "Failed to create sync node",
- syncer::TYPED_URLS);
- error_handler()->OnSingleDataTypeUnrecoverableError(error);
+ error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ "Failed to create typed_url sync node.");
return false;
}
@@ -173,11 +194,8 @@ void TypedUrlChangeProcessor::HandleURLsDeleted(
if (details->all_history) {
if (!model_associator_->DeleteAllNodes(&trans)) {
- syncer::SyncError error(FROM_HERE,
- syncer::SyncError::DATATYPE_ERROR,
- "Failed to delete local nodes.",
- syncer::TYPED_URLS);
- error_handler()->OnSingleDataTypeUnrecoverableError(error);
+ error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ std::string());
return;
}
} else {
@@ -236,11 +254,8 @@ void TypedUrlChangeProcessor::ApplyChangesFromSyncModel(
syncer::ReadNode typed_url_root(trans);
if (typed_url_root.InitTypeRoot(syncer::TYPED_URLS) !=
syncer::BaseNode::INIT_OK) {
- syncer::SyncError error(FROM_HERE,
- syncer::SyncError::DATATYPE_ERROR,
- "Failed to init type root.",
- syncer::TYPED_URLS);
- error_handler()->OnSingleDataTypeUnrecoverableError(error);
+ error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ "TypedUrl root node lookup failed.");
return;
}
@@ -261,11 +276,8 @@ void TypedUrlChangeProcessor::ApplyChangesFromSyncModel(
syncer::ReadNode sync_node(trans);
if (sync_node.InitByIdLookup(it->id) != syncer::BaseNode::INIT_OK) {
- syncer::SyncError error(FROM_HERE,
- syncer::SyncError::DATATYPE_ERROR,
- "Failed to init sync node.",
- syncer::TYPED_URLS);
- error_handler()->OnSingleDataTypeUnrecoverableError(error);
+ error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ "TypedUrl node lookup failed.");
return;
}
diff --git a/chrome/browser/sync/glue/typed_url_data_type_controller.cc b/chrome/browser/sync/glue/typed_url_data_type_controller.cc
index caaa099..403d6b0 100644
--- a/chrome/browser/sync/glue/typed_url_data_type_controller.cc
+++ b/chrome/browser/sync/glue/typed_url_data_type_controller.cc
@@ -126,7 +126,7 @@ void TypedUrlDataTypeController::OnSavingBrowserHistoryDisabledChanged() {
syncer::SyncError::DATATYPE_POLICY_ERROR,
"History saving is now disabled by policy.",
syncer::TYPED_URLS);
- OnSingleDataTypeUnrecoverableError(error);
+ profile_sync_service()->DisableDatatype(error);
}
}
}
diff --git a/chrome/browser/sync/profile_sync_components_factory_impl.cc b/chrome/browser/sync/profile_sync_components_factory_impl.cc
index 5a74820..9778962 100644
--- a/chrome/browser/sync/profile_sync_components_factory_impl.cc
+++ b/chrome/browser/sync/profile_sync_components_factory_impl.cc
@@ -179,6 +179,24 @@ void ProfileSyncComponentsFactoryImpl::RegisterDataTypes(
#endif
}
+void ProfileSyncComponentsFactoryImpl::DisableBrokenType(
+ syncer::ModelType type,
+ const tracked_objects::Location& from_here,
+ const std::string& message) {
+ ProfileSyncService* p = ProfileSyncServiceFactory::GetForProfile(profile_);
+ syncer::SyncError error(
+ from_here, syncer::SyncError::DATATYPE_ERROR, message, type);
+ p->DisableDatatype(error);
+}
+
+DataTypeController::DisableTypeCallback
+ProfileSyncComponentsFactoryImpl::MakeDisableCallbackFor(
+ syncer::ModelType type) {
+ return base::Bind(&ProfileSyncComponentsFactoryImpl::DisableBrokenType,
+ weak_factory_.GetWeakPtr(),
+ type);
+}
+
void ProfileSyncComponentsFactoryImpl::RegisterCommonDataTypes(
syncer::ModelTypeSet disabled_types,
syncer::ModelTypeSet enabled_types,
@@ -187,14 +205,16 @@ void ProfileSyncComponentsFactoryImpl::RegisterCommonDataTypes(
// disabled.
if (!disabled_types.Has(syncer::AUTOFILL)) {
pss->RegisterDataTypeController(
- new AutofillDataTypeController(this, profile_));
+ new AutofillDataTypeController(
+ this, profile_, MakeDisableCallbackFor(syncer::AUTOFILL)));
}
// Autofill profile sync is enabled by default. Register unless explicitly
// disabled.
if (!disabled_types.Has(syncer::AUTOFILL_PROFILE)) {
pss->RegisterDataTypeController(
- new AutofillProfileDataTypeController(this, profile_));
+ new AutofillProfileDataTypeController(
+ this, profile_, MakeDisableCallbackFor(syncer::AUTOFILL_PROFILE)));
}
// Bookmark sync is enabled by default. Register unless explicitly
@@ -219,20 +239,23 @@ void ProfileSyncComponentsFactoryImpl::RegisterCommonDataTypes(
new UIDataTypeController(
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
base::Bind(&ChromeReportUnrecoverableError),
+ MakeDisableCallbackFor(syncer::HISTORY_DELETE_DIRECTIVES),
syncer::HISTORY_DELETE_DIRECTIVES,
this));
}
// Session sync is enabled by default. Register unless explicitly disabled.
if (!disabled_types.Has(syncer::PROXY_TABS)) {
- pss->RegisterDataTypeController(new ProxyDataTypeController(
- BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
- syncer::PROXY_TABS));
+ pss->RegisterDataTypeController(new ProxyDataTypeController(
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
+ syncer::PROXY_TABS));
pss->RegisterDataTypeController(
- new SessionDataTypeController(this,
- profile_,
- pss->GetSyncedWindowDelegatesGetter(),
- pss->GetLocalDeviceInfoProvider()));
+ new SessionDataTypeController(
+ this,
+ profile_,
+ pss->GetSyncedWindowDelegatesGetter(),
+ pss->GetLocalDeviceInfoProvider(),
+ MakeDisableCallbackFor(syncer::SESSIONS)));
}
// Favicon sync is enabled by default. Register unless explicitly disabled.
@@ -242,12 +265,14 @@ void ProfileSyncComponentsFactoryImpl::RegisterCommonDataTypes(
new UIDataTypeController(
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
base::Bind(&ChromeReportUnrecoverableError),
+ MakeDisableCallbackFor(syncer::FAVICON_IMAGES),
syncer::FAVICON_IMAGES,
this));
pss->RegisterDataTypeController(
new UIDataTypeController(
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
base::Bind(&ChromeReportUnrecoverableError),
+ MakeDisableCallbackFor(syncer::FAVICON_TRACKING),
syncer::FAVICON_TRACKING,
this));
}
@@ -256,7 +281,8 @@ void ProfileSyncComponentsFactoryImpl::RegisterCommonDataTypes(
// disabled.
if (!disabled_types.Has(syncer::PASSWORDS)) {
pss->RegisterDataTypeController(
- new PasswordDataTypeController(this, profile_));
+ new PasswordDataTypeController(
+ this, profile_, MakeDisableCallbackFor(syncer::PASSWORDS)));
}
// Article sync is disabled by default. Register only if explicitly enabled.
@@ -265,6 +291,7 @@ void ProfileSyncComponentsFactoryImpl::RegisterCommonDataTypes(
new UIDataTypeController(
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
base::Bind(&ChromeReportUnrecoverableError),
+ MakeDisableCallbackFor(syncer::ARTICLES),
syncer::ARTICLES,
this));
}
@@ -272,16 +299,19 @@ void ProfileSyncComponentsFactoryImpl::RegisterCommonDataTypes(
#if defined(ENABLE_MANAGED_USERS)
pss->RegisterDataTypeController(
new SupervisedUserSyncDataTypeController(
+ MakeDisableCallbackFor(syncer::SUPERVISED_USER_SETTINGS),
syncer::SUPERVISED_USER_SETTINGS,
this,
profile_));
pss->RegisterDataTypeController(
new SupervisedUserSyncDataTypeController(
+ MakeDisableCallbackFor(syncer::SUPERVISED_USERS),
syncer::SUPERVISED_USERS,
this,
profile_));
pss->RegisterDataTypeController(
new SupervisedUserSyncDataTypeController(
+ MakeDisableCallbackFor(syncer::SUPERVISED_USER_SHARED_SETTINGS),
syncer::SUPERVISED_USER_SHARED_SETTINGS,
this,
profile_));
@@ -296,14 +326,17 @@ void ProfileSyncComponentsFactoryImpl::RegisterDesktopDataTypes(
// disabled.
if (!disabled_types.Has(syncer::APPS)) {
pss->RegisterDataTypeController(
- new ExtensionDataTypeController(syncer::APPS, this, profile_));
+ new ExtensionDataTypeController(syncer::APPS, this, profile_,
+ MakeDisableCallbackFor(syncer::APPS)));
}
// Extension sync is enabled by default. Register unless explicitly
// disabled.
if (!disabled_types.Has(syncer::EXTENSIONS)) {
pss->RegisterDataTypeController(
- new ExtensionDataTypeController(syncer::EXTENSIONS, this, profile_));
+ new ExtensionDataTypeController(
+ syncer::EXTENSIONS, this, profile_,
+ MakeDisableCallbackFor(syncer::EXTENSIONS)));
}
// Preference sync is enabled by default. Register unless explicitly
@@ -313,6 +346,7 @@ void ProfileSyncComponentsFactoryImpl::RegisterDesktopDataTypes(
new UIDataTypeController(
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
base::Bind(&ChromeReportUnrecoverableError),
+ MakeDisableCallbackFor(syncer::PREFERENCES),
syncer::PREFERENCES,
this));
}
@@ -322,6 +356,7 @@ void ProfileSyncComponentsFactoryImpl::RegisterDesktopDataTypes(
new UIDataTypeController(
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
base::Bind(&ChromeReportUnrecoverableError),
+ MakeDisableCallbackFor(syncer::PRIORITY_PREFERENCES),
syncer::PRIORITY_PREFERENCES,
this));
}
@@ -330,7 +365,8 @@ void ProfileSyncComponentsFactoryImpl::RegisterDesktopDataTypes(
// Theme sync is enabled by default. Register unless explicitly disabled.
if (!disabled_types.Has(syncer::THEMES)) {
pss->RegisterDataTypeController(
- new ThemeDataTypeController(this, profile_));
+ new ThemeDataTypeController(this, profile_,
+ MakeDisableCallbackFor(syncer::THEMES)));
}
#endif
@@ -338,21 +374,26 @@ void ProfileSyncComponentsFactoryImpl::RegisterDesktopDataTypes(
// disabled.
if (!disabled_types.Has(syncer::SEARCH_ENGINES)) {
pss->RegisterDataTypeController(
- new SearchEngineDataTypeController(this, profile_));
+ new SearchEngineDataTypeController(
+ this, profile_, MakeDisableCallbackFor(syncer::SEARCH_ENGINES)));
}
// Extension setting sync is enabled by default. Register unless explicitly
// disabled.
if (!disabled_types.Has(syncer::EXTENSION_SETTINGS)) {
- pss->RegisterDataTypeController(new ExtensionSettingDataTypeController(
- syncer::EXTENSION_SETTINGS, this, profile_));
+ pss->RegisterDataTypeController(
+ new ExtensionSettingDataTypeController(
+ syncer::EXTENSION_SETTINGS, this, profile_,
+ MakeDisableCallbackFor(syncer::EXTENSION_SETTINGS)));
}
// App setting sync is enabled by default. Register unless explicitly
// disabled.
if (!disabled_types.Has(syncer::APP_SETTINGS)) {
- pss->RegisterDataTypeController(new ExtensionSettingDataTypeController(
- syncer::APP_SETTINGS, this, profile_));
+ pss->RegisterDataTypeController(
+ new ExtensionSettingDataTypeController(
+ syncer::APP_SETTINGS, this, profile_,
+ MakeDisableCallbackFor(syncer::APP_SETTINGS)));
}
#if defined(ENABLE_APP_LIST)
@@ -361,6 +402,7 @@ void ProfileSyncComponentsFactoryImpl::RegisterDesktopDataTypes(
new UIDataTypeController(
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
base::Bind(&ChromeReportUnrecoverableError),
+ MakeDisableCallbackFor(syncer::APP_LIST),
syncer::APP_LIST,
this));
}
@@ -371,6 +413,7 @@ void ProfileSyncComponentsFactoryImpl::RegisterDesktopDataTypes(
if (enabled_types.Has(syncer::SYNCED_NOTIFICATIONS)) {
pss->RegisterDataTypeController(
new ExtensionBackedDataTypeController(
+ MakeDisableCallbackFor(syncer::SYNCED_NOTIFICATIONS),
syncer::SYNCED_NOTIFICATIONS,
"", // TODO(dewittj): pass the extension hash here.
this,
@@ -378,6 +421,7 @@ void ProfileSyncComponentsFactoryImpl::RegisterDesktopDataTypes(
pss->RegisterDataTypeController(
new ExtensionBackedDataTypeController(
+ MakeDisableCallbackFor(syncer::SYNCED_NOTIFICATION_APP_INFO),
syncer::SYNCED_NOTIFICATION_APP_INFO,
"", // TODO(dewittj): pass the extension hash here.
this,
@@ -392,6 +436,7 @@ void ProfileSyncComponentsFactoryImpl::RegisterDesktopDataTypes(
new UIDataTypeController(
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
base::Bind(&ChromeReportUnrecoverableError),
+ MakeDisableCallbackFor(syncer::DICTIONARY),
syncer::DICTIONARY,
this));
}
diff --git a/chrome/browser/sync/profile_sync_service.cc b/chrome/browser/sync/profile_sync_service.cc
index 4f5353e..79defa9 100644
--- a/chrome/browser/sync/profile_sync_service.cc
+++ b/chrome/browser/sync/profile_sync_service.cc
@@ -951,6 +951,24 @@ void ProfileSyncService::OnUnrecoverableErrorImpl(
syncer::DISABLE_SYNC : syncer::STOP_SYNC));
}
+// TODO(zea): Move this logic into the DataTypeController/DataTypeManager.
+void ProfileSyncService::DisableDatatype(const syncer::SyncError& error) {
+ // First deactivate the type so that no further server changes are
+ // passed onto the change processor.
+ DeactivateDataType(error.model_type());
+
+ std::map<syncer::ModelType, syncer::SyncError> errors;
+ errors[error.model_type()] = error;
+
+ // Update this before posting a task. So if a configure happens before
+ // the task that we are going to post, this type would still be disabled.
+ failed_data_types_handler_.UpdateFailedDataTypes(errors);
+
+ base::MessageLoop::current()->PostTask(FROM_HERE,
+ base::Bind(&ProfileSyncService::ReconfigureDatatypeManager,
+ weak_factory_.GetWeakPtr()));
+}
+
void ProfileSyncService::ReenableDatatype(syncer::ModelType type) {
// Only reconfigure if the type actually had a data type or unready error.
if (!failed_data_types_handler_.ResetDataTypeErrorFor(type) &&
@@ -1366,10 +1384,7 @@ void ProfileSyncService::OnEncryptedTypesChanged(
syncer::SyncError::DATATYPE_POLICY_ERROR,
"Delete directives not supported with encryption.",
syncer::HISTORY_DELETE_DIRECTIVES);
- FailedDataTypesHandler::TypeErrorMap error_map;
- error_map[error.model_type()] = error;
- failed_data_types_handler_.UpdateFailedDataTypes(error_map);
- ReconfigureDatatypeManager();
+ DisableDatatype(error);
}
}
@@ -1777,9 +1792,7 @@ void ProfileSyncService::OnUserChoseDatatypes(
syncer::SyncError::DATATYPE_POLICY_ERROR,
"Delete directives not supported with encryption.",
syncer::HISTORY_DELETE_DIRECTIVES);
- FailedDataTypesHandler::TypeErrorMap error_map;
- error_map[error.model_type()] = error;
- failed_data_types_handler_.UpdateFailedDataTypes(error_map);
+ DisableDatatype(error);
}
ChangePreferredDataTypes(chosen_types);
AcknowledgeSyncedTypes();
diff --git a/chrome/browser/sync/profile_sync_service.h b/chrome/browser/sync/profile_sync_service.h
index 98d3254..455075d 100644
--- a/chrome/browser/sync/profile_sync_service.h
+++ b/chrome/browser/sync/profile_sync_service.h
@@ -558,6 +558,11 @@ class ProfileSyncService : public ProfileSyncServiceBase,
const tracked_objects::Location& from_here,
const std::string& message) OVERRIDE;
+ // Called when a datatype wishes to disable itself. The datatype to be
+ // disabled is passed via |error.model_type()|. Note, this does not change
+ // preferred state of a datatype and is not persisted across restarts.
+ virtual void DisableDatatype(const syncer::SyncError& error);
+
// Called to re-enable a type disabled by DisableDatatype(..). Note, this does
// not change the preferred state of a datatype, and is not persisted across
// restarts.
diff --git a/chrome/browser/sync/profile_sync_service_autofill_unittest.cc b/chrome/browser/sync/profile_sync_service_autofill_unittest.cc
index 8c7cddf..fd9d5ec 100644
--- a/chrome/browser/sync/profile_sync_service_autofill_unittest.cc
+++ b/chrome/browser/sync/profile_sync_service_autofill_unittest.cc
@@ -392,7 +392,10 @@ class AutofillEntryFactory : public AbstractAutofillFactory {
ProfileSyncComponentsFactory* factory,
TestingProfile* profile,
ProfileSyncService* service) OVERRIDE {
- return new AutofillDataTypeController(factory, profile);
+ return new AutofillDataTypeController(
+ factory,
+ profile,
+ DataTypeController::DisableTypeCallback());
}
virtual void SetExpectation(ProfileSyncComponentsFactoryMock* factory,
@@ -410,7 +413,10 @@ class AutofillProfileFactory : public AbstractAutofillFactory {
ProfileSyncComponentsFactory* factory,
TestingProfile* profile,
ProfileSyncService* service) OVERRIDE {
- return new AutofillProfileDataTypeController(factory, profile);
+ return new AutofillProfileDataTypeController(
+ factory,
+ profile,
+ DataTypeController::DisableTypeCallback());
}
virtual void SetExpectation(ProfileSyncComponentsFactoryMock* factory,
diff --git a/chrome/browser/sync/profile_sync_service_bookmark_unittest.cc b/chrome/browser/sync/profile_sync_service_bookmark_unittest.cc
index f276ac8..f0adb7c 100644
--- a/chrome/browser/sync/profile_sync_service_bookmark_unittest.cc
+++ b/chrome/browser/sync/profile_sync_service_bookmark_unittest.cc
@@ -1163,7 +1163,7 @@ TEST_F(ProfileSyncServiceBookmarkTest, RepeatedMiddleInsertion) {
// puts itself into a lame, error state.
TEST_F(ProfileSyncServiceBookmarkTest, UnrecoverableErrorSuspendsService) {
EXPECT_CALL(mock_error_handler_,
- OnSingleDataTypeUnrecoverableError(_));
+ OnSingleDatatypeUnrecoverableError(_, _));
LoadBookmarkModel(DELETE_EXISTING_STORAGE, DONT_SAVE_TO_STORAGE);
StartSync();
diff --git a/chrome/browser/sync/sessions/session_data_type_controller.cc b/chrome/browser/sync/sessions/session_data_type_controller.cc
index 24930ad..466ece1 100644
--- a/chrome/browser/sync/sessions/session_data_type_controller.cc
+++ b/chrome/browser/sync/sessions/session_data_type_controller.cc
@@ -22,10 +22,12 @@ SessionDataTypeController::SessionDataTypeController(
sync_driver::SyncApiComponentFactory* sync_factory,
Profile* profile,
SyncedWindowDelegatesGetter* synced_window_getter,
- LocalDeviceInfoProvider* local_device)
+ LocalDeviceInfoProvider* local_device,
+ const DisableTypeCallback& disable_callback)
: UIDataTypeController(
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
base::Bind(&ChromeReportUnrecoverableError),
+ disable_callback,
syncer::SESSIONS,
sync_factory),
profile_(profile),
diff --git a/chrome/browser/sync/sessions/session_data_type_controller.h b/chrome/browser/sync/sessions/session_data_type_controller.h
index 3ba97f4..851fa28 100644
--- a/chrome/browser/sync/sessions/session_data_type_controller.h
+++ b/chrome/browser/sync/sessions/session_data_type_controller.h
@@ -25,7 +25,8 @@ class SessionDataTypeController : public sync_driver::UIDataTypeController,
SessionDataTypeController(sync_driver::SyncApiComponentFactory* factory,
Profile* profile,
SyncedWindowDelegatesGetter* synced_window_getter,
- LocalDeviceInfoProvider* local_device);
+ LocalDeviceInfoProvider* local_device,
+ const DisableTypeCallback& disable_callback);
// NotificationObserver interface.
virtual void Observe(int type,
diff --git a/chrome/browser/sync/sessions/session_data_type_controller_unittest.cc b/chrome/browser/sync/sessions/session_data_type_controller_unittest.cc
index 5044803..4b86bab 100644
--- a/chrome/browser/sync/sessions/session_data_type_controller_unittest.cc
+++ b/chrome/browser/sync/sessions/session_data_type_controller_unittest.cc
@@ -103,7 +103,8 @@ class SessionDataTypeControllerTest
&profile_sync_factory_,
&profile_,
synced_window_getter_.get(),
- local_device_.get());
+ local_device_.get(),
+ sync_driver::DataTypeController::DisableTypeCallback());
load_finished_ = false;
last_type_ = syncer::UNSPECIFIED;
diff --git a/components/sync_driver/change_processor_mock.h b/components/sync_driver/change_processor_mock.h
index 7acf83f..aaa7e82d 100644
--- a/components/sync_driver/change_processor_mock.h
+++ b/components/sync_driver/change_processor_mock.h
@@ -25,8 +25,9 @@ class ChangeProcessorMock
MOCK_CONST_METHOD0(IsRunning, bool());
MOCK_METHOD2(OnUnrecoverableError, void(const tracked_objects::Location&,
const std::string&));
- MOCK_METHOD1(OnSingleDataTypeUnrecoverableError,
- void(const syncer::SyncError&));
+ MOCK_METHOD2(OnSingleDatatypeUnrecoverableError,
+ void(const tracked_objects::Location&,
+ const std::string&));
MOCK_METHOD3(CreateAndUploadError,
syncer::SyncError(const tracked_objects::Location&,
const std::string&,
diff --git a/components/sync_driver/data_type_controller.cc b/components/sync_driver/data_type_controller.cc
index db26151..3f7a681 100644
--- a/components/sync_driver/data_type_controller.cc
+++ b/components/sync_driver/data_type_controller.cc
@@ -12,9 +12,11 @@ namespace sync_driver {
DataTypeController::DataTypeController(
scoped_refptr<base::MessageLoopProxy> ui_thread,
- const base::Closure& error_callback)
+ const base::Closure& error_callback,
+ const DisableTypeCallback& disable_callback)
: base::RefCountedDeleteOnMessageLoop<DataTypeController>(ui_thread),
error_callback_(error_callback),
+ disable_callback_(disable_callback),
user_share_(NULL) {
}
@@ -49,6 +51,11 @@ syncer::UserShare* DataTypeController::user_share() const {
return user_share_;
}
+DataTypeController::DisableTypeCallback
+DataTypeController::disable_callback() {
+ return disable_callback_;
+}
+
bool DataTypeController::ReadyForStart() const {
return true;
}
diff --git a/components/sync_driver/data_type_controller.h b/components/sync_driver/data_type_controller.h
index a673b1f..7d8b67c 100644
--- a/components/sync_driver/data_type_controller.h
+++ b/components/sync_driver/data_type_controller.h
@@ -149,7 +149,8 @@ class DataTypeController
friend class base::DeleteHelper<DataTypeController>;
DataTypeController(scoped_refptr<base::MessageLoopProxy> ui_thread,
- const base::Closure& error_callback);
+ const base::Closure& error_callback,
+ const DisableTypeCallback& disable_callback);
// If the DTC is waiting for models to load, once the models are
// loaded the datatype service will call this function on DTC to let
@@ -159,12 +160,16 @@ class DataTypeController
virtual ~DataTypeController();
syncer::UserShare* user_share() const;
+ DisableTypeCallback disable_callback();
// The callback that will be invoked when an unrecoverable error occurs.
// TODO(sync): protected for use by legacy controllers.
base::Closure error_callback_;
private:
+ // TODO(tim): Bug 383480. Do we need two callbacks?
+ DisableTypeCallback disable_callback_;
+
syncer::UserShare* user_share_;
};
diff --git a/components/sync_driver/data_type_error_handler.h b/components/sync_driver/data_type_error_handler.h
index 174b9a8..a33a151 100644
--- a/components/sync_driver/data_type_error_handler.h
+++ b/components/sync_driver/data_type_error_handler.h
@@ -18,8 +18,9 @@ class DataTypeErrorHandler {
public:
// Call this to disable a datatype while it is running. This is usually
// called for a runtime failure that is specific to a datatype.
- virtual void OnSingleDataTypeUnrecoverableError(
- const syncer::SyncError& error) = 0;
+ virtual void OnSingleDatatypeUnrecoverableError(
+ const tracked_objects::Location& from_here,
+ const std::string& message) = 0;
// This will create a syncer::SyncError object. This will also upload
// a breakpad call stack to crash server. A sync error usually means
diff --git a/components/sync_driver/data_type_error_handler_mock.h b/components/sync_driver/data_type_error_handler_mock.h
index a5cd6d4..6e70e2b 100644
--- a/components/sync_driver/data_type_error_handler_mock.h
+++ b/components/sync_driver/data_type_error_handler_mock.h
@@ -14,8 +14,8 @@ class DataTypeErrorHandlerMock : public DataTypeErrorHandler {
public:
DataTypeErrorHandlerMock();
virtual ~DataTypeErrorHandlerMock();
- MOCK_METHOD1(OnSingleDataTypeUnrecoverableError,
- void(const syncer::SyncError&));
+ MOCK_METHOD2(OnSingleDatatypeUnrecoverableError,
+ void(const tracked_objects::Location&, const std::string&));
MOCK_METHOD3(CreateAndUploadError,
syncer::SyncError(const tracked_objects::Location&,
const std::string&,
diff --git a/components/sync_driver/fake_data_type_controller.cc b/components/sync_driver/fake_data_type_controller.cc
index 897e77a..5ba1c4c 100644
--- a/components/sync_driver/fake_data_type_controller.cc
+++ b/components/sync_driver/fake_data_type_controller.cc
@@ -12,7 +12,8 @@ using syncer::ModelType;
namespace sync_driver {
FakeDataTypeController::FakeDataTypeController(ModelType type)
- : DataTypeController(base::MessageLoopProxy::current(), base::Closure()),
+ : DataTypeController(base::MessageLoopProxy::current(), base::Closure(),
+ DisableTypeCallback()),
state_(NOT_RUNNING),
model_load_delayed_(false),
type_(type),
@@ -136,8 +137,11 @@ DataTypeController::State FakeDataTypeController::state() const {
return state_;
}
-void FakeDataTypeController::OnSingleDataTypeUnrecoverableError(
- const syncer::SyncError& error) {
+void FakeDataTypeController::OnSingleDatatypeUnrecoverableError(
+ const tracked_objects::Location& from_here,
+ const std::string& message) {
+ syncer::SyncError error(
+ from_here, syncer::SyncError::DATATYPE_ERROR, message, type_);
syncer::SyncMergeResult local_merge_result(type());
local_merge_result.set_error(error);
last_start_callback_.Run(
diff --git a/components/sync_driver/fake_data_type_controller.h b/components/sync_driver/fake_data_type_controller.h
index a84bc27..840a5b2 100644
--- a/components/sync_driver/fake_data_type_controller.h
+++ b/components/sync_driver/fake_data_type_controller.h
@@ -33,8 +33,9 @@ class FakeDataTypeController : public DataTypeController {
virtual syncer::ModelSafeGroup model_safe_group() const OVERRIDE;
virtual ChangeProcessor* GetChangeProcessor() const OVERRIDE;
virtual State state() const OVERRIDE;
- virtual void OnSingleDataTypeUnrecoverableError(
- const syncer::SyncError& error) OVERRIDE;
+ virtual void OnSingleDatatypeUnrecoverableError(
+ const tracked_objects::Location& from_here,
+ const std::string& message) OVERRIDE;
virtual bool ReadyForStart() const OVERRIDE;
void FinishStart(ConfigureResult result);
diff --git a/components/sync_driver/generic_change_processor.cc b/components/sync_driver/generic_change_processor.cc
index c44ce72..d7a5c6e 100644
--- a/components/sync_driver/generic_change_processor.cc
+++ b/components/sync_driver/generic_change_processor.cc
@@ -144,13 +144,10 @@ void GenericChangeProcessor::ApplyChangesFromSyncModel(
// Need to load specifics from node.
syncer::ReadNode read_node(trans);
if (read_node.InitByIdLookup(it->id) != syncer::BaseNode::INIT_OK) {
- syncer::SyncError error(
+ error_handler()->OnSingleDatatypeUnrecoverableError(
FROM_HERE,
- syncer::SyncError::DATATYPE_ERROR,
"Failed to look up data for received change with id " +
- base::Int64ToString(it->id),
- syncer::GetModelTypeFromSpecifics(it->specifics));
- error_handler()->OnSingleDataTypeUnrecoverableError(error);
+ base::Int64ToString(it->id));
return;
}
syncer_changes_.push_back(syncer::SyncChange(
@@ -171,14 +168,17 @@ void GenericChangeProcessor::CommitChangesFromSyncModel() {
syncer::SyncError::DATATYPE_ERROR,
"Local service destroyed.",
type);
- error_handler()->OnSingleDataTypeUnrecoverableError(error);
+ error_handler()->OnSingleDatatypeUnrecoverableError(error.location(),
+ error.message());
return;
}
syncer::SyncError error = local_service_->ProcessSyncChanges(FROM_HERE,
syncer_changes_);
syncer_changes_.clear();
- if (error.IsSet())
- error_handler()->OnSingleDataTypeUnrecoverableError(error);
+ if (error.IsSet()) {
+ error_handler()->OnSingleDatatypeUnrecoverableError(
+ error.location(), error.message());
+ }
}
syncer::SyncDataList GenericChangeProcessor::GetAllSyncData(
@@ -285,8 +285,9 @@ int GenericChangeProcessor::GetSyncCountForType(syncer::ModelType type) {
namespace {
+// TODO(isherman): Investigating http://crbug.com/121592
// WARNING: this code is sensitive to compiler optimizations. Be careful
-// modifying any code around an OnSingleDataTypeUnrecoverableError call, else
+// modifying any code around an OnSingleDatatypeUnrecoverableError call, else
// the compiler attempts to merge it with other calls, losing useful information
// in breakpad uploads.
syncer::SyncError LogLookupFailure(
@@ -302,21 +303,24 @@ syncer::SyncError LogLookupFailure(
error_prefix +
"could not find entry matching the lookup criteria.",
type);
- error_handler->OnSingleDataTypeUnrecoverableError(error);
+ error_handler->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ error.message());
LOG(ERROR) << "Delete: Bad entry.";
return error;
}
case syncer::BaseNode::INIT_FAILED_ENTRY_IS_DEL: {
syncer::SyncError error;
error.Reset(from_here, error_prefix + "entry is already deleted.", type);
- error_handler->OnSingleDataTypeUnrecoverableError(error);
+ error_handler->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ error.message());
LOG(ERROR) << "Delete: Deleted entry.";
return error;
}
case syncer::BaseNode::INIT_FAILED_DECRYPT_IF_NECESSARY: {
syncer::SyncError error;
error.Reset(from_here, error_prefix + "unable to decrypt", type);
- error_handler->OnSingleDataTypeUnrecoverableError(error);
+ error_handler->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ error.message());
LOG(ERROR) << "Delete: Undecryptable entry.";
return error;
}
@@ -325,7 +329,8 @@ syncer::SyncError LogLookupFailure(
error.Reset(from_here,
error_prefix + "a precondition was not met for calling init.",
type);
- error_handler->OnSingleDataTypeUnrecoverableError(error);
+ error_handler->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ error.message());
LOG(ERROR) << "Delete: Failed precondition.";
return error;
}
@@ -333,7 +338,8 @@ syncer::SyncError LogLookupFailure(
syncer::SyncError error;
// Should have listed all the possible error cases above.
error.Reset(from_here, error_prefix + "unknown error", type);
- error_handler->OnSingleDataTypeUnrecoverableError(error);
+ error_handler->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ error.message());
LOG(ERROR) << "Delete: Unknown error.";
return error;
}
@@ -355,7 +361,8 @@ syncer::SyncError AttemptDelete(const syncer::SyncChange& change,
"Failed to delete " + type_str + " node. Local data, empty tag. " +
change.location().ToString(),
type);
- error_handler->OnSingleDataTypeUnrecoverableError(error);
+ error_handler->OnSingleDatatypeUnrecoverableError(error.location(),
+ error.message());
NOTREACHED();
return error;
}
@@ -457,7 +464,8 @@ syncer::SyncError GenericChangeProcessor::ProcessSyncChanges(
"Received unset SyncChange in the change processor, " +
change.location().ToString(),
type);
- error_handler()->OnSingleDataTypeUnrecoverableError(error);
+ error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ error.message());
NOTREACHED();
LOG(ERROR) << "Unset sync change.";
return error;
@@ -472,7 +480,7 @@ syncer::SyncError GenericChangeProcessor::ProcessSyncChanges(
}
// WARNING: this code is sensitive to compiler optimizations. Be careful
-// modifying any code around an OnSingleDataTypeUnrecoverableError call, else
+// modifying any code around an OnSingleDatatypeUnrecoverableError call, else
// the compiler attempts to merge it with other calls, losing useful information
// in breakpad uploads.
syncer::SyncError GenericChangeProcessor::HandleActionAdd(
@@ -492,7 +500,8 @@ syncer::SyncError GenericChangeProcessor::HandleActionAdd(
syncer::SyncError::DATATYPE_ERROR,
"Failed to look up root node for type " + type_str,
type);
- error_handler()->OnSingleDataTypeUnrecoverableError(error);
+ error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ error.message());
NOTREACHED();
LOG(ERROR) << "Create: no root node.";
return error;
@@ -507,21 +516,24 @@ syncer::SyncError GenericChangeProcessor::HandleActionAdd(
case syncer::WriteNode::INIT_FAILED_EMPTY_TAG: {
syncer::SyncError error;
error.Reset(FROM_HERE, error_prefix + "empty tag", type);
- error_handler()->OnSingleDataTypeUnrecoverableError(error);
+ error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ error.message());
LOG(ERROR) << "Create: Empty tag.";
return error;
}
case syncer::WriteNode::INIT_FAILED_ENTRY_ALREADY_EXISTS: {
syncer::SyncError error;
error.Reset(FROM_HERE, error_prefix + "entry already exists", type);
- error_handler()->OnSingleDataTypeUnrecoverableError(error);
+ error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ error.message());
LOG(ERROR) << "Create: Entry exists.";
return error;
}
case syncer::WriteNode::INIT_FAILED_COULD_NOT_CREATE_ENTRY: {
syncer::SyncError error;
error.Reset(FROM_HERE, error_prefix + "failed to create entry", type);
- error_handler()->OnSingleDataTypeUnrecoverableError(error);
+ error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ error.message());
LOG(ERROR) << "Create: Could not create entry.";
return error;
}
@@ -529,14 +541,16 @@ syncer::SyncError GenericChangeProcessor::HandleActionAdd(
syncer::SyncError error;
error.Reset(
FROM_HERE, error_prefix + "failed to set predecessor", type);
- error_handler()->OnSingleDataTypeUnrecoverableError(error);
+ error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ error.message());
LOG(ERROR) << "Create: Bad predecessor.";
return error;
}
default: {
syncer::SyncError error;
error.Reset(FROM_HERE, error_prefix + "unknown error", type);
- error_handler()->OnSingleDataTypeUnrecoverableError(error);
+ error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ error.message());
LOG(ERROR) << "Create: Unknown error.";
return error;
}
@@ -561,7 +575,7 @@ syncer::SyncError GenericChangeProcessor::HandleActionAdd(
return syncer::SyncError();
}
// WARNING: this code is sensitive to compiler optimizations. Be careful
-// modifying any code around an OnSingleDataTypeUnrecoverableError call, else
+// modifying any code around an OnSingleDatatypeUnrecoverableError call, else
// the compiler attempts to merge it with other calls, losing useful information
// in breakpad uploads.
syncer::SyncError GenericChangeProcessor::HandleActionUpdate(
@@ -583,19 +597,22 @@ syncer::SyncError GenericChangeProcessor::HandleActionUpdate(
if (result == syncer::BaseNode::INIT_FAILED_PRECONDITION) {
syncer::SyncError error;
error.Reset(FROM_HERE, error_prefix + "empty tag", type);
- error_handler()->OnSingleDataTypeUnrecoverableError(error);
+ error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ error.message());
LOG(ERROR) << "Update: Empty tag.";
return error;
} else if (result == syncer::BaseNode::INIT_FAILED_ENTRY_NOT_GOOD) {
syncer::SyncError error;
error.Reset(FROM_HERE, error_prefix + "bad entry", type);
- error_handler()->OnSingleDataTypeUnrecoverableError(error);
+ error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ error.message());
LOG(ERROR) << "Update: bad entry.";
return error;
} else if (result == syncer::BaseNode::INIT_FAILED_ENTRY_IS_DEL) {
syncer::SyncError error;
error.Reset(FROM_HERE, error_prefix + "deleted entry", type);
- error_handler()->OnSingleDataTypeUnrecoverableError(error);
+ error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ error.message());
LOG(ERROR) << "Update: deleted entry.";
return error;
} else {
@@ -613,7 +630,8 @@ syncer::SyncError GenericChangeProcessor::HandleActionUpdate(
"nigori mismatch for " +
type_str + ".",
type);
- error_handler()->OnSingleDataTypeUnrecoverableError(error);
+ error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ error.message());
LOG(ERROR) << "Update: encr case 1.";
return error;
} else if (agreement && can_decrypt) {
@@ -623,7 +641,8 @@ syncer::SyncError GenericChangeProcessor::HandleActionUpdate(
"and the nigori matches (?!) for " +
type_str + ".",
type);
- error_handler()->OnSingleDataTypeUnrecoverableError(error);
+ error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ error.message());
LOG(ERROR) << "Update: encr case 2.";
return error;
} else if (agreement) {
@@ -633,7 +652,8 @@ syncer::SyncError GenericChangeProcessor::HandleActionUpdate(
"the nigori matches for " +
type_str + ".",
type);
- error_handler()->OnSingleDataTypeUnrecoverableError(error);
+ error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ error.message());
LOG(ERROR) << "Update: encr case 3.";
return error;
} else {
@@ -643,7 +663,8 @@ syncer::SyncError GenericChangeProcessor::HandleActionUpdate(
"(?!) and nigori mismatch for " +
type_str + ".",
type);
- error_handler()->OnSingleDataTypeUnrecoverableError(error);
+ error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
+ error.message());
LOG(ERROR) << "Update: encr case 4.";
return error;
}
diff --git a/components/sync_driver/model_association_manager_unittest.cc b/components/sync_driver/model_association_manager_unittest.cc
index 5c26319..906d99b 100644
--- a/components/sync_driver/model_association_manager_unittest.cc
+++ b/components/sync_driver/model_association_manager_unittest.cc
@@ -339,12 +339,8 @@ TEST_F(SyncModelAssociationManagerTest, StopAfterConfiguration) {
testing::Mock::VerifyAndClearExpectations(&delegate_);
EXPECT_CALL(delegate_,
OnSingleDataTypeWillStop(syncer::BOOKMARKS, _));
- syncer::SyncError error(FROM_HERE,
- syncer::SyncError::DATATYPE_ERROR,
- "error",
- syncer::BOOKMARKS);
GetController(controllers_, syncer::BOOKMARKS)
- ->OnSingleDataTypeUnrecoverableError(error);
+ ->OnSingleDatatypeUnrecoverableError(FROM_HERE, "runtime error");
}
} // namespace sync_driver
diff --git a/components/sync_driver/non_ui_data_type_controller.cc b/components/sync_driver/non_ui_data_type_controller.cc
index 67edb40..211f142 100644
--- a/components/sync_driver/non_ui_data_type_controller.cc
+++ b/components/sync_driver/non_ui_data_type_controller.cc
@@ -24,8 +24,9 @@ NonUIDataTypeController::CreateSharedChangeProcessor() {
NonUIDataTypeController::NonUIDataTypeController(
scoped_refptr<base::MessageLoopProxy> ui_thread,
const base::Closure& error_callback,
+ const DisableTypeCallback& disable_callback,
SyncApiComponentFactory* sync_factory)
- : DataTypeController(ui_thread, error_callback),
+ : DataTypeController(ui_thread, error_callback, disable_callback),
sync_factory_(sync_factory),
state_(NOT_RUNNING),
ui_thread_(ui_thread) {
@@ -110,7 +111,6 @@ void NonUIDataTypeController::StartAssociating(
void NonUIDataTypeController::Stop() {
DCHECK(ui_thread_->BelongsToCurrentThread());
-
if (state() == NOT_RUNNING)
return;
@@ -166,20 +166,22 @@ DataTypeController::State NonUIDataTypeController::state() const {
return state_;
}
-void NonUIDataTypeController::OnSingleDataTypeUnrecoverableError(
- const syncer::SyncError& error) {
+void NonUIDataTypeController::OnSingleDatatypeUnrecoverableError(
+ const tracked_objects::Location& from_here, const std::string& message) {
DCHECK(!ui_thread_->BelongsToCurrentThread());
// TODO(tim): We double-upload some errors. See bug 383480.
if (!error_callback_.is_null())
error_callback_.Run();
- ui_thread_->PostTask(error.location(),
+ ui_thread_->PostTask(from_here,
base::Bind(&NonUIDataTypeController::DisableImpl,
this,
- error));
+ from_here,
+ message));
}
NonUIDataTypeController::NonUIDataTypeController()
- : DataTypeController(base::MessageLoopProxy::current(), base::Closure()),
+ : DataTypeController(base::MessageLoopProxy::current(), base::Closure(),
+ DisableTypeCallback()),
sync_factory_(NULL) {}
NonUIDataTypeController::~NonUIDataTypeController() {}
@@ -270,12 +272,15 @@ void NonUIDataTypeController::AbortModelLoad() {
}
void NonUIDataTypeController::DisableImpl(
- const syncer::SyncError& error) {
+ const tracked_objects::Location& from_here,
+ const std::string& message) {
DCHECK(ui_thread_->BelongsToCurrentThread());
UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeRunFailures",
ModelTypeToHistogramInt(type()),
syncer::MODEL_TYPE_COUNT);
if (!start_callback_.is_null()) {
+ syncer::SyncError error(
+ from_here, syncer::SyncError::DATATYPE_ERROR, message, type());
syncer::SyncMergeResult local_merge_result(type());
local_merge_result.set_error(error);
start_callback_.Run(RUNTIME_ERROR,
diff --git a/components/sync_driver/non_ui_data_type_controller.h b/components/sync_driver/non_ui_data_type_controller.h
index 0f4fdab..17a0dbe 100644
--- a/components/sync_driver/non_ui_data_type_controller.h
+++ b/components/sync_driver/non_ui_data_type_controller.h
@@ -27,6 +27,7 @@ class NonUIDataTypeController : public DataTypeController {
NonUIDataTypeController(
scoped_refptr<base::MessageLoopProxy> ui_thread,
const base::Closure& error_callback,
+ const DisableTypeCallback& disable_callback,
SyncApiComponentFactory* sync_factory);
// DataTypeController interface.
@@ -39,8 +40,9 @@ class NonUIDataTypeController : public DataTypeController {
virtual ChangeProcessor* GetChangeProcessor() const OVERRIDE;
virtual std::string name() const OVERRIDE;
virtual State state() const OVERRIDE;
- virtual void OnSingleDataTypeUnrecoverableError(
- const syncer::SyncError& error) OVERRIDE;
+ virtual void OnSingleDatatypeUnrecoverableError(
+ const tracked_objects::Location& from_here,
+ const std::string& message) OVERRIDE;
protected:
// For testing only.
@@ -123,7 +125,8 @@ class NonUIDataTypeController : public DataTypeController {
// Disable this type with the sync service. Should only be invoked in case of
// an unrecoverable error.
// Note: this is performed on the UI thread.
- void DisableImpl(const syncer::SyncError& error);
+ void DisableImpl(const tracked_objects::Location& from_here,
+ const std::string& message);
SyncApiComponentFactory* const sync_factory_;
diff --git a/components/sync_driver/non_ui_data_type_controller_mock.h b/components/sync_driver/non_ui_data_type_controller_mock.h
index 3716a35..1369c33 100644
--- a/components/sync_driver/non_ui_data_type_controller_mock.h
+++ b/components/sync_driver/non_ui_data_type_controller_mock.h
@@ -26,8 +26,9 @@ class NonUIDataTypeControllerMock
MOCK_CONST_METHOD0(name, std::string());
MOCK_CONST_METHOD0(model_safe_group, syncer::ModelSafeGroup());
MOCK_CONST_METHOD0(state, State());
- MOCK_METHOD1(OnSingleDataTypeUnrecoverableError,
- void(const syncer::SyncError& error));
+ MOCK_METHOD2(OnSingleDataTypeUnrecoverableError,
+ void(const tracked_objects::Location&,
+ const std::string&));
// NonUIDataTypeController mocks.
MOCK_METHOD0(StartModels, bool());
diff --git a/components/sync_driver/non_ui_data_type_controller_unittest.cc b/components/sync_driver/non_ui_data_type_controller_unittest.cc
index 875523d..021db41 100644
--- a/components/sync_driver/non_ui_data_type_controller_unittest.cc
+++ b/components/sync_driver/non_ui_data_type_controller_unittest.cc
@@ -96,10 +96,12 @@ class NonUIDataTypeControllerFake
SyncApiComponentFactory* sync_factory,
NonUIDataTypeControllerMock* mock,
SharedChangeProcessor* change_processor,
+ const DisableTypeCallback& disable_callback,
scoped_refptr<base::MessageLoopProxy> backend_loop)
: NonUIDataTypeController(
base::MessageLoopProxy::current(),
base::Closure(),
+ disable_callback,
sync_factory),
blocked_(false),
mock_(mock),
@@ -186,17 +188,22 @@ class NonUIDataTypeControllerFake
class SyncNonUIDataTypeControllerTest : public testing::Test {
public:
SyncNonUIDataTypeControllerTest()
- : backend_thread_("dbthread") {}
+ : backend_thread_("dbthread"),
+ disable_callback_invoked_(false) {}
virtual void SetUp() OVERRIDE {
backend_thread_.Start();
change_processor_ = new SharedChangeProcessorMock();
// All of these are refcounted, so don't need to be released.
dtc_mock_ = new StrictMock<NonUIDataTypeControllerMock>();
+ DataTypeController::DisableTypeCallback disable_callback =
+ base::Bind(&SyncNonUIDataTypeControllerTest::DisableTypeCallback,
+ base::Unretained(this));
non_ui_dtc_ =
new NonUIDataTypeControllerFake(NULL,
dtc_mock_.get(),
change_processor_,
+ disable_callback,
backend_thread_.message_loop_proxy());
}
@@ -264,6 +271,12 @@ class SyncNonUIDataTypeControllerTest : public testing::Test {
done->Signal();
}
+ void DisableTypeCallback(const tracked_objects::Location& location,
+ const std::string& message) {
+ disable_callback_invoked_ = true;
+ non_ui_dtc_->Stop();
+ }
+
base::MessageLoopForUI message_loop_;
base::Thread backend_thread_;
@@ -275,6 +288,8 @@ class SyncNonUIDataTypeControllerTest : public testing::Test {
scoped_refptr<NonUIDataTypeControllerMock> dtc_mock_;
scoped_refptr<SharedChangeProcessorMock> change_processor_;
scoped_ptr<syncer::SyncChangeProcessor> saved_change_processor_;
+
+ bool disable_callback_invoked_;
};
TEST_F(SyncNonUIDataTypeControllerTest, StartOk) {
@@ -481,7 +496,7 @@ TEST_F(SyncNonUIDataTypeControllerTest, StopStart) {
EXPECT_EQ(DataTypeController::RUNNING, non_ui_dtc_->state());
}
-TEST_F(SyncNonUIDataTypeControllerTest, OnSingleDataTypeUnrecoverableError) {
+TEST_F(SyncNonUIDataTypeControllerTest, OnSingleDatatypeUnrecoverableError) {
SetStartExpectations();
SetAssociateExpectations();
SetActivateExpectations(DataTypeController::OK);
@@ -492,15 +507,12 @@ TEST_F(SyncNonUIDataTypeControllerTest, OnSingleDataTypeUnrecoverableError) {
testing::Mock::VerifyAndClearExpectations(&start_callback_);
EXPECT_CALL(start_callback_, Run(DataTypeController::RUNTIME_ERROR, _, _));
- syncer::SyncError error(FROM_HERE,
- syncer::SyncError::DATATYPE_ERROR,
- "error",
- non_ui_dtc_->type());
backend_thread_.message_loop_proxy()->PostTask(FROM_HERE, base::Bind(
&NonUIDataTypeControllerFake::
- OnSingleDataTypeUnrecoverableError,
+ OnSingleDatatypeUnrecoverableError,
non_ui_dtc_.get(),
- error));
+ FROM_HERE,
+ std::string("Test")));
WaitForDTC();
}
diff --git a/components/sync_driver/proxy_data_type_controller.cc b/components/sync_driver/proxy_data_type_controller.cc
index c017802..ae1ea53 100644
--- a/components/sync_driver/proxy_data_type_controller.cc
+++ b/components/sync_driver/proxy_data_type_controller.cc
@@ -9,7 +9,7 @@ namespace sync_driver {
ProxyDataTypeController::ProxyDataTypeController(
scoped_refptr<base::MessageLoopProxy> ui_thread,
syncer::ModelType type)
- : DataTypeController(ui_thread, base::Closure()),
+ : DataTypeController(ui_thread, base::Closure(), DisableTypeCallback()),
state_(NOT_RUNNING),
type_(type) {
DCHECK(syncer::ProxyTypes().Has(type_));
@@ -61,8 +61,8 @@ DataTypeController::State ProxyDataTypeController::state() const {
return state_;
}
-void ProxyDataTypeController::OnSingleDataTypeUnrecoverableError(
- const syncer::SyncError& error) {
+void ProxyDataTypeController::OnSingleDatatypeUnrecoverableError(
+ const tracked_objects::Location& from_here, const std::string& message) {
NOTIMPLEMENTED();
}
diff --git a/components/sync_driver/proxy_data_type_controller.h b/components/sync_driver/proxy_data_type_controller.h
index 6e255c6..e90ee24 100644
--- a/components/sync_driver/proxy_data_type_controller.h
+++ b/components/sync_driver/proxy_data_type_controller.h
@@ -32,8 +32,9 @@ class ProxyDataTypeController : public DataTypeController {
virtual State state() const OVERRIDE;
// DataTypeErrorHandler interface.
- virtual void OnSingleDataTypeUnrecoverableError(
- const syncer::SyncError& error) OVERRIDE;
+ virtual void OnSingleDatatypeUnrecoverableError(
+ const tracked_objects::Location& from_here,
+ const std::string& message) OVERRIDE;
protected:
// DataTypeController is RefCounted.
diff --git a/components/sync_driver/ui_data_type_controller.cc b/components/sync_driver/ui_data_type_controller.cc
index eca5779..3b7945c 100644
--- a/components/sync_driver/ui_data_type_controller.cc
+++ b/components/sync_driver/ui_data_type_controller.cc
@@ -17,7 +17,8 @@ namespace sync_driver {
UIDataTypeController::UIDataTypeController()
: DataTypeController(base::MessageLoopProxy::current(),
- base::Closure()),
+ base::Closure(),
+ DisableTypeCallback()),
sync_factory_(NULL),
state_(NOT_RUNNING),
type_(syncer::UNSPECIFIED) {
@@ -26,9 +27,10 @@ UIDataTypeController::UIDataTypeController()
UIDataTypeController::UIDataTypeController(
scoped_refptr<base::MessageLoopProxy> ui_thread,
const base::Closure& error_callback,
+ const DisableTypeCallback& disable_callback,
syncer::ModelType type,
SyncApiComponentFactory* sync_factory)
- : DataTypeController(ui_thread, error_callback),
+ : DataTypeController(ui_thread, error_callback, disable_callback),
sync_factory_(sync_factory),
state_(NOT_RUNNING),
type_(type),
@@ -267,9 +269,6 @@ void UIDataTypeController::Stop() {
DCHECK(ui_thread_->BelongsToCurrentThread());
DCHECK(syncer::IsRealDataType(type_));
- if (state_ == NOT_RUNNING)
- return;
-
State prev_state = state_;
state_ = STOPPING;
@@ -319,9 +318,8 @@ DataTypeController::State UIDataTypeController::state() const {
return state_;
}
-void UIDataTypeController::OnSingleDataTypeUnrecoverableError(
- const syncer::SyncError& error) {
- DCHECK_EQ(type(), error.model_type());
+void UIDataTypeController::OnSingleDatatypeUnrecoverableError(
+ const tracked_objects::Location& from_here, const std::string& message) {
UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeRunFailures",
ModelTypeToHistogramInt(type()),
syncer::MODEL_TYPE_COUNT);
@@ -329,6 +327,8 @@ void UIDataTypeController::OnSingleDataTypeUnrecoverableError(
if (!error_callback_.is_null())
error_callback_.Run();
if (!start_callback_.is_null()) {
+ syncer::SyncError error(
+ from_here, syncer::SyncError::DATATYPE_ERROR, message, type());
syncer::SyncMergeResult local_merge_result(type());
local_merge_result.set_error(error);
start_callback_.Run(RUNTIME_ERROR,
diff --git a/components/sync_driver/ui_data_type_controller.h b/components/sync_driver/ui_data_type_controller.h
index 3028991..ae7983e 100644
--- a/components/sync_driver/ui_data_type_controller.h
+++ b/components/sync_driver/ui_data_type_controller.h
@@ -34,6 +34,7 @@ class UIDataTypeController : public DataTypeController {
UIDataTypeController(
scoped_refptr<base::MessageLoopProxy> ui_thread,
const base::Closure& error_callback,
+ const DisableTypeCallback& disable_callback,
syncer::ModelType type,
SyncApiComponentFactory* sync_factory);
@@ -49,8 +50,9 @@ class UIDataTypeController : public DataTypeController {
virtual State state() const OVERRIDE;
// DataTypeErrorHandler interface.
- virtual void OnSingleDataTypeUnrecoverableError(
- const syncer::SyncError& error) OVERRIDE;
+ virtual void OnSingleDatatypeUnrecoverableError(
+ const tracked_objects::Location& from_here,
+ const std::string& message) OVERRIDE;
// Used by tests to override the factory used to create
// GenericChangeProcessors.
diff --git a/components/sync_driver/ui_data_type_controller_unittest.cc b/components/sync_driver/ui_data_type_controller_unittest.cc
index 20bd304..e1b6356 100644
--- a/components/sync_driver/ui_data_type_controller_unittest.cc
+++ b/components/sync_driver/ui_data_type_controller_unittest.cc
@@ -31,13 +31,17 @@ class SyncUIDataTypeControllerTest : public testing::Test,
public:
SyncUIDataTypeControllerTest()
: type_(syncer::PREFERENCES),
- change_processor_(NULL) {}
+ change_processor_(NULL),
+ disable_callback_invoked_(false) {}
virtual void SetUp() {
preference_dtc_ =
new UIDataTypeController(
base::MessageLoopProxy::current(),
base::Closure(),
+ base::Bind(&SyncUIDataTypeControllerTest::DisableTypeCallback,
+ base::Unretained(this),
+ type_),
type_,
this);
SetStartExpectations();
@@ -85,6 +89,13 @@ class SyncUIDataTypeControllerTest : public testing::Test,
message_loop_.RunUntilIdle();
}
+ void DisableTypeCallback(syncer::ModelType type,
+ const tracked_objects::Location& location,
+ const std::string& message) {
+ disable_callback_invoked_ = true;
+ preference_dtc_->Stop();
+ }
+
base::MessageLoopForUI message_loop_;
const syncer::ModelType type_;
StartCallbackMock start_callback_;
@@ -92,6 +103,7 @@ class SyncUIDataTypeControllerTest : public testing::Test,
scoped_refptr<UIDataTypeController> preference_dtc_;
FakeGenericChangeProcessor* change_processor_;
syncer::FakeSyncableService syncable_service_;
+ bool disable_callback_invoked_;
};
// Start the DTC. Verify that the callback is called with OK, the
@@ -188,11 +200,7 @@ TEST_F(SyncUIDataTypeControllerTest, OnSingleDatatypeUnrecoverableError) {
testing::Mock::VerifyAndClearExpectations(&start_callback_);
EXPECT_CALL(start_callback_, Run(DataTypeController::RUNTIME_ERROR, _, _));
- syncer::SyncError error(FROM_HERE,
- syncer::SyncError::DATATYPE_ERROR,
- "error",
- syncer::PREFERENCES);
- preference_dtc_->OnSingleDataTypeUnrecoverableError(error);
+ preference_dtc_->OnSingleDatatypeUnrecoverableError(FROM_HERE, "Test");
}
} // namespace