summaryrefslogtreecommitdiff
path: root/sync
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2014-04-16 11:17:03 +0100
committerBen Murdoch <benm@google.com>2014-04-16 11:17:03 +0100
commita02191e04bc25c4935f804f2c080ae28663d096d (patch)
tree3cf38961650b5734763e473336009287244306ac /sync
parent8bad47e0f7d0c250a0443923cceb52f4a4abcd40 (diff)
downloadchromium_org-a02191e04bc25c4935f804f2c080ae28663d096d.tar.gz
Merge from Chromium at DEPS revision 263965
This commit was generated by merge_to_master.py. Change-Id: Ia1121eddd985123f160afde6372525c3d25975bf
Diffstat (limited to 'sync')
-rw-r--r--sync/PRESUBMIT.py2
-rw-r--r--sync/api/attachments/attachment_service_proxy.cc77
-rw-r--r--sync/api/attachments/attachment_service_proxy.h69
-rw-r--r--sync/api/attachments/attachment_service_proxy_for_test.cc52
-rw-r--r--sync/api/attachments/attachment_service_proxy_for_test.h50
-rw-r--r--sync/api/sync_change_unittest.cc47
-rw-r--r--sync/api/sync_data.cc11
-rw-r--r--sync/api/sync_data.h7
-rw-r--r--sync/api/sync_data_unittest.cc10
-rw-r--r--sync/engine/all_status.cc16
-rw-r--r--sync/engine/backoff_delay_provider.cc8
-rw-r--r--sync/engine/backoff_delay_provider_unittest.cc8
-rw-r--r--sync/engine/directory_update_handler.cc22
-rw-r--r--sync/engine/directory_update_handler.h2
-rw-r--r--sync/engine/directory_update_handler_unittest.cc91
-rw-r--r--sync/engine/get_updates_processor.cc26
-rw-r--r--sync/engine/get_updates_processor.h2
-rw-r--r--sync/engine/non_blocking_type_processor_core.cc3
-rw-r--r--sync/engine/non_blocking_type_processor_core.h2
-rw-r--r--sync/engine/update_handler.h6
-rw-r--r--sync/internal_api/js_sync_encryption_handler_observer.cc1
-rw-r--r--sync/internal_api/js_sync_manager_observer.cc1
-rw-r--r--sync/internal_api/non_blocking_type_processor.cc5
-rw-r--r--sync/internal_api/public/engine/sync_status.cc6
-rw-r--r--sync/internal_api/public/engine/sync_status.h12
-rw-r--r--sync/internal_api/public/non_blocking_type_processor.h5
-rw-r--r--sync/internal_api/public/read_transaction.h10
-rw-r--r--sync/internal_api/public/sync_core_proxy.h35
-rw-r--r--sync/internal_api/public/sync_manager.h5
-rw-r--r--sync/internal_api/public/test/fake_sync_manager.h5
-rw-r--r--sync/internal_api/public/test/null_sync_core_proxy.h31
-rw-r--r--sync/internal_api/public/util/syncer_error.cc1
-rw-r--r--sync/internal_api/public/util/syncer_error.h3
-rw-r--r--sync/internal_api/read_transaction.cc9
-rw-r--r--sync/internal_api/sync_core_proxy.cc29
-rw-r--r--sync/internal_api/sync_core_proxy_impl.cc40
-rw-r--r--sync/internal_api/sync_core_proxy_impl.h55
-rw-r--r--sync/internal_api/sync_core_proxy_impl_unittest.cc (renamed from sync/internal_api/sync_core_proxy_unittest.cc)20
-rw-r--r--sync/internal_api/sync_manager_impl.cc22
-rw-r--r--sync/internal_api/sync_manager_impl.h10
-rw-r--r--sync/internal_api/test/fake_sync_manager.cc4
-rw-r--r--sync/internal_api/test/null_sync_core_proxy.cc23
-rw-r--r--sync/js/README.js64
-rw-r--r--sync/js/js_arg_list.cc27
-rw-r--r--sync/js/js_arg_list.h44
-rw-r--r--sync/js/js_arg_list_unittest.cc40
-rw-r--r--sync/js/js_backend.h8
-rw-r--r--sync/js/js_controller.h8
-rw-r--r--sync/js/js_reply_handler.h29
-rw-r--r--sync/js/js_test_util.cc47
-rw-r--r--sync/js/js_test_util.h26
-rw-r--r--sync/js/sync_js_controller.cc29
-rw-r--r--sync/js/sync_js_controller.h22
-rw-r--r--sync/js/sync_js_controller_unittest.cc86
-rw-r--r--sync/notifier/invalidation_util.h2
-rw-r--r--sync/protocol/autofill_specifics.proto1
-rw-r--r--sync/protocol/proto_value_conversions.cc1
-rw-r--r--sync/sync_api.gypi2
-rw-r--r--sync/sync_core.gypi3
-rw-r--r--sync/sync_internal_api.gypi2
-rw-r--r--sync/sync_tests.gypi5
-rw-r--r--sync/syncable/directory.cc25
-rw-r--r--sync/syncable/directory.h3
-rw-r--r--sync/syncable/syncable_unittest.cc33
-rw-r--r--sync/test/engine/mock_update_handler.cc3
-rw-r--r--sync/test/engine/mock_update_handler.h2
66 files changed, 701 insertions, 654 deletions
diff --git a/sync/PRESUBMIT.py b/sync/PRESUBMIT.py
index 80e88922f9..f82e95a543 100644
--- a/sync/PRESUBMIT.py
+++ b/sync/PRESUBMIT.py
@@ -13,6 +13,6 @@ def GetPreferredTryMasters(project, change):
'tryserver.chromium': {
'linux_chromium_rel': set(['defaulttests']),
'mac_chromium_rel': set(['defaulttests']),
- 'win_rel': set(['sync_integration_tests']),
+ 'win_chromium_rel': set(['defaulttests']),
}
}
diff --git a/sync/api/attachments/attachment_service_proxy.cc b/sync/api/attachments/attachment_service_proxy.cc
index 065f467b54..b95a41faa3 100644
--- a/sync/api/attachments/attachment_service_proxy.cc
+++ b/sync/api/attachments/attachment_service_proxy.cc
@@ -36,16 +36,26 @@ void ProxyDropCallback(
} // namespace
-AttachmentServiceProxy::AttachmentServiceProxy() {}
+AttachmentServiceProxy::AttachmentServiceProxy() {
+}
AttachmentServiceProxy::AttachmentServiceProxy(
const scoped_refptr<base::SequencedTaskRunner>& wrapped_task_runner,
- base::WeakPtr<syncer::AttachmentService> wrapped)
- : wrapped_task_runner_(wrapped_task_runner), wrapped_(wrapped) {
+ const base::WeakPtr<syncer::AttachmentService>& wrapped)
+ : wrapped_task_runner_(wrapped_task_runner), core_(new Core(wrapped)) {
DCHECK(wrapped_task_runner_);
}
-AttachmentServiceProxy::~AttachmentServiceProxy() {}
+AttachmentServiceProxy::AttachmentServiceProxy(
+ const scoped_refptr<base::SequencedTaskRunner>& wrapped_task_runner,
+ const scoped_refptr<Core>& core)
+ : wrapped_task_runner_(wrapped_task_runner), core_(core) {
+ DCHECK(wrapped_task_runner_);
+ DCHECK(core_);
+}
+
+AttachmentServiceProxy::~AttachmentServiceProxy() {
+}
void AttachmentServiceProxy::GetOrDownloadAttachments(
const AttachmentIdList& attachment_ids,
@@ -56,7 +66,7 @@ void AttachmentServiceProxy::GetOrDownloadAttachments(
wrapped_task_runner_->PostTask(
FROM_HERE,
base::Bind(&AttachmentService::GetOrDownloadAttachments,
- wrapped_,
+ core_,
attachment_ids,
proxy_callback));
}
@@ -69,7 +79,7 @@ void AttachmentServiceProxy::DropAttachments(
&ProxyDropCallback, base::MessageLoopProxy::current(), callback);
wrapped_task_runner_->PostTask(FROM_HERE,
base::Bind(&AttachmentService::DropAttachments,
- wrapped_,
+ core_,
attachment_ids,
proxy_callback));
}
@@ -78,14 +88,14 @@ void AttachmentServiceProxy::OnSyncDataAdd(const SyncData& sync_data) {
DCHECK(wrapped_task_runner_);
wrapped_task_runner_->PostTask(
FROM_HERE,
- base::Bind(&AttachmentService::OnSyncDataAdd, wrapped_, sync_data));
+ base::Bind(&AttachmentService::OnSyncDataAdd, core_, sync_data));
}
void AttachmentServiceProxy::OnSyncDataDelete(const SyncData& sync_data) {
DCHECK(wrapped_task_runner_);
wrapped_task_runner_->PostTask(
FROM_HERE,
- base::Bind(&AttachmentService::OnSyncDataDelete, wrapped_, sync_data));
+ base::Bind(&AttachmentService::OnSyncDataDelete, core_, sync_data));
}
void AttachmentServiceProxy::OnSyncDataUpdate(
@@ -95,9 +105,58 @@ void AttachmentServiceProxy::OnSyncDataUpdate(
wrapped_task_runner_->PostTask(
FROM_HERE,
base::Bind(&AttachmentService::OnSyncDataUpdate,
- wrapped_,
+ core_,
old_attachment_ids,
updated_sync_data));
}
+AttachmentServiceProxy::Core::Core(
+ const base::WeakPtr<syncer::AttachmentService>& wrapped)
+ : wrapped_(wrapped) {
+}
+
+AttachmentServiceProxy::Core::~Core() {
+}
+
+void AttachmentServiceProxy::Core::GetOrDownloadAttachments(
+ const AttachmentIdList& attachment_ids,
+ const GetOrDownloadCallback& callback) {
+ if (!wrapped_) {
+ return;
+ }
+ wrapped_->GetOrDownloadAttachments(attachment_ids, callback);
+}
+
+void AttachmentServiceProxy::Core::DropAttachments(
+ const AttachmentIdList& attachment_ids,
+ const DropCallback& callback) {
+ if (!wrapped_) {
+ return;
+ }
+ wrapped_->DropAttachments(attachment_ids, callback);
+}
+
+void AttachmentServiceProxy::Core::OnSyncDataAdd(const SyncData& sync_data) {
+ if (!wrapped_) {
+ return;
+ }
+ wrapped_->OnSyncDataAdd(sync_data);
+}
+
+void AttachmentServiceProxy::Core::OnSyncDataDelete(const SyncData& sync_data) {
+ if (!wrapped_) {
+ return;
+ }
+ wrapped_->OnSyncDataDelete(sync_data);
+}
+
+void AttachmentServiceProxy::Core::OnSyncDataUpdate(
+ const AttachmentIdList& old_attachment_ids,
+ const SyncData& updated_sync_data) {
+ if (!wrapped_) {
+ return;
+ }
+ wrapped_->OnSyncDataUpdate(old_attachment_ids, updated_sync_data);
+}
+
} // namespace syncer
diff --git a/sync/api/attachments/attachment_service_proxy.h b/sync/api/attachments/attachment_service_proxy.h
index 5bec1b3206..70856255cf 100644
--- a/sync/api/attachments/attachment_service_proxy.h
+++ b/sync/api/attachments/attachment_service_proxy.h
@@ -20,7 +20,8 @@ namespace syncer {
class SyncData;
// AttachmentServiceProxy wraps an AttachmentService allowing multiple threads
-// to share the wrapped AttachmentService.
+// to share the wrapped AttachmentService and invoke its methods in the
+// appropriate thread.
//
// Callbacks passed to methods on this class will be invoked in the same thread
// from which the method was called.
@@ -29,10 +30,10 @@ class SyncData;
// holds a WeakPtr to the wrapped object. Once the the wrapped object is
// destroyed, method calls on this object will be no-ops.
//
-// Users of this class should take care to destroy the wrapped object on the
-// correct thread (wrapped_task_runner).
+// Users of this class should take care to destroy the wrapped object on the
+// correct thread (wrapped_task_runner).
//
-// This class is thread-safe.
+// This class is thread-safe and is designed to be passed by const-ref.
class SYNC_EXPORT AttachmentServiceProxy : public AttachmentService {
public:
// Default copy and assignment are welcome.
@@ -42,16 +43,19 @@ class SYNC_EXPORT AttachmentServiceProxy : public AttachmentService {
// Construct an AttachmentServiceProxy that forwards calls to |wrapped| on the
// |wrapped_task_runner| thread.
+ //
+ // Note, this object does not own |wrapped|. When |wrapped| is destroyed,
+ // calls to this object become no-ops.
AttachmentServiceProxy(
const scoped_refptr<base::SequencedTaskRunner>& wrapped_task_runner,
- base::WeakPtr<syncer::AttachmentService> wrapped);
+ const base::WeakPtr<syncer::AttachmentService>& wrapped);
virtual ~AttachmentServiceProxy();
// AttachmentService implementation.
- virtual void GetOrDownloadAttachments(const AttachmentIdList& attachment_ids,
- const GetOrDownloadCallback& callback)
- OVERRIDE;
+ virtual void GetOrDownloadAttachments(
+ const AttachmentIdList& attachment_ids,
+ const GetOrDownloadCallback& callback) OVERRIDE;
virtual void DropAttachments(const AttachmentIdList& attachment_ids,
const DropCallback& callback) OVERRIDE;
virtual void OnSyncDataAdd(const SyncData& sync_data) OVERRIDE;
@@ -59,10 +63,55 @@ class SYNC_EXPORT AttachmentServiceProxy : public AttachmentService {
virtual void OnSyncDataUpdate(const AttachmentIdList& old_attachment_ids,
const SyncData& updated_sync_data) OVERRIDE;
+ protected:
+ // Core does the work of proxying calls to AttachmentService methods from one
+ // thread to another so AttachmentServiceProxy can be an easy-to-use,
+ // non-ref-counted A ref-counted class.
+ //
+ // Callback from AttachmentService are proxied back using free functions
+ // defined in the .cc file (ProxyFooCallback functions).
+ //
+ // Core is ref-counted because we want to allow AttachmentServiceProxy to be
+ // copy-constructable while allowing for different implementations of Core
+ // (e.g. one type of core might own the wrapped AttachmentService).
+ //
+ // Calls to objects of this class become no-ops once its wrapped object is
+ // destroyed.
+ class SYNC_EXPORT Core : public AttachmentService,
+ public base::RefCountedThreadSafe<Core> {
+ public:
+ // Construct an AttachmentServiceProxyCore that forwards calls to |wrapped|.
+ Core(const base::WeakPtr<syncer::AttachmentService>& wrapped);
+
+ // AttachmentService implementation.
+ virtual void GetOrDownloadAttachments(
+ const AttachmentIdList& attachment_ids,
+ const GetOrDownloadCallback& callback) OVERRIDE;
+ virtual void DropAttachments(const AttachmentIdList& attachment_ids,
+ const DropCallback& callback) OVERRIDE;
+ virtual void OnSyncDataAdd(const SyncData& sync_data) OVERRIDE;
+ virtual void OnSyncDataDelete(const SyncData& sync_data) OVERRIDE;
+ virtual void OnSyncDataUpdate(const AttachmentIdList& old_attachment_ids,
+ const SyncData& updated_sync_data) OVERRIDE;
+
+ protected:
+ friend class base::RefCountedThreadSafe<Core>;
+ virtual ~Core();
+
+ private:
+ base::WeakPtr<AttachmentService> wrapped_;
+
+ DISALLOW_COPY_AND_ASSIGN(Core);
+ };
+
+ // Used in tests to create an AttachmentServiceProxy with a custom Core.
+ AttachmentServiceProxy(
+ const scoped_refptr<base::SequencedTaskRunner>& wrapped_task_runner,
+ const scoped_refptr<Core>& core);
+
private:
scoped_refptr<base::SequencedTaskRunner> wrapped_task_runner_;
- // wrapped_ must only be dereferenced on the wrapped_task_runner_ thread.
- base::WeakPtr<AttachmentService> wrapped_;
+ scoped_refptr<Core> core_;
};
} // namespace syncer
diff --git a/sync/api/attachments/attachment_service_proxy_for_test.cc b/sync/api/attachments/attachment_service_proxy_for_test.cc
new file mode 100644
index 0000000000..7f9f873b28
--- /dev/null
+++ b/sync/api/attachments/attachment_service_proxy_for_test.cc
@@ -0,0 +1,52 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "sync/api/attachments/attachment_service_proxy_for_test.h"
+
+#include "base/message_loop/message_loop_proxy.h"
+#include "sync/api/attachments/fake_attachment_service.h"
+
+namespace syncer {
+
+AttachmentServiceProxyForTest::OwningCore::OwningCore(
+ scoped_ptr<AttachmentService> wrapped,
+ scoped_ptr<base::WeakPtrFactory<AttachmentService> > weak_ptr_factory)
+ : Core(weak_ptr_factory->GetWeakPtr()),
+ wrapped_(wrapped.Pass()),
+ weak_ptr_factory_(weak_ptr_factory.Pass()) {
+ DCHECK(wrapped_);
+}
+
+AttachmentServiceProxyForTest::OwningCore::~OwningCore() {
+}
+
+// Static.
+AttachmentServiceProxy AttachmentServiceProxyForTest::Create() {
+ scoped_ptr<AttachmentService> wrapped(FakeAttachmentService::CreateForTest());
+ // This class's base class, AttachmentServiceProxy, must be initialized with a
+ // WeakPtr to an AttachmentService. Because the base class ctor must be
+ // invoked before any of this class's members are initialized, we create the
+ // WeakPtrFactory here and pass it to the ctor so that it may initialize its
+ // base class and own the WeakPtrFactory.
+ //
+ // We must pass by scoped_ptr because WeakPtrFactory has no copy constructor.
+ scoped_ptr<base::WeakPtrFactory<AttachmentService> > weak_ptr_factory(
+ new base::WeakPtrFactory<AttachmentService>(wrapped.get()));
+
+ scoped_refptr<Core> core_for_test(
+ new OwningCore(wrapped.Pass(), weak_ptr_factory.Pass()));
+ return AttachmentServiceProxyForTest(base::MessageLoopProxy::current(),
+ core_for_test);
+}
+
+AttachmentServiceProxyForTest::~AttachmentServiceProxyForTest() {
+}
+
+AttachmentServiceProxyForTest::AttachmentServiceProxyForTest(
+ const scoped_refptr<base::SequencedTaskRunner>& wrapped_task_runner,
+ const scoped_refptr<Core>& core)
+ : AttachmentServiceProxy(wrapped_task_runner, core) {
+}
+
+} // namespace syncer
diff --git a/sync/api/attachments/attachment_service_proxy_for_test.h b/sync/api/attachments/attachment_service_proxy_for_test.h
new file mode 100644
index 0000000000..916e788d74
--- /dev/null
+++ b/sync/api/attachments/attachment_service_proxy_for_test.h
@@ -0,0 +1,50 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SYNC_API_ATTACHMENTS_ATTACHMENT_SERVICE_PROXY_FOR_TEST_H_
+#define SYNC_API_ATTACHMENTS_ATTACHMENT_SERVICE_PROXY_FOR_TEST_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "sync/api/attachments/attachment_service_proxy.h"
+#include "sync/base/sync_export.h"
+
+namespace syncer {
+
+// An self-contained AttachmentServiceProxy to reduce boilerplate code in tests.
+//
+// Constructs and owns an AttachmentService suitable for use in tests. Assumes
+// the current thread has a MessageLoop.
+class SYNC_EXPORT AttachmentServiceProxyForTest
+ : public AttachmentServiceProxy {
+ public:
+ static AttachmentServiceProxy Create();
+ virtual ~AttachmentServiceProxyForTest();
+
+ private:
+ // A Core that owns the wrapped AttachmentService.
+ class OwningCore : public AttachmentServiceProxy::Core {
+ public:
+ OwningCore(
+ scoped_ptr<AttachmentService>,
+ scoped_ptr<base::WeakPtrFactory<AttachmentService> > weak_ptr_factory);
+
+ private:
+ scoped_ptr<AttachmentService> wrapped_;
+ // WeakPtrFactory for wrapped_. See Create() for why this is a scoped_ptr.
+ scoped_ptr<base::WeakPtrFactory<AttachmentService> > weak_ptr_factory_;
+
+ virtual ~OwningCore();
+
+ DISALLOW_COPY_AND_ASSIGN(OwningCore);
+ };
+
+ AttachmentServiceProxyForTest(
+ const scoped_refptr<base::SequencedTaskRunner>& wrapped_task_runner,
+ const scoped_refptr<Core>& core);
+};
+
+} // namespace syncer
+
+#endif // SYNC_API_ATTACHMENTS_ATTACHMENT_SERVICE_PROXY_FOR_TEST_H_
diff --git a/sync/api/sync_change_unittest.cc b/sync/api/sync_change_unittest.cc
index 5f937ab7c9..a09776ed80 100644
--- a/sync/api/sync_change_unittest.cc
+++ b/sync/api/sync_change_unittest.cc
@@ -7,8 +7,11 @@
#include <string>
#include "base/memory/scoped_ptr.h"
+#include "base/message_loop/message_loop.h"
#include "base/time/time.h"
#include "base/values.h"
+#include "sync/api/attachments/attachment_id.h"
+#include "sync/api/attachments/attachment_service_proxy_for_test.h"
#include "sync/protocol/preference_specifics.pb.h"
#include "sync/protocol/proto_value_conversions.h"
#include "sync/protocol/sync.pb.h"
@@ -21,7 +24,10 @@ typedef std::vector<SyncChange> SyncChangeList;
namespace {
-typedef testing::Test SyncChangeTest;
+class SyncChangeTest : public testing::Test {
+ private:
+ base::MessageLoop message_loop;
+};
TEST_F(SyncChangeTest, LocalDelete) {
SyncChange::SyncChangeType change_type = SyncChange::ACTION_DELETE;
@@ -82,28 +88,43 @@ TEST_F(SyncChangeTest, SyncerChanges) {
sync_pb::PreferenceSpecifics* pref_specifics =
update_specifics.mutable_preference();
pref_specifics->set_name("update");
- change_list.push_back(SyncChange(
- FROM_HERE,
- SyncChange::ACTION_UPDATE,
- SyncData::CreateRemoteData(1, update_specifics, base::Time())));
+ change_list.push_back(
+ SyncChange(FROM_HERE,
+ SyncChange::ACTION_UPDATE,
+ SyncData::CreateRemoteData(
+ 1,
+ update_specifics,
+ base::Time(),
+ syncer::AttachmentIdList(),
+ syncer::AttachmentServiceProxyForTest::Create())));
// Create an add.
sync_pb::EntitySpecifics add_specifics;
pref_specifics = add_specifics.mutable_preference();
pref_specifics->set_name("add");
- change_list.push_back(SyncChange(
- FROM_HERE,
- SyncChange::ACTION_ADD,
- SyncData::CreateRemoteData(2, add_specifics, base::Time())));
+ change_list.push_back(
+ SyncChange(FROM_HERE,
+ SyncChange::ACTION_ADD,
+ SyncData::CreateRemoteData(
+ 2,
+ add_specifics,
+ base::Time(),
+ syncer::AttachmentIdList(),
+ syncer::AttachmentServiceProxyForTest::Create())));
// Create a delete.
sync_pb::EntitySpecifics delete_specifics;
pref_specifics = delete_specifics.mutable_preference();
pref_specifics->set_name("add");
- change_list.push_back(SyncChange(
- FROM_HERE,
- SyncChange::ACTION_DELETE,
- SyncData::CreateRemoteData(3, delete_specifics, base::Time())));
+ change_list.push_back(
+ SyncChange(FROM_HERE,
+ SyncChange::ACTION_DELETE,
+ SyncData::CreateRemoteData(
+ 3,
+ delete_specifics,
+ base::Time(),
+ syncer::AttachmentIdList(),
+ syncer::AttachmentServiceProxyForTest::Create())));
ASSERT_EQ(3U, change_list.size());
diff --git a/sync/api/sync_data.cc b/sync/api/sync_data.cc
index 5d84941227..fa48ea5edc 100644
--- a/sync/api/sync_data.cc
+++ b/sync/api/sync_data.cc
@@ -143,17 +143,6 @@ SyncData SyncData::CreateRemoteData(
id, &entity, &attachments, modification_time, attachment_service);
}
-// Static.
-SyncData SyncData::CreateRemoteData(int64 id,
- const sync_pb::EntitySpecifics& specifics,
- const base::Time& modification_time) {
- return CreateRemoteData(id,
- specifics,
- modification_time,
- AttachmentIdList(),
- AttachmentServiceProxy());
-}
-
bool SyncData::IsValid() const { return is_valid_; }
const sync_pb::EntitySpecifics& SyncData::GetSpecifics() const {
diff --git a/sync/api/sync_data.h b/sync/api/sync_data.h
index 717b1e1175..bb99b74457 100644
--- a/sync/api/sync_data.h
+++ b/sync/api/sync_data.h
@@ -11,6 +11,7 @@
#include "base/basictypes.h"
#include "base/callback.h"
+#include "base/memory/ref_counted.h"
#include "base/stl_util.h"
#include "base/time/time.h"
#include "sync/api/attachments/attachment.h"
@@ -64,18 +65,12 @@ class SYNC_EXPORT SyncData {
const AttachmentList& attachments);
// Helper method for creating SyncData objects originating from the syncer.
- //
- // TODO(maniscalco): Replace all calls to 3-arg CreateRemoteData with calls to
- // the 5-arg version (bug 353296).
static SyncData CreateRemoteData(
int64 id,
const sync_pb::EntitySpecifics& specifics,
const base::Time& last_modified_time,
const AttachmentIdList& attachment_ids,
const syncer::AttachmentServiceProxy& attachment_service);
- static SyncData CreateRemoteData(int64 id,
- const sync_pb::EntitySpecifics& specifics,
- const base::Time& last_modified_time);
// Whether this SyncData holds valid data. The only way to have a SyncData
// without valid data is to use the default constructor.
diff --git a/sync/api/sync_data_unittest.cc b/sync/api/sync_data_unittest.cc
index 7ca39bf221..4eab286a95 100644
--- a/sync/api/sync_data_unittest.cc
+++ b/sync/api/sync_data_unittest.cc
@@ -120,16 +120,6 @@ TEST_F(SyncDataTest, CreateRemoteData) {
EXPECT_TRUE(data.GetAttachmentIds().empty());
}
-TEST_F(SyncDataTest, CreateRemoteData_WithoutAttachmentService) {
- specifics.mutable_preference();
- SyncData data = SyncData::CreateRemoteData(kId, specifics, kLastModifiedTime);
- EXPECT_TRUE(data.IsValid());
- EXPECT_FALSE(data.IsLocal());
- EXPECT_EQ(kId, SyncDataRemote(data).GetId());
- EXPECT_EQ(kLastModifiedTime, SyncDataRemote(data).GetModifiedTime());
- EXPECT_TRUE(data.GetSpecifics().has_preference());
-}
-
// TODO(maniscalco): Add test cases that verify GetLocalAttachmentsForUpload and
// DropAttachments calls are passed through to the underlying AttachmentService.
diff --git a/sync/engine/all_status.cc b/sync/engine/all_status.cc
index d73f206eae..3deda48fb2 100644
--- a/sync/engine/all_status.cc
+++ b/sync/engine/all_status.cc
@@ -71,22 +71,6 @@ SyncStatus AllStatus::CalcSyncing(const SyncCycleEvent &event) const {
snapshot.model_neutral_state().num_local_overwrites;
status.num_server_overwrites_total +=
snapshot.model_neutral_state().num_server_overwrites;
- if (snapshot.model_neutral_state().num_updates_downloaded_total == 0) {
- ++status.empty_get_updates;
- } else {
- ++status.nonempty_get_updates;
- }
- if (snapshot.model_neutral_state().num_successful_commits == 0) {
- ++status.sync_cycles_without_commits;
- } else {
- ++status.sync_cycles_with_commits;
- }
- if (snapshot.model_neutral_state().num_successful_commits == 0 &&
- snapshot.model_neutral_state().num_updates_downloaded_total == 0) {
- ++status.useless_sync_cycles;
- } else {
- ++status.useful_sync_cycles;
- }
}
return status;
}
diff --git a/sync/engine/backoff_delay_provider.cc b/sync/engine/backoff_delay_provider.cc
index f8e2750876..bff3fd61c6 100644
--- a/sync/engine/backoff_delay_provider.cc
+++ b/sync/engine/backoff_delay_provider.cc
@@ -97,6 +97,11 @@ TimeDelta BackoffDelayProvider::GetInitialDelay(
return short_initial_backoff_;
}
+ // If a datatype decides the GetUpdates must be retried (e.g. because the
+ // context has been updated since the request), use the short delay.
+ if (state.last_download_updates_result == DATATYPE_TRIGGERED_RETRY)
+ return short_initial_backoff_;
+
// When the server tells us we have a conflict, then we should download the
// latest updates so we can see the conflict ourselves, resolve it locally,
// then try again to commit. Running another sync cycle will do all these
@@ -105,9 +110,8 @@ TimeDelta BackoffDelayProvider::GetInitialDelay(
// TODO(sync): We shouldn't need to handle this in BackoffDelayProvider.
// There should be a way to deal with protocol errors before we get to this
// point.
- if (state.commit_result == SERVER_RETURN_CONFLICT) {
+ if (state.commit_result == SERVER_RETURN_CONFLICT)
return short_initial_backoff_;
- }
return default_initial_backoff_;
}
diff --git a/sync/engine/backoff_delay_provider_unittest.cc b/sync/engine/backoff_delay_provider_unittest.cc
index 1bf17cbd5f..2e5818665f 100644
--- a/sync/engine/backoff_delay_provider_unittest.cc
+++ b/sync/engine/backoff_delay_provider_unittest.cc
@@ -57,6 +57,10 @@ TEST_F(BackoffDelayProviderTest, GetInitialDelay) {
EXPECT_EQ(kInitialBackoffRetrySeconds,
delay->GetInitialDelay(state).InSeconds());
+ state.last_download_updates_result = DATATYPE_TRIGGERED_RETRY;
+ EXPECT_EQ(kInitialBackoffImmediateRetrySeconds,
+ delay->GetInitialDelay(state).InSeconds());
+
state.last_download_updates_result = SYNCER_OK;
// Note that updating credentials triggers a canary job, trumping
// the initial delay, but in theory we still expect this function to treat
@@ -99,6 +103,10 @@ TEST_F(BackoffDelayProviderTest, GetInitialDelayWithOverride) {
EXPECT_EQ(kInitialBackoffShortRetrySeconds,
delay->GetInitialDelay(state).InSeconds());
+ state.last_download_updates_result = DATATYPE_TRIGGERED_RETRY;
+ EXPECT_EQ(kInitialBackoffImmediateRetrySeconds,
+ delay->GetInitialDelay(state).InSeconds());
+
state.last_download_updates_result = SYNCER_OK;
// Note that updating credentials triggers a canary job, trumping
// the initial delay, but in theory we still expect this function to treat
diff --git a/sync/engine/directory_update_handler.cc b/sync/engine/directory_update_handler.cc
index 55095202fa..72cdf121d2 100644
--- a/sync/engine/directory_update_handler.cc
+++ b/sync/engine/directory_update_handler.cc
@@ -37,19 +37,12 @@ void DirectoryUpdateHandler::GetDataTypeContext(
dir_->GetDataTypeContext(&trans, type_, context);
}
-void DirectoryUpdateHandler::ProcessGetUpdatesResponse(
+SyncerError DirectoryUpdateHandler::ProcessGetUpdatesResponse(
const sync_pb::DataTypeProgressMarker& progress_marker,
const sync_pb::DataTypeContext& mutated_context,
const SyncEntityList& applicable_updates,
sessions::StatusController* status) {
syncable::ModelNeutralWriteTransaction trans(FROM_HERE, SYNCER, dir_);
- UpdateSyncEntities(&trans, applicable_updates, status);
-
- if (IsValidProgressMarker(progress_marker)) {
- ExpireEntriesIfNeeded(&trans, progress_marker);
- UpdateProgressMarker(progress_marker);
- }
-
if (mutated_context.has_context()) {
sync_pb::DataTypeContext local_context;
dir_->GetDataTypeContext(&trans, type_, &local_context);
@@ -61,8 +54,21 @@ void DirectoryUpdateHandler::ProcessGetUpdatesResponse(
local_context.context() != mutated_context.context()) {
dir_->SetDataTypeContext(&trans, type_, mutated_context);
// TODO(zea): trigger the datatype's UpdateDataTypeContext method.
+ } else if (mutated_context.version() < local_context.version()) {
+ // A GetUpdates using the old context was in progress when the context was
+ // set. Fail this get updates cycle, to force a retry.
+ DVLOG(1) << "GU Context conflict detected, forcing GU retry.";
+ return DATATYPE_TRIGGERED_RETRY;
}
}
+
+ UpdateSyncEntities(&trans, applicable_updates, status);
+
+ if (IsValidProgressMarker(progress_marker)) {
+ ExpireEntriesIfNeeded(&trans, progress_marker);
+ UpdateProgressMarker(progress_marker);
+ }
+ return SYNCER_OK;
}
void DirectoryUpdateHandler::ApplyUpdates(sessions::StatusController* status) {
diff --git a/sync/engine/directory_update_handler.h b/sync/engine/directory_update_handler.h
index 74c7046771..ef5052dee6 100644
--- a/sync/engine/directory_update_handler.h
+++ b/sync/engine/directory_update_handler.h
@@ -52,7 +52,7 @@ class SYNC_EXPORT_PRIVATE DirectoryUpdateHandler : public UpdateHandler {
sync_pb::DataTypeProgressMarker* progress_marker) const OVERRIDE;
virtual void GetDataTypeContext(sync_pb::DataTypeContext* context) const
OVERRIDE;
- virtual void ProcessGetUpdatesResponse(
+ virtual SyncerError ProcessGetUpdatesResponse(
const sync_pb::DataTypeProgressMarker& progress_marker,
const sync_pb::DataTypeContext& mutated_context,
const SyncEntityList& applicable_updates,
diff --git a/sync/engine/directory_update_handler_unittest.cc b/sync/engine/directory_update_handler_unittest.cc
index 6d1b35a199..ec8cc35f39 100644
--- a/sync/engine/directory_update_handler_unittest.cc
+++ b/sync/engine/directory_update_handler_unittest.cc
@@ -195,14 +195,14 @@ TEST_F(DirectoryUpdateHandlerProcessUpdateTest,
// Test the receipt of a non-bookmark item.
TEST_F(DirectoryUpdateHandlerProcessUpdateTest, ReceiveNonBookmarkItem) {
- DirectoryUpdateHandler handler(dir(), PREFERENCES, ui_worker());
+ DirectoryUpdateHandler handler(dir(), AUTOFILL, ui_worker());
sync_pb::GetUpdatesResponse gu_response;
sessions::StatusController status;
std::string root = syncable::GetNullId().GetServerId();
syncable::Id server_id = syncable::Id::CreateFromServerId("xyz");
scoped_ptr<sync_pb::SyncEntity> e =
- CreateUpdate(SyncableIdToProto(server_id), root, PREFERENCES);
+ CreateUpdate(SyncableIdToProto(server_id), root, AUTOFILL);
e->set_server_defined_unique_tag("9PGRuKdX5sHyGMB17CvYTXuC43I=");
// Add it to the applicable updates list.
@@ -283,7 +283,9 @@ TEST_F(DirectoryUpdateHandlerProcessUpdateTest, GarbageCollectionByVersion) {
updates.push_back(e2.get());
// Process and apply updates.
- handler.ProcessGetUpdatesResponse(progress, context, updates, &status);
+ EXPECT_EQ(
+ SYNCER_OK,
+ handler.ProcessGetUpdatesResponse(progress, context, updates, &status));
handler.ApplyUpdates(&status);
// Verify none is deleted because they are unapplied during GC.
@@ -293,14 +295,93 @@ TEST_F(DirectoryUpdateHandlerProcessUpdateTest, GarbageCollectionByVersion) {
// Process and apply again. Old entry is deleted but not root.
progress.mutable_gc_directive()->set_version_watermark(kDefaultVersion + 20);
- handler.ProcessGetUpdatesResponse(
- progress, context, SyncEntityList(), &status);
+ EXPECT_EQ(SYNCER_OK,
+ handler.ProcessGetUpdatesResponse(
+ progress, context, SyncEntityList(), &status));
handler.ApplyUpdates(&status);
EXPECT_TRUE(EntryExists(type_root->id_string()));
EXPECT_FALSE(EntryExists(e1->id_string()));
EXPECT_TRUE(EntryExists(e2->id_string()));
}
+TEST_F(DirectoryUpdateHandlerProcessUpdateTest, ContextVersion) {
+ DirectoryUpdateHandler handler(dir(), SYNCED_NOTIFICATIONS, ui_worker());
+ sessions::StatusController status;
+ int field_number = GetSpecificsFieldNumberFromModelType(SYNCED_NOTIFICATIONS);
+
+ sync_pb::DataTypeProgressMarker progress;
+ progress.set_data_type_id(
+ GetSpecificsFieldNumberFromModelType(SYNCED_NOTIFICATIONS));
+ progress.set_token("token");
+
+ sync_pb::DataTypeContext old_context;
+ old_context.set_version(1);
+ old_context.set_context("data");
+ old_context.set_data_type_id(field_number);
+
+ scoped_ptr<sync_pb::SyncEntity> type_root =
+ CreateUpdate(SyncableIdToProto(syncable::Id::CreateFromServerId("root")),
+ syncable::GetNullId().GetServerId(),
+ SYNCED_NOTIFICATIONS);
+ type_root->set_server_defined_unique_tag(
+ ModelTypeToRootTag(SYNCED_NOTIFICATIONS));
+ type_root->set_folder(true);
+ scoped_ptr<sync_pb::SyncEntity> e1 =
+ CreateUpdate(SyncableIdToProto(syncable::Id::CreateFromServerId("e1")),
+ type_root->id_string(),
+ SYNCED_NOTIFICATIONS);
+
+ SyncEntityList updates;
+ updates.push_back(type_root.get());
+ updates.push_back(e1.get());
+
+ // The first response should be processed fine.
+ EXPECT_EQ(SYNCER_OK,
+ handler.ProcessGetUpdatesResponse(
+ progress, old_context, updates, &status));
+ handler.ApplyUpdates(&status);
+
+ EXPECT_TRUE(EntryExists(type_root->id_string()));
+ EXPECT_TRUE(EntryExists(e1->id_string()));
+
+ {
+ sync_pb::DataTypeContext dir_context;
+ syncable::ReadTransaction trans(FROM_HERE, dir());
+ trans.directory()->GetDataTypeContext(
+ &trans, SYNCED_NOTIFICATIONS, &dir_context);
+ EXPECT_EQ(old_context.SerializeAsString(), dir_context.SerializeAsString());
+ }
+
+ sync_pb::DataTypeContext new_context;
+ new_context.set_version(0);
+ new_context.set_context("old");
+ new_context.set_data_type_id(field_number);
+
+ scoped_ptr<sync_pb::SyncEntity> e2 =
+ CreateUpdate(SyncableIdToProto(syncable::Id::CreateFromServerId("e2")),
+ type_root->id_string(),
+ SYNCED_NOTIFICATIONS);
+ updates.clear();
+ updates.push_back(e2.get());
+
+ // The second response, with an old context version, should result in an
+ // error and the updates should be dropped.
+ EXPECT_EQ(DATATYPE_TRIGGERED_RETRY,
+ handler.ProcessGetUpdatesResponse(
+ progress, new_context, updates, &status));
+ handler.ApplyUpdates(&status);
+
+ EXPECT_FALSE(EntryExists(e2->id_string()));
+
+ {
+ sync_pb::DataTypeContext dir_context;
+ syncable::ReadTransaction trans(FROM_HERE, dir());
+ trans.directory()->GetDataTypeContext(
+ &trans, SYNCED_NOTIFICATIONS, &dir_context);
+ EXPECT_EQ(old_context.SerializeAsString(), dir_context.SerializeAsString());
+ }
+}
+
// A test harness for tests that focus on applying updates.
//
// Update application is performed when we want to take updates that were
diff --git a/sync/engine/get_updates_processor.cc b/sync/engine/get_updates_processor.cc
index d0aa9b989f..8666e0a25c 100644
--- a/sync/engine/get_updates_processor.cc
+++ b/sync/engine/get_updates_processor.cc
@@ -284,9 +284,10 @@ SyncerError GetUpdatesProcessor::ProcessResponse(
}
status->set_num_server_changes_remaining(gu_response.changes_remaining());
- if (!ProcessGetUpdatesResponse(request_types, gu_response, status)) {
- return SERVER_RESPONSE_VALIDATION_FAILED;
- }
+ syncer::SyncerError result =
+ ProcessGetUpdatesResponse(request_types, gu_response, status);
+ if (result != syncer::SYNCER_OK)
+ return result;
if (gu_response.changes_remaining() == 0) {
return SYNCER_OK;
@@ -295,7 +296,7 @@ SyncerError GetUpdatesProcessor::ProcessResponse(
}
}
-bool GetUpdatesProcessor::ProcessGetUpdatesResponse(
+syncer::SyncerError GetUpdatesProcessor::ProcessGetUpdatesResponse(
ModelTypeSet gu_types,
const sync_pb::GetUpdatesResponse& gu_response,
sessions::StatusController* status_controller) {
@@ -309,7 +310,7 @@ bool GetUpdatesProcessor::ProcessGetUpdatesResponse(
&progress_index_by_type);
if (gu_types.Size() != progress_index_by_type.size()) {
NOTREACHED() << "Missing progress markers in GetUpdates response.";
- return false;
+ return syncer::SERVER_RESPONSE_VALIDATION_FAILED;
}
TypeToIndexMap context_by_type;
@@ -334,11 +335,14 @@ bool GetUpdatesProcessor::ProcessGetUpdatesResponse(
context.CopyFrom(gu_response.context_mutations(context_iter->second));
if (update_handler_iter != update_handler_map_->end()) {
- update_handler_iter->second->ProcessGetUpdatesResponse(
- gu_response.new_progress_marker(progress_marker_iter->second),
- context,
- updates_iter->second,
- status_controller);
+ syncer::SyncerError result =
+ update_handler_iter->second->ProcessGetUpdatesResponse(
+ gu_response.new_progress_marker(progress_marker_iter->second),
+ context,
+ updates_iter->second,
+ status_controller);
+ if (result != syncer::SYNCER_OK)
+ return result;
} else {
DLOG(WARNING)
<< "Ignoring received updates of a type we can't handle. "
@@ -349,7 +353,7 @@ bool GetUpdatesProcessor::ProcessGetUpdatesResponse(
DCHECK(progress_marker_iter == progress_index_by_type.end() &&
updates_iter == updates_by_type.end());
- return true;
+ return syncer::SYNCER_OK;
}
void GetUpdatesProcessor::ApplyUpdates(
diff --git a/sync/engine/get_updates_processor.h b/sync/engine/get_updates_processor.h
index 40a5c3aca7..e66d100927 100644
--- a/sync/engine/get_updates_processor.h
+++ b/sync/engine/get_updates_processor.h
@@ -82,7 +82,7 @@ class SYNC_EXPORT_PRIVATE GetUpdatesProcessor {
sessions::StatusController* status);
// Processes a GetUpdates responses for each type.
- bool ProcessGetUpdatesResponse(
+ syncer::SyncerError ProcessGetUpdatesResponse(
ModelTypeSet gu_types,
const sync_pb::GetUpdatesResponse& gu_response,
sessions::StatusController* status_controller);
diff --git a/sync/engine/non_blocking_type_processor_core.cc b/sync/engine/non_blocking_type_processor_core.cc
index c1bc60ad0d..ea0f91889a 100644
--- a/sync/engine/non_blocking_type_processor_core.cc
+++ b/sync/engine/non_blocking_type_processor_core.cc
@@ -44,7 +44,7 @@ void NonBlockingTypeProcessorCore::GetDataTypeContext(
context->Clear();
}
-void NonBlockingTypeProcessorCore::ProcessGetUpdatesResponse(
+SyncerError NonBlockingTypeProcessorCore::ProcessGetUpdatesResponse(
const sync_pb::DataTypeProgressMarker& progress_marker,
const sync_pb::DataTypeContext& mutated_context,
const SyncEntityList& applicable_updates,
@@ -53,6 +53,7 @@ void NonBlockingTypeProcessorCore::ProcessGetUpdatesResponse(
// TODO(rlarocque): Implement this properly. crbug.com/351005.
DVLOG(1) << "Processing updates response for: " << ModelTypeToString(type_);
progress_marker_ = progress_marker;
+ return SYNCER_OK;
}
void NonBlockingTypeProcessorCore::ApplyUpdates(
diff --git a/sync/engine/non_blocking_type_processor_core.h b/sync/engine/non_blocking_type_processor_core.h
index 0c1cc1c0bf..c9cec886b4 100644
--- a/sync/engine/non_blocking_type_processor_core.h
+++ b/sync/engine/non_blocking_type_processor_core.h
@@ -59,7 +59,7 @@ class SYNC_EXPORT NonBlockingTypeProcessorCore
sync_pb::DataTypeProgressMarker* progress_marker) const OVERRIDE;
virtual void GetDataTypeContext(sync_pb::DataTypeContext* context) const
OVERRIDE;
- virtual void ProcessGetUpdatesResponse(
+ virtual SyncerError ProcessGetUpdatesResponse(
const sync_pb::DataTypeProgressMarker& progress_marker,
const sync_pb::DataTypeContext& mutated_context,
const SyncEntityList& applicable_updates,
diff --git a/sync/engine/update_handler.h b/sync/engine/update_handler.h
index 29bdbc9dee..e4c9abc24b 100644
--- a/sync/engine/update_handler.h
+++ b/sync/engine/update_handler.h
@@ -8,6 +8,7 @@
#include <vector>
#include "sync/base/sync_export.h"
+#include "sync/internal_api/public/util/syncer_error.h"
namespace sync_pb {
class DataTypeContext;
@@ -49,7 +50,10 @@ class SYNC_EXPORT_PRIVATE UpdateHandler {
//
// In this context, "applicable_updates" means the set of updates belonging to
// this type.
- virtual void ProcessGetUpdatesResponse(
+ //
+ // Returns SYNCER_OK if the all data was processed successfully, a syncer
+ // error otherwise.
+ virtual SyncerError ProcessGetUpdatesResponse(
const sync_pb::DataTypeProgressMarker& progress_marker,
const sync_pb::DataTypeContext& mutated_context,
const SyncEntityList& applicable_updates,
diff --git a/sync/internal_api/js_sync_encryption_handler_observer.cc b/sync/internal_api/js_sync_encryption_handler_observer.cc
index d6bd50ecf5..a000fa674f 100644
--- a/sync/internal_api/js_sync_encryption_handler_observer.cc
+++ b/sync/internal_api/js_sync_encryption_handler_observer.cc
@@ -12,7 +12,6 @@
#include "base/values.h"
#include "sync/internal_api/public/base/model_type.h"
#include "sync/internal_api/public/util/sync_string_conversions.h"
-#include "sync/js/js_arg_list.h"
#include "sync/js/js_event_details.h"
#include "sync/js/js_event_handler.h"
#include "sync/util/cryptographer.h"
diff --git a/sync/internal_api/js_sync_manager_observer.cc b/sync/internal_api/js_sync_manager_observer.cc
index b5f84524ad..1361c8b8fe 100644
--- a/sync/internal_api/js_sync_manager_observer.cc
+++ b/sync/internal_api/js_sync_manager_observer.cc
@@ -14,7 +14,6 @@
#include "sync/internal_api/public/change_record.h"
#include "sync/internal_api/public/sessions/sync_session_snapshot.h"
#include "sync/internal_api/public/util/sync_string_conversions.h"
-#include "sync/js/js_arg_list.h"
#include "sync/js/js_event_details.h"
#include "sync/js/js_event_handler.h"
diff --git a/sync/internal_api/non_blocking_type_processor.cc b/sync/internal_api/non_blocking_type_processor.cc
index 242c42f257..8fd0d2775d 100644
--- a/sync/internal_api/non_blocking_type_processor.cc
+++ b/sync/internal_api/non_blocking_type_processor.cc
@@ -6,6 +6,7 @@
#include "base/message_loop/message_loop_proxy.h"
#include "sync/engine/non_blocking_type_processor_core.h"
+#include "sync/internal_api/public/sync_core_proxy.h"
namespace syncer {
@@ -25,9 +26,9 @@ ModelType NonBlockingTypeProcessor::GetModelType() const {
return type_;
}
-void NonBlockingTypeProcessor::Enable(SyncCoreProxy core_proxy_) {
+void NonBlockingTypeProcessor::Enable(SyncCoreProxy* core_proxy) {
DCHECK(CalledOnValidThread());
- core_proxy_.ConnectTypeToCore(
+ core_proxy->ConnectTypeToCore(
GetModelType(),
AsWeakPtr());
}
diff --git a/sync/internal_api/public/engine/sync_status.cc b/sync/internal_api/public/engine/sync_status.cc
index 6291b290a4..b1687e31d5 100644
--- a/sync/internal_api/public/engine/sync_status.cc
+++ b/sync/internal_api/public/engine/sync_status.cc
@@ -21,12 +21,6 @@ SyncStatus::SyncStatus()
num_commits_total(0),
num_local_overwrites_total(0),
num_server_overwrites_total(0),
- nonempty_get_updates(0),
- empty_get_updates(0),
- sync_cycles_with_commits(0),
- sync_cycles_without_commits(0),
- useless_sync_cycles(0),
- useful_sync_cycles(0),
nudge_source_notification(0),
nudge_source_local(0),
nudge_source_local_refresh(0),
diff --git a/sync/internal_api/public/engine/sync_status.h b/sync/internal_api/public/engine/sync_status.h
index 124dac6b0e..c32be00b41 100644
--- a/sync/internal_api/public/engine/sync_status.h
+++ b/sync/internal_api/public/engine/sync_status.h
@@ -65,18 +65,6 @@ struct SYNC_EXPORT SyncStatus {
int num_local_overwrites_total;
int num_server_overwrites_total;
- // Count of empty and non empty getupdates;
- int nonempty_get_updates;
- int empty_get_updates;
-
- // Count of sync cycles that successfully committed items;
- int sync_cycles_with_commits;
- int sync_cycles_without_commits;
-
- // Count of useless and useful syncs we perform.
- int useless_sync_cycles;
- int useful_sync_cycles;
-
// Nudge counts for each possible source
int nudge_source_notification;
int nudge_source_local;
diff --git a/sync/internal_api/public/non_blocking_type_processor.h b/sync/internal_api/public/non_blocking_type_processor.h
index a9079d5a03..0198c2763e 100644
--- a/sync/internal_api/public/non_blocking_type_processor.h
+++ b/sync/internal_api/public/non_blocking_type_processor.h
@@ -5,17 +5,16 @@
#ifndef SYNC_ENGINE_NON_BLOCKING_TYPE_PROCESSOR_H_
#define SYNC_ENGINE_NON_BLOCKING_TYPE_PROCESSOR_H_
-#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/sequenced_task_runner.h"
#include "base/threading/non_thread_safe.h"
#include "sync/base/sync_export.h"
#include "sync/internal_api/public/base/model_type.h"
-#include "sync/internal_api/public/sync_core_proxy.h"
#include "sync/protocol/sync.pb.h"
namespace syncer {
+class SyncCoreProxy;
class NonBlockingTypeProcessorCore;
// A sync component embedded on the synced type's thread that helps to handle
@@ -32,7 +31,7 @@ class SYNC_EXPORT_PRIVATE NonBlockingTypeProcessor : base::NonThreadSafe {
ModelType GetModelType() const;
// Starts the handshake with the sync thread.
- void Enable(SyncCoreProxy core_proxy_);
+ void Enable(SyncCoreProxy* core_proxy);
// Severs all ties to the sync thread.
// Another call to Enable() can be used to re-establish this connection.
diff --git a/sync/internal_api/public/read_transaction.h b/sync/internal_api/public/read_transaction.h
index 02e2633d8e..3a3dc8d8ac 100644
--- a/sync/internal_api/public/read_transaction.h
+++ b/sync/internal_api/public/read_transaction.h
@@ -13,6 +13,10 @@ namespace tracked_objects {
class Location;
} // namespace tracked_objects
+namespace sync_pb {
+class DataTypeContext;
+}
+
namespace syncer {
struct UserShare;
@@ -35,7 +39,11 @@ class SYNC_EXPORT ReadTransaction : public BaseTransaction {
// Return |transaction_version| of |type| stored in sync directory's
// persisted info.
- int64 GetModelVersion(ModelType type);
+ int64 GetModelVersion(ModelType type) const;
+
+ // Fills |context| with the datatype context associated with |type|.
+ void GetDataTypeContext(ModelType type,
+ sync_pb::DataTypeContext* context) const;
private:
void* operator new(size_t size); // Transaction is meant for stack use only.
diff --git a/sync/internal_api/public/sync_core_proxy.h b/sync/internal_api/public/sync_core_proxy.h
index dd5a4ac08b..8750b421b6 100644
--- a/sync/internal_api/public/sync_core_proxy.h
+++ b/sync/internal_api/public/sync_core_proxy.h
@@ -5,49 +5,30 @@
#ifndef SYNC_INTERNAL_API_PUBLIC_SYNC_CORE_PROXY_H_
#define SYNC_INTERNAL_API_PUBLIC_SYNC_CORE_PROXY_H_
-#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
-#include "base/sequenced_task_runner.h"
-#include "sync/base/sync_export.h"
#include "sync/internal_api/public/base/model_type.h"
namespace syncer {
-class SyncCore;
class NonBlockingTypeProcessor;
-// Encapsulates a reference to the sync core and the thread it's running on.
-// Used by sync's data types to connect with the sync core.
+// Interface for the datatype integration logic from non-sync threads.
//
-// It is epxected that this object will be copied to and used on many different
-// threads. It is small and safe to pass by value.
+// See SyncCoreProxyImpl for an actual implementation.
class SYNC_EXPORT_PRIVATE SyncCoreProxy {
public:
- SyncCoreProxy(
- scoped_refptr<base::SequencedTaskRunner> sync_task_runner,
- base::WeakPtr<SyncCore> sync_core);
- ~SyncCoreProxy();
+ SyncCoreProxy();
+ virtual ~SyncCoreProxy();
// Attempts to connect a non-blocking type to the sync core.
//
- // This may fail under some unusual circumstances, like shutdown. Due to the
- // nature of WeakPtrs and cross-thread communication, the caller will be
- // unable to distinguish a slow success from failure.
- //
// Must be called from the thread where the data type lives.
- void ConnectTypeToCore(
+ virtual void ConnectTypeToCore(
syncer::ModelType type,
- base::WeakPtr<NonBlockingTypeProcessor> type_processor);
-
- // Constructs and returns a useless instance of this object.
- static SyncCoreProxy GetInvalidSyncCoreProxyForTest();
-
- private:
- // A SequencedTaskRunner representing the thread where the SyncCore lives.
- scoped_refptr<base::SequencedTaskRunner> sync_task_runner_;
+ base::WeakPtr<NonBlockingTypeProcessor> type_processor) = 0;
- // The SyncCore this object is wrapping.
- base::WeakPtr<SyncCore> sync_core_;
+ // Creates a clone of this SyncCoreProxy.
+ virtual scoped_ptr<SyncCoreProxy> Clone() = 0;
};
} // namespace syncer
diff --git a/sync/internal_api/public/sync_manager.h b/sync/internal_api/public/sync_manager.h
index d10b9989eb..74885864a0 100644
--- a/sync/internal_api/public/sync_manager.h
+++ b/sync/internal_api/public/sync_manager.h
@@ -22,6 +22,7 @@
#include "sync/internal_api/public/engine/model_safe_worker.h"
#include "sync/internal_api/public/engine/sync_status.h"
#include "sync/internal_api/public/events/protocol_event.h"
+#include "sync/internal_api/public/sync_core_proxy.h"
#include "sync/internal_api/public/sync_encryption_handler.h"
#include "sync/internal_api/public/util/report_unrecoverable_error_function.h"
#include "sync/internal_api/public/util/unrecoverable_error_handler.h"
@@ -44,7 +45,7 @@ class HttpPostProviderFactory;
class InternalComponentsFactory;
class JsBackend;
class JsEventHandler;
-class SyncCore;
+class SyncCoreProxy;
class SyncEncryptionHandler;
class ProtocolEvent;
class SyncScheduler;
@@ -334,7 +335,7 @@ class SYNC_EXPORT SyncManager : public syncer::InvalidationHandler {
virtual UserShare* GetUserShare() = 0;
// Returns an instance of the main interface for non-blocking sync types.
- virtual base::WeakPtr<syncer::SyncCore> GetSyncCore() = 0;
+ virtual syncer::SyncCoreProxy* GetSyncCoreProxy() = 0;
// Returns the cache_guid of the currently open database.
// Requires that the SyncManager be initialized.
diff --git a/sync/internal_api/public/test/fake_sync_manager.h b/sync/internal_api/public/test/fake_sync_manager.h
index fae4c8eab6..55e4f3b3c5 100644
--- a/sync/internal_api/public/test/fake_sync_manager.h
+++ b/sync/internal_api/public/test/fake_sync_manager.h
@@ -10,6 +10,7 @@
#include "base/memory/ref_counted.h"
#include "base/observer_list.h"
#include "sync/internal_api/public/sync_manager.h"
+#include "sync/internal_api/public/test/null_sync_core_proxy.h"
#include "sync/internal_api/public/test/test_user_share.h"
#include "sync/notifier/invalidator_registrar.h"
@@ -119,7 +120,7 @@ class FakeSyncManager : public SyncManager {
virtual void SaveChanges() OVERRIDE;
virtual void ShutdownOnSyncThread() OVERRIDE;
virtual UserShare* GetUserShare() OVERRIDE;
- virtual base::WeakPtr<syncer::SyncCore> GetSyncCore() OVERRIDE;
+ virtual syncer::SyncCoreProxy* GetSyncCoreProxy() OVERRIDE;
virtual const std::string cache_guid() OVERRIDE;
virtual bool ReceivedExperiment(Experiments* experiments) OVERRIDE;
virtual bool HasUnsyncedItems() OVERRIDE;
@@ -163,6 +164,8 @@ class FakeSyncManager : public SyncManager {
TestUserShare test_user_share_;
+ NullSyncCoreProxy null_sync_core_proxy_;
+
DISALLOW_COPY_AND_ASSIGN(FakeSyncManager);
};
diff --git a/sync/internal_api/public/test/null_sync_core_proxy.h b/sync/internal_api/public/test/null_sync_core_proxy.h
new file mode 100644
index 0000000000..410a9927b3
--- /dev/null
+++ b/sync/internal_api/public/test/null_sync_core_proxy.h
@@ -0,0 +1,31 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SYNC_INTERNAL_API_PUBLIC_TEST_NULL_SYNC_CORE_PROXY_H_
+#define SYNC_INTERNAL_API_PUBLIC_TEST_NULL_SYNC_CORE_PROXY_H_
+
+#include "sync/internal_api/public/sync_core_proxy.h"
+#include "base/memory/weak_ptr.h"
+
+namespace syncer {
+
+class NonBlockingTypeProcessor;
+
+// A non-functional implementation of SyncCoreProxy.
+//
+// It supports Clone(), but not much else. Useful for testing.
+class NullSyncCoreProxy : public SyncCoreProxy {
+ public:
+ NullSyncCoreProxy();
+ virtual ~NullSyncCoreProxy();
+
+ virtual void ConnectTypeToCore(
+ syncer::ModelType type,
+ base::WeakPtr<NonBlockingTypeProcessor> processor) OVERRIDE;
+ virtual scoped_ptr<SyncCoreProxy> Clone() OVERRIDE;
+};
+
+} // namespace syncer
+
+#endif // SYNC_INTERNAL_API_PUBLIC_TEST_NULL_SYNC_CORE_PROXY_H_
diff --git a/sync/internal_api/public/util/syncer_error.cc b/sync/internal_api/public/util/syncer_error.cc
index e7cb66fbf4..81805d22aa 100644
--- a/sync/internal_api/public/util/syncer_error.cc
+++ b/sync/internal_api/public/util/syncer_error.cc
@@ -28,6 +28,7 @@ const char* GetSyncerErrorString(SyncerError value) {
ENUM_CASE(SERVER_RESPONSE_VALIDATION_FAILED);
ENUM_CASE(SERVER_RETURN_DISABLED_BY_ADMIN);
ENUM_CASE(SERVER_MORE_TO_DOWNLOAD);
+ ENUM_CASE(DATATYPE_TRIGGERED_RETRY);
ENUM_CASE(SYNCER_OK);
}
NOTREACHED();
diff --git a/sync/internal_api/public/util/syncer_error.h b/sync/internal_api/public/util/syncer_error.h
index 02da22c193..1a5ec79301 100644
--- a/sync/internal_api/public/util/syncer_error.h
+++ b/sync/internal_api/public/util/syncer_error.h
@@ -31,6 +31,9 @@ enum SYNC_EXPORT_PRIVATE SyncerError {
SERVER_RESPONSE_VALIDATION_FAILED,
SERVER_RETURN_DISABLED_BY_ADMIN,
+ // A datatype decided the sync cycle needed to be performed again.
+ DATATYPE_TRIGGERED_RETRY,
+
SERVER_MORE_TO_DOWNLOAD,
SYNCER_OK
diff --git a/sync/internal_api/read_transaction.cc b/sync/internal_api/read_transaction.cc
index 81e53400d2..ebc56ecc40 100644
--- a/sync/internal_api/read_transaction.cc
+++ b/sync/internal_api/read_transaction.cc
@@ -36,8 +36,15 @@ syncable::BaseTransaction* ReadTransaction::GetWrappedTrans() const {
return transaction_;
}
-int64 ReadTransaction::GetModelVersion(ModelType type) {
+int64 ReadTransaction::GetModelVersion(ModelType type) const {
return transaction_->directory()->GetTransactionVersion(type);
}
+void ReadTransaction::GetDataTypeContext(
+ ModelType type,
+ sync_pb::DataTypeContext* context) const {
+ return transaction_->directory()->GetDataTypeContext(
+ transaction_, type, context);
+}
+
} // namespace syncer
diff --git a/sync/internal_api/sync_core_proxy.cc b/sync/internal_api/sync_core_proxy.cc
index 5ba3135f6d..4e6f7f6573 100644
--- a/sync/internal_api/sync_core_proxy.cc
+++ b/sync/internal_api/sync_core_proxy.cc
@@ -4,37 +4,10 @@
#include "sync/internal_api/public/sync_core_proxy.h"
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/message_loop/message_loop_proxy.h"
-#include "sync/internal_api/sync_core.h"
-
namespace syncer {
-SyncCoreProxy::SyncCoreProxy(
- scoped_refptr<base::SequencedTaskRunner> sync_task_runner,
- base::WeakPtr<SyncCore> sync_core)
- : sync_task_runner_(sync_task_runner),
- sync_core_(sync_core) {}
+SyncCoreProxy::SyncCoreProxy() {}
SyncCoreProxy::~SyncCoreProxy() {}
-void SyncCoreProxy::ConnectTypeToCore(
- ModelType type,
- base::WeakPtr<NonBlockingTypeProcessor> type_processor) {
- VLOG(1) << "ConnectSyncTypeToCore: " << ModelTypeToString(type);
- sync_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&SyncCore::ConnectSyncTypeToCore,
- sync_core_,
- type,
- base::MessageLoopProxy::current(),
- type_processor));
-}
-
-SyncCoreProxy SyncCoreProxy::GetInvalidSyncCoreProxyForTest() {
- return SyncCoreProxy(scoped_refptr<base::SequencedTaskRunner>(),
- base::WeakPtr<SyncCore>());
-}
-
} // namespace syncer
diff --git a/sync/internal_api/sync_core_proxy_impl.cc b/sync/internal_api/sync_core_proxy_impl.cc
new file mode 100644
index 0000000000..bfdd1462aa
--- /dev/null
+++ b/sync/internal_api/sync_core_proxy_impl.cc
@@ -0,0 +1,40 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "sync/internal_api/sync_core_proxy_impl.h"
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/message_loop/message_loop_proxy.h"
+#include "sync/internal_api/sync_core.h"
+
+namespace syncer {
+
+SyncCoreProxyImpl::SyncCoreProxyImpl(
+ scoped_refptr<base::SequencedTaskRunner> sync_task_runner,
+ base::WeakPtr<SyncCore> sync_core)
+ : sync_task_runner_(sync_task_runner),
+ sync_core_(sync_core) {}
+
+SyncCoreProxyImpl::~SyncCoreProxyImpl() {}
+
+void SyncCoreProxyImpl::ConnectTypeToCore(
+ ModelType type,
+ base::WeakPtr<NonBlockingTypeProcessor> type_processor) {
+ VLOG(1) << "ConnectTypeToCore: " << ModelTypeToString(type);
+ sync_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&SyncCore::ConnectSyncTypeToCore,
+ sync_core_,
+ type,
+ base::MessageLoopProxy::current(),
+ type_processor));
+}
+
+scoped_ptr<SyncCoreProxy> SyncCoreProxyImpl::Clone() {
+ return scoped_ptr<SyncCoreProxy>(
+ new SyncCoreProxyImpl(sync_task_runner_, sync_core_));
+}
+
+} // namespace syncer
diff --git a/sync/internal_api/sync_core_proxy_impl.h b/sync/internal_api/sync_core_proxy_impl.h
new file mode 100644
index 0000000000..7ccb26a722
--- /dev/null
+++ b/sync/internal_api/sync_core_proxy_impl.h
@@ -0,0 +1,55 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SYNC_INTERNAL_API_SYNC_CORE_PROXY_IMPL_H_
+#define SYNC_INTERNAL_API_SYNC_CORE_PROXY_IMPL_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/sequenced_task_runner.h"
+#include "sync/base/sync_export.h"
+#include "sync/internal_api/public/base/model_type.h"
+#include "sync/internal_api/public/sync_core_proxy.h"
+
+namespace syncer {
+
+class SyncCore;
+class NonBlockingTypeProcessor;
+
+// Encapsulates a reference to the sync core and the thread it's running on.
+// Used by sync's data types to connect with the sync core.
+//
+// It is epxected that this object will be copied to and used on many different
+// threads. It is small and safe to pass by value.
+class SYNC_EXPORT_PRIVATE SyncCoreProxyImpl : public SyncCoreProxy {
+ public:
+ SyncCoreProxyImpl(
+ scoped_refptr<base::SequencedTaskRunner> sync_task_runner,
+ base::WeakPtr<SyncCore> sync_core);
+ virtual ~SyncCoreProxyImpl();
+
+ // Attempts to connect a non-blocking type to the sync core.
+ //
+ // This may fail under some unusual circumstances, like shutdown. Due to the
+ // nature of WeakPtrs and cross-thread communication, the caller will be
+ // unable to distinguish a slow success from failure.
+ //
+ // Must be called from the thread where the data type lives.
+ virtual void ConnectTypeToCore(
+ syncer::ModelType type,
+ base::WeakPtr<NonBlockingTypeProcessor> type_processor) OVERRIDE;
+
+ virtual scoped_ptr<SyncCoreProxy> Clone() OVERRIDE;
+
+ private:
+ // A SequencedTaskRunner representing the thread where the SyncCore lives.
+ scoped_refptr<base::SequencedTaskRunner> sync_task_runner_;
+
+ // The SyncCore this object is wrapping.
+ base::WeakPtr<SyncCore> sync_core_;
+};
+
+} // namespace syncer
+
+#endif // SYNC_INTERNAL_API_SYNC_CORE_PROXY_IMPL_H_
diff --git a/sync/internal_api/sync_core_proxy_unittest.cc b/sync/internal_api/sync_core_proxy_impl_unittest.cc
index d6885bfcb4..a3e228c9f4 100644
--- a/sync/internal_api/sync_core_proxy_unittest.cc
+++ b/sync/internal_api/sync_core_proxy_impl_unittest.cc
@@ -8,16 +8,16 @@
#include "base/sequenced_task_runner.h"
#include "sync/internal_api/public/base/model_type.h"
#include "sync/internal_api/public/non_blocking_type_processor.h"
-#include "sync/internal_api/public/sync_core_proxy.h"
#include "sync/internal_api/sync_core.h"
+#include "sync/internal_api/sync_core_proxy_impl.h"
#include "sync/sessions/model_type_registry.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace syncer {
-class SyncCoreProxyTest : public ::testing::Test {
+class SyncCoreProxyImplTest : public ::testing::Test {
public:
- SyncCoreProxyTest()
+ SyncCoreProxyImplTest()
: sync_task_runner_(base::MessageLoopProxy::current()),
type_task_runner_(base::MessageLoopProxy::current()),
core_(new SyncCore(&registry_)),
@@ -31,8 +31,8 @@ class SyncCoreProxyTest : public ::testing::Test {
core_.reset();
}
- SyncCoreProxy GetProxy() {
- return core_proxy_;
+ SyncCoreProxy* GetProxy() {
+ return &core_proxy_;
}
private:
@@ -41,11 +41,11 @@ class SyncCoreProxyTest : public ::testing::Test {
scoped_refptr<base::SequencedTaskRunner> type_task_runner_;
ModelTypeRegistry registry_;
scoped_ptr<SyncCore> core_;
- SyncCoreProxy core_proxy_;
+ SyncCoreProxyImpl core_proxy_;
};
// Try to connect a type to a SyncCore that has already shut down.
-TEST_F(SyncCoreProxyTest, FailToConnect1) {
+TEST_F(SyncCoreProxyImplTest, FailToConnect1) {
NonBlockingTypeProcessor themes_processor(syncer::THEMES);
DisableSync();
themes_processor.Enable(GetProxy());
@@ -56,7 +56,7 @@ TEST_F(SyncCoreProxyTest, FailToConnect1) {
}
// Try to connect a type to a SyncCore as it shuts down.
-TEST_F(SyncCoreProxyTest, FailToConnect2) {
+TEST_F(SyncCoreProxyImplTest, FailToConnect2) {
NonBlockingTypeProcessor themes_processor(syncer::THEMES);
themes_processor.Enable(GetProxy());
DisableSync();
@@ -67,7 +67,7 @@ TEST_F(SyncCoreProxyTest, FailToConnect2) {
}
// Tests the case where the type's processor shuts down first.
-TEST_F(SyncCoreProxyTest, TypeDisconnectsFirst) {
+TEST_F(SyncCoreProxyImplTest, TypeDisconnectsFirst) {
scoped_ptr<NonBlockingTypeProcessor> themes_processor
(new NonBlockingTypeProcessor(syncer::THEMES));
themes_processor->Enable(GetProxy());
@@ -80,7 +80,7 @@ TEST_F(SyncCoreProxyTest, TypeDisconnectsFirst) {
}
// Tests the case where the sync thread shuts down first.
-TEST_F(SyncCoreProxyTest, SyncDisconnectsFirst) {
+TEST_F(SyncCoreProxyImplTest, SyncDisconnectsFirst) {
scoped_ptr<NonBlockingTypeProcessor> themes_processor
(new NonBlockingTypeProcessor(syncer::THEMES));
themes_processor->Enable(GetProxy());
diff --git a/sync/internal_api/sync_manager_impl.cc b/sync/internal_api/sync_manager_impl.cc
index 94dfc5856d..7658f58184 100644
--- a/sync/internal_api/sync_manager_impl.cc
+++ b/sync/internal_api/sync_manager_impl.cc
@@ -29,11 +29,13 @@
#include "sync/internal_api/public/internal_components_factory.h"
#include "sync/internal_api/public/read_node.h"
#include "sync/internal_api/public/read_transaction.h"
+#include "sync/internal_api/public/sync_core_proxy.h"
#include "sync/internal_api/public/user_share.h"
#include "sync/internal_api/public/util/experiments.h"
#include "sync/internal_api/public/write_node.h"
#include "sync/internal_api/public/write_transaction.h"
#include "sync/internal_api/sync_core.h"
+#include "sync/internal_api/sync_core_proxy_impl.h"
#include "sync/internal_api/syncapi_internal.h"
#include "sync/internal_api/syncapi_server_connection_manager.h"
#include "sync/notifier/invalidation_util.h"
@@ -397,6 +399,14 @@ void SyncManagerImpl::Init(
sync_core_.reset(new SyncCore(model_type_registry_.get()));
+ // Bind the SyncCore WeakPtr to this thread. This helps us crash earlier if
+ // the pointer is misused in debug mode.
+ base::WeakPtr<SyncCore> weak_core = sync_core_->AsWeakPtr();
+ weak_core.get();
+
+ sync_core_proxy_.reset(
+ new SyncCoreProxyImpl(base::MessageLoopProxy::current(), weak_core));
+
// Build a SyncSessionContext and store the worker in it.
DVLOG(1) << "Sync is bringing up SyncSessionContext.";
std::vector<SyncEngineEventListener*> listeners;
@@ -941,14 +951,6 @@ void SyncManagerImpl::SetJsEventHandler(
js_sync_encryption_handler_observer_.SetJsEventHandler(event_handler);
}
-// TODO(rlarocque): This function is no longer needed and should be removed.
-// See http://crbug.com/357821.
-void SyncManagerImpl::ProcessJsMessage(
- const std::string& name, const JsArgList& args,
- const WeakHandle<JsReplyHandler>& reply_handler) {
- NOTREACHED();
-}
-
scoped_ptr<base::ListValue> SyncManagerImpl::GetAllNodesForType(
syncer::ModelType type) {
DirectoryTypeDebugInfoEmitterMap* emitter_map =
@@ -1025,9 +1027,9 @@ UserShare* SyncManagerImpl::GetUserShare() {
return &share_;
}
-base::WeakPtr<syncer::SyncCore> SyncManagerImpl::GetSyncCore() {
+syncer::SyncCoreProxy* SyncManagerImpl::GetSyncCoreProxy() {
DCHECK(initialized_);
- return sync_core_->AsWeakPtr();
+ return sync_core_proxy_.get();
}
const std::string SyncManagerImpl::cache_guid() {
diff --git a/sync/internal_api/sync_manager_impl.h b/sync/internal_api/sync_manager_impl.h
index 52d382ed1a..653e48a357 100644
--- a/sync/internal_api/sync_manager_impl.h
+++ b/sync/internal_api/sync_manager_impl.h
@@ -19,6 +19,7 @@
#include "sync/internal_api/js_sync_encryption_handler_observer.h"
#include "sync/internal_api/js_sync_manager_observer.h"
#include "sync/internal_api/protocol_event_buffer.h"
+#include "sync/internal_api/public/sync_core_proxy.h"
#include "sync/internal_api/public/sync_manager.h"
#include "sync/internal_api/public/user_share.h"
#include "sync/internal_api/sync_encryption_handler_impl.h"
@@ -33,6 +34,7 @@ namespace syncer {
class ModelTypeRegistry;
class SyncAPIServerConnectionManager;
+class SyncCore;
class WriteNode;
class WriteTransaction;
@@ -110,7 +112,7 @@ class SYNC_EXPORT_PRIVATE SyncManagerImpl :
virtual void SaveChanges() OVERRIDE;
virtual void ShutdownOnSyncThread() OVERRIDE;
virtual UserShare* GetUserShare() OVERRIDE;
- virtual base::WeakPtr<syncer::SyncCore> GetSyncCore() OVERRIDE;
+ virtual syncer::SyncCoreProxy* GetSyncCoreProxy() OVERRIDE;
virtual const std::string cache_guid() OVERRIDE;
virtual bool ReceivedExperiment(Experiments* experiments) OVERRIDE;
virtual bool HasUnsyncedItems() OVERRIDE;
@@ -156,9 +158,6 @@ class SYNC_EXPORT_PRIVATE SyncManagerImpl :
// JsBackend implementation.
virtual void SetJsEventHandler(
const WeakHandle<JsEventHandler>& event_handler) OVERRIDE;
- virtual void ProcessJsMessage(
- const std::string& name, const JsArgList& args,
- const WeakHandle<JsReplyHandler>& reply_handler) OVERRIDE;
// DirectoryChangeDelegate implementation.
// This listener is called upon completion of a syncable transaction, and
@@ -301,8 +300,9 @@ class SYNC_EXPORT_PRIVATE SyncManagerImpl :
// This state changes when entering or exiting a configuration cycle.
scoped_ptr<ModelTypeRegistry> model_type_registry_;
- // The main interface for non-blocking sync types.
+ // The main interface for non-blocking sync types and a thread-safe wrapper.
scoped_ptr<SyncCore> sync_core_;
+ scoped_ptr<SyncCoreProxy> sync_core_proxy_;
// A container of various bits of information used by the SyncScheduler to
// create SyncSessions. Must outlive the SyncScheduler.
diff --git a/sync/internal_api/test/fake_sync_manager.cc b/sync/internal_api/test/fake_sync_manager.cc
index 9f1abb8c08..c7873a80cc 100644
--- a/sync/internal_api/test/fake_sync_manager.cc
+++ b/sync/internal_api/test/fake_sync_manager.cc
@@ -218,8 +218,8 @@ UserShare* FakeSyncManager::GetUserShare() {
return test_user_share_.user_share();
}
-base::WeakPtr<syncer::SyncCore> FakeSyncManager::GetSyncCore() {
- return base::WeakPtr<syncer::SyncCore>();
+syncer::SyncCoreProxy* FakeSyncManager::GetSyncCoreProxy() {
+ return &null_sync_core_proxy_;
}
const std::string FakeSyncManager::cache_guid() {
diff --git a/sync/internal_api/test/null_sync_core_proxy.cc b/sync/internal_api/test/null_sync_core_proxy.cc
new file mode 100644
index 0000000000..866e68b33f
--- /dev/null
+++ b/sync/internal_api/test/null_sync_core_proxy.cc
@@ -0,0 +1,23 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "sync/internal_api/public/test/null_sync_core_proxy.h"
+
+namespace syncer {
+
+NullSyncCoreProxy::NullSyncCoreProxy() {}
+
+NullSyncCoreProxy::~NullSyncCoreProxy() {}
+
+void NullSyncCoreProxy::ConnectTypeToCore(
+ syncer::ModelType type,
+ base::WeakPtr<NonBlockingTypeProcessor> processor) {
+ NOTREACHED() << "NullSyncCoreProxy is not meant to be used";
+}
+
+scoped_ptr<SyncCoreProxy> NullSyncCoreProxy::Clone() {
+ return scoped_ptr<SyncCoreProxy>(new NullSyncCoreProxy());
+}
+
+} // namespace syncer
diff --git a/sync/js/README.js b/sync/js/README.js
index 0fbfa66bc0..3a99d1e7a3 100644
--- a/sync/js/README.js
+++ b/sync/js/README.js
@@ -1,48 +1,16 @@
-Overview of chrome://sync-internals
------------------------------------
-
-This note explains how chrome://sync-internals (also known as
-about:sync) interacts with the sync service/backend.
-
-Basically, chrome://sync-internals sends messages to the sync backend
-and the sync backend sends the reply asynchronously. The sync backend
-also asynchronously raises events which chrome://sync-internals listen
-to.
-
-A message and its reply has a name and a list of arguments, which is
-basically a wrapper around an immutable ListValue.
-
-An event has a name and a details object, which is represented by a
-JsEventDetails (js_event_details.h) object, which is basically a
-wrapper around an immutable DictionaryValue.
-
-Message/event flow
-------------------
-
-chrome://sync-internals is represented by SyncInternalsUI
-(chrome/browser/ui/webui/sync_internals_ui.h). SyncInternalsUI
-interacts with the sync service via a JsController (js_controller.h)
-object, which has a ProcessJsMessage() method that just delegates to
-an underlying JsBackend instance (js_backend.h). The SyncInternalsUI
-object also registers itself (as a JsEventHandler
-[js_event_handler.h]) to the JsController object, and any events
-raised by the JsBackend are propagated to the JsController and then to
-the registered JsEventHandlers.
-
-The ProcessJsMessage() takes a WeakHandle (weak_handle.h) to a
-JsReplyHandler (js_reply_handler.h), which the backend uses to send
-replies safely across threads. SyncInternalsUI implements
-JsReplyHandler, so it simply passes itself as the reply handler when
-it calls ProcessJsMessage() on the JsController.
-
-The following objects live on the UI thread:
-
-- SyncInternalsUI (implements JsEventHandler, JsReplyHandler)
-- SyncJsController (implements JsController, JsEventHandler)
-
-The following objects live on the sync thread:
-
-- SyncManager::SyncInternal (implements JsBackend)
-
-Of course, none of these objects need to know where the other objects
-live, since they interact via WeakHandles.
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+This framework was once used to implement an asynchronous request/reply
+protocol between the chrome://sync-internals page and the sync backend thread.
+Much of it has been removed in favor of an ad-hoc system that allows us to
+offer better safety guarantees, and to dispatch requests to different threads.
+
+All that remains are some WeakHandles that allow us to send JsEvents from the
+sync backend to about:sync. The SyncInternalsUI implements JsEventHandler in
+order to receive these events. The SyncManager implements JsBackend in order
+to send them. The SyncJsController acts as an intermediary between them.
+
+The old framework may still be useful to someone. Feel free to retrieve it
+from SVN history if you feel you can make use of it.
diff --git a/sync/js/js_arg_list.cc b/sync/js/js_arg_list.cc
deleted file mode 100644
index e3317e5f57..0000000000
--- a/sync/js/js_arg_list.cc
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sync/js/js_arg_list.h"
-
-#include "base/json/json_writer.h"
-
-namespace syncer {
-
-JsArgList::JsArgList() {}
-
-JsArgList::JsArgList(base::ListValue* args) : args_(args) {}
-
-JsArgList::~JsArgList() {}
-
-const base::ListValue& JsArgList::Get() const {
- return args_.Get();
-}
-
-std::string JsArgList::ToString() const {
- std::string str;
- base::JSONWriter::Write(&Get(), &str);
- return str;
-}
-
-} // namespace syncer
diff --git a/sync/js/js_arg_list.h b/sync/js/js_arg_list.h
deleted file mode 100644
index 34a0cf6966..0000000000
--- a/sync/js/js_arg_list.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SYNC_JS_JS_ARG_LIST_H_
-#define SYNC_JS_JS_ARG_LIST_H_
-
-// See README.js for design comments.
-
-#include <string>
-
-#include "base/values.h"
-#include "sync/base/sync_export.h"
-#include "sync/internal_api/public/util/immutable.h"
-
-namespace syncer {
-
-// A thin wrapper around Immutable<ListValue>. Used for passing
-// around argument lists to different threads.
-class SYNC_EXPORT JsArgList {
- public:
- // Uses an empty argument list.
- JsArgList();
-
- // Takes over the data in |args|, leaving |args| empty.
- explicit JsArgList(base::ListValue* args);
-
- ~JsArgList();
-
- const base::ListValue& Get() const;
-
- std::string ToString() const;
-
- // Copy constructor and assignment operator welcome.
-
- private:
- typedef Immutable<base::ListValue, HasSwapMemFnByPtr<base::ListValue> >
- ImmutableListValue;
- ImmutableListValue args_;
-};
-
-} // namespace syncer
-
-#endif // SYNC_JS_JS_ARG_LIST_H_
diff --git a/sync/js/js_arg_list_unittest.cc b/sync/js/js_arg_list_unittest.cc
deleted file mode 100644
index 2a10286751..0000000000
--- a/sync/js/js_arg_list_unittest.cc
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sync/js/js_arg_list.h"
-
-#include "base/memory/scoped_ptr.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace syncer {
-namespace {
-
-class JsArgListTest : public testing::Test {};
-
-TEST_F(JsArgListTest, EmptyList) {
- JsArgList arg_list;
- EXPECT_TRUE(arg_list.Get().empty());
- EXPECT_EQ("[]", arg_list.ToString());
-}
-
-TEST_F(JsArgListTest, FromList) {
- scoped_ptr<base::ListValue> list(new base::ListValue());
- list->Append(new base::FundamentalValue(false));
- list->Append(new base::FundamentalValue(5));
- base::DictionaryValue* dict = new base::DictionaryValue();
- list->Append(dict);
- dict->SetString("foo", "bar");
- dict->Set("baz", new base::ListValue());
-
- scoped_ptr<base::ListValue> list_copy(list->DeepCopy());
-
- JsArgList arg_list(list.get());
-
- // |arg_list| should take over |list|'s data.
- EXPECT_TRUE(list->empty());
- EXPECT_TRUE(arg_list.Get().Equals(list_copy.get()));
-}
-
-} // namespace
-} // namespace syncer
diff --git a/sync/js/js_backend.h b/sync/js/js_backend.h
index e39600a8bc..a0ef317ba6 100644
--- a/sync/js/js_backend.h
+++ b/sync/js/js_backend.h
@@ -13,9 +13,7 @@
namespace syncer {
-class JsArgList;
class JsEventHandler;
-class JsReplyHandler;
template <typename T> class WeakHandle;
// Interface representing the backend of chrome://sync-internals. A
@@ -27,12 +25,6 @@ class SYNC_EXPORT_PRIVATE JsBackend {
virtual void SetJsEventHandler(
const WeakHandle<JsEventHandler>& event_handler) = 0;
- // Processes the given message and replies via the given handler, if
- // initialized.
- virtual void ProcessJsMessage(
- const std::string& name, const JsArgList& args,
- const WeakHandle<JsReplyHandler>& reply_handler) = 0;
-
protected:
virtual ~JsBackend() {}
};
diff --git a/sync/js/js_controller.h b/sync/js/js_controller.h
index 08432bf004..482c8c1eba 100644
--- a/sync/js/js_controller.h
+++ b/sync/js/js_controller.h
@@ -13,9 +13,7 @@
namespace syncer {
-class JsArgList;
class JsEventHandler;
-class JsReplyHandler;
template <typename T> class WeakHandle;
// An interface for objects that JsEventHandlers directly interact
@@ -36,12 +34,6 @@ class SYNC_EXPORT JsController {
// immediately stop receiving any JS events.
virtual void RemoveJsEventHandler(JsEventHandler* event_handler) = 0;
- // Processes a JS message. The reply (if any) will be sent to
- // |reply_handler| if it is initialized.
- virtual void ProcessJsMessage(
- const std::string& name, const JsArgList& args,
- const WeakHandle<JsReplyHandler>& reply_handler) = 0;
-
protected:
virtual ~JsController() {}
};
diff --git a/sync/js/js_reply_handler.h b/sync/js/js_reply_handler.h
deleted file mode 100644
index 3026b7b4da..0000000000
--- a/sync/js/js_reply_handler.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SYNC_JS_JS_REPLY_HANDLER_H_
-#define SYNC_JS_JS_REPLY_HANDLER_H_
-
-// See README.js for design comments.
-
-#include <string>
-
-namespace syncer {
-
-class JsArgList;
-
-// An interface for objects that handle Javascript message replies
-// (e.g., WebUIs).
-class JsReplyHandler {
- public:
- virtual void HandleJsReply(
- const std::string& name, const JsArgList& args) = 0;
-
- protected:
- virtual ~JsReplyHandler() {}
-};
-
-} // namespace syncer
-
-#endif // SYNC_JS_JS_REPLY_HANDLER_H_
diff --git a/sync/js/js_test_util.cc b/sync/js/js_test_util.cc
index 7d40289ef9..f596136a76 100644
--- a/sync/js/js_test_util.cc
+++ b/sync/js/js_test_util.cc
@@ -6,51 +6,16 @@
#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
-#include "sync/js/js_arg_list.h"
#include "sync/js/js_event_details.h"
namespace syncer {
-void PrintTo(const JsArgList& args, ::std::ostream* os) {
- *os << args.ToString();
-}
-
void PrintTo(const JsEventDetails& details, ::std::ostream* os) {
*os << details.ToString();
}
namespace {
-// Matcher implementation for HasArgs().
-class HasArgsMatcher
- : public ::testing::MatcherInterface<const JsArgList&> {
- public:
- explicit HasArgsMatcher(const JsArgList& expected_args)
- : expected_args_(expected_args) {}
-
- virtual ~HasArgsMatcher() {}
-
- virtual bool MatchAndExplain(
- const JsArgList& args,
- ::testing::MatchResultListener* listener) const {
- // No need to annotate listener since we already define PrintTo().
- return args.Get().Equals(&expected_args_.Get());
- }
-
- virtual void DescribeTo(::std::ostream* os) const {
- *os << "has args " << expected_args_.ToString();
- }
-
- virtual void DescribeNegationTo(::std::ostream* os) const {
- *os << "doesn't have args " << expected_args_.ToString();
- }
-
- private:
- const JsArgList expected_args_;
-
- DISALLOW_COPY_AND_ASSIGN(HasArgsMatcher);
-};
-
// Matcher implementation for HasDetails().
class HasDetailsMatcher
: public ::testing::MatcherInterface<const JsEventDetails&> {
@@ -83,10 +48,6 @@ class HasDetailsMatcher
} // namespace
-::testing::Matcher<const JsArgList&> HasArgs(const JsArgList& expected_args) {
- return ::testing::MakeMatcher(new HasArgsMatcher(expected_args));
-}
-
::testing::Matcher<const JsEventDetails&> HasDetails(
const JsEventDetails& expected_details) {
return ::testing::MakeMatcher(new HasDetailsMatcher(expected_details));
@@ -119,13 +80,5 @@ WeakHandle<JsEventHandler> MockJsEventHandler::AsWeakHandle() {
MockJsEventHandler::~MockJsEventHandler() {}
-MockJsReplyHandler::MockJsReplyHandler() {}
-
-MockJsReplyHandler::~MockJsReplyHandler() {}
-
-WeakHandle<JsReplyHandler> MockJsReplyHandler::AsWeakHandle() {
- return MakeWeakHandle(AsWeakPtr());
-}
-
} // namespace syncer
diff --git a/sync/js/js_test_util.h b/sync/js/js_test_util.h
index 8f9824837f..b5ae4e8d78 100644
--- a/sync/js/js_test_util.h
+++ b/sync/js/js_test_util.h
@@ -13,7 +13,6 @@
#include "sync/js/js_backend.h"
#include "sync/js/js_controller.h"
#include "sync/js/js_event_handler.h"
-#include "sync/js/js_reply_handler.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace base {
@@ -23,18 +22,11 @@ class ListValue;
namespace syncer {
-class JsArgList;
class JsEventDetails;
// Defined for googletest. Equivalent to "*os << args.ToString()".
-void PrintTo(const JsArgList& args, ::std::ostream* os);
void PrintTo(const JsEventDetails& details, ::std::ostream* os);
-// A gmock matcher for JsArgList. Use like:
-//
-// EXPECT_CALL(mock, HandleJsReply("foo", HasArgs(expected_args)));
-::testing::Matcher<const JsArgList&> HasArgs(const JsArgList& expected_args);
-
// A gmock matcher for JsEventDetails. Use like:
//
// EXPECT_CALL(mock, HandleJsEvent("foo", HasArgs(expected_details)));
@@ -56,8 +48,6 @@ class MockJsBackend : public JsBackend,
WeakHandle<JsBackend> AsWeakHandle();
MOCK_METHOD1(SetJsEventHandler, void(const WeakHandle<JsEventHandler>&));
- MOCK_METHOD3(ProcessJsMessage, void(const ::std::string&, const JsArgList&,
- const WeakHandle<JsReplyHandler>&));
};
class MockJsController : public JsController,
@@ -68,9 +58,6 @@ class MockJsController : public JsController,
MOCK_METHOD1(AddJsEventHandler, void(JsEventHandler*));
MOCK_METHOD1(RemoveJsEventHandler, void(JsEventHandler*));
- MOCK_METHOD3(ProcessJsMessage,
- void(const ::std::string&, const JsArgList&,
- const WeakHandle<JsReplyHandler>&));
};
class MockJsEventHandler
@@ -86,19 +73,6 @@ class MockJsEventHandler
void(const ::std::string&, const JsEventDetails&));
};
-class MockJsReplyHandler
- : public JsReplyHandler,
- public base::SupportsWeakPtr<MockJsReplyHandler> {
- public:
- MockJsReplyHandler();
- virtual ~MockJsReplyHandler();
-
- WeakHandle<JsReplyHandler> AsWeakHandle();
-
- MOCK_METHOD2(HandleJsReply,
- void(const ::std::string&, const JsArgList&));
-};
-
} // namespace syncer
#endif // SYNC_JS_JS_TEST_UTIL_H_
diff --git a/sync/js/sync_js_controller.cc b/sync/js/sync_js_controller.cc
index 4d3148fdd0..42199d2997 100644
--- a/sync/js/sync_js_controller.cc
+++ b/sync/js/sync_js_controller.cc
@@ -10,13 +10,6 @@
namespace syncer {
-SyncJsController::PendingJsMessage::PendingJsMessage(
- const std::string& name, const JsArgList& args,
- const WeakHandle<JsReplyHandler>& reply_handler)
- : name(name), args(args), reply_handler(reply_handler) {}
-
-SyncJsController::PendingJsMessage::~PendingJsMessage() {}
-
SyncJsController::SyncJsController() {}
SyncJsController::~SyncJsController() {
@@ -37,28 +30,6 @@ void SyncJsController::AttachJsBackend(
const WeakHandle<JsBackend>& js_backend) {
js_backend_ = js_backend;
UpdateBackendEventHandler();
-
- if (js_backend_.IsInitialized()) {
- // Process any queued messages.
- for (PendingJsMessageList::const_iterator it =
- pending_js_messages_.begin();
- it != pending_js_messages_.end(); ++it) {
- js_backend_.Call(FROM_HERE, &JsBackend::ProcessJsMessage,
- it->name, it->args, it->reply_handler);
- }
- }
-}
-
-void SyncJsController::ProcessJsMessage(
- const std::string& name, const JsArgList& args,
- const WeakHandle<JsReplyHandler>& reply_handler) {
- if (js_backend_.IsInitialized()) {
- js_backend_.Call(FROM_HERE, &JsBackend::ProcessJsMessage,
- name, args, reply_handler);
- } else {
- pending_js_messages_.push_back(
- PendingJsMessage(name, args, reply_handler));
- }
}
void SyncJsController::HandleJsEvent(const std::string& name,
diff --git a/sync/js/sync_js_controller.h b/sync/js/sync_js_controller.h
index 0e259f860a..f0bb423b8c 100644
--- a/sync/js/sync_js_controller.h
+++ b/sync/js/sync_js_controller.h
@@ -14,7 +14,6 @@
#include "base/observer_list.h"
#include "sync/base/sync_export.h"
#include "sync/internal_api/public/util/weak_handle.h"
-#include "sync/js/js_arg_list.h"
#include "sync/js/js_controller.h"
#include "sync/js/js_event_handler.h"
@@ -39,39 +38,18 @@ class SYNC_EXPORT SyncJsController
// JsController implementation.
virtual void AddJsEventHandler(JsEventHandler* event_handler) OVERRIDE;
virtual void RemoveJsEventHandler(JsEventHandler* event_handler) OVERRIDE;
- // Queues up any messages that are sent when there is no attached
- // initialized backend.
- virtual void ProcessJsMessage(
- const std::string& name, const JsArgList& args,
- const WeakHandle<JsReplyHandler>& reply_handler) OVERRIDE;
// JsEventHandler implementation.
virtual void HandleJsEvent(const std::string& name,
const JsEventDetails& details) OVERRIDE;
private:
- // A struct used to hold the arguments to ProcessJsMessage() for
- // future invocation.
- struct PendingJsMessage {
- std::string name;
- JsArgList args;
- WeakHandle<JsReplyHandler> reply_handler;
-
- PendingJsMessage(const std::string& name, const JsArgList& args,
- const WeakHandle<JsReplyHandler>& reply_handler);
-
- ~PendingJsMessage();
- };
-
- typedef std::vector<PendingJsMessage> PendingJsMessageList;
-
// Sets |js_backend_|'s event handler depending on how many
// underlying event handlers we have.
void UpdateBackendEventHandler();
WeakHandle<JsBackend> js_backend_;
ObserverList<JsEventHandler> js_event_handlers_;
- PendingJsMessageList pending_js_messages_;
DISALLOW_COPY_AND_ASSIGN(SyncJsController);
};
diff --git a/sync/js/sync_js_controller_unittest.cc b/sync/js/sync_js_controller_unittest.cc
index eca617c2d4..f6f1abf85b 100644
--- a/sync/js/sync_js_controller_unittest.cc
+++ b/sync/js/sync_js_controller_unittest.cc
@@ -6,7 +6,6 @@
#include "base/message_loop/message_loop.h"
#include "base/values.h"
-#include "sync/js/js_arg_list.h"
#include "sync/js/js_event_details.h"
#include "sync/js/js_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -30,91 +29,6 @@ class SyncJsControllerTest : public testing::Test {
base::MessageLoop message_loop_;
};
-ACTION_P(ReplyToMessage, reply_name) {
- arg2.Call(FROM_HERE, &JsReplyHandler::HandleJsReply, reply_name, JsArgList());
-}
-
-TEST_F(SyncJsControllerTest, Messages) {
- InSequence dummy;
- // |mock_backend| needs to outlive |sync_js_controller|.
- StrictMock<MockJsBackend> mock_backend;
- StrictMock<MockJsReplyHandler> mock_reply_handler;
- SyncJsController sync_js_controller;
-
- base::ListValue arg_list1, arg_list2;
- arg_list1.Append(new base::FundamentalValue(false));
- arg_list2.Append(new base::FundamentalValue(5));
- JsArgList args1(&arg_list1), args2(&arg_list2);
-
- EXPECT_CALL(mock_backend, SetJsEventHandler(_));
- EXPECT_CALL(mock_backend, ProcessJsMessage("test1", HasArgs(args2), _))
- .WillOnce(ReplyToMessage("test1_reply"));
- EXPECT_CALL(mock_backend, ProcessJsMessage("test2", HasArgs(args1), _))
- .WillOnce(ReplyToMessage("test2_reply"));
-
- sync_js_controller.AttachJsBackend(mock_backend.AsWeakHandle());
- sync_js_controller.ProcessJsMessage("test1",
- args2,
- mock_reply_handler.AsWeakHandle());
- sync_js_controller.ProcessJsMessage("test2",
- args1,
- mock_reply_handler.AsWeakHandle());
-
- // The replies should be waiting on our message loop.
- EXPECT_CALL(mock_reply_handler, HandleJsReply("test1_reply", _));
- EXPECT_CALL(mock_reply_handler, HandleJsReply("test2_reply", _));
- PumpLoop();
-
- // Let destructor of |sync_js_controller| call RemoveBackend().
-}
-
-TEST_F(SyncJsControllerTest, QueuedMessages) {
- // |mock_backend| needs to outlive |sync_js_controller|.
- StrictMock<MockJsBackend> mock_backend;
- StrictMock<MockJsReplyHandler> mock_reply_handler;
- SyncJsController sync_js_controller;
-
- base::ListValue arg_list1, arg_list2;
- arg_list1.Append(new base::FundamentalValue(false));
- arg_list2.Append(new base::FundamentalValue(5));
- JsArgList args1(&arg_list1), args2(&arg_list2);
-
- // Should queue messages.
- sync_js_controller.ProcessJsMessage(
- "test1",
- args2,
- mock_reply_handler.AsWeakHandle());
- sync_js_controller.ProcessJsMessage(
- "test2",
- args1,
- mock_reply_handler.AsWeakHandle());
-
- // Should do nothing.
- PumpLoop();
- Mock::VerifyAndClearExpectations(&mock_backend);
-
-
- // Should call the queued messages.
- EXPECT_CALL(mock_backend, SetJsEventHandler(_));
- EXPECT_CALL(mock_backend, ProcessJsMessage("test1", HasArgs(args2), _))
- .WillOnce(ReplyToMessage("test1_reply"));
- EXPECT_CALL(mock_backend, ProcessJsMessage("test2", HasArgs(args1), _))
- .WillOnce(ReplyToMessage("test2_reply"));
- EXPECT_CALL(mock_reply_handler, HandleJsReply("test1_reply", _));
- EXPECT_CALL(mock_reply_handler, HandleJsReply("test2_reply", _));
-
- sync_js_controller.AttachJsBackend(mock_backend.AsWeakHandle());
- PumpLoop();
-
- // Should do nothing.
- sync_js_controller.AttachJsBackend(WeakHandle<JsBackend>());
- PumpLoop();
-
- // Should also do nothing.
- sync_js_controller.AttachJsBackend(WeakHandle<JsBackend>());
- PumpLoop();
-}
-
TEST_F(SyncJsControllerTest, Events) {
InSequence dummy;
SyncJsController sync_js_controller;
diff --git a/sync/notifier/invalidation_util.h b/sync/notifier/invalidation_util.h
index 392a15e53b..eac4bac5b6 100644
--- a/sync/notifier/invalidation_util.h
+++ b/sync/notifier/invalidation_util.h
@@ -40,7 +40,7 @@ struct SYNC_EXPORT ObjectIdLessThan {
const invalidation::ObjectId& rhs) const;
};
-struct InvalidationVersionLessThan {
+struct SYNC_EXPORT InvalidationVersionLessThan {
bool operator()(const syncer::Invalidation& a,
const syncer::Invalidation& b) const;
};
diff --git a/sync/protocol/autofill_specifics.proto b/sync/protocol/autofill_specifics.proto
index 1402e47d85..64d8e1e8ed 100644
--- a/sync/protocol/autofill_specifics.proto
+++ b/sync/protocol/autofill_specifics.proto
@@ -40,6 +40,7 @@ message AutofillProfileSpecifics {
optional string address_home_street_address = 17;
optional string address_home_sorting_code = 18;
optional string address_home_dependent_locality = 19;
+ optional string address_home_language_code = 20;
// Phone.
repeated string phone_home_whole_number = 13;
diff --git a/sync/protocol/proto_value_conversions.cc b/sync/protocol/proto_value_conversions.cc
index 06ecdfee27..04c5f06d76 100644
--- a/sync/protocol/proto_value_conversions.cc
+++ b/sync/protocol/proto_value_conversions.cc
@@ -438,6 +438,7 @@ base::DictionaryValue* AutofillProfileSpecificsToValue(
SET_STR(address_home_street_address);
SET_STR(address_home_sorting_code);
SET_STR(address_home_dependent_locality);
+ SET_STR(address_home_language_code);
SET_STR_REP(phone_home_whole_number);
return value;
diff --git a/sync/sync_api.gypi b/sync/sync_api.gypi
index 02ff2c4367..8e5b911f23 100644
--- a/sync/sync_api.gypi
+++ b/sync/sync_api.gypi
@@ -22,6 +22,8 @@
'api/attachments/attachment_service.h',
'api/attachments/attachment_service_proxy.cc',
'api/attachments/attachment_service_proxy.h',
+ 'api/attachments/attachment_service_proxy_for_test.cc',
+ 'api/attachments/attachment_service_proxy_for_test.h',
'api/attachments/attachment_store.cc',
'api/attachments/attachment_store.h',
'api/attachments/fake_attachment_service.cc',
diff --git a/sync/sync_core.gypi b/sync/sync_core.gypi
index 4ba949c81e..e7019a013f 100644
--- a/sync/sync_core.gypi
+++ b/sync/sync_core.gypi
@@ -93,14 +93,11 @@
'engine/update_applicator.h',
'engine/update_handler.cc',
'engine/update_handler.h',
- 'js/js_arg_list.cc',
- 'js/js_arg_list.h',
'js/js_backend.h',
'js/js_controller.h',
'js/js_event_details.cc',
'js/js_event_details.h',
'js/js_event_handler.h',
- 'js/js_reply_handler.h',
'js/sync_js_controller.cc',
'js/sync_js_controller.h',
'protocol/proto_enum_conversions.cc',
diff --git a/sync/sync_internal_api.gypi b/sync/sync_internal_api.gypi
index b0a476ba0b..3a572dfd38 100644
--- a/sync/sync_internal_api.gypi
+++ b/sync/sync_internal_api.gypi
@@ -125,6 +125,8 @@
'internal_api/sync_core.cc',
'internal_api/sync_core.h',
'internal_api/sync_core_proxy.cc',
+ 'internal_api/sync_core_proxy_impl.cc',
+ 'internal_api/sync_core_proxy_impl.h',
'internal_api/sync_encryption_handler_impl.cc',
'internal_api/sync_encryption_handler_impl.h',
'internal_api/sync_manager_factory.cc',
diff --git a/sync/sync_tests.gypi b/sync/sync_tests.gypi
index f5c5301f3f..6841beceb2 100644
--- a/sync/sync_tests.gypi
+++ b/sync/sync_tests.gypi
@@ -191,11 +191,13 @@
'internal_api/public/base/invalidation_test_util.cc',
'internal_api/public/base/invalidation_test_util.h',
'internal_api/public/test/fake_sync_manager.h',
+ 'internal_api/public/test/null_sync_core_proxy.h',
'internal_api/public/test/sync_manager_factory_for_profile_sync_test.h',
'internal_api/public/test/test_entry_factory.h',
'internal_api/public/test/test_internal_components_factory.h',
'internal_api/public/test/test_user_share.h',
'internal_api/test/fake_sync_manager.cc',
+ 'internal_api/test/null_sync_core_proxy.cc',
'internal_api/test/sync_manager_factory_for_profile_sync_test.cc',
'internal_api/test/sync_manager_for_profile_sync_test.cc',
'internal_api/test/sync_manager_for_profile_sync_test.h',
@@ -291,7 +293,6 @@
'engine/sync_scheduler_unittest.cc',
'engine/syncer_proto_util_unittest.cc',
'engine/syncer_unittest.cc',
- 'js/js_arg_list_unittest.cc',
'js/js_event_details_unittest.cc',
'js/sync_js_controller_unittest.cc',
'protocol/proto_enum_conversions_unittest.cc',
@@ -419,7 +420,7 @@
'internal_api/protocol_event_buffer_unittest.cc',
'internal_api/public/change_record_unittest.cc',
'internal_api/public/sessions/sync_session_snapshot_unittest.cc',
- 'internal_api/sync_core_proxy_unittest.cc',
+ 'internal_api/sync_core_proxy_impl_unittest.cc',
'internal_api/sync_encryption_handler_impl_unittest.cc',
'internal_api/sync_manager_impl_unittest.cc',
'internal_api/syncapi_server_connection_manager_unittest.cc',
diff --git a/sync/syncable/directory.cc b/sync/syncable/directory.cc
index 11bc9562bd..75c1bec561 100644
--- a/sync/syncable/directory.cc
+++ b/sync/syncable/directory.cc
@@ -39,19 +39,22 @@ Directory::PersistedKernelInfo::PersistedKernelInfo()
ModelTypeSet protocol_types = ProtocolTypes();
for (ModelTypeSet::Iterator iter = protocol_types.First(); iter.Good();
iter.Inc()) {
- reset_download_progress(iter.Get());
+ ResetDownloadProgress(iter.Get());
transaction_version[iter.Get()] = 0;
}
}
Directory::PersistedKernelInfo::~PersistedKernelInfo() {}
-void Directory::PersistedKernelInfo::reset_download_progress(
+void Directory::PersistedKernelInfo::ResetDownloadProgress(
ModelType model_type) {
+ // Clear everything except the data type id field.
+ download_progress[model_type].Clear();
download_progress[model_type].set_data_type_id(
GetSpecificsFieldNumberFromModelType(model_type));
- // An empty-string token indicates no prior knowledge.
- download_progress[model_type].set_token(std::string());
+
+ // Explicitly set an empty token field to denote no progress.
+ download_progress[model_type].set_token("");
}
Directory::SaveChangesSnapshot::SaveChangesSnapshot()
@@ -321,10 +324,6 @@ int Directory::GetPositionIndex(
return std::distance(siblings->begin(), it);
}
-EntryKernel* Directory::GetRootEntry() {
- return GetEntryById(Id());
-}
-
bool Directory::InsertEntry(BaseWriteTransaction* trans, EntryKernel* entry) {
ScopedKernelLock lock(this);
return InsertEntry(trans, entry, &lock);
@@ -716,10 +715,14 @@ bool Directory::PurgeEntriesWithTypeIn(ModelTypeSet disabled_types,
it.Good(); it.Inc()) {
kernel_->persisted_info.transaction_version[it.Get()] = 0;
- // Don't discard progress markers for unapplied types.
- if (!types_to_unapply.Has(it.Get()))
- kernel_->persisted_info.reset_download_progress(it.Get());
+ // Don't discard progress markers or context for unapplied types.
+ if (!types_to_unapply.Has(it.Get())) {
+ kernel_->persisted_info.ResetDownloadProgress(it.Get());
+ kernel_->persisted_info.datatype_context[it.Get()].Clear();
+ }
}
+
+ kernel_->info_status = KERNEL_SHARE_INFO_DIRTY;
}
}
return true;
diff --git a/sync/syncable/directory.h b/sync/syncable/directory.h
index 6b91a5ab99..fdac9b4afe 100644
--- a/sync/syncable/directory.h
+++ b/sync/syncable/directory.h
@@ -100,7 +100,7 @@ class SYNC_EXPORT Directory {
// Set the |download_progress| entry for the given model to a
// "first sync" start point. When such a value is sent to the server,
// a full download of all objects of the model will be initiated.
- void reset_download_progress(ModelType model_type);
+ void ResetDownloadProgress(ModelType model_type);
// Last sync timestamp fetched from the server.
sync_pb::DataTypeProgressMarker download_progress[MODEL_TYPE_COUNT];
@@ -390,7 +390,6 @@ class SYNC_EXPORT Directory {
virtual EntryKernel* GetEntryById(const Id& id);
EntryKernel* GetEntryByServerTag(const std::string& tag);
virtual EntryKernel* GetEntryByClientTag(const std::string& tag);
- EntryKernel* GetRootEntry();
bool ReindexId(BaseWriteTransaction* trans, EntryKernel* const entry,
const Id& new_id);
bool ReindexParentId(BaseWriteTransaction* trans, EntryKernel* const entry,
diff --git a/sync/syncable/syncable_unittest.cc b/sync/syncable/syncable_unittest.cc
index 8f261c7d94..01176c2c4d 100644
--- a/sync/syncable/syncable_unittest.cc
+++ b/sync/syncable/syncable_unittest.cc
@@ -489,6 +489,14 @@ class SyncableDirectoryTest : public testing::Test {
for (ModelTypeSet::Iterator it = types_to_purge.First();
it.Good(); it.Inc()) {
EXPECT_FALSE(dir_->InitialSyncEndedForType(it.Get()));
+ sync_pb::DataTypeProgressMarker progress;
+ dir_->GetDownloadProgress(it.Get(), &progress);
+ EXPECT_EQ("", progress.token());
+
+ ReadTransaction trans(FROM_HERE, dir_.get());
+ sync_pb::DataTypeContext context;
+ dir_->GetDataTypeContext(&trans, it.Get(), &context);
+ EXPECT_TRUE(context.SerializeAsString().empty());
}
EXPECT_FALSE(types_to_purge.Has(BOOKMARKS));
EXPECT_TRUE(dir_->InitialSyncEndedForType(BOOKMARKS));
@@ -1686,6 +1694,20 @@ class OnDiskSyncableDirectoryTest : public SyncableDirectoryTest {
base::FilePath file_path_;
};
+sync_pb::DataTypeProgressMarker BuildProgress(ModelType type) {
+ sync_pb::DataTypeProgressMarker progress;
+ progress.set_token("token");
+ progress.set_data_type_id(GetSpecificsFieldNumberFromModelType(type));
+ return progress;
+}
+
+sync_pb::DataTypeContext BuildContext(ModelType type) {
+ sync_pb::DataTypeContext context;
+ context.set_context("context");
+ context.set_data_type_id(GetSpecificsFieldNumberFromModelType(type));
+ return context;
+}
+
TEST_F(OnDiskSyncableDirectoryTest, TestPurgeEntriesWithTypeIn) {
sync_pb::EntitySpecifics bookmark_specs;
sync_pb::EntitySpecifics autofill_specs;
@@ -1696,11 +1718,22 @@ TEST_F(OnDiskSyncableDirectoryTest, TestPurgeEntriesWithTypeIn) {
ModelTypeSet types_to_purge(PREFERENCES, AUTOFILL);
+ dir_->SetDownloadProgress(BOOKMARKS,
+ BuildProgress(BOOKMARKS));
+ dir_->SetDownloadProgress(PREFERENCES,
+ BuildProgress(PREFERENCES));
+ dir_->SetDownloadProgress(AUTOFILL,
+ BuildProgress(AUTOFILL));
+
TestIdFactory id_factory;
// Create some items for each type.
{
WriteTransaction trans(FROM_HERE, UNITTEST, dir_.get());
+ dir_->SetDataTypeContext(&trans, BOOKMARKS, BuildContext(BOOKMARKS));
+ dir_->SetDataTypeContext(&trans, PREFERENCES, BuildContext(PREFERENCES));
+ dir_->SetDataTypeContext(&trans, AUTOFILL, BuildContext(AUTOFILL));
+
// Make it look like these types have completed initial sync.
CreateTypeRoot(&trans, dir_.get(), BOOKMARKS);
CreateTypeRoot(&trans, dir_.get(), PREFERENCES);
diff --git a/sync/test/engine/mock_update_handler.cc b/sync/test/engine/mock_update_handler.cc
index da2db885f7..b4e1bd2d9e 100644
--- a/sync/test/engine/mock_update_handler.cc
+++ b/sync/test/engine/mock_update_handler.cc
@@ -29,12 +29,13 @@ void MockUpdateHandler::GetDataTypeContext(
context->Clear();
}
-void MockUpdateHandler::ProcessGetUpdatesResponse(
+SyncerError MockUpdateHandler::ProcessGetUpdatesResponse(
const sync_pb::DataTypeProgressMarker& progress_marker,
const sync_pb::DataTypeContext& mutated_context,
const SyncEntityList& applicable_updates,
sessions::StatusController* status) {
progress_marker_.CopyFrom(progress_marker);
+ return syncer::SYNCER_OK;
}
void MockUpdateHandler::ApplyUpdates(sessions::StatusController* status) {
diff --git a/sync/test/engine/mock_update_handler.h b/sync/test/engine/mock_update_handler.h
index 0cbeca3847..64654adf30 100644
--- a/sync/test/engine/mock_update_handler.h
+++ b/sync/test/engine/mock_update_handler.h
@@ -22,7 +22,7 @@ class MockUpdateHandler : public UpdateHandler {
sync_pb::DataTypeProgressMarker* progress_marker) const OVERRIDE;
virtual void GetDataTypeContext(sync_pb::DataTypeContext* context) const
OVERRIDE;
- virtual void ProcessGetUpdatesResponse(
+ virtual SyncerError ProcessGetUpdatesResponse(
const sync_pb::DataTypeProgressMarker& progress_marker,
const sync_pb::DataTypeContext& mutated_context,
const SyncEntityList& applicable_updates,