summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/sync/glue/invalidation_adapter.cc39
-rw-r--r--chrome/browser/sync/glue/invalidation_adapter.h32
-rw-r--r--chrome/browser/sync/glue/sync_backend_host_core.cc26
-rw-r--r--chrome/chrome_browser.gypi2
-rw-r--r--components/invalidation/sync_invalidation_listener_unittest.cc34
-rw-r--r--sync/engine/get_updates_processor_unittest.cc18
-rw-r--r--sync/engine/sync_scheduler.h5
-rw-r--r--sync/engine/sync_scheduler_impl.cc9
-rw-r--r--sync/engine/sync_scheduler_impl.h3
-rw-r--r--sync/engine/sync_scheduler_unittest.cc23
-rw-r--r--sync/internal_api/public/base/invalidation.cc14
-rw-r--r--sync/internal_api/public/base/invalidation.h10
-rw-r--r--sync/internal_api/public/base/invalidation_interface.cc29
-rw-r--r--sync/internal_api/public/base/invalidation_interface.h55
-rw-r--r--sync/internal_api/public/base/model_type_test_util.cc1
-rw-r--r--sync/internal_api/public/sync_manager.h7
-rw-r--r--sync/internal_api/public/test/fake_sync_manager.h6
-rw-r--r--sync/internal_api/sync_manager_impl.cc28
-rw-r--r--sync/internal_api/sync_manager_impl.h4
-rw-r--r--sync/internal_api/sync_manager_impl_unittest.cc8
-rw-r--r--sync/internal_api/sync_rollback_manager_base.cc7
-rw-r--r--sync/internal_api/sync_rollback_manager_base.h4
-rw-r--r--sync/internal_api/test/fake_sync_manager.cc5
-rw-r--r--sync/notifier/dropped_invalidation_tracker.cc45
-rw-r--r--sync/notifier/dropped_invalidation_tracker.h74
-rw-r--r--sync/sessions/data_type_tracker.cc141
-rw-r--r--sync/sessions/data_type_tracker.h31
-rw-r--r--sync/sessions/nudge_tracker.cc80
-rw-r--r--sync/sessions/nudge_tracker.h8
-rw-r--r--sync/sessions/nudge_tracker_unittest.cc271
-rw-r--r--sync/sync_internal_api.gypi2
-rw-r--r--sync/sync_notifier.gypi2
-rw-r--r--sync/sync_tests.gypi6
-rw-r--r--sync/test/engine/fake_sync_scheduler.cc3
-rw-r--r--sync/test/engine/fake_sync_scheduler.h3
-rw-r--r--sync/test/mock_invalidation.cc57
-rw-r--r--sync/test/mock_invalidation.h48
-rw-r--r--sync/test/mock_invalidation_tracker.cc63
-rw-r--r--sync/test/mock_invalidation_tracker.h65
-rw-r--r--sync/test/trackable_mock_invalidation.cc41
-rw-r--r--sync/test/trackable_mock_invalidation.h54
-rw-r--r--sync/tools/sync_client.cc78
42 files changed, 909 insertions, 532 deletions
diff --git a/chrome/browser/sync/glue/invalidation_adapter.cc b/chrome/browser/sync/glue/invalidation_adapter.cc
new file mode 100644
index 0000000..96aca500
--- /dev/null
+++ b/chrome/browser/sync/glue/invalidation_adapter.cc
@@ -0,0 +1,39 @@
+// 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 "chrome/browser/sync/glue/invalidation_adapter.h"
+
+#include <string>
+
+namespace browser_sync {
+
+InvalidationAdapter::InvalidationAdapter(
+ const syncer::Invalidation& invalidation)
+ : invalidation_(invalidation) {
+}
+
+InvalidationAdapter::~InvalidationAdapter() {
+}
+
+bool InvalidationAdapter::IsUnknownVersion() const {
+ return invalidation_.is_unknown_version();
+}
+
+const std::string& InvalidationAdapter::GetPayload() const {
+ return invalidation_.payload();
+}
+
+int64 InvalidationAdapter::GetVersion() const {
+ return invalidation_.version();
+}
+
+void InvalidationAdapter::Acknowledge() {
+ invalidation_.Acknowledge();
+}
+
+void InvalidationAdapter::Drop() {
+ invalidation_.Drop();
+}
+
+} // namespace browser_sync
diff --git a/chrome/browser/sync/glue/invalidation_adapter.h b/chrome/browser/sync/glue/invalidation_adapter.h
new file mode 100644
index 0000000..509a872
--- /dev/null
+++ b/chrome/browser/sync/glue/invalidation_adapter.h
@@ -0,0 +1,32 @@
+// 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 CHROME_BROWSER_SYNC_GLUE_INVALIDATION_ADAPTER_H_
+#define CHROME_BROWSER_SYNC_GLUE_INVALIDATION_ADAPTER_H_
+
+#include "sync/internal_api/public/base/invalidation.h"
+#include "sync/internal_api/public/base/invalidation_interface.h"
+
+namespace browser_sync {
+
+// Wraps a syncer::Invalidation in the syncer::InvalidationInterface.
+class InvalidationAdapter : public syncer::InvalidationInterface {
+ public:
+ explicit InvalidationAdapter(const syncer::Invalidation& invalidation);
+ virtual ~InvalidationAdapter();
+
+ // Implementation of InvalidationInterface.
+ virtual bool IsUnknownVersion() const OVERRIDE;
+ virtual const std::string& GetPayload() const OVERRIDE;
+ virtual int64 GetVersion() const OVERRIDE;
+ virtual void Acknowledge() OVERRIDE;
+ virtual void Drop() OVERRIDE;
+
+ private:
+ syncer::Invalidation invalidation_;
+};
+
+} // namespace browser_sync
+
+#endif // CHROME_BROWSER_SYNC_GLUE_INVALIDATION_ADAPTER_H_
diff --git a/chrome/browser/sync/glue/sync_backend_host_core.cc b/chrome/browser/sync/glue/sync_backend_host_core.cc
index 1b6a5ff..50f16cc 100644
--- a/chrome/browser/sync/glue/sync_backend_host_core.cc
+++ b/chrome/browser/sync/glue/sync_backend_host_core.cc
@@ -7,6 +7,7 @@
#include "base/file_util.h"
#include "base/metrics/histogram.h"
#include "chrome/browser/sync/glue/device_info.h"
+#include "chrome/browser/sync/glue/invalidation_adapter.h"
#include "chrome/browser/sync/glue/sync_backend_registrar.h"
#include "chrome/browser/sync/glue/synced_device_tracker.h"
#include "chrome/common/chrome_version_info.h"
@@ -20,6 +21,8 @@
#include "sync/internal_api/public/sync_context_proxy.h"
#include "sync/internal_api/public/sync_manager.h"
#include "sync/internal_api/public/sync_manager_factory.h"
+#include "sync/notifier/invalidation_util.h"
+#include "sync/notifier/object_id_invalidation_map.h"
// Helper macros to log with the syncer thread name; useful when there
// are multiple syncers involved.
@@ -369,7 +372,28 @@ void SyncBackendHostCore::DoOnInvalidatorStateChange(
void SyncBackendHostCore::DoOnIncomingInvalidation(
const syncer::ObjectIdInvalidationMap& invalidation_map) {
DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
- sync_manager_->OnIncomingInvalidation(invalidation_map);
+
+ syncer::ObjectIdSet ids = invalidation_map.GetObjectIds();
+ for (syncer::ObjectIdSet::const_iterator ids_it = ids.begin();
+ ids_it != ids.end();
+ ++ids_it) {
+ syncer::ModelType type;
+ if (!NotificationTypeToRealModelType(ids_it->name(), &type)) {
+ DLOG(WARNING) << "Notification has invalid id: "
+ << syncer::ObjectIdToString(*ids_it);
+ } else {
+ syncer::SingleObjectInvalidationSet invalidation_set =
+ invalidation_map.ForObject(*ids_it);
+ for (syncer::SingleObjectInvalidationSet::const_iterator inv_it =
+ invalidation_set.begin();
+ inv_it != invalidation_set.end();
+ ++inv_it) {
+ scoped_ptr<syncer::InvalidationInterface> inv_adapter(
+ new InvalidationAdapter(*inv_it));
+ sync_manager_->OnIncomingInvalidation(type, inv_adapter.Pass());
+ }
+ }
+ }
}
void SyncBackendHostCore::DoInitialize(
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 0d03fa0..4c5ceab 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -1320,6 +1320,8 @@
'browser/sync/glue/frontend_data_type_controller.h',
'browser/sync/glue/history_model_worker.cc',
'browser/sync/glue/history_model_worker.h',
+ 'browser/sync/glue/invalidation_adapter.cc',
+ 'browser/sync/glue/invalidation_adapter.h',
'browser/sync/glue/non_frontend_data_type_controller.cc',
'browser/sync/glue/non_frontend_data_type_controller.h',
'browser/sync/glue/password_data_type_controller.cc',
diff --git a/components/invalidation/sync_invalidation_listener_unittest.cc b/components/invalidation/sync_invalidation_listener_unittest.cc
index f7ff05a..0399039 100644
--- a/components/invalidation/sync_invalidation_listener_unittest.cc
+++ b/components/invalidation/sync_invalidation_listener_unittest.cc
@@ -18,7 +18,6 @@
#include "google/cacheinvalidation/include/types.h"
#include "jingle/notifier/listener/fake_push_client.h"
#include "sync/internal_api/public/util/weak_handle.h"
-#include "sync/notifier/dropped_invalidation_tracker.h"
#include "sync/notifier/invalidation_util.h"
#include "sync/notifier/object_id_invalidation_map.h"
#include "sync/notifier/unacked_invalidation_set_test_util.h"
@@ -138,8 +137,7 @@ class FakeInvalidationClient : public invalidation::InvalidationClient {
class FakeDelegate : public SyncInvalidationListener::Delegate {
public:
explicit FakeDelegate(SyncInvalidationListener* listener)
- : state_(TRANSIENT_INVALIDATION_ERROR),
- drop_handlers_deleter_(&drop_handlers_) {}
+ : state_(TRANSIENT_INVALIDATION_ERROR) {}
virtual ~FakeDelegate() {}
size_t GetInvalidationCount(const ObjectId& id) const {
@@ -195,17 +193,6 @@ class FakeDelegate : public SyncInvalidationListener::Delegate {
return state_;
}
- DroppedInvalidationTracker* GetDropTrackerForObject(const ObjectId& id) {
- DropHandlers::iterator it = drop_handlers_.find(id);
- if (it == drop_handlers_.end()) {
- drop_handlers_.insert(
- std::make_pair(id, new DroppedInvalidationTracker(id)));
- return drop_handlers_.find(id)->second;
- } else {
- return it->second;
- }
- }
-
void AcknowledgeNthInvalidation(const ObjectId& id, size_t n) {
List& list = invalidations_[id];
List::iterator it = list.begin() + n;
@@ -220,15 +207,19 @@ class FakeDelegate : public SyncInvalidationListener::Delegate {
}
void DropNthInvalidation(const ObjectId& id, size_t n) {
- DroppedInvalidationTracker* drop_tracker = GetDropTrackerForObject(id);
List& list = invalidations_[id];
List::iterator it = list.begin() + n;
- it->Drop(drop_tracker);
+ it->Drop();
+ dropped_invalidations_map_.erase(id);
+ dropped_invalidations_map_.insert(std::make_pair(id, *it));
}
void RecoverFromDropEvent(const ObjectId& id) {
- DroppedInvalidationTracker* drop_tracker = GetDropTrackerForObject(id);
- drop_tracker->RecordRecoveryFromDropEvent();
+ DropMap::iterator it = dropped_invalidations_map_.find(id);
+ if (it != dropped_invalidations_map_.end()) {
+ it->second.Acknowledge();
+ dropped_invalidations_map_.erase(it);
+ }
}
// SyncInvalidationListener::Delegate implementation.
@@ -250,14 +241,11 @@ class FakeDelegate : public SyncInvalidationListener::Delegate {
private:
typedef std::vector<Invalidation> List;
typedef std::map<ObjectId, List, ObjectIdLessThan> Map;
- typedef std::map<ObjectId,
- DroppedInvalidationTracker*,
- ObjectIdLessThan> DropHandlers;
+ typedef std::map<ObjectId, Invalidation, ObjectIdLessThan> DropMap;
Map invalidations_;
InvalidatorState state_;
- DropHandlers drop_handlers_;
- STLValueDeleter<DropHandlers> drop_handlers_deleter_;
+ DropMap dropped_invalidations_map_;
};
invalidation::InvalidationClient* CreateFakeInvalidationClient(
diff --git a/sync/engine/get_updates_processor_unittest.cc b/sync/engine/get_updates_processor_unittest.cc
index 7c87fed..54ce503 100644
--- a/sync/engine/get_updates_processor_unittest.cc
+++ b/sync/engine/get_updates_processor_unittest.cc
@@ -15,11 +15,23 @@
#include "sync/sessions/status_controller.h"
#include "sync/test/engine/fake_model_worker.h"
#include "sync/test/engine/mock_update_handler.h"
+#include "sync/test/mock_invalidation.h"
#include "sync/test/sessions/mock_debug_info_getter.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace syncer {
+namespace {
+
+scoped_ptr<InvalidationInterface> BuildInvalidation(
+ int64 version,
+ const std::string& payload) {
+ return MockInvalidation::Build(version, payload)
+ .PassAs<InvalidationInterface>();
+}
+
+} // namespace
+
using sessions::MockDebugInfoGetter;
// A test fixture for tests exercising download updates functions.
@@ -133,11 +145,11 @@ TEST_F(GetUpdatesProcessorTest, BookmarkNudge) {
TEST_F(GetUpdatesProcessorTest, NotifyMany) {
sessions::NudgeTracker nudge_tracker;
nudge_tracker.RecordRemoteInvalidation(
- BuildInvalidationMap(AUTOFILL, 1, "autofill_payload"));
+ AUTOFILL, BuildInvalidation(1, "autofill_payload"));
nudge_tracker.RecordRemoteInvalidation(
- BuildInvalidationMap(BOOKMARKS, 1, "bookmark_payload"));
+ BOOKMARKS, BuildInvalidation(1, "bookmark_payload"));
nudge_tracker.RecordRemoteInvalidation(
- BuildInvalidationMap(PREFERENCES, 1, "preferences_payload"));
+ PREFERENCES, BuildInvalidation(1, "preferences_payload"));
ModelTypeSet notified_types;
notified_types.Put(AUTOFILL);
notified_types.Put(BOOKMARKS);
diff --git a/sync/engine/sync_scheduler.h b/sync/engine/sync_scheduler.h
index aef0118..b512042 100644
--- a/sync/engine/sync_scheduler.h
+++ b/sync/engine/sync_scheduler.h
@@ -13,6 +13,7 @@
#include "base/time/time.h"
#include "sync/base/sync_export.h"
#include "sync/engine/nudge_source.h"
+#include "sync/internal_api/public/base/invalidation_interface.h"
#include "sync/sessions/sync_session.h"
namespace tracked_objects {
@@ -21,7 +22,6 @@ class Location;
namespace syncer {
-class ObjectIdInvalidationMap;
struct ServerConnectionEvent;
struct SYNC_EXPORT_PRIVATE ConfigurationParams {
@@ -115,7 +115,8 @@ class SYNC_EXPORT_PRIVATE SyncScheduler
// order to fetch the update.
virtual void ScheduleInvalidationNudge(
const base::TimeDelta& desired_delay,
- const ObjectIdInvalidationMap& invalidations,
+ syncer::ModelType type,
+ scoped_ptr<InvalidationInterface> invalidation,
const tracked_objects::Location& nudge_location) = 0;
// Change status of notifications in the SyncSessionContext.
diff --git a/sync/engine/sync_scheduler_impl.cc b/sync/engine/sync_scheduler_impl.cc
index 01a054a..c5629ba 100644
--- a/sync/engine/sync_scheduler_impl.cc
+++ b/sync/engine/sync_scheduler_impl.cc
@@ -387,16 +387,15 @@ void SyncSchedulerImpl::ScheduleLocalRefreshRequest(
void SyncSchedulerImpl::ScheduleInvalidationNudge(
const TimeDelta& desired_delay,
- const ObjectIdInvalidationMap& invalidation_map,
+ syncer::ModelType model_type,
+ scoped_ptr<InvalidationInterface> invalidation,
const tracked_objects::Location& nudge_location) {
DCHECK(CalledOnValidThread());
- DCHECK(!invalidation_map.Empty());
SDVLOG_LOC(nudge_location, 2)
<< "Scheduling sync because we received invalidation for "
- << ModelTypeSetToString(
- ObjectIdSetToModelTypeSet(invalidation_map.GetObjectIds()));
- nudge_tracker_.RecordRemoteInvalidation(invalidation_map);
+ << ModelTypeToString(model_type);
+ nudge_tracker_.RecordRemoteInvalidation(model_type, invalidation.Pass());
ScheduleNudgeImpl(desired_delay, nudge_location);
}
diff --git a/sync/engine/sync_scheduler_impl.h b/sync/engine/sync_scheduler_impl.h
index 75cad3e..d78b5d6 100644
--- a/sync/engine/sync_scheduler_impl.h
+++ b/sync/engine/sync_scheduler_impl.h
@@ -65,7 +65,8 @@ class SYNC_EXPORT_PRIVATE SyncSchedulerImpl
const tracked_objects::Location& nudge_location) OVERRIDE;
virtual void ScheduleInvalidationNudge(
const base::TimeDelta& desired_delay,
- const ObjectIdInvalidationMap& invalidation_map,
+ syncer::ModelType type,
+ scoped_ptr<InvalidationInterface> invalidation,
const tracked_objects::Location& nudge_location) OVERRIDE;
virtual void SetNotificationsEnabled(bool notifications_enabled) OVERRIDE;
diff --git a/sync/engine/sync_scheduler_unittest.cc b/sync/engine/sync_scheduler_unittest.cc
index c231087..8348eab 100644
--- a/sync/engine/sync_scheduler_unittest.cc
+++ b/sync/engine/sync_scheduler_unittest.cc
@@ -20,6 +20,7 @@
#include "sync/test/engine/fake_model_worker.h"
#include "sync/test/engine/mock_connection_manager.h"
#include "sync/test/engine/test_directory_setter_upper.h"
+#include "sync/test/mock_invalidation.h"
#include "sync/util/extensions_activity.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -220,6 +221,13 @@ class SyncSchedulerTest : public testing::Test {
return scheduler_->retry_timer_.GetCurrentDelay();
}
+ static scoped_ptr<InvalidationInterface> BuildInvalidation(
+ int64 version,
+ const std::string& payload) {
+ return MockInvalidation::Build(version, payload)
+ .PassAs<InvalidationInterface>();
+ }
+
private:
syncable::Directory* directory() {
return dir_maker_.directory();
@@ -523,25 +531,23 @@ TEST_F(SyncSchedulerTest, NudgeWithStates) {
StartSyncScheduler(SyncScheduler::NORMAL_MODE);
SyncShareTimes times1;
- ObjectIdInvalidationMap invalidations1 =
- BuildInvalidationMap(BOOKMARKS, 10, "test");
EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
.WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
RecordSyncShare(&times1)))
.RetiresOnSaturation();
- scheduler()->ScheduleInvalidationNudge(zero(), invalidations1, FROM_HERE);
+ scheduler()->ScheduleInvalidationNudge(
+ zero(), BOOKMARKS, BuildInvalidation(10, "test"), FROM_HERE);
RunLoop();
Mock::VerifyAndClearExpectations(syncer());
// Make sure a second, later, nudge is unaffected by first (no coalescing).
SyncShareTimes times2;
- ObjectIdInvalidationMap invalidations2 =
- BuildInvalidationMap(AUTOFILL, 10, "test2");
EXPECT_CALL(*syncer(), NormalSyncShare(_,_,_))
.WillOnce(DoAll(Invoke(sessions::test_util::SimulateNormalSuccess),
RecordSyncShare(&times2)));
- scheduler()->ScheduleInvalidationNudge(zero(), invalidations2, FROM_HERE);
+ scheduler()->ScheduleInvalidationNudge(
+ zero(), AUTOFILL, BuildInvalidation(10, "test2"), FROM_HERE);
RunLoop();
}
@@ -834,9 +840,8 @@ TEST_F(SyncSchedulerTest, TypeThrottlingDoesBlockOtherSources) {
EXPECT_TRUE(GetThrottledTypes().HasAll(throttled_types));
// Ignore invalidations for throttled types.
- ObjectIdInvalidationMap invalidations =
- BuildInvalidationMap(BOOKMARKS, 10, "test");
- scheduler()->ScheduleInvalidationNudge(zero(), invalidations, FROM_HERE);
+ scheduler()->ScheduleInvalidationNudge(
+ zero(), BOOKMARKS, BuildInvalidation(10, "test"), FROM_HERE);
PumpLoop();
// Ignore refresh requests for throttled types.
diff --git a/sync/internal_api/public/base/invalidation.cc b/sync/internal_api/public/base/invalidation.cc
index ff7a5a7..e6a64be 100644
--- a/sync/internal_api/public/base/invalidation.cc
+++ b/sync/internal_api/public/base/invalidation.cc
@@ -11,7 +11,6 @@
#include "base/strings/string_number_conversions.h"
#include "base/values.h"
#include "sync/notifier/ack_handler.h"
-#include "sync/notifier/dropped_invalidation_tracker.h"
#include "sync/notifier/invalidation_util.h"
namespace syncer {
@@ -43,6 +42,15 @@ Invalidation Invalidation::InitFromDroppedInvalidation(
std::string(), dropped.ack_handle_);
}
+Invalidation::Invalidation(const Invalidation& other)
+ : id_(other.id_),
+ is_unknown_version_(other.is_unknown_version_),
+ version_(other.version_),
+ payload_(other.payload_),
+ ack_handle_(other.ack_handle_),
+ ack_handler_(other.ack_handler_) {
+}
+
scoped_ptr<Invalidation> Invalidation::InitFromValue(
const base::DictionaryValue& value) {
invalidation::ObjectId id;
@@ -128,9 +136,7 @@ void Invalidation::Acknowledge() const {
}
}
-void Invalidation::Drop(DroppedInvalidationTracker* tracker) const {
- DCHECK(tracker->object_id() == object_id());
- tracker->RecordDropEvent(ack_handler_, ack_handle_);
+void Invalidation::Drop() {
if (SupportsAcknowledgement()) {
ack_handler_.Call(FROM_HERE,
&AckHandler::Drop,
diff --git a/sync/internal_api/public/base/invalidation.h b/sync/internal_api/public/base/invalidation.h
index cf26112..309eb7d 100644
--- a/sync/internal_api/public/base/invalidation.h
+++ b/sync/internal_api/public/base/invalidation.h
@@ -35,6 +35,7 @@ class SYNC_EXPORT Invalidation {
static scoped_ptr<Invalidation> InitFromValue(
const base::DictionaryValue& value);
+ Invalidation(const Invalidation& other);
~Invalidation();
// Compares two invalidations. The comparison ignores ack-tracking state.
@@ -84,12 +85,9 @@ class SYNC_EXPORT Invalidation {
// invalidations in order to allow the ack tracker to drop the invalidation,
// too.
//
- // The drop record will be tracked by the specified
- // DroppedInvalidationTracker. The caller should hang on to this tracker. It
- // will need to use it when it recovers from this drop event, or if it needs
- // to record another drop event for the same ObjectID. Refer to the
- // documentation of DroppedInvalidationTracker for more details.
- void Drop(DroppedInvalidationTracker* tracker) const;
+ // To indicate recovery from a drop event, the client should call
+ // Acknowledge() on the most recently dropped inavlidation.
+ void Drop();
scoped_ptr<base::DictionaryValue> ToValue() const;
std::string ToString() const;
diff --git a/sync/internal_api/public/base/invalidation_interface.cc b/sync/internal_api/public/base/invalidation_interface.cc
new file mode 100644
index 0000000..0284170
--- /dev/null
+++ b/sync/internal_api/public/base/invalidation_interface.cc
@@ -0,0 +1,29 @@
+// 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/base/invalidation_interface.h"
+
+namespace syncer {
+
+bool InvalidationInterface::LessThanByVersion(const InvalidationInterface& a,
+ const InvalidationInterface& b) {
+ if (a.IsUnknownVersion() && !b.IsUnknownVersion())
+ return true;
+
+ if (!a.IsUnknownVersion() && b.IsUnknownVersion())
+ return false;
+
+ if (a.IsUnknownVersion() && b.IsUnknownVersion())
+ return false;
+
+ return a.GetVersion() < b.GetVersion();
+}
+
+InvalidationInterface::InvalidationInterface() {
+}
+
+InvalidationInterface::~InvalidationInterface() {
+}
+
+} // namespace syncer
diff --git a/sync/internal_api/public/base/invalidation_interface.h b/sync/internal_api/public/base/invalidation_interface.h
new file mode 100644
index 0000000..d7dbbe8
--- /dev/null
+++ b/sync/internal_api/public/base/invalidation_interface.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_PUBLIC_BASE_INVALIDATION_INTERFACE_H_
+#define SYNC_INTERNAL_API_PUBLIC_BASE_INVALIDATION_INTERFACE_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "sync/base/sync_export.h"
+
+namespace syncer {
+
+// An interface that wraps sync's interactions with the component that provides
+// it with invalidations.
+class SYNC_EXPORT InvalidationInterface {
+ public:
+ // Orders invalidations based on version number and IsUnknownVersion().
+ static bool LessThanByVersion(const InvalidationInterface& a,
+ const InvalidationInterface& b);
+
+ InvalidationInterface();
+ virtual ~InvalidationInterface();
+
+ // Returns true if this is an 'unknown version' invalidation.
+ // Such invalidations have no valid payload or version number.
+ virtual bool IsUnknownVersion() const = 0;
+
+ // Returns the payload of this item.
+ // DCHECKs if this is an unknown version invalidation.
+ virtual const std::string& GetPayload() const = 0;
+
+ // Retursn the version of this item.
+ // DCHECKs if this is an unknown version invalidation.
+ //
+ // It is preferable to use the LessThan() function, which handles unknown
+ // versions properly, rather than this function.
+ virtual int64 GetVersion() const = 0;
+
+ // This function will be called when the invalidation has been handled
+ // successfully.
+ virtual void Acknowledge() = 0;
+
+ // This function should be called if a lack of buffer space required that we
+ // drop this invalidation.
+ //
+ // To indicate recovery from a drop event, the receiver of this invalidation
+ // will call Acknowledge() on the most recently dropped invalidation.
+ virtual void Drop() = 0;
+};
+
+} // namespace syncer
+
+#endif
diff --git a/sync/internal_api/public/base/model_type_test_util.cc b/sync/internal_api/public/base/model_type_test_util.cc
index 4876962..5893922 100644
--- a/sync/internal_api/public/base/model_type_test_util.cc
+++ b/sync/internal_api/public/base/model_type_test_util.cc
@@ -3,7 +3,6 @@
// found in the LICENSE file.
#include "sync/internal_api/public/base/model_type_test_util.h"
-#include "sync/internal_api/public/base/ack_handle.h"
namespace syncer {
diff --git a/sync/internal_api/public/sync_manager.h b/sync/internal_api/public/sync_manager.h
index 073b8ed..b8cc50d 100644
--- a/sync/internal_api/public/sync_manager.h
+++ b/sync/internal_api/public/sync_manager.h
@@ -12,11 +12,13 @@
#include "base/callback_forward.h"
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/task_runner.h"
#include "base/threading/thread_checker.h"
#include "google_apis/gaia/oauth2_token_service.h"
#include "sync/base/sync_export.h"
+#include "sync/internal_api/public/base/invalidation_interface.h"
#include "sync/internal_api/public/base/model_type.h"
#include "sync/internal_api/public/change_record.h"
#include "sync/internal_api/public/configure_reason.h"
@@ -89,7 +91,7 @@ struct SYNC_EXPORT SyncCredentials {
//
// Unless stated otherwise, all methods of SyncManager should be called on the
// same thread.
-class SYNC_EXPORT SyncManager : public syncer::InvalidationHandler {
+class SYNC_EXPORT SyncManager {
public:
// An interface the embedding application implements to be notified
// on change events. Note that these methods may be called on *any*
@@ -314,7 +316,8 @@ class SYNC_EXPORT SyncManager : public syncer::InvalidationHandler {
// Inform the syncer that its cached information about a type is obsolete.
virtual void OnIncomingInvalidation(
- const ObjectIdInvalidationMap& invalidation_map) = 0;
+ syncer::ModelType type,
+ scoped_ptr<syncer::InvalidationInterface> invalidation) = 0;
// Adds a listener to be notified of sync events.
// NOTE: It is OK (in fact, it's probably a good idea) to call this before
diff --git a/sync/internal_api/public/test/fake_sync_manager.h b/sync/internal_api/public/test/fake_sync_manager.h
index df14a52..f4ea19a 100644
--- a/sync/internal_api/public/test/fake_sync_manager.h
+++ b/sync/internal_api/public/test/fake_sync_manager.h
@@ -63,14 +63,12 @@ class FakeSyncManager : public SyncManager {
// Posts a method to invalidate the given IDs on the sync thread.
virtual void OnIncomingInvalidation(
- const ObjectIdInvalidationMap& invalidation_map) OVERRIDE;
+ syncer::ModelType type,
+ scoped_ptr<InvalidationInterface> interface) OVERRIDE;
// Posts a method to update the invalidator state on the sync thread.
virtual void OnInvalidatorStateChange(InvalidatorState state) OVERRIDE;
- // Returns this class name for logging purposes.
- virtual std::string GetOwnerName() const OVERRIDE;
-
// Block until the sync thread has finished processing any pending messages.
void WaitForSyncThread();
diff --git a/sync/internal_api/sync_manager_impl.cc b/sync/internal_api/sync_manager_impl.cc
index 0e3caf3..d0ae309 100644
--- a/sync/internal_api/sync_manager_impl.cc
+++ b/sync/internal_api/sync_manager_impl.cc
@@ -20,6 +20,7 @@
#include "sync/engine/syncer_types.h"
#include "sync/internal_api/change_reorder_buffer.h"
#include "sync/internal_api/public/base/cancelation_signal.h"
+#include "sync/internal_api/public/base/invalidation_interface.h"
#include "sync/internal_api/public/base/model_type.h"
#include "sync/internal_api/public/base_node.h"
#include "sync/internal_api/public/configure_reason.h"
@@ -979,30 +980,17 @@ void SyncManagerImpl::OnInvalidatorStateChange(InvalidatorState state) {
}
void SyncManagerImpl::OnIncomingInvalidation(
- const ObjectIdInvalidationMap& invalidation_map) {
+ syncer::ModelType type,
+ scoped_ptr<InvalidationInterface> invalidation) {
DCHECK(thread_checker_.CalledOnValidThread());
- // We should never receive IDs from non-sync objects.
- ObjectIdSet ids = invalidation_map.GetObjectIds();
- for (ObjectIdSet::const_iterator it = ids.begin(); it != ids.end(); ++it) {
- ModelType type;
- if (!ObjectIdToRealModelType(*it, &type)) {
- DLOG(WARNING) << "Notification has invalid id: " << ObjectIdToString(*it);
- }
- }
-
- if (invalidation_map.Empty()) {
- LOG(WARNING) << "Sync received invalidation without any type information.";
- } else {
- scheduler_->ScheduleInvalidationNudge(
- TimeDelta::FromMilliseconds(kSyncSchedulerDelayMsec),
- invalidation_map, FROM_HERE);
- debug_info_event_listener_.OnIncomingNotification(invalidation_map);
- }
+ scheduler_->ScheduleInvalidationNudge(
+ TimeDelta::FromMilliseconds(kSyncSchedulerDelayMsec),
+ type,
+ invalidation.Pass(),
+ FROM_HERE);
}
-std::string SyncManagerImpl::GetOwnerName() const { return "SyncManagerImpl"; }
-
void SyncManagerImpl::RefreshTypes(ModelTypeSet types) {
DCHECK(thread_checker_.CalledOnValidThread());
if (types.Empty()) {
diff --git a/sync/internal_api/sync_manager_impl.h b/sync/internal_api/sync_manager_impl.h
index 2ca5fd6..7efde2d 100644
--- a/sync/internal_api/sync_manager_impl.h
+++ b/sync/internal_api/sync_manager_impl.h
@@ -104,8 +104,8 @@ class SYNC_EXPORT_PRIVATE SyncManagerImpl :
const base::Closure& retry_task) OVERRIDE;
virtual void OnInvalidatorStateChange(InvalidatorState state) OVERRIDE;
virtual void OnIncomingInvalidation(
- const ObjectIdInvalidationMap& invalidation_map) OVERRIDE;
- virtual std::string GetOwnerName() const OVERRIDE;
+ syncer::ModelType type,
+ scoped_ptr<InvalidationInterface> invalidation) OVERRIDE;
virtual void AddObserver(SyncManager::Observer* observer) OVERRIDE;
virtual void RemoveObserver(SyncManager::Observer* observer) OVERRIDE;
virtual SyncStatus GetDetailedStatus() const OVERRIDE;
diff --git a/sync/internal_api/sync_manager_impl_unittest.cc b/sync/internal_api/sync_manager_impl_unittest.cc
index 3fd4c5d..b4b5f87 100644
--- a/sync/internal_api/sync_manager_impl_unittest.cc
+++ b/sync/internal_api/sync_manager_impl_unittest.cc
@@ -983,14 +983,6 @@ class SyncManagerTest : public testing::Test,
sync_manager_.OnInvalidatorStateChange(state);
}
- void TriggerOnIncomingNotificationForTest(ModelTypeSet model_types) {
- DCHECK(sync_manager_.thread_checker_.CalledOnValidThread());
- ObjectIdSet id_set = ModelTypeSetToObjectIdSet(model_types);
- ObjectIdInvalidationMap invalidation_map =
- ObjectIdInvalidationMap::InvalidateAll(id_set);
- sync_manager_.OnIncomingInvalidation(invalidation_map);
- }
-
void SetProgressMarkerForType(ModelType type, bool set) {
if (set) {
sync_pb::DataTypeProgressMarker marker;
diff --git a/sync/internal_api/sync_rollback_manager_base.cc b/sync/internal_api/sync_rollback_manager_base.cc
index 28afb8b..b7d1fef 100644
--- a/sync/internal_api/sync_rollback_manager_base.cc
+++ b/sync/internal_api/sync_rollback_manager_base.cc
@@ -133,7 +133,8 @@ void SyncRollbackManagerBase::OnInvalidatorStateChange(InvalidatorState state) {
}
void SyncRollbackManagerBase::OnIncomingInvalidation(
- const ObjectIdInvalidationMap& invalidation_map) {
+ syncer::ModelType type,
+ scoped_ptr<InvalidationInterface> invalidation) {
NOTREACHED();
}
@@ -233,10 +234,6 @@ void SyncRollbackManagerBase::NotifyInitializationFailure() {
false, ModelTypeSet()));
}
-std::string SyncRollbackManagerBase::GetOwnerName() const {
- return "";
-}
-
syncer::SyncContextProxy* SyncRollbackManagerBase::GetSyncContextProxy() {
return NULL;
}
diff --git a/sync/internal_api/sync_rollback_manager_base.h b/sync/internal_api/sync_rollback_manager_base.h
index 8d32d7d..e18535f 100644
--- a/sync/internal_api/sync_rollback_manager_base.h
+++ b/sync/internal_api/sync_rollback_manager_base.h
@@ -73,7 +73,8 @@ class SYNC_EXPORT_PRIVATE SyncRollbackManagerBase :
const base::Closure& retry_task) OVERRIDE;
virtual void OnInvalidatorStateChange(InvalidatorState state) OVERRIDE;
virtual void OnIncomingInvalidation(
- const ObjectIdInvalidationMap& invalidation_map) OVERRIDE;
+ syncer::ModelType type,
+ scoped_ptr<InvalidationInterface> invalidation) OVERRIDE;
virtual void AddObserver(SyncManager::Observer* observer) OVERRIDE;
virtual void RemoveObserver(SyncManager::Observer* observer) OVERRIDE;
virtual SyncStatus GetDetailedStatus() const OVERRIDE;
@@ -85,7 +86,6 @@ class SYNC_EXPORT_PRIVATE SyncRollbackManagerBase :
virtual bool HasUnsyncedItems() OVERRIDE;
virtual SyncEncryptionHandler* GetEncryptionHandler() OVERRIDE;
virtual void RefreshTypes(ModelTypeSet types) OVERRIDE;
- virtual std::string GetOwnerName() const OVERRIDE;
virtual SyncContextProxy* GetSyncContextProxy() OVERRIDE;
virtual ScopedVector<ProtocolEvent> GetBufferedProtocolEvents()
OVERRIDE;
diff --git a/sync/internal_api/test/fake_sync_manager.cc b/sync/internal_api/test/fake_sync_manager.cc
index 7b5e32f..5bb4f10 100644
--- a/sync/internal_api/test/fake_sync_manager.cc
+++ b/sync/internal_api/test/fake_sync_manager.cc
@@ -263,7 +263,8 @@ bool FakeSyncManager::HasDirectoryTypeDebugInfoObserver(
void FakeSyncManager::RequestEmitDebugInfo() {}
void FakeSyncManager::OnIncomingInvalidation(
- const ObjectIdInvalidationMap& invalidation_map) {
+ syncer::ModelType type,
+ scoped_ptr<InvalidationInterface> invalidation) {
// Do nothing.
}
@@ -275,6 +276,4 @@ void FakeSyncManager::OnInvalidatorStateChange(InvalidatorState state) {
// Do nothing.
}
-std::string FakeSyncManager::GetOwnerName() const { return "FakeSyncManager"; }
-
} // namespace syncer
diff --git a/sync/notifier/dropped_invalidation_tracker.cc b/sync/notifier/dropped_invalidation_tracker.cc
deleted file mode 100644
index fc576e8..0000000
--- a/sync/notifier/dropped_invalidation_tracker.cc
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2013 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/notifier/dropped_invalidation_tracker.h"
-
-#include "sync/internal_api/public/base/invalidation.h"
-
-namespace syncer {
-
-DroppedInvalidationTracker::DroppedInvalidationTracker(
- const invalidation::ObjectId& id)
- : id_(id),
- drop_ack_handle_(AckHandle::InvalidAckHandle()),
- recovering_from_drop_(false) {}
-
-DroppedInvalidationTracker::~DroppedInvalidationTracker() {}
-
-const invalidation::ObjectId& DroppedInvalidationTracker::object_id() const {
- return id_;
-}
-
-void DroppedInvalidationTracker::RecordDropEvent(
- WeakHandle<AckHandler> handler, AckHandle handle) {
- drop_ack_handler_ = handler;
- drop_ack_handle_ = handle;
- recovering_from_drop_ = true;
-}
-
-void DroppedInvalidationTracker::RecordRecoveryFromDropEvent() {
- if (drop_ack_handler_.IsInitialized()) {
- drop_ack_handler_.Call(FROM_HERE,
- &AckHandler::Acknowledge,
- id_,
- drop_ack_handle_);
- }
- drop_ack_handler_ = syncer::WeakHandle<AckHandler>();
- recovering_from_drop_ = false;
-}
-
-bool DroppedInvalidationTracker::IsRecoveringFromDropEvent() const {
- return recovering_from_drop_;
-}
-
-} // namespace syncer
diff --git a/sync/notifier/dropped_invalidation_tracker.h b/sync/notifier/dropped_invalidation_tracker.h
deleted file mode 100644
index 20f32af..0000000
--- a/sync/notifier/dropped_invalidation_tracker.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2013 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_NOTIFIER_DROPPED_INVALIDATION_TRACKER_H_
-#define SYNC_NOTIFIER_DROPPED_INVALIDATION_TRACKER_H_
-
-#include "google/cacheinvalidation/include/types.h"
-#include "sync/base/sync_export.h"
-#include "sync/internal_api/public/base/ack_handle.h"
-#include "sync/internal_api/public/util/weak_handle.h"
-#include "sync/notifier/ack_handler.h"
-
-namespace syncer {
-
-class Invalidation;
-
-// Helps InvalidationHandlers keep track of dropped invalidations for a given
-// ObjectId.
-//
-// The intent of this class is to hide some of the implementation details around
-// how the invalidations system manages dropping and drop recovery. Any
-// invalidation handler that intends to buffer and occasionally drop
-// invalidations should keep one instance of it per registered ObjectId.
-//
-// When an invalidation handler wishes to drop an invalidation, it must provide
-// an instance of this class to that Invalidation's Drop() method. In order to
-// indicate recovery from a drop, the handler can call this class'
-// RecordRecoveryFromDropEvent().
-//
-// Copy and assign are allowed for this class so we can use it in STL
-// containers.
-class SYNC_EXPORT DroppedInvalidationTracker {
- public:
- explicit DroppedInvalidationTracker(const invalidation::ObjectId& id);
- ~DroppedInvalidationTracker();
-
- const invalidation::ObjectId& object_id() const;
-
- // Called by Invalidation::Drop() to keep track of a drop event.
- //
- // Takes ownership of the internals belonging to a soon to be discarded
- // dropped invalidation. See also the comment for this class'
- // |drop_ack_handler_| member.
- void RecordDropEvent(WeakHandle<AckHandler> handler, AckHandle handle);
-
- // Returns true if we're still recovering from a drop event.
- bool IsRecoveringFromDropEvent() const;
-
- // Called by the InvalidationHandler when it recovers from the drop event.
- void RecordRecoveryFromDropEvent();
-
- private:
- invalidation::ObjectId id_;
- AckHandle drop_ack_handle_;
-
- // This flag is set to true when we have dropped an invalidation and have not
- // yet recovered from this drop event. Note that this may not always coincide
- // with drop_ack_handler_ being initialized because a null AckHandler could be
- // passed in to RecordDropEvent().
- bool recovering_from_drop_;
-
- // A WeakHandle to the enitity responsible for persisting invalidation
- // acknowledgement state on disk. We can get away with using a WeakHandle
- // because we don't care if our drop recovery message doesn't gets delivered
- // in some shutdown cases. If that happens, we'll have to process the
- // invalidation state again on the next restart. It would be a waste of time
- // and resources, but otherwise not particularly harmful.
- WeakHandle<AckHandler> drop_ack_handler_;
-};
-
-} // namespace syncer
-
-#endif // SYNC_NOTIFIER_DROPPED_INVALIDATION_TRACKER_H_
diff --git a/sync/sessions/data_type_tracker.cc b/sync/sessions/data_type_tracker.cc
index 5e0ee90..ed7f07f 100644
--- a/sync/sessions/data_type_tracker.cc
+++ b/sync/sessions/data_type_tracker.cc
@@ -5,19 +5,17 @@
#include "sync/sessions/data_type_tracker.h"
#include "base/logging.h"
-#include "sync/internal_api/public/base/invalidation.h"
-#include "sync/notifier/invalidation_util.h"
-#include "sync/notifier/single_object_invalidation_set.h"
+#include "sync/internal_api/public/base/invalidation_interface.h"
#include "sync/sessions/nudge_tracker.h"
namespace syncer {
namespace sessions {
-DataTypeTracker::DataTypeTracker(const invalidation::ObjectId& object_id)
- : local_nudge_count_(0),
- local_refresh_request_count_(0),
- payload_buffer_size_(NudgeTracker::kDefaultMaxPayloadsPerType),
- drop_tracker_(object_id) { }
+DataTypeTracker::DataTypeTracker()
+ : local_nudge_count_(0),
+ local_refresh_request_count_(0),
+ payload_buffer_size_(NudgeTracker::kDefaultMaxPayloadsPerType) {
+}
DataTypeTracker::~DataTypeTracker() { }
@@ -29,20 +27,11 @@ void DataTypeTracker::RecordLocalRefreshRequest() {
local_refresh_request_count_++;
}
-namespace {
-
-bool IsInvalidationVersionLessThan(
- const Invalidation& a,
- const Invalidation& b) {
- InvalidationVersionLessThan comparator;
- return comparator(a, b);
-}
-
-} // namespace
+void DataTypeTracker::RecordRemoteInvalidation(
+ scoped_ptr<InvalidationInterface> incoming) {
+ DCHECK(incoming);
-void DataTypeTracker::RecordRemoteInvalidations(
- const SingleObjectInvalidationSet& invalidations) {
- // Merge the incoming invalidations into our list of pending invalidations.
+ // Merge the incoming invalidation into our list of pending invalidations.
//
// We won't use STL algorithms here because our concept of equality doesn't
// quite fit the expectations of set_intersection. In particular, two
@@ -50,52 +39,50 @@ void DataTypeTracker::RecordRemoteInvalidations(
// rules (ie. have equal versions), but still have different AckHandle values
// and need to be acknowledged separately.
//
- // The invalidaitons service can only track one outsanding invalidation per
+ // The invalidations service can only track one outsanding invalidation per
// type and version, so the acknowledgement here should be redundant. We'll
// acknowledge them anyway since it should do no harm, and makes this code a
// bit easier to test.
//
// Overlaps should be extremely rare for most invalidations. They can happen
// for unknown version invalidations, though.
- SingleObjectInvalidationSet::const_iterator incoming_it =
- invalidations.begin();
- SingleObjectInvalidationSet::const_iterator existing_it =
+
+ ScopedVector<InvalidationInterface>::iterator it =
pending_invalidations_.begin();
- while (incoming_it != invalidations.end()) {
- // Keep existing_it ahead of incoming_it.
- while (existing_it != pending_invalidations_.end()
- && IsInvalidationVersionLessThan(*existing_it, *incoming_it)) {
- existing_it++;
- }
+ // Find the lower bound.
+ while (it != pending_invalidations_.end() &&
+ InvalidationInterface::LessThanByVersion(**it, *incoming)) {
+ it++;
+ }
- if (existing_it != pending_invalidations_.end()
- && !IsInvalidationVersionLessThan(*incoming_it, *existing_it)
- && !IsInvalidationVersionLessThan(*existing_it, *incoming_it)) {
- // Incoming overlaps with existing. Either both are unknown versions
- // (likely) or these two have the same version number (very unlikely).
- // Acknowledge and overwrite existing.
- SingleObjectInvalidationSet::const_iterator old_inv = existing_it;
- existing_it++;
- old_inv->Acknowledge();
- pending_invalidations_.Erase(old_inv);
- pending_invalidations_.Insert(*incoming_it);
- incoming_it++;
- } else {
- DCHECK(existing_it == pending_invalidations_.end()
- || IsInvalidationVersionLessThan(*incoming_it, *existing_it));
- // The incoming_it points at a version not in the pending_invalidations_
- // list. Add it to the list then increment past it.
- pending_invalidations_.Insert(*incoming_it);
- incoming_it++;
- }
+ if (it != pending_invalidations_.end() &&
+ !InvalidationInterface::LessThanByVersion(*incoming, **it) &&
+ !InvalidationInterface::LessThanByVersion(**it, *incoming)) {
+ // Incoming overlaps with existing. Either both are unknown versions
+ // (likely) or these two have the same version number (very unlikely).
+ // Acknowledge and overwrite existing.
+
+ // Insert before the existing and get iterator to inserted.
+ ScopedVector<InvalidationInterface>::iterator it2 =
+ pending_invalidations_.insert(it, incoming.release());
+
+ // Increment that iterator to the old one, then acknowledge and remove it.
+ ++it2;
+ (*it2)->Acknowledge();
+ pending_invalidations_.erase(it2);
+ } else {
+ // The incoming has a version not in the pending_invalidations_ list.
+ // Add it to the list at the proper position.
+ pending_invalidations_.insert(it, incoming.release());
}
- // Those incoming invalidations may have caused us to exceed our buffer size.
+ // The incoming invalidation may have caused us to exceed our buffer size.
// Trim some items from our list, if necessary.
- while (pending_invalidations_.GetSize() > payload_buffer_size_) {
- pending_invalidations_.begin()->Drop(&drop_tracker_);
- pending_invalidations_.Erase(pending_invalidations_.begin());
+ while (pending_invalidations_.size() > payload_buffer_size_) {
+ last_dropped_invalidation_.reset(pending_invalidations_.front());
+ last_dropped_invalidation_->Drop();
+ pending_invalidations_.weak_erase(pending_invalidations_.begin());
}
}
@@ -112,15 +99,17 @@ void DataTypeTracker::RecordSuccessfulSyncCycle() {
// crash before writing all our state, we should wait until the results of
// this sync cycle have been written to disk before updating the invalidations
// state. See crbug.com/324996.
- for (SingleObjectInvalidationSet::const_iterator it =
- pending_invalidations_.begin();
- it != pending_invalidations_.end(); ++it) {
- it->Acknowledge();
+ for (ScopedVector<InvalidationInterface>::const_iterator it =
+ pending_invalidations_.begin();
+ it != pending_invalidations_.end();
+ ++it) {
+ (*it)->Acknowledge();
}
- pending_invalidations_.Clear();
+ pending_invalidations_.clear();
- if (drop_tracker_.IsRecoveringFromDropEvent()) {
- drop_tracker_.RecordRecoveryFromDropEvent();
+ if (last_dropped_invalidation_) {
+ last_dropped_invalidation_->Acknowledge();
+ last_dropped_invalidation_.reset();
}
}
@@ -147,8 +136,7 @@ bool DataTypeTracker::HasRefreshRequestPending() const {
}
bool DataTypeTracker::HasPendingInvalidation() const {
- return !pending_invalidations_.IsEmpty()
- || drop_tracker_.IsRecoveringFromDropEvent();
+ return !pending_invalidations_.empty() || last_dropped_invalidation_;
}
void DataTypeTracker::SetLegacyNotificationHint(
@@ -156,16 +144,17 @@ void DataTypeTracker::SetLegacyNotificationHint(
DCHECK(!IsThrottled())
<< "We should not make requests if the type is throttled.";
- if (!pending_invalidations_.IsEmpty() &&
- !pending_invalidations_.back().is_unknown_version()) {
+ if (!pending_invalidations_.empty() &&
+ !pending_invalidations_.back()->IsUnknownVersion()) {
// The old-style source info can contain only one hint per type. We grab
// the most recent, to mimic the old coalescing behaviour.
- progress->set_notification_hint(pending_invalidations_.back().payload());
+ progress->set_notification_hint(
+ pending_invalidations_.back()->GetPayload());
} else if (HasLocalChangePending()) {
// The old-style source info sent up an empty string (as opposed to
// nothing at all) when the type was locally nudged, but had not received
// any invalidations.
- progress->set_notification_hint("");
+ progress->set_notification_hint(std::string());
}
}
@@ -174,17 +163,19 @@ void DataTypeTracker::FillGetUpdatesTriggersMessage(
// Fill the list of payloads, if applicable. The payloads must be ordered
// oldest to newest, so we insert them in the same order as we've been storing
// them internally.
- for (SingleObjectInvalidationSet::const_iterator it =
- pending_invalidations_.begin();
- it != pending_invalidations_.end(); ++it) {
- if (!it->is_unknown_version()) {
- msg->add_notification_hint(it->payload());
+ for (ScopedVector<InvalidationInterface>::const_iterator it =
+ pending_invalidations_.begin();
+ it != pending_invalidations_.end();
+ ++it) {
+ if (!(*it)->IsUnknownVersion()) {
+ msg->add_notification_hint((*it)->GetPayload());
}
}
msg->set_server_dropped_hints(
- pending_invalidations_.StartsWithUnknownVersion());
- msg->set_client_dropped_hints(drop_tracker_.IsRecoveringFromDropEvent());
+ !pending_invalidations_.empty() &&
+ (*pending_invalidations_.begin())->IsUnknownVersion());
+ msg->set_client_dropped_hints(last_dropped_invalidation_);
msg->set_local_modification_nudges(local_nudge_count_);
msg->set_datatype_refresh_nudges(local_refresh_request_count_);
}
diff --git a/sync/sessions/data_type_tracker.h b/sync/sessions/data_type_tracker.h
index 59ec993..8d78cde 100644
--- a/sync/sessions/data_type_tracker.h
+++ b/sync/sessions/data_type_tracker.h
@@ -1,32 +1,30 @@
// Copyright 2013 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.
-//
-// A class to track the per-type scheduling data.
+
#ifndef SYNC_SESSIONS_DATA_TYPE_TRACKER_H_
#define SYNC_SESSIONS_DATA_TYPE_TRACKER_H_
-#include <deque>
#include <string>
#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/scoped_vector.h"
#include "base/time/time.h"
-#include "sync/notifier/dropped_invalidation_tracker.h"
-#include "sync/notifier/single_object_invalidation_set.h"
+#include "sync/internal_api/public/base/invalidation_interface.h"
+#include "sync/internal_api/public/base/model_type.h"
#include "sync/protocol/sync.pb.h"
namespace syncer {
-class Invalidation;
-class SingleObjectInvalidationSet;
+class InvalidationInterface;
namespace sessions {
-typedef std::deque<std::string> PayloadList;
-
+// A class to track the per-type scheduling data.
class DataTypeTracker {
public:
- explicit DataTypeTracker(const invalidation::ObjectId& object_id);
+ explicit DataTypeTracker();
~DataTypeTracker();
// For STL compatibility, we do not forbid the creation of a default copy
@@ -39,8 +37,7 @@ class DataTypeTracker {
void RecordLocalRefreshRequest();
// Tracks that we received invalidation notifications for this type.
- void RecordRemoteInvalidations(
- const SingleObjectInvalidationSet& invalidations);
+ void RecordRemoteInvalidation(scoped_ptr<InvalidationInterface> incoming);
// Records that a sync cycle has been performed successfully.
// Generally, this means that all local changes have been committed and all
@@ -105,7 +102,9 @@ class DataTypeTracker {
// The list of invalidations received since the last successful sync cycle.
// This list may be incomplete. See also:
// drop_tracker_.IsRecoveringFromDropEvent() and server_payload_overflow_.
- SingleObjectInvalidationSet pending_invalidations_;
+ //
+ // This list takes ownership of its contents.
+ ScopedVector<InvalidationInterface> pending_invalidations_;
size_t payload_buffer_size_;
@@ -114,10 +113,12 @@ class DataTypeTracker {
base::TimeTicks unthrottle_time_;
// A helper to keep track invalidations we dropped due to overflow.
- DroppedInvalidationTracker drop_tracker_;
+ scoped_ptr<InvalidationInterface> last_dropped_invalidation_;
+
+ DISALLOW_COPY_AND_ASSIGN(DataTypeTracker);
};
-} // namespace syncer
} // namespace sessions
+} // namespace syncer
#endif // SYNC_SESSIONS_DATA_TYPE_TRACKER_H_
diff --git a/sync/sessions/nudge_tracker.cc b/sync/sessions/nudge_tracker.cc
index e9e731d..8dd6d2a 100644
--- a/sync/sessions/nudge_tracker.cc
+++ b/sync/sessions/nudge_tracker.cc
@@ -16,18 +16,14 @@ namespace sessions {
size_t NudgeTracker::kDefaultMaxPayloadsPerType = 10;
NudgeTracker::NudgeTracker()
- : invalidations_enabled_(false),
+ : type_tracker_deleter_(&type_trackers_),
+ invalidations_enabled_(false),
invalidations_out_of_sync_(true) {
ModelTypeSet protocol_types = ProtocolTypes();
// Default initialize all the type trackers.
for (ModelTypeSet::Iterator it = protocol_types.First(); it.Good();
it.Inc()) {
- invalidation::ObjectId id;
- if (!RealModelTypeToObjectId(it.Get(), &id)) {
- NOTREACHED();
- } else {
- type_trackers_.insert(std::make_pair(it.Get(), DataTypeTracker(id)));
- }
+ type_trackers_.insert(std::make_pair(it.Get(), new DataTypeTracker()));
}
}
@@ -39,7 +35,7 @@ bool NudgeTracker::IsSyncRequired() const {
for (TypeTrackerMap::const_iterator it = type_trackers_.begin();
it != type_trackers_.end(); ++it) {
- if (it->second.IsSyncRequired()) {
+ if (it->second->IsSyncRequired()) {
return true;
}
}
@@ -56,7 +52,7 @@ bool NudgeTracker::IsGetUpdatesRequired() const {
for (TypeTrackerMap::const_iterator it = type_trackers_.begin();
it != type_trackers_.end(); ++it) {
- if (it->second.IsGetUpdatesRequired()) {
+ if (it->second->IsGetUpdatesRequired()) {
return true;
}
}
@@ -83,7 +79,7 @@ void NudgeTracker::RecordSuccessfulSyncCycle() {
for (TypeTrackerMap::iterator it = type_trackers_.begin();
it != type_trackers_.end(); ++it) {
- it->second.RecordSuccessfulSyncCycle();
+ it->second->RecordSuccessfulSyncCycle();
}
}
@@ -92,7 +88,7 @@ void NudgeTracker::RecordLocalChange(ModelTypeSet types) {
type_it.Inc()) {
TypeTrackerMap::iterator tracker_it = type_trackers_.find(type_it.Get());
DCHECK(tracker_it != type_trackers_.end());
- tracker_it->second.RecordLocalChange();
+ tracker_it->second->RecordLocalChange();
}
}
@@ -100,34 +96,17 @@ void NudgeTracker::RecordLocalRefreshRequest(ModelTypeSet types) {
for (ModelTypeSet::Iterator it = types.First(); it.Good(); it.Inc()) {
TypeTrackerMap::iterator tracker_it = type_trackers_.find(it.Get());
DCHECK(tracker_it != type_trackers_.end());
- tracker_it->second.RecordLocalRefreshRequest();
+ tracker_it->second->RecordLocalRefreshRequest();
}
}
void NudgeTracker::RecordRemoteInvalidation(
- const ObjectIdInvalidationMap& invalidation_map) {
- // Be very careful here. The invalidations acknowledgement system requires a
- // sort of manual memory management. We'll leak a small amount of memory if
- // we fail to acknowledge or drop any of these incoming invalidations.
-
- ObjectIdSet id_set = invalidation_map.GetObjectIds();
- for (ObjectIdSet::iterator it = id_set.begin(); it != id_set.end(); ++it) {
- ModelType type;
-
- // This should never happen. If it does, we'll start to leak memory.
- if (!ObjectIdToRealModelType(*it, &type)) {
- NOTREACHED()
- << "Object ID " << ObjectIdToString(*it)
- << " does not map to valid model type";
- continue;
- }
-
- // Forward the invalidations to the proper recipient.
- TypeTrackerMap::iterator tracker_it = type_trackers_.find(type);
- DCHECK(tracker_it != type_trackers_.end());
- tracker_it->second.RecordRemoteInvalidations(
- invalidation_map.ForObject(*it));
- }
+ syncer::ModelType type,
+ scoped_ptr<InvalidationInterface> invalidation) {
+ // Forward the invalidations to the proper recipient.
+ TypeTrackerMap::iterator tracker_it = type_trackers_.find(type);
+ DCHECK(tracker_it != type_trackers_.end());
+ tracker_it->second->RecordRemoteInvalidation(invalidation.Pass());
}
void NudgeTracker::OnInvalidationsEnabled() {
@@ -145,21 +124,21 @@ void NudgeTracker::SetTypesThrottledUntil(
base::TimeTicks now) {
for (ModelTypeSet::Iterator it = types.First(); it.Good(); it.Inc()) {
TypeTrackerMap::iterator tracker_it = type_trackers_.find(it.Get());
- tracker_it->second.ThrottleType(length, now);
+ tracker_it->second->ThrottleType(length, now);
}
}
void NudgeTracker::UpdateTypeThrottlingState(base::TimeTicks now) {
for (TypeTrackerMap::iterator it = type_trackers_.begin();
it != type_trackers_.end(); ++it) {
- it->second.UpdateThrottleState(now);
+ it->second->UpdateThrottleState(now);
}
}
bool NudgeTracker::IsAnyTypeThrottled() const {
for (TypeTrackerMap::const_iterator it = type_trackers_.begin();
it != type_trackers_.end(); ++it) {
- if (it->second.IsThrottled()) {
+ if (it->second->IsThrottled()) {
return true;
}
}
@@ -168,7 +147,7 @@ bool NudgeTracker::IsAnyTypeThrottled() const {
bool NudgeTracker::IsTypeThrottled(ModelType type) const {
DCHECK(type_trackers_.find(type) != type_trackers_.end());
- return type_trackers_.find(type)->second.IsThrottled();
+ return type_trackers_.find(type)->second->IsThrottled();
}
base::TimeDelta NudgeTracker::GetTimeUntilNextUnthrottle(
@@ -179,10 +158,9 @@ base::TimeDelta NudgeTracker::GetTimeUntilNextUnthrottle(
base::TimeDelta time_until_next_unthrottle = base::TimeDelta::Max();
for (TypeTrackerMap::const_iterator it = type_trackers_.begin();
it != type_trackers_.end(); ++it) {
- if (it->second.IsThrottled()) {
- time_until_next_unthrottle =
- std::min(time_until_next_unthrottle,
- it->second.GetTimeUntilUnthrottle(now));
+ if (it->second->IsThrottled()) {
+ time_until_next_unthrottle = std::min(
+ time_until_next_unthrottle, it->second->GetTimeUntilUnthrottle(now));
}
}
DCHECK(!time_until_next_unthrottle.is_max());
@@ -194,7 +172,7 @@ ModelTypeSet NudgeTracker::GetThrottledTypes() const {
ModelTypeSet result;
for (TypeTrackerMap::const_iterator it = type_trackers_.begin();
it != type_trackers_.end(); ++it) {
- if (it->second.IsThrottled()) {
+ if (it->second->IsThrottled()) {
result.Put(it->first);
}
}
@@ -205,7 +183,7 @@ ModelTypeSet NudgeTracker::GetNudgedTypes() const {
ModelTypeSet result;
for (TypeTrackerMap::const_iterator it = type_trackers_.begin();
it != type_trackers_.end(); ++it) {
- if (it->second.HasLocalChangePending()) {
+ if (it->second->HasLocalChangePending()) {
result.Put(it->first);
}
}
@@ -216,7 +194,7 @@ ModelTypeSet NudgeTracker::GetNotifiedTypes() const {
ModelTypeSet result;
for (TypeTrackerMap::const_iterator it = type_trackers_.begin();
it != type_trackers_.end(); ++it) {
- if (it->second.HasPendingInvalidation()) {
+ if (it->second->HasPendingInvalidation()) {
result.Put(it->first);
}
}
@@ -227,7 +205,7 @@ ModelTypeSet NudgeTracker::GetRefreshRequestedTypes() const {
ModelTypeSet result;
for (TypeTrackerMap::const_iterator it = type_trackers_.begin();
it != type_trackers_.end(); ++it) {
- if (it->second.HasRefreshRequestPending()) {
+ if (it->second->HasRefreshRequestPending()) {
result.Put(it->first);
}
}
@@ -238,7 +216,7 @@ void NudgeTracker::SetLegacyNotificationHint(
ModelType type,
sync_pb::DataTypeProgressMarker* progress) const {
DCHECK(type_trackers_.find(type) != type_trackers_.end());
- type_trackers_.find(type)->second.SetLegacyNotificationHint(progress);
+ type_trackers_.find(type)->second->SetLegacyNotificationHint(progress);
}
sync_pb::GetUpdatesCallerInfo::GetUpdatesSource NudgeTracker::GetLegacySource()
@@ -257,7 +235,7 @@ sync_pb::GetUpdatesCallerInfo::GetUpdatesSource NudgeTracker::GetLegacySource()
for (TypeTrackerMap::const_iterator it = type_trackers_.begin();
it != type_trackers_.end(); ++it) {
- const DataTypeTracker& tracker = it->second;
+ const DataTypeTracker& tracker = *it->second;
if (!tracker.IsThrottled() && tracker.HasPendingInvalidation()) {
has_invalidation_pending = true;
}
@@ -291,7 +269,7 @@ void NudgeTracker::FillProtoMessage(
msg->set_invalidations_out_of_sync(invalidations_out_of_sync_);
// Delegate the type-specific work to the DataTypeTracker class.
- type_trackers_.find(type)->second.FillGetUpdatesTriggersMessage(msg);
+ type_trackers_.find(type)->second->FillGetUpdatesTriggersMessage(msg);
}
void NudgeTracker::SetSyncCycleStartTime(base::TimeTicks now) {
@@ -320,7 +298,7 @@ void NudgeTracker::SetSyncCycleStartTime(base::TimeTicks now) {
void NudgeTracker::SetHintBufferSize(size_t size) {
for (TypeTrackerMap::iterator it = type_trackers_.begin();
it != type_trackers_.end(); ++it) {
- it->second.UpdatePayloadBufferSize(size);
+ it->second->UpdatePayloadBufferSize(size);
}
}
diff --git a/sync/sessions/nudge_tracker.h b/sync/sessions/nudge_tracker.h
index e14f31f..4c8d445 100644
--- a/sync/sessions/nudge_tracker.h
+++ b/sync/sessions/nudge_tracker.h
@@ -11,6 +11,7 @@
#include <map>
#include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
#include "sync/base/sync_export.h"
#include "sync/internal_api/public/base/model_type.h"
#include "sync/protocol/sync.pb.h"
@@ -57,8 +58,8 @@ class SYNC_EXPORT_PRIVATE NudgeTracker {
void RecordLocalRefreshRequest(ModelTypeSet types);
// Takes note of the receipt of an invalidation notice from the server.
- void RecordRemoteInvalidation(
- const ObjectIdInvalidationMap& invalidation_map);
+ void RecordRemoteInvalidation(syncer::ModelType type,
+ scoped_ptr<InvalidationInterface> invalidation);
// These functions should be called to keep this class informed of the status
// of the connection to the invalidations server.
@@ -137,9 +138,10 @@ class SYNC_EXPORT_PRIVATE NudgeTracker {
void SetNextRetryTime(base::TimeTicks next_retry_time);
private:
- typedef std::map<ModelType, DataTypeTracker> TypeTrackerMap;
+ typedef std::map<ModelType, DataTypeTracker*> TypeTrackerMap;
TypeTrackerMap type_trackers_;
+ STLValueDeleter<TypeTrackerMap> type_tracker_deleter_;
// Merged updates source. This should be obsolete, but the server still
// relies on it for some heuristics.
diff --git a/sync/sessions/nudge_tracker_unittest.cc b/sync/sessions/nudge_tracker_unittest.cc
index dc7f5ba..53b38a7 100644
--- a/sync/sessions/nudge_tracker_unittest.cc
+++ b/sync/sessions/nudge_tracker_unittest.cc
@@ -9,6 +9,9 @@
#include "sync/notifier/mock_ack_handler.h"
#include "sync/notifier/object_id_invalidation_map.h"
#include "sync/sessions/nudge_tracker.h"
+#include "sync/test/mock_invalidation.h"
+#include "sync/test/mock_invalidation_tracker.h"
+#include "sync/test/trackable_mock_invalidation.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace syncer {
@@ -25,14 +28,6 @@ testing::AssertionResult ModelTypeSetEquals(ModelTypeSet a, ModelTypeSet b) {
}
}
-syncer::Invalidation BuildUnknownVersionInvalidation(ModelType type) {
- invalidation::ObjectId id;
- bool result = RealModelTypeToObjectId(type, &id);
- DCHECK(result);
- return Invalidation::InitUnknownVersion(id);
-}
-
-
} // namespace
namespace sessions {
@@ -72,6 +67,18 @@ class NudgeTrackerTest : public ::testing::Test {
nudge_tracker_.RecordSuccessfulSyncCycle();
}
+ scoped_ptr<InvalidationInterface> BuildInvalidation(
+ int64 version,
+ const std::string& payload) {
+ return MockInvalidation::Build(version, payload)
+ .PassAs<InvalidationInterface>();
+ }
+
+ static scoped_ptr<InvalidationInterface> BuildUnknownVersionInvalidation() {
+ return MockInvalidation::BuildUnknownVersion()
+ .PassAs<InvalidationInterface>();
+ }
+
protected:
NudgeTracker nudge_tracker_;
};
@@ -119,9 +126,8 @@ TEST_F(NudgeTrackerTest, SourcePriorities) {
nudge_tracker_.GetLegacySource());
// An invalidation will override the refresh request source.
- ObjectIdInvalidationMap invalidation_map =
- BuildInvalidationMap(PREFERENCES, 1, "hint");
- nudge_tracker_.RecordRemoteInvalidation(invalidation_map);
+ nudge_tracker_.RecordRemoteInvalidation(PREFERENCES,
+ BuildInvalidation(1, "hint"));
EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::NOTIFICATION,
nudge_tracker_.GetLegacySource());
@@ -138,9 +144,8 @@ TEST_F(NudgeTrackerTest, SourcePriorities) {
TEST_F(NudgeTrackerTest, HintCoalescing) {
// Easy case: record one hint.
{
- ObjectIdInvalidationMap invalidation_map =
- BuildInvalidationMap(BOOKMARKS, 1, "bm_hint_1");
- nudge_tracker_.RecordRemoteInvalidation(invalidation_map);
+ nudge_tracker_.RecordRemoteInvalidation(BOOKMARKS,
+ BuildInvalidation(1, "bm_hint_1"));
sync_pb::GetUpdateTriggers gu_trigger;
nudge_tracker_.FillProtoMessage(BOOKMARKS, &gu_trigger);
@@ -151,9 +156,8 @@ TEST_F(NudgeTrackerTest, HintCoalescing) {
// Record a second hint for the same type.
{
- ObjectIdInvalidationMap invalidation_map =
- BuildInvalidationMap(BOOKMARKS, 2, "bm_hint_2");
- nudge_tracker_.RecordRemoteInvalidation(invalidation_map);
+ nudge_tracker_.RecordRemoteInvalidation(BOOKMARKS,
+ BuildInvalidation(2, "bm_hint_2"));
sync_pb::GetUpdateTriggers gu_trigger;
nudge_tracker_.FillProtoMessage(BOOKMARKS, &gu_trigger);
@@ -167,9 +171,8 @@ TEST_F(NudgeTrackerTest, HintCoalescing) {
// Record a hint for a different type.
{
- ObjectIdInvalidationMap invalidation_map =
- BuildInvalidationMap(PASSWORDS, 1, "pw_hint_1");
- nudge_tracker_.RecordRemoteInvalidation(invalidation_map);
+ nudge_tracker_.RecordRemoteInvalidation(PASSWORDS,
+ BuildInvalidation(1, "pw_hint_1"));
// Re-verify the bookmarks to make sure they're unaffected.
sync_pb::GetUpdateTriggers bm_gu_trigger;
@@ -192,9 +195,8 @@ TEST_F(NudgeTrackerTest, HintCoalescing) {
// Test the dropping of invalidation hints. Receives invalidations one by one.
TEST_F(NudgeTrackerTest, DropHintsLocally_OneAtATime) {
for (size_t i = 0; i < GetHintBufferSize(); ++i) {
- ObjectIdInvalidationMap invalidation_map =
- BuildInvalidationMap(BOOKMARKS, i, "hint");
- nudge_tracker_.RecordRemoteInvalidation(invalidation_map);
+ nudge_tracker_.RecordRemoteInvalidation(BOOKMARKS,
+ BuildInvalidation(i, "hint"));
}
{
sync_pb::GetUpdateTriggers gu_trigger;
@@ -205,9 +207,8 @@ TEST_F(NudgeTrackerTest, DropHintsLocally_OneAtATime) {
}
// Force an overflow.
- ObjectIdInvalidationMap invalidation_map2 =
- BuildInvalidationMap(BOOKMARKS, 1000, "new_hint");
- nudge_tracker_.RecordRemoteInvalidation(invalidation_map2);
+ nudge_tracker_.RecordRemoteInvalidation(BOOKMARKS,
+ BuildInvalidation(1000, "new_hint"));
{
sync_pb::GetUpdateTriggers gu_trigger;
@@ -224,52 +225,11 @@ TEST_F(NudgeTrackerTest, DropHintsLocally_OneAtATime) {
}
}
-// Test the dropping of invalidation hints.
-// Receives invalidations in large batches.
-TEST_F(NudgeTrackerTest, DropHintsLocally_ManyHints) {
- ObjectIdInvalidationMap invalidation_map;
- for (size_t i = 0; i < GetHintBufferSize(); ++i) {
- invalidation_map.Insert(BuildInvalidation(BOOKMARKS, i, "hint"));
- }
- nudge_tracker_.RecordRemoteInvalidation(invalidation_map);
- {
- sync_pb::GetUpdateTriggers gu_trigger;
- nudge_tracker_.FillProtoMessage(BOOKMARKS, &gu_trigger);
- EXPECT_EQ(GetHintBufferSize(),
- static_cast<size_t>(gu_trigger.notification_hint_size()));
- EXPECT_FALSE(gu_trigger.client_dropped_hints());
- }
-
- // Force an overflow.
- ObjectIdInvalidationMap invalidation_map2;
- invalidation_map2.Insert(BuildInvalidation(BOOKMARKS, 1000, "new_hint"));
- invalidation_map2.Insert(BuildInvalidation(BOOKMARKS, 1001, "newer_hint"));
- nudge_tracker_.RecordRemoteInvalidation(invalidation_map2);
-
- {
- sync_pb::GetUpdateTriggers gu_trigger;
- nudge_tracker_.FillProtoMessage(BOOKMARKS, &gu_trigger);
- EXPECT_TRUE(gu_trigger.client_dropped_hints());
- ASSERT_EQ(GetHintBufferSize(),
- static_cast<size_t>(gu_trigger.notification_hint_size()));
-
- // Verify the newest hints were not dropped and are the last in the list.
- EXPECT_EQ("newer_hint",
- gu_trigger.notification_hint(GetHintBufferSize()-1));
- EXPECT_EQ("new_hint", gu_trigger.notification_hint(GetHintBufferSize()-2));
-
- // Verify the oldest hint, too.
- EXPECT_EQ("hint", gu_trigger.notification_hint(0));
- }
-}
-
// Tests the receipt of 'unknown version' invalidations.
TEST_F(NudgeTrackerTest, DropHintsAtServer_Alone) {
- ObjectIdInvalidationMap invalidation_map;
- invalidation_map.Insert(BuildUnknownVersionInvalidation(BOOKMARKS));
-
// Record the unknown version invalidation.
- nudge_tracker_.RecordRemoteInvalidation(invalidation_map);
+ nudge_tracker_.RecordRemoteInvalidation(BOOKMARKS,
+ BuildUnknownVersionInvalidation());
{
sync_pb::GetUpdateTriggers gu_trigger;
nudge_tracker_.FillProtoMessage(BOOKMARKS, &gu_trigger);
@@ -292,12 +252,12 @@ TEST_F(NudgeTrackerTest, DropHintsAtServer_Alone) {
// Tests the receipt of 'unknown version' invalidations. This test also
// includes a known version invalidation to mix things up a bit.
TEST_F(NudgeTrackerTest, DropHintsAtServer_WithOtherInvalidations) {
- ObjectIdInvalidationMap invalidation_map;
- invalidation_map.Insert(BuildUnknownVersionInvalidation(BOOKMARKS));
- invalidation_map.Insert(BuildInvalidation(BOOKMARKS, 10, "hint"));
+ // Record the two invalidations, one with unknown version, the other known.
+ nudge_tracker_.RecordRemoteInvalidation(BOOKMARKS,
+ BuildUnknownVersionInvalidation());
+ nudge_tracker_.RecordRemoteInvalidation(BOOKMARKS,
+ BuildInvalidation(10, "hint"));
- // Record the two invalidations, one with unknown version, the other unknown.
- nudge_tracker_.RecordRemoteInvalidation(invalidation_map);
{
sync_pb::GetUpdateTriggers gu_trigger;
nudge_tracker_.FillProtoMessage(BOOKMARKS, &gu_trigger);
@@ -400,9 +360,8 @@ TEST_F(NudgeTrackerTest, IsSyncRequired) {
EXPECT_FALSE(nudge_tracker_.IsSyncRequired());
// Invalidations.
- ObjectIdInvalidationMap invalidation_map =
- BuildInvalidationMap(PREFERENCES, 1, "hint");
- nudge_tracker_.RecordRemoteInvalidation(invalidation_map);
+ nudge_tracker_.RecordRemoteInvalidation(PREFERENCES,
+ BuildInvalidation(1, "hint"));
EXPECT_TRUE(nudge_tracker_.IsSyncRequired());
nudge_tracker_.RecordSuccessfulSyncCycle();
EXPECT_FALSE(nudge_tracker_.IsSyncRequired());
@@ -425,9 +384,8 @@ TEST_F(NudgeTrackerTest, IsGetUpdatesRequired) {
EXPECT_FALSE(nudge_tracker_.IsGetUpdatesRequired());
// Invalidations.
- ObjectIdInvalidationMap invalidation_map =
- BuildInvalidationMap(PREFERENCES, 1, "hint");
- nudge_tracker_.RecordRemoteInvalidation(invalidation_map);
+ nudge_tracker_.RecordRemoteInvalidation(PREFERENCES,
+ BuildInvalidation(1, "hint"));
EXPECT_TRUE(nudge_tracker_.IsGetUpdatesRequired());
nudge_tracker_.RecordSuccessfulSyncCycle();
EXPECT_FALSE(nudge_tracker_.IsGetUpdatesRequired());
@@ -744,60 +702,48 @@ class NudgeTrackerAckTrackingTest : public NudgeTrackerTest {
public:
NudgeTrackerAckTrackingTest() {}
- bool IsInvalidationUnacknowledged(const syncer::Invalidation& invalidation) {
- // Run pending tasks before checking with the MockAckHandler.
- // The WeakHandle may have posted some tasks for it.
- base::RunLoop().RunUntilIdle();
- return mock_ack_handler_.IsUnacked(invalidation);
+ bool IsInvalidationUnacknowledged(int tracking_id) {
+ return tracker_.IsUnacked(tracking_id);
}
- bool IsInvalidationAcknowledged(const syncer::Invalidation& invalidation) {
- // Run pending tasks before checking with the MockAckHandler.
- // The WeakHandle may have posted some tasks for it.
- base::RunLoop().RunUntilIdle();
- return mock_ack_handler_.IsAcknowledged(invalidation);
+ bool IsInvalidationAcknowledged(int tracking_id) {
+ return tracker_.IsAcknowledged(tracking_id);
}
- bool IsInvalidationDropped(const syncer::Invalidation& invalidation) {
- // Run pending tasks before checking with the MockAckHandler.
- // The WeakHandle may have posted some tasks for it.
- base::RunLoop().RunUntilIdle();
- return mock_ack_handler_.IsDropped(invalidation);
+ bool IsInvalidationDropped(int tracking_id) {
+ return tracker_.IsDropped(tracking_id);
}
- bool AllInvalidationsAccountedFor() {
- return mock_ack_handler_.AllInvalidationsAccountedFor();
- }
-
- Invalidation SendInvalidation(
- ModelType type,
- int64 version,
- const std::string& hint) {
+ int SendInvalidation(ModelType type, int version, const std::string& hint) {
// Build and register the invalidation.
- syncer::Invalidation invalidation = BuildInvalidation(type, version, hint);
- mock_ack_handler_.RegisterInvalidation(&invalidation);
+ scoped_ptr<TrackableMockInvalidation> inv =
+ tracker_.IssueInvalidation(version, hint);
+ int id = inv->GetTrackingId();
// Send it to the NudgeTracker.
- ObjectIdInvalidationMap invalidation_map;
- invalidation_map.Insert(invalidation);
- nudge_tracker_.RecordRemoteInvalidation(invalidation_map);
+ nudge_tracker_.RecordRemoteInvalidation(
+ type, inv.PassAs<InvalidationInterface>());
- // Return it to the test framework for use in assertions.
- return invalidation;
+ // Return its ID to the test framework for use in assertions.
+ return id;
}
- Invalidation SendUnknownVersionInvalidation(ModelType type) {
+ int SendUnknownVersionInvalidation(ModelType type) {
// Build and register the invalidation.
- syncer::Invalidation invalidation = BuildUnknownVersionInvalidation(type);
- mock_ack_handler_.RegisterInvalidation(&invalidation);
+ scoped_ptr<TrackableMockInvalidation> inv =
+ tracker_.IssueUnknownVersionInvalidation();
+ int id = inv->GetTrackingId();
// Send it to the NudgeTracker.
- ObjectIdInvalidationMap invalidation_map;
- invalidation_map.Insert(invalidation);
- nudge_tracker_.RecordRemoteInvalidation(invalidation_map);
+ nudge_tracker_.RecordRemoteInvalidation(
+ type, inv.PassAs<InvalidationInterface>());
+
+ // Return its ID to the test framework for use in assertions.
+ return id;
+ }
- // Return it to the test framework for use in assertions.
- return invalidation;
+ bool AllInvalidationsAccountedFor() const {
+ return tracker_.AllInvalidationsAccountedFor();
}
void RecordSuccessfulSyncCycle() {
@@ -805,109 +751,110 @@ class NudgeTrackerAckTrackingTest : public NudgeTrackerTest {
}
private:
- syncer::MockAckHandler mock_ack_handler_;
- base::MessageLoop loop_;
+ MockInvalidationTracker tracker_;
};
// Test the acknowledgement of a single invalidation.
TEST_F(NudgeTrackerAckTrackingTest, SimpleAcknowledgement) {
- Invalidation inv = SendInvalidation(BOOKMARKS, 10, "hint");
+ int inv_id = SendInvalidation(BOOKMARKS, 10, "hint");
- EXPECT_TRUE(IsInvalidationUnacknowledged(inv));
+ EXPECT_TRUE(IsInvalidationUnacknowledged(inv_id));
RecordSuccessfulSyncCycle();
- EXPECT_TRUE(IsInvalidationAcknowledged(inv));
+ EXPECT_TRUE(IsInvalidationAcknowledged(inv_id));
EXPECT_TRUE(AllInvalidationsAccountedFor());
}
// Test the acknowledgement of many invalidations.
TEST_F(NudgeTrackerAckTrackingTest, ManyAcknowledgements) {
- Invalidation inv1 = SendInvalidation(BOOKMARKS, 10, "hint");
- Invalidation inv2 = SendInvalidation(BOOKMARKS, 14, "hint2");
- Invalidation inv3 = SendInvalidation(PREFERENCES, 8, "hint3");
+ int inv1_id = SendInvalidation(BOOKMARKS, 10, "hint");
+ int inv2_id = SendInvalidation(BOOKMARKS, 14, "hint2");
+ int inv3_id = SendInvalidation(PREFERENCES, 8, "hint3");
- EXPECT_TRUE(IsInvalidationUnacknowledged(inv1));
- EXPECT_TRUE(IsInvalidationUnacknowledged(inv2));
- EXPECT_TRUE(IsInvalidationUnacknowledged(inv3));
+ EXPECT_TRUE(IsInvalidationUnacknowledged(inv1_id));
+ EXPECT_TRUE(IsInvalidationUnacknowledged(inv2_id));
+ EXPECT_TRUE(IsInvalidationUnacknowledged(inv3_id));
RecordSuccessfulSyncCycle();
- EXPECT_TRUE(IsInvalidationAcknowledged(inv1));
- EXPECT_TRUE(IsInvalidationAcknowledged(inv2));
- EXPECT_TRUE(IsInvalidationAcknowledged(inv3));
+ EXPECT_TRUE(IsInvalidationAcknowledged(inv1_id));
+ EXPECT_TRUE(IsInvalidationAcknowledged(inv2_id));
+ EXPECT_TRUE(IsInvalidationAcknowledged(inv3_id));
EXPECT_TRUE(AllInvalidationsAccountedFor());
}
// Test dropping when the buffer overflows and subsequent drop recovery.
TEST_F(NudgeTrackerAckTrackingTest, OverflowAndRecover) {
- std::vector<Invalidation> invalidations;
+ std::vector<int> invalidation_ids;
- Invalidation inv10 = SendInvalidation(BOOKMARKS, 10, "hint");
+ int inv10_id = SendInvalidation(BOOKMARKS, 10, "hint");
for (size_t i = 1; i < GetHintBufferSize(); ++i) {
- invalidations.push_back(SendInvalidation(BOOKMARKS, i+10, "hint"));
+ invalidation_ids.push_back(SendInvalidation(BOOKMARKS, i + 10, "hint"));
}
- for (std::vector<Invalidation>::iterator it = invalidations.begin();
- it != invalidations.end(); ++it) {
+ for (std::vector<int>::iterator it = invalidation_ids.begin();
+ it != invalidation_ids.end();
+ ++it) {
EXPECT_TRUE(IsInvalidationUnacknowledged(*it));
}
// This invalidation, though arriving the most recently, has the oldest
// version number so it should be dropped first.
- Invalidation inv5 = SendInvalidation(BOOKMARKS, 5, "old_hint");
- EXPECT_TRUE(IsInvalidationDropped(inv5));
+ int inv5_id = SendInvalidation(BOOKMARKS, 5, "old_hint");
+ EXPECT_TRUE(IsInvalidationDropped(inv5_id));
// This invalidation has a larger version number, so it will force a
// previously delivered invalidation to be dropped.
- Invalidation inv100 = SendInvalidation(BOOKMARKS, 100, "new_hint");
- EXPECT_TRUE(IsInvalidationDropped(inv10));
+ int inv100_id = SendInvalidation(BOOKMARKS, 100, "new_hint");
+ EXPECT_TRUE(IsInvalidationDropped(inv10_id));
// This should recover from the drop and bring us back into sync.
RecordSuccessfulSyncCycle();
- for (std::vector<Invalidation>::iterator it = invalidations.begin();
- it != invalidations.end(); ++it) {
+ for (std::vector<int>::iterator it = invalidation_ids.begin();
+ it != invalidation_ids.end();
+ ++it) {
EXPECT_TRUE(IsInvalidationAcknowledged(*it));
}
- EXPECT_TRUE(IsInvalidationAcknowledged(inv100));
+ EXPECT_TRUE(IsInvalidationAcknowledged(inv100_id));
EXPECT_TRUE(AllInvalidationsAccountedFor());
}
// Test receipt of an unknown version invalidation from the server.
TEST_F(NudgeTrackerAckTrackingTest, UnknownVersionFromServer_Simple) {
- Invalidation inv = SendUnknownVersionInvalidation(BOOKMARKS);
- EXPECT_TRUE(IsInvalidationUnacknowledged(inv));
+ int inv_id = SendUnknownVersionInvalidation(BOOKMARKS);
+ EXPECT_TRUE(IsInvalidationUnacknowledged(inv_id));
RecordSuccessfulSyncCycle();
- EXPECT_TRUE(IsInvalidationAcknowledged(inv));
+ EXPECT_TRUE(IsInvalidationAcknowledged(inv_id));
EXPECT_TRUE(AllInvalidationsAccountedFor());
}
// Test receipt of multiple unknown version invalidations from the server.
TEST_F(NudgeTrackerAckTrackingTest, UnknownVersionFromServer_Complex) {
- Invalidation inv1 = SendUnknownVersionInvalidation(BOOKMARKS);
- Invalidation inv2 = SendInvalidation(BOOKMARKS, 10, "hint");
- Invalidation inv3 = SendUnknownVersionInvalidation(BOOKMARKS);
- Invalidation inv4 = SendUnknownVersionInvalidation(BOOKMARKS);
- Invalidation inv5 = SendInvalidation(BOOKMARKS, 20, "hint2");
+ int inv1_id = SendUnknownVersionInvalidation(BOOKMARKS);
+ int inv2_id = SendInvalidation(BOOKMARKS, 10, "hint");
+ int inv3_id = SendUnknownVersionInvalidation(BOOKMARKS);
+ int inv4_id = SendUnknownVersionInvalidation(BOOKMARKS);
+ int inv5_id = SendInvalidation(BOOKMARKS, 20, "hint2");
// These invalidations have been overridden, so they got acked early.
- EXPECT_TRUE(IsInvalidationAcknowledged(inv1));
- EXPECT_TRUE(IsInvalidationAcknowledged(inv3));
+ EXPECT_TRUE(IsInvalidationAcknowledged(inv1_id));
+ EXPECT_TRUE(IsInvalidationAcknowledged(inv3_id));
// These invalidations are still waiting to be used.
- EXPECT_TRUE(IsInvalidationUnacknowledged(inv2));
- EXPECT_TRUE(IsInvalidationUnacknowledged(inv4));
- EXPECT_TRUE(IsInvalidationUnacknowledged(inv5));
+ EXPECT_TRUE(IsInvalidationUnacknowledged(inv2_id));
+ EXPECT_TRUE(IsInvalidationUnacknowledged(inv4_id));
+ EXPECT_TRUE(IsInvalidationUnacknowledged(inv5_id));
// Finish the sync cycle and expect all remaining invalidations to be acked.
RecordSuccessfulSyncCycle();
- EXPECT_TRUE(IsInvalidationAcknowledged(inv1));
- EXPECT_TRUE(IsInvalidationAcknowledged(inv2));
- EXPECT_TRUE(IsInvalidationAcknowledged(inv3));
- EXPECT_TRUE(IsInvalidationAcknowledged(inv4));
- EXPECT_TRUE(IsInvalidationAcknowledged(inv5));
+ EXPECT_TRUE(IsInvalidationAcknowledged(inv1_id));
+ EXPECT_TRUE(IsInvalidationAcknowledged(inv2_id));
+ EXPECT_TRUE(IsInvalidationAcknowledged(inv3_id));
+ EXPECT_TRUE(IsInvalidationAcknowledged(inv4_id));
+ EXPECT_TRUE(IsInvalidationAcknowledged(inv5_id));
EXPECT_TRUE(AllInvalidationsAccountedFor());
}
diff --git a/sync/sync_internal_api.gypi b/sync/sync_internal_api.gypi
index 6920ea0..1ff913f 100644
--- a/sync/sync_internal_api.gypi
+++ b/sync/sync_internal_api.gypi
@@ -64,6 +64,8 @@
'internal_api/public/base/enum_set.h',
'internal_api/public/base/invalidation.cc',
'internal_api/public/base/invalidation.h',
+ 'internal_api/public/base/invalidation_interface.cc',
+ 'internal_api/public/base/invalidation_interface.h',
'internal_api/public/base/invalidator_state.cc',
'internal_api/public/base/invalidator_state.h',
'internal_api/public/base/model_type.h',
diff --git a/sync/sync_notifier.gypi b/sync/sync_notifier.gypi
index 9c6dc38..dbbc232 100644
--- a/sync/sync_notifier.gypi
+++ b/sync/sync_notifier.gypi
@@ -25,8 +25,6 @@
'sources': [
'notifier/ack_handler.cc',
'notifier/ack_handler.h',
- 'notifier/dropped_invalidation_tracker.cc',
- 'notifier/dropped_invalidation_tracker.h',
'notifier/invalidation_handler.h',
'notifier/invalidation_state_tracker.cc',
'notifier/invalidation_state_tracker.h',
diff --git a/sync/sync_tests.gypi b/sync/sync_tests.gypi
index 416cd8a..1b48fe4 100644
--- a/sync/sync_tests.gypi
+++ b/sync/sync_tests.gypi
@@ -59,6 +59,12 @@
'test/fake_encryptor.h',
'test/fake_sync_encryption_handler.cc',
'test/fake_sync_encryption_handler.h',
+ 'test/mock_invalidation.cc',
+ 'test/mock_invalidation.h',
+ 'test/mock_invalidation_tracker.cc',
+ 'test/mock_invalidation_tracker.h',
+ 'test/trackable_mock_invalidation.cc',
+ 'test/trackable_mock_invalidation.h',
'test/null_directory_change_delegate.cc',
'test/null_directory_change_delegate.h',
'test/null_transaction_observer.cc',
diff --git a/sync/test/engine/fake_sync_scheduler.cc b/sync/test/engine/fake_sync_scheduler.cc
index acbd701..9fbbf14 100644
--- a/sync/test/engine/fake_sync_scheduler.cc
+++ b/sync/test/engine/fake_sync_scheduler.cc
@@ -30,7 +30,8 @@ void FakeSyncScheduler::ScheduleLocalRefreshRequest(
void FakeSyncScheduler::ScheduleInvalidationNudge(
const base::TimeDelta& desired_delay,
- const ObjectIdInvalidationMap& invalidation_map,
+ syncer::ModelType type,
+ scoped_ptr<InvalidationInterface> interface,
const tracked_objects::Location& nudge_location) {
}
diff --git a/sync/test/engine/fake_sync_scheduler.h b/sync/test/engine/fake_sync_scheduler.h
index 9da8a0f..c43e503 100644
--- a/sync/test/engine/fake_sync_scheduler.h
+++ b/sync/test/engine/fake_sync_scheduler.h
@@ -31,7 +31,8 @@ class FakeSyncScheduler : public SyncScheduler {
const tracked_objects::Location& nudge_location) OVERRIDE;
virtual void ScheduleInvalidationNudge(
const base::TimeDelta& desired_delay,
- const ObjectIdInvalidationMap& invalidation_map,
+ syncer::ModelType type,
+ scoped_ptr<InvalidationInterface> interface,
const tracked_objects::Location& nudge_location) OVERRIDE;
virtual void ScheduleConfiguration(
const ConfigurationParams& params) OVERRIDE;
diff --git a/sync/test/mock_invalidation.cc b/sync/test/mock_invalidation.cc
new file mode 100644
index 0000000..bfcb3c3
--- /dev/null
+++ b/sync/test/mock_invalidation.cc
@@ -0,0 +1,57 @@
+// 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/test/mock_invalidation.h"
+
+#include "base/logging.h"
+#include "sync/test/mock_invalidation_tracker.h"
+
+namespace syncer {
+
+scoped_ptr<MockInvalidation> MockInvalidation::BuildUnknownVersion() {
+ return scoped_ptr<MockInvalidation>(
+ new MockInvalidation(true, -1, std::string()));
+}
+
+scoped_ptr<MockInvalidation> MockInvalidation::Build(
+ int64 version,
+ const std::string& payload) {
+ return scoped_ptr<MockInvalidation>(
+ new MockInvalidation(false, version, payload));
+}
+
+MockInvalidation::~MockInvalidation() {
+}
+
+bool MockInvalidation::IsUnknownVersion() const {
+ return is_unknown_version_;
+}
+
+const std::string& MockInvalidation::GetPayload() const {
+ DCHECK(!is_unknown_version_);
+ return payload_;
+}
+
+int64 MockInvalidation::GetVersion() const {
+ DCHECK(!is_unknown_version_);
+ return version_;
+}
+
+void MockInvalidation::Acknowledge() {
+ // Do nothing.
+}
+
+void MockInvalidation::Drop() {
+ // Do nothing.
+}
+
+MockInvalidation::MockInvalidation(bool is_unknown_version,
+ int64 version,
+ const std::string& payload)
+ : is_unknown_version_(is_unknown_version),
+ version_(version),
+ payload_(payload) {
+}
+
+} // namespace syncer
diff --git a/sync/test/mock_invalidation.h b/sync/test/mock_invalidation.h
new file mode 100644
index 0000000..808f02c
--- /dev/null
+++ b/sync/test/mock_invalidation.h
@@ -0,0 +1,48 @@
+// 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_TEST_MOCK_INVALIDATION_H_
+#define SYNC_TEST_MOCK_INVALIDATION_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "sync/internal_api/public/base/invalidation_interface.h"
+
+namespace syncer {
+
+// An InvalidationInterface used by sync for testing.
+// It does not support any form of acknowledgements.
+class MockInvalidation : public InvalidationInterface {
+ public:
+ // Helpers to build new MockInvalidations.
+ static scoped_ptr<MockInvalidation> BuildUnknownVersion();
+ static scoped_ptr<MockInvalidation> Build(int64 version,
+ const std::string& payload);
+
+ virtual ~MockInvalidation();
+
+ // Implementation of InvalidationInterface.
+ virtual bool IsUnknownVersion() const OVERRIDE;
+ virtual const std::string& GetPayload() const OVERRIDE;
+ virtual int64 GetVersion() const OVERRIDE;
+ virtual void Acknowledge() OVERRIDE;
+ virtual void Drop() OVERRIDE;
+
+ protected:
+ MockInvalidation(bool is_unknown_version,
+ int64 version,
+ const std::string& payload);
+
+ // Whether or not this is an 'unknown version' invalidation.
+ const bool is_unknown_version_;
+
+ // The version of this invalidation. Valid only if !is_unknown_version_.
+ const int64 version_;
+
+ // The payload of this invalidation. Valid only if !is_unknown_version_.
+ const std::string payload_;
+};
+
+} // namespace syncer
+
+#endif // SYNC_TEST_MOCK_INVALIDATION_H_
diff --git a/sync/test/mock_invalidation_tracker.cc b/sync/test/mock_invalidation_tracker.cc
new file mode 100644
index 0000000..6e816a6
--- /dev/null
+++ b/sync/test/mock_invalidation_tracker.cc
@@ -0,0 +1,63 @@
+// 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/test/mock_invalidation_tracker.h"
+
+#include "base/logging.h"
+#include "sync/test/trackable_mock_invalidation.h"
+
+namespace syncer {
+
+scoped_ptr<TrackableMockInvalidation>
+MockInvalidationTracker::IssueUnknownVersionInvalidation() {
+ return scoped_ptr<TrackableMockInvalidation>(
+ new TrackableMockInvalidation(true, -1, std::string(), this, next_id_++));
+}
+
+scoped_ptr<TrackableMockInvalidation>
+MockInvalidationTracker::IssueInvalidation(int64 version,
+ const std::string& payload) {
+ return scoped_ptr<TrackableMockInvalidation>(
+ new TrackableMockInvalidation(false, version, payload, this, next_id_++));
+}
+
+MockInvalidationTracker::MockInvalidationTracker() : next_id_(0) {
+}
+
+MockInvalidationTracker::~MockInvalidationTracker() {
+}
+
+void MockInvalidationTracker::Acknowledge(int invalidation_id) {
+ acknowledged_.insert(invalidation_id);
+}
+
+void MockInvalidationTracker::Drop(int invalidation_id) {
+ dropped_.insert(invalidation_id);
+}
+
+bool MockInvalidationTracker::IsUnacked(int invalidation_id) const {
+ DCHECK_LE(invalidation_id, next_id_);
+ return !IsAcknowledged(invalidation_id) && !IsDropped(invalidation_id);
+}
+
+bool MockInvalidationTracker::IsAcknowledged(int invalidation_id) const {
+ DCHECK_LE(invalidation_id, next_id_);
+ return acknowledged_.find(invalidation_id) != acknowledged_.end();
+}
+
+bool MockInvalidationTracker::IsDropped(int invalidation_id) const {
+ DCHECK_LE(invalidation_id, next_id_);
+ return dropped_.find(invalidation_id) != dropped_.end();
+}
+
+bool MockInvalidationTracker::AllInvalidationsAccountedFor() const {
+ for (int i = 0; i < next_id_; ++i) {
+ if (IsUnacked(i)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+} // namespace syncer
diff --git a/sync/test/mock_invalidation_tracker.h b/sync/test/mock_invalidation_tracker.h
new file mode 100644
index 0000000..9f0e5bd
--- /dev/null
+++ b/sync/test/mock_invalidation_tracker.h
@@ -0,0 +1,65 @@
+// 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_TEST_MOCK_INVALIDATION_TRACKER_H_
+#define SYNC_TEST_MOCK_INVALIDATION_TRACKER_H_
+
+#include <set>
+
+#include "base/memory/scoped_ptr.h"
+#include "sync/test/trackable_mock_invalidation.h"
+
+namespace syncer {
+
+// Instantiates and track the acknowledgement state of
+// TrackableMockInvalidations.
+class MockInvalidationTracker {
+ public:
+ // Builers to return new TrackableMockInvalidations associated with this
+ // object.
+ scoped_ptr<TrackableMockInvalidation> IssueUnknownVersionInvalidation();
+ scoped_ptr<TrackableMockInvalidation> IssueInvalidation(
+ int64 version,
+ const std::string& payload);
+
+ MockInvalidationTracker();
+ ~MockInvalidationTracker();
+
+ // Records the acknowledgement of the invalidation
+ // specified by the given ID.
+ void Acknowledge(int invaliation_id);
+
+ // Records the drop of the invalidation specified by the given ID.
+ void Drop(int invalidation_id);
+
+ // Returns true if the invalidation associated with the given ID is neither
+ // acknowledged nor dropped.
+ bool IsUnacked(int invalidation_id) const;
+
+ // Returns true if the invalidation associated with the given ID is
+ // acknowledged.
+ bool IsAcknowledged(int invalidation_id) const;
+
+ // Returns true if the invalidation associated with the given ID is dropped.
+ bool IsDropped(int invalidation_id) const;
+
+ // Returns true if all issued invalidations were acknowledged or dropped.
+ bool AllInvalidationsAccountedFor() const;
+
+ private:
+ // A counter used to assign strictly increasing IDs to each invalidation
+ // issued by this class.
+ int next_id_;
+
+ // Acknowledgements and drops are tracked by adding the IDs for the
+ // acknowledged or dropped items to the proper set. An invalidation may be
+ // both dropped and acknowledged if it represents the recovery from a drop
+ // event.
+ std::set<int> dropped_;
+ std::set<int> acknowledged_;
+};
+
+} // namespace syncer
+
+#endif // SYNC_TEST_MOCK_INVALIDATION_TRACKER_H_
diff --git a/sync/test/trackable_mock_invalidation.cc b/sync/test/trackable_mock_invalidation.cc
new file mode 100644
index 0000000..0f00814
--- /dev/null
+++ b/sync/test/trackable_mock_invalidation.cc
@@ -0,0 +1,41 @@
+// 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/test/trackable_mock_invalidation.h"
+
+#include "sync/test/mock_invalidation_tracker.h"
+
+namespace syncer {
+
+TrackableMockInvalidation::TrackableMockInvalidation(
+ bool is_unknown_version,
+ int64 version,
+ const std::string& payload,
+ MockInvalidationTracker* tracker,
+ int tracking_id)
+ : MockInvalidation(is_unknown_version, version, payload),
+ tracker_(tracker),
+ tracking_id_(tracking_id) {
+}
+
+TrackableMockInvalidation::~TrackableMockInvalidation() {
+}
+
+void TrackableMockInvalidation::Acknowledge() {
+ if (tracker_) {
+ tracker_->Acknowledge(tracking_id_);
+ }
+}
+
+void TrackableMockInvalidation::Drop() {
+ if (tracker_) {
+ tracker_->Drop(tracking_id_);
+ }
+}
+
+int TrackableMockInvalidation::GetTrackingId() {
+ return tracking_id_;
+}
+
+} // namespace syncer
diff --git a/sync/test/trackable_mock_invalidation.h b/sync/test/trackable_mock_invalidation.h
new file mode 100644
index 0000000..1ad3697
--- /dev/null
+++ b/sync/test/trackable_mock_invalidation.h
@@ -0,0 +1,54 @@
+// 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_TEST_TRACKABLE_MOCK_INVALIDATION_H_
+#define SYNC_TEST_TRACKABLE_MOCK_INVALIDATION_H_
+
+#include "sync/test/mock_invalidation.h"
+
+namespace syncer {
+
+class MockInvalidationTracker;
+
+// A variant of MockInvalidation that supports acknowledgements.
+//
+// With the help of a MockInvalidationTracker, this can be used to test
+// sync's use of the Drop() and Acknowledge() methods.
+class TrackableMockInvalidation : public MockInvalidation {
+ public:
+ TrackableMockInvalidation(bool is_unknown_version,
+ int64 version,
+ const std::string& payload,
+ MockInvalidationTracker* tracker,
+ int tracking_id);
+ virtual ~TrackableMockInvalidation();
+
+ // Forwards notice of the acknowledgement of this invalidation to the
+ // |tracker_|.
+ virtual void Acknowledge() OVERRIDE;
+
+ // Forwards notice of the drop of this invalidation to the |tracker_|.
+ virtual void Drop() OVERRIDE;
+
+ // Returns the integer used to identify this object with the |tracker_|.
+ int GetTrackingId();
+
+ private:
+ // The MockInvalidationTracker that initialized this object, and which keeps
+ // track of its acknowledgement status. It is expected to outlive the
+ // invalidations. The data required for unit test assertions lives there.
+ MockInvalidationTracker* tracker_;
+
+ // An identifier that uniquely identifies this invalidation to its
+ // |tracker_|.
+ //
+ // This is necessary in part because invalidations may be short lived; the
+ // invalidation may be deleted by the time we want to make assertions about
+ // its state.
+ int tracking_id_;
+};
+
+} // namespace syncer
+
+#endif // SYNC_TEST_TRACKABLE_MOCK_INVALIDATION_H_
diff --git a/sync/tools/sync_client.cc b/sync/tools/sync_client.cc
index a5890cf..2b626db 100644
--- a/sync/tools/sync_client.cc
+++ b/sync/tools/sync_client.cc
@@ -42,6 +42,7 @@
#include "sync/internal_api/public/util/weak_handle.h"
#include "sync/js/js_event_details.h"
#include "sync/js/js_event_handler.h"
+#include "sync/notifier/object_id_invalidation_map.h"
#include "sync/test/fake_encryptor.h"
#include "sync/tools/null_invalidation_state_tracker.h"
@@ -184,6 +185,78 @@ class LoggingJsEventHandler
}
};
+class InvalidationAdapter : public syncer::InvalidationInterface {
+ public:
+ explicit InvalidationAdapter(const syncer::Invalidation& invalidation)
+ : invalidation_(invalidation) {}
+ virtual ~InvalidationAdapter() {}
+
+ virtual bool IsUnknownVersion() const OVERRIDE {
+ return invalidation_.is_unknown_version();
+ }
+
+ virtual const std::string& GetPayload() const OVERRIDE {
+ return invalidation_.payload();
+ }
+
+ virtual int64 GetVersion() const OVERRIDE {
+ return invalidation_.version();
+ }
+
+ virtual void Acknowledge() OVERRIDE {
+ invalidation_.Acknowledge();
+ }
+
+ virtual void Drop() OVERRIDE {
+ invalidation_.Drop();
+ }
+
+ private:
+ syncer::Invalidation invalidation_;
+};
+
+class InvalidatorShim : public InvalidationHandler {
+ public:
+ explicit InvalidatorShim(SyncManager* sync_manager)
+ : sync_manager_(sync_manager) {}
+
+ virtual void OnInvalidatorStateChange(InvalidatorState state) OVERRIDE {
+ sync_manager_->OnInvalidatorStateChange(state);
+ }
+
+ virtual void OnIncomingInvalidation(
+ const ObjectIdInvalidationMap& invalidation_map) OVERRIDE {
+ syncer::ObjectIdSet ids = invalidation_map.GetObjectIds();
+ for (syncer::ObjectIdSet::const_iterator ids_it = ids.begin();
+ ids_it != ids.end();
+ ++ids_it) {
+ syncer::ModelType type;
+ if (!NotificationTypeToRealModelType(ids_it->name(), &type)) {
+ DLOG(WARNING) << "Notification has invalid id: "
+ << syncer::ObjectIdToString(*ids_it);
+ } else {
+ syncer::SingleObjectInvalidationSet invalidation_set =
+ invalidation_map.ForObject(*ids_it);
+ for (syncer::SingleObjectInvalidationSet::const_iterator inv_it =
+ invalidation_set.begin();
+ inv_it != invalidation_set.end();
+ ++inv_it) {
+ scoped_ptr<syncer::InvalidationInterface> inv_adapter(
+ new InvalidationAdapter(*inv_it));
+ sync_manager_->OnIncomingInvalidation(type, inv_adapter.Pass());
+ }
+ }
+ }
+ }
+
+ virtual std::string GetOwnerName() const OVERRIDE {
+ return "InvalidatorShim";
+ }
+
+ private:
+ SyncManager* sync_manager_;
+};
+
void LogUnrecoverableErrorContext() {
base::debug::StackTrace().Print();
}
@@ -380,9 +453,10 @@ int SyncClientMain(int argc, char* argv[]) {
// TODO(akalin): Avoid passing in model parameters multiple times by
// organizing handling of model types.
invalidator->UpdateCredentials(credentials.email, credentials.sync_token);
- invalidator->RegisterHandler(sync_manager.get());
+ scoped_ptr<InvalidatorShim> shim(new InvalidatorShim(sync_manager.get()));
+ invalidator->RegisterHandler(shim.get());
invalidator->UpdateRegisteredIds(
- sync_manager.get(), ModelTypeSetToObjectIdSet(model_types));
+ shim.get(), ModelTypeSetToObjectIdSet(model_types));
sync_manager->StartSyncingNormally(routing_info);
sync_loop.Run();