diff options
27 files changed, 892 insertions, 468 deletions
@@ -67,7 +67,7 @@ deps = { "src/third_party/cacheinvalidation/files/src/google": (Var("googlecode_url") % "google-cache-invalidation-api") + - "/trunk/src/google@80", + "/trunk/src/google@114", "src/third_party/leveldb": (Var("googlecode_url") % "leveldb") + "/trunk@31", diff --git a/chrome/browser/sync/engine/syncapi.cc b/chrome/browser/sync/engine/syncapi.cc index 51e603c..f0d7246 100644 --- a/chrome/browser/sync/engine/syncapi.cc +++ b/chrome/browser/sync/engine/syncapi.cc @@ -1938,7 +1938,7 @@ bool SyncManager::SyncInternal::SignIn(const SyncCredentials& credentials) { std::string state; if (lookup.good()) { unique_id = lookup->cache_guid(); - state = lookup->GetAndClearNotificationState(); + state = lookup->GetNotificationState(); VLOG(1) << "Read notification unique ID: " << unique_id; if (VLOG_IS_ON(1)) { std::string encoded_state; diff --git a/chrome/browser/sync/notifier/cache_invalidation_packet_handler.cc b/chrome/browser/sync/notifier/cache_invalidation_packet_handler.cc index de3a6d7..4e62001 100644 --- a/chrome/browser/sync/notifier/cache_invalidation_packet_handler.cc +++ b/chrome/browser/sync/notifier/cache_invalidation_packet_handler.cc @@ -12,7 +12,9 @@ #include "base/logging.h" #include "base/rand_util.h" #include "base/string_number_conversions.h" -#include "google/cacheinvalidation/invalidation-client.h" +#include "google/cacheinvalidation/v2/constants.h" +#include "google/cacheinvalidation/v2/invalidation-client.h" +#include "google/cacheinvalidation/v2/system-resources.h" #include "jingle/notifier/listener/xml_element_util.h" #include "talk/xmpp/constants.h" #include "talk/xmpp/jid.h" @@ -30,6 +32,8 @@ const buzz::QName kQnData("google:notifier", "data"); const buzz::QName kQnSeq("", "seq"); const buzz::QName kQnSid("", "sid"); const buzz::QName kQnServiceUrl("", "serviceUrl"); +const buzz::QName kQnProtocolVersion("", "protocolVersion"); +const buzz::QName kQnChannelContext("", "channelContext"); // TODO(akalin): Move these task classes out so that they can be // unit-tested. This'll probably be done easier once we consolidate @@ -41,8 +45,11 @@ class CacheInvalidationListenTask : public buzz::XmppTask { public: // Takes ownership of callback. CacheInvalidationListenTask(Task* parent, + std::string* channel_context, Callback1<const std::string&>::Type* callback) - : XmppTask(parent, buzz::XmppEngine::HL_TYPE), callback_(callback) {} + : XmppTask(parent, buzz::XmppEngine::HL_TYPE), + channel_context_(channel_context), + callback_(callback) {} virtual ~CacheInvalidationListenTask() {} virtual int ProcessStart() { @@ -73,6 +80,9 @@ class CacheInvalidationListenTask : public buzz::XmppTask { virtual bool HandleStanza(const buzz::XmlElement* stanza) { VLOG(1) << "Stanza received: " << notifier::XmlElementToString(*stanza); + if (stanza->HasAttr(kQnChannelContext)) { + *channel_context_ = stanza->Attr(kQnChannelContext); + } if (IsValidCacheInvalidationIqPacket(stanza)) { VLOG(2) << "Queueing stanza"; QueueStanza(stanza); @@ -102,10 +112,17 @@ class CacheInvalidationListenTask : public buzz::XmppTask { return true; } + std::string* channel_context_; scoped_ptr<Callback1<const std::string&>::Type> callback_; DISALLOW_COPY_AND_ASSIGN(CacheInvalidationListenTask); }; +std::string MakeProtocolVersion() { + return base::Uint64ToString(invalidation::Constants::kProtocolMajorVersion) + + "." + + base::Uint64ToString(invalidation::Constants::kProtocolMinorVersion); +} + // A task that sends a single outbound ClientInvalidation message. class CacheInvalidationSendMessageTask : public buzz::XmppTask { public: @@ -113,15 +130,17 @@ class CacheInvalidationSendMessageTask : public buzz::XmppTask { const buzz::Jid& to_jid, const std::string& msg, int seq, - const std::string& sid) + const std::string& sid, + const std::string& channel_context) : XmppTask(parent, buzz::XmppEngine::HL_SINGLE), - to_jid_(to_jid), msg_(msg), seq_(seq), sid_(sid) {} + to_jid_(to_jid), msg_(msg), seq_(seq), sid_(sid), + channel_context_(channel_context) {} virtual ~CacheInvalidationSendMessageTask() {} virtual int ProcessStart() { scoped_ptr<buzz::XmlElement> stanza( MakeCacheInvalidationIqPacket(to_jid_, task_id(), msg_, - seq_, sid_)); + seq_, sid_, channel_context_)); VLOG(1) << "Sending message: " << notifier::XmlElementToString(*stanza.get()); if (SendStanza(stanza.get()) != buzz::XMPP_RETURN_OK) { @@ -160,7 +179,7 @@ class CacheInvalidationSendMessageTask : public buzz::XmppTask { const buzz::Jid& to_jid, const std::string& task_id, const std::string& msg, - int seq, const std::string& sid) { + int seq, const std::string& sid, const std::string channel_context) { buzz::XmlElement* iq = MakeIq(buzz::STR_SET, to_jid, task_id); buzz::XmlElement* cache_invalidation_iq_packet = new buzz::XmlElement(kQnData, true); @@ -168,6 +187,12 @@ class CacheInvalidationSendMessageTask : public buzz::XmppTask { cache_invalidation_iq_packet->SetAttr(kQnSeq, base::IntToString(seq)); cache_invalidation_iq_packet->SetAttr(kQnSid, sid); cache_invalidation_iq_packet->SetAttr(kQnServiceUrl, kServiceUrl); + cache_invalidation_iq_packet->SetAttr( + kQnProtocolVersion, MakeProtocolVersion()); + if (!channel_context.empty()) { + cache_invalidation_iq_packet->SetAttr(kQnChannelContext, + channel_context); + } cache_invalidation_iq_packet->SetBodyText(msg); return iq; } @@ -176,6 +201,7 @@ class CacheInvalidationSendMessageTask : public buzz::XmppTask { std::string msg_; int seq_; std::string sid_; + std::string channel_context_; DISALLOW_COPY_AND_ASSIGN(CacheInvalidationSendMessageTask); }; @@ -188,18 +214,16 @@ std::string MakeSid() { } // namespace CacheInvalidationPacketHandler::CacheInvalidationPacketHandler( - base::WeakPtr<talk_base::Task> base_task, - invalidation::InvalidationClient* invalidation_client) + base::WeakPtr<talk_base::Task> base_task) : scoped_callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), base_task_(base_task), - invalidation_client_(invalidation_client), seq_(0), sid_(MakeSid()) { CHECK(base_task_.get()); // Owned by base_task. Takes ownership of the callback. CacheInvalidationListenTask* listen_task = new CacheInvalidationListenTask( - base_task_, scoped_callback_factory_.NewCallback( + base_task_, &channel_context_, scoped_callback_factory_.NewCallback( &CacheInvalidationPacketHandler::HandleInboundPacket)); listen_task->Start(); } @@ -208,15 +232,12 @@ CacheInvalidationPacketHandler::~CacheInvalidationPacketHandler() { DCHECK(non_thread_safe_.CalledOnValidThread()); } -void CacheInvalidationPacketHandler::HandleOutboundPacket( - invalidation::NetworkEndpoint* network_endpoint) { +void CacheInvalidationPacketHandler::SendMessage( + const std::string& message) { DCHECK(non_thread_safe_.CalledOnValidThread()); if (!base_task_.get()) { return; } - CHECK_EQ(network_endpoint, invalidation_client_->network_endpoint()); - invalidation::string message; - network_endpoint->TakeOutboundMessage(&message); std::string encoded_message; if (!base::Base64Encode(message, &encoded_message)) { LOG(ERROR) << "Could not base64-encode message to send: " @@ -228,23 +249,26 @@ void CacheInvalidationPacketHandler::HandleOutboundPacket( new CacheInvalidationSendMessageTask(base_task_, buzz::Jid(kBotJid), encoded_message, - seq_, sid_); + seq_, sid_, channel_context_); send_message_task->Start(); ++seq_; } +void CacheInvalidationPacketHandler::SetMessageReceiver( + invalidation::MessageCallback* incoming_receiver) { + incoming_receiver_.reset(incoming_receiver); +} + void CacheInvalidationPacketHandler::HandleInboundPacket( const std::string& packet) { DCHECK(non_thread_safe_.CalledOnValidThread()); - invalidation::NetworkEndpoint* network_endpoint = - invalidation_client_->network_endpoint(); std::string decoded_message; if (!base::Base64Decode(packet, &decoded_message)) { LOG(ERROR) << "Could not base64-decode received message: " << packet; return; } - network_endpoint->HandleInboundMessage(decoded_message); + incoming_receiver_->Run(decoded_message); } } // namespace sync_notifier diff --git a/chrome/browser/sync/notifier/cache_invalidation_packet_handler.h b/chrome/browser/sync/notifier/cache_invalidation_packet_handler.h index 707dacb..e44fd0b 100644 --- a/chrome/browser/sync/notifier/cache_invalidation_packet_handler.h +++ b/chrome/browser/sync/notifier/cache_invalidation_packet_handler.h @@ -12,15 +12,12 @@ #include <string> #include "base/basictypes.h" +#include "base/scoped_ptr.h" #include "base/gtest_prod_util.h" #include "base/memory/scoped_callback_factory.h" #include "base/memory/weak_ptr.h" #include "base/threading/non_thread_safe.h" - -namespace invalidation { -class InvalidationClient; -class NetworkEndpoint; -} // namespace invalidation +#include "google/cacheinvalidation/v2/system-resources.h" namespace talk_base { class Task; @@ -35,17 +32,18 @@ class CacheInvalidationPacketHandler { // |invalidation_client| must not already be routing packets through // something. Does not take ownership of |invalidation_client|. CacheInvalidationPacketHandler( - base::WeakPtr<talk_base::Task> base_task, - invalidation::InvalidationClient* invalidation_client); + base::WeakPtr<talk_base::Task> base_task); // Makes the invalidation client passed into the constructor not // route packets through the XMPP client passed into the constructor // anymore. - ~CacheInvalidationPacketHandler(); + virtual ~CacheInvalidationPacketHandler(); + + // If |base_task| is non-NULL, sends the outgoing message. + virtual void SendMessage(const std::string& outgoing_message); - // If |base_task| is non-NULL, sends any existing pending outbound - // packets. - void HandleOutboundPacket(invalidation::NetworkEndpoint* network_endpoint); + virtual void SetMessageReceiver( + invalidation::MessageCallback* incoming_receiver); private: FRIEND_TEST(CacheInvalidationPacketHandlerTest, Basic); @@ -57,7 +55,8 @@ class CacheInvalidationPacketHandler { scoped_callback_factory_; base::WeakPtr<talk_base::Task> base_task_; - invalidation::InvalidationClient* invalidation_client_; + + scoped_ptr<invalidation::MessageCallback> incoming_receiver_; // Parameters for sent messages. @@ -65,6 +64,8 @@ class CacheInvalidationPacketHandler { int seq_; // Unique session token. const std::string sid_; + // Channel context. + std::string channel_context_; DISALLOW_COPY_AND_ASSIGN(CacheInvalidationPacketHandler); }; diff --git a/chrome/browser/sync/notifier/cache_invalidation_packet_handler_unittest.cc b/chrome/browser/sync/notifier/cache_invalidation_packet_handler_unittest.cc index 52f9591..ce6f87e 100644 --- a/chrome/browser/sync/notifier/cache_invalidation_packet_handler_unittest.cc +++ b/chrome/browser/sync/notifier/cache_invalidation_packet_handler_unittest.cc @@ -7,7 +7,8 @@ #include "base/base64.h" #include "base/memory/weak_ptr.h" #include "base/message_loop.h" -#include "google/cacheinvalidation/invalidation-client.h" +#include "google/cacheinvalidation/callback.h" +#include "google/cacheinvalidation/v2/system-resources.h" #include "jingle/notifier/base/fake_base_task.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -19,21 +20,13 @@ namespace sync_notifier { using ::testing::_; using ::testing::Return; -class MockNetworkEndpoint : public invalidation::NetworkEndpoint { +class MockMessageCallback { public: - MOCK_METHOD1(RegisterOutboundListener, - void(invalidation::NetworkCallback*)); - MOCK_METHOD1(HandleInboundMessage, void(const invalidation::string&)); - MOCK_METHOD1(TakeOutboundMessage, void(invalidation::string*)); - MOCK_METHOD1(AdviseNetworkStatus, void(bool)); -}; + void StoreMessage(const std::string& message) { + last_message = message; + } -class MockInvalidationClient : public invalidation::InvalidationClient { - public: - MOCK_METHOD1(Start, void(const std::string& str)); - MOCK_METHOD1(Register, void(const invalidation::ObjectId&)); - MOCK_METHOD1(Unregister, void(const invalidation::ObjectId&)); - MOCK_METHOD0(network_endpoint, invalidation::NetworkEndpoint*()); + std::string last_message; }; class CacheInvalidationPacketHandlerTest : public testing::Test { @@ -46,20 +39,17 @@ TEST_F(CacheInvalidationPacketHandlerTest, Basic) { notifier::FakeBaseTask fake_base_task; - MockNetworkEndpoint mock_network_endpoint; - MockInvalidationClient mock_invalidation_client; - - EXPECT_CALL(mock_invalidation_client, network_endpoint()). - WillRepeatedly(Return(&mock_network_endpoint)); + std::string last_message; + MockMessageCallback callback; + invalidation::MessageCallback* mock_message_callback = + invalidation::NewPermanentCallback( + &callback, &MockMessageCallback::StoreMessage); const char kInboundMessage[] = "non-bogus"; - EXPECT_CALL(mock_network_endpoint, - HandleInboundMessage(kInboundMessage)).Times(1); - EXPECT_CALL(mock_network_endpoint, TakeOutboundMessage(_)).Times(1); - { - CacheInvalidationPacketHandler handler( - fake_base_task.AsWeakPtr(), &mock_invalidation_client); + CacheInvalidationPacketHandler handler(fake_base_task.AsWeakPtr()); + handler.SetMessageReceiver(mock_message_callback); + // Take care of any tasks posted by the constructor. message_loop.RunAllPending(); @@ -71,9 +61,10 @@ TEST_F(CacheInvalidationPacketHandlerTest, Basic) { handler.HandleInboundPacket(inbound_message_encoded); } - handler.HandleOutboundPacket(&mock_network_endpoint); // Take care of any tasks posted by HandleOutboundPacket(). message_loop.RunAllPending(); + + EXPECT_EQ(callback.last_message, kInboundMessage); } } diff --git a/chrome/browser/sync/notifier/chrome_invalidation_client.cc b/chrome/browser/sync/notifier/chrome_invalidation_client.cc index 074e481..463265a 100644 --- a/chrome/browser/sync/notifier/chrome_invalidation_client.cc +++ b/chrome/browser/sync/notifier/chrome_invalidation_client.cc @@ -13,7 +13,13 @@ #include "chrome/browser/sync/notifier/invalidation_util.h" #include "chrome/browser/sync/notifier/registration_manager.h" #include "chrome/browser/sync/syncable/model_type.h" -#include "google/cacheinvalidation/invalidation-client-impl.h" +#include "google/cacheinvalidation/v2/invalidation-client-impl.h" + +namespace { + +const char kApplicationName[] = "chrome-sync"; + +} // anonymous namespace namespace sync_notifier { @@ -22,11 +28,9 @@ ChromeInvalidationClient::Listener::~Listener() {} ChromeInvalidationClient::ChromeInvalidationClient() : chrome_system_resources_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), scoped_callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), - handle_outbound_packet_callback_( - scoped_callback_factory_.NewCallback( - &ChromeInvalidationClient::HandleOutboundPacket)), listener_(NULL), - state_writer_(NULL) { + state_writer_(NULL), + ticl_ready_(false) { DCHECK(non_thread_safe_.CalledOnValidThread()); } @@ -44,7 +48,13 @@ void ChromeInvalidationClient::Start( DCHECK(non_thread_safe_.CalledOnValidThread()); Stop(); - chrome_system_resources_.StartScheduler(); + chrome_system_resources_.set_platform(client_info); + chrome_system_resources_.Start(); + + // The Storage resource is implemented as a write-through cache. We populate + // it with the initial state on startup, so subsequent writes go to disk and + // update the in-memory cache, while reads just return the cached state. + chrome_system_resources_.storage()->SetInitialState(state); DCHECK(!listener_); DCHECK(listener); @@ -53,29 +63,19 @@ void ChromeInvalidationClient::Start( DCHECK(state_writer); state_writer_ = state_writer; - invalidation::ClientType client_type; - client_type.set_type(invalidation::ClientType::CHROME_SYNC); + int client_type = ipc::invalidation::ClientType::CHROME_SYNC; // TODO(akalin): Use InvalidationClient::Create() once it supports // taking a ClientConfig. - invalidation::ClientConfig client_config; - // Bump up limits so that we reduce the number of registration - // replies we get. - client_config.max_registrations_per_message = 20; - client_config.max_ops_per_message = 40; + invalidation::InvalidationClientImpl::Config client_config; invalidation_client_.reset( new invalidation::InvalidationClientImpl( - &chrome_system_resources_, client_type, client_id, client_info, - client_config, this)); - invalidation_client_->Start(state); - invalidation::NetworkEndpoint* network_endpoint = - invalidation_client_->network_endpoint(); - CHECK(network_endpoint); - network_endpoint->RegisterOutboundListener( - handle_outbound_packet_callback_.get()); + &chrome_system_resources_, client_type, client_id, client_config, + kApplicationName, this)); ChangeBaseTask(base_task); + invalidation_client_->Start(); + registration_manager_.reset( new RegistrationManager(invalidation_client_.get())); - registration_manager_->SetRegisteredTypes(registered_types_); } void ChromeInvalidationClient::ChangeBaseTask( @@ -83,8 +83,9 @@ void ChromeInvalidationClient::ChangeBaseTask( DCHECK(invalidation_client_.get()); DCHECK(base_task.get()); cache_invalidation_packet_handler_.reset( - new CacheInvalidationPacketHandler(base_task, - invalidation_client_.get())); + new CacheInvalidationPacketHandler(base_task)); + chrome_system_resources_.network()->UpdatePacketHandler( + cache_invalidation_packet_handler_.get()); } void ChromeInvalidationClient::Stop() { @@ -94,10 +95,11 @@ void ChromeInvalidationClient::Stop() { return; } - chrome_system_resources_.StopScheduler(); - registration_manager_.reset(); cache_invalidation_packet_handler_.reset(); + chrome_system_resources_.Stop(); + invalidation_client_->Stop(); + invalidation_client_.reset(); state_writer_ = NULL; listener_ = NULL; @@ -107,24 +109,30 @@ void ChromeInvalidationClient::RegisterTypes( const syncable::ModelTypeSet& types) { DCHECK(non_thread_safe_.CalledOnValidThread()); registered_types_ = types; - if (registration_manager_.get()) { + if (ticl_ready_ && registration_manager_.get()) { registration_manager_->SetRegisteredTypes(registered_types_); } // TODO(akalin): Clear invalidation versions for unregistered types. } +void ChromeInvalidationClient::Ready( + invalidation::InvalidationClient* client) { + ticl_ready_ = true; + registration_manager_->SetRegisteredTypes(registered_types_); +} + void ChromeInvalidationClient::Invalidate( + invalidation::InvalidationClient* client, const invalidation::Invalidation& invalidation, - invalidation::Closure* callback) { + const invalidation::AckHandle& ack_handle) { DCHECK(non_thread_safe_.CalledOnValidThread()); - DCHECK(invalidation::IsCallbackRepeatable(callback)); VLOG(1) << "Invalidate: " << InvalidationToString(invalidation); syncable::ModelType model_type; if (!ObjectIdToRealModelType(invalidation.object_id(), &model_type)) { LOG(WARNING) << "Could not get invalidation model type; " << "invalidating everything"; EmitInvalidation(registered_types_, std::string()); - RunAndDeleteClosure(callback); + client->Acknowledge(ack_handle); return; } // The invalidation API spec allows for the possibility of redundant @@ -137,17 +145,15 @@ void ChromeInvalidationClient::Invalidate( // newly-unregistered types may already be in flight. // // TODO(akalin): Persist |max_invalidation_versions_| somehow. - if (invalidation.version() != UNKNOWN_OBJECT_VERSION) { - std::map<syncable::ModelType, int64>::const_iterator it = - max_invalidation_versions_.find(model_type); - if ((it != max_invalidation_versions_.end()) && - (invalidation.version() <= it->second)) { - // Drop redundant invalidations. - RunAndDeleteClosure(callback); - return; - } - max_invalidation_versions_[model_type] = invalidation.version(); + std::map<syncable::ModelType, int64>::const_iterator it = + max_invalidation_versions_.find(model_type); + if ((it != max_invalidation_versions_.end()) && + (invalidation.version() <= it->second)) { + // Drop redundant invalidations. + client->Acknowledge(ack_handle); + return; } + max_invalidation_versions_[model_type] = invalidation.version(); std::string payload; // payload() CHECK()'s has_payload(), so we must check it ourselves first. @@ -157,22 +163,46 @@ void ChromeInvalidationClient::Invalidate( syncable::ModelTypeSet types; types.insert(model_type); EmitInvalidation(types, payload); - // TODO(akalin): We should really |callback| only after we get the + // TODO(akalin): We should really acknowledge only after we get the + // updates from the sync server. (see http://crbug.com/78462). + client->Acknowledge(ack_handle); +} + +void ChromeInvalidationClient::InvalidateUnknownVersion( + invalidation::InvalidationClient* client, + const invalidation::ObjectId& object_id, + const invalidation::AckHandle& ack_handle) { + DCHECK(non_thread_safe_.CalledOnValidThread()); + VLOG(1) << "InvalidateUnknownVersion"; + + syncable::ModelType model_type; + if (!ObjectIdToRealModelType(object_id, &model_type)) { + LOG(WARNING) << "Could not get invalidation model type; " + << "invalidating everything"; + EmitInvalidation(registered_types_, std::string()); + client->Acknowledge(ack_handle); + return; + } + + syncable::ModelTypeSet types; + types.insert(model_type); + EmitInvalidation(types, ""); + // TODO(akalin): We should really acknowledge only after we get the // updates from the sync server. (see http://crbug.com/78462). - RunAndDeleteClosure(callback); + client->Acknowledge(ack_handle); } // This should behave as if we got an invalidation with version // UNKNOWN_OBJECT_VERSION for all known data types. void ChromeInvalidationClient::InvalidateAll( - invalidation::Closure* callback) { + invalidation::InvalidationClient* client, + const invalidation::AckHandle& ack_handle) { DCHECK(non_thread_safe_.CalledOnValidThread()); - DCHECK(invalidation::IsCallbackRepeatable(callback)); VLOG(1) << "InvalidateAll"; EmitInvalidation(registered_types_, std::string()); - // TODO(akalin): We should really |callback| only after we get the + // TODO(akalin): We should really acknowledge only after we get the // updates from the sync server. (see http://crbug.com/76482). - RunAndDeleteClosure(callback); + client->Acknowledge(ack_handle); } void ChromeInvalidationClient::EmitInvalidation( @@ -186,17 +216,13 @@ void ChromeInvalidationClient::EmitInvalidation( listener_->OnInvalidate(type_payloads); } -void ChromeInvalidationClient::RegistrationStateChanged( - const invalidation::ObjectId& object_id, - invalidation::RegistrationState new_state, - const invalidation::UnknownHint& unknown_hint) { +void ChromeInvalidationClient::InformRegistrationStatus( + invalidation::InvalidationClient* client, + const invalidation::ObjectId& object_id, + InvalidationListener::RegistrationState new_state) { DCHECK(non_thread_safe_.CalledOnValidThread()); - VLOG(1) << "RegistrationStateChanged: " + VLOG(1) << "InformRegistrationStatus: " << ObjectIdToString(object_id) << " " << new_state; - if (new_state == invalidation::RegistrationState_UNKNOWN) { - VLOG(1) << "is_transient=" << unknown_hint.is_transient() - << ", message=" << unknown_hint.message(); - } syncable::ModelType model_type; if (!ObjectIdToRealModelType(object_id, &model_type)) { @@ -204,25 +230,47 @@ void ChromeInvalidationClient::RegistrationStateChanged( return; } - if (new_state != invalidation::RegistrationState_REGISTERED) { - // We don't care about |unknown_hint|; we let - // |registration_manager_| handle the registration backoff policy. + if (new_state != InvalidationListener::REGISTERED) { + // Let |registration_manager_| handle the registration backoff policy. registration_manager_->MarkRegistrationLost(model_type); } } -void ChromeInvalidationClient::AllRegistrationsLost( - invalidation::Closure* callback) { +void ChromeInvalidationClient::InformRegistrationFailure( + invalidation::InvalidationClient* client, + const invalidation::ObjectId& object_id, + bool is_transient, + const std::string& error_message) { + DCHECK(non_thread_safe_.CalledOnValidThread()); + VLOG(1) << "InformRegistrationFailure: " + << ObjectIdToString(object_id) + << "is_transient=" << is_transient + << ", message=" << error_message; + + syncable::ModelType model_type; + if (!ObjectIdToRealModelType(object_id, &model_type)) { + LOG(WARNING) << "Could not get object id model type; ignoring"; + return; + } + + // We don't care about |unknown_hint|; we let + // |registration_manager_| handle the registration backoff policy. + registration_manager_->MarkRegistrationLost(model_type); +} + +void ChromeInvalidationClient::ReissueRegistrations( + invalidation::InvalidationClient* client, + const std::string& prefix, + int prefix_length) { DCHECK(non_thread_safe_.CalledOnValidThread()); - DCHECK(invalidation::IsCallbackRepeatable(callback)); VLOG(1) << "AllRegistrationsLost"; registration_manager_->MarkAllRegistrationsLost(); - RunAndDeleteClosure(callback); } -void ChromeInvalidationClient::SessionStatusChanged(bool has_session) { - VLOG(1) << "SessionStatusChanged: " << has_session; - listener_->OnSessionStatusChanged(has_session); +void ChromeInvalidationClient::InformError( + invalidation::InvalidationClient* client, + const invalidation::ErrorInfo& error_info) { + // TODO(ghc): handle the error. } void ChromeInvalidationClient::WriteState(const std::string& state) { @@ -231,12 +279,4 @@ void ChromeInvalidationClient::WriteState(const std::string& state) { state_writer_->WriteState(state); } -void ChromeInvalidationClient::HandleOutboundPacket( - invalidation::NetworkEndpoint* const& network_endpoint) { - DCHECK(non_thread_safe_.CalledOnValidThread()); - CHECK(cache_invalidation_packet_handler_.get()); - cache_invalidation_packet_handler_-> - HandleOutboundPacket(network_endpoint); -} - } // namespace sync_notifier diff --git a/chrome/browser/sync/notifier/chrome_invalidation_client.h b/chrome/browser/sync/notifier/chrome_invalidation_client.h index 7ab0f3a..aa99074 100644 --- a/chrome/browser/sync/notifier/chrome_invalidation_client.h +++ b/chrome/browser/sync/notifier/chrome_invalidation_client.h @@ -22,7 +22,7 @@ #include "chrome/browser/sync/notifier/state_writer.h" #include "chrome/browser/sync/syncable/model_type.h" #include "chrome/browser/sync/syncable/model_type_payload_map.h" -#include "google/cacheinvalidation/invalidation-client.h" +#include "google/cacheinvalidation/v2/invalidation-listener.h" // TODO(akalin): Move invalidation::InvalidationListener into its own // file and include that instead of invalidation-client.h (which @@ -34,11 +34,13 @@ class Task; namespace sync_notifier { +using invalidation::InvalidationListener; + class CacheInvalidationPacketHandler; class RegistrationManager; class ChromeInvalidationClient - : public invalidation::InvalidationListener, + : public InvalidationListener, public StateWriter { public: class Listener { @@ -74,26 +76,42 @@ class ChromeInvalidationClient // notifications for. May be called at any time. void RegisterTypes(const syncable::ModelTypeSet& types); + virtual void WriteState(const std::string& state); + // invalidation::InvalidationListener implementation. - virtual void Invalidate(const invalidation::Invalidation& invalidation, - invalidation::Closure* callback) OVERRIDE; - virtual void InvalidateAll(invalidation::Closure* callback) OVERRIDE; - virtual void RegistrationStateChanged( + virtual void Ready( + invalidation::InvalidationClient* client) OVERRIDE; + virtual void Invalidate( + invalidation::InvalidationClient* client, + const invalidation::Invalidation& invalidation, + const invalidation::AckHandle& ack_handle) OVERRIDE; + virtual void InvalidateUnknownVersion( + invalidation::InvalidationClient* client, const invalidation::ObjectId& object_id, - invalidation::RegistrationState new_state, - const invalidation::UnknownHint& unknown_hint) OVERRIDE; - virtual void AllRegistrationsLost(invalidation::Closure* callback) OVERRIDE; - virtual void SessionStatusChanged(bool has_session) OVERRIDE; - - // StateWriter implementation. - virtual void WriteState(const std::string& state) OVERRIDE; + const invalidation::AckHandle& ack_handle) OVERRIDE; + virtual void InvalidateAll( + invalidation::InvalidationClient* client, + const invalidation::AckHandle& ack_handle) OVERRIDE; + virtual void InformRegistrationStatus( + invalidation::InvalidationClient* client, + const invalidation::ObjectId& object_id, + InvalidationListener::RegistrationState reg_state) OVERRIDE; + virtual void InformRegistrationFailure( + invalidation::InvalidationClient* client, + const invalidation::ObjectId& object_id, + bool is_transient, + const std::string& error_message) OVERRIDE; + virtual void ReissueRegistrations( + invalidation::InvalidationClient* client, + const std::string& prefix, + int prefix_length) OVERRIDE; + virtual void InformError( + invalidation::InvalidationClient* client, + const invalidation::ErrorInfo& error_info) OVERRIDE; private: friend class ChromeInvalidationClientTest; - // Should only be called between calls to Start() and Stop(). - void HandleOutboundPacket( - invalidation::NetworkEndpoint* const& network_endpoint); void EmitInvalidation( const syncable::ModelTypeSet& types, const std::string& payload); @@ -101,7 +119,6 @@ class ChromeInvalidationClient ChromeSystemResources chrome_system_resources_; base::ScopedCallbackFactory<ChromeInvalidationClient> scoped_callback_factory_; - scoped_ptr<invalidation::NetworkCallback> handle_outbound_packet_callback_; Listener* listener_; StateWriter* state_writer_; scoped_ptr<invalidation::InvalidationClient> invalidation_client_; @@ -111,6 +128,7 @@ class ChromeInvalidationClient std::map<syncable::ModelType, int64> max_invalidation_versions_; // Stored to pass to |registration_manager_| on start. syncable::ModelTypeSet registered_types_; + bool ticl_ready_; DISALLOW_COPY_AND_ASSIGN(ChromeInvalidationClient); }; diff --git a/chrome/browser/sync/notifier/chrome_invalidation_client_unittest.cc b/chrome/browser/sync/notifier/chrome_invalidation_client_unittest.cc index 5a99e77..80f896f 100644 --- a/chrome/browser/sync/notifier/chrome_invalidation_client_unittest.cc +++ b/chrome/browser/sync/notifier/chrome_invalidation_client_unittest.cc @@ -9,6 +9,9 @@ #include "chrome/browser/sync/notifier/state_writer.h" #include "chrome/browser/sync/syncable/model_type.h" #include "chrome/browser/sync/syncable/model_type_payload_map.h" +#include "google/cacheinvalidation/v2/invalidation-client.h" +#include "google/cacheinvalidation/v2/types.h" +#include "google/cacheinvalidation/v2/types.pb.h" #include "jingle/notifier/base/fake_base_task.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -25,8 +28,16 @@ const char kClientId[] = "client_id"; const char kClientInfo[] = "client_info"; const char kState[] = "state"; -static const int64 kUnknownVersion = - invalidation::InvalidationListener::UNKNOWN_OBJECT_VERSION; +class MockInvalidationClient : public invalidation::InvalidationClient { + public: + MOCK_METHOD0(Start, void()); + MOCK_METHOD0(Stop, void()); + MOCK_METHOD1(Register, void(const invalidation::ObjectId&)); + MOCK_METHOD1(Register, void(const std::vector<invalidation::ObjectId>&)); + MOCK_METHOD1(Unregister, void(const invalidation::ObjectId&)); + MOCK_METHOD1(Unregister, void(const std::vector<invalidation::ObjectId>&)); + MOCK_METHOD1(Acknowledge, void(const invalidation::AckHandle&)); +}; class MockListener : public ChromeInvalidationClient::Listener { public: @@ -63,42 +74,44 @@ class ChromeInvalidationClientTest : public testing::Test { message_loop_.RunAllPending(); } - // Simulates DoInformOutboundListener() from network-manager.cc. - void SimulateInformOutboundListener() { - // Explicitness hack here to work around broken callback - // implementations. - void (invalidation::NetworkCallback::*run_function)( - invalidation::NetworkEndpoint* const&) = - &invalidation::NetworkCallback::Run; - - client_.chrome_system_resources_.ScheduleOnListenerThread( - invalidation::NewPermanentCallback( - client_.handle_outbound_packet_callback_.get(), run_function, - client_.invalidation_client_->network_endpoint())); - } - // |payload| can be NULL, but not |type_name|. void FireInvalidate(const char* type_name, int64 version, const char* payload) { const invalidation::ObjectId object_id( - invalidation::ObjectSource::CHROME_SYNC, type_name); + ipc::invalidation::ObjectSource::CHROME_SYNC, type_name); std::string payload_tmp = payload ? payload : ""; - const invalidation::Invalidation invalidation( - object_id, version, payload ? &payload_tmp : NULL, NULL); - MockCallback mock_callback; - EXPECT_CALL(mock_callback, Run()); - client_.Invalidate(invalidation, mock_callback.MakeClosure()); + invalidation::Invalidation inv; + if (payload) { + inv = invalidation::Invalidation(object_id, version, payload); + } else { + inv = invalidation::Invalidation(object_id, version); + } + invalidation::AckHandle ack_handle("fakedata"); + EXPECT_CALL(mock_invalidation_client_, Acknowledge(ack_handle)); + client_.Invalidate(&mock_invalidation_client_, inv, ack_handle); + } + + // |payload| can be NULL, but not |type_name|. + void FireInvalidateUnknownVersion(const char* type_name) { + const invalidation::ObjectId object_id( + ipc::invalidation::ObjectSource::CHROME_SYNC, type_name); + + invalidation::AckHandle ack_handle("fakedata"); + EXPECT_CALL(mock_invalidation_client_, Acknowledge(ack_handle)); + client_.InvalidateUnknownVersion(&mock_invalidation_client_, object_id, + ack_handle); } void FireInvalidateAll() { - MockCallback mock_callback; - EXPECT_CALL(mock_callback, Run()); - client_.InvalidateAll(mock_callback.MakeClosure()); + invalidation::AckHandle ack_handle("fakedata"); + EXPECT_CALL(mock_invalidation_client_, Acknowledge(ack_handle)); + client_.InvalidateAll(&mock_invalidation_client_, ack_handle); } MessageLoop message_loop_; StrictMock<MockListener> mock_listener_; StrictMock<MockStateWriter> mock_state_writer_; + StrictMock<MockInvalidationClient> mock_invalidation_client_; notifier::FakeBaseTask fake_base_task_; ChromeInvalidationClient client_; }; @@ -131,6 +144,7 @@ TEST_F(ChromeInvalidationClientTest, InvalidateBadObjectId) { client_.RegisterTypes(types); EXPECT_CALL(mock_listener_, OnInvalidate(MakeMapFromSet(types, ""))); FireInvalidate("bad", 1, NULL); + message_loop_.RunAllPending(); } TEST_F(ChromeInvalidationClientTest, InvalidateNoPayload) { @@ -166,8 +180,8 @@ TEST_F(ChromeInvalidationClientTest, InvalidateUnknownVersion) { .Times(2); // Should trigger twice. - FireInvalidate("EXTENSION", kUnknownVersion, NULL); - FireInvalidate("EXTENSION", kUnknownVersion, NULL); + FireInvalidateUnknownVersion("EXTENSION"); + FireInvalidateUnknownVersion("EXTENSION"); } TEST_F(ChromeInvalidationClientTest, InvalidateVersionMultipleTypes) { @@ -235,24 +249,6 @@ TEST_F(ChromeInvalidationClientTest, RegisterTypes) { FireInvalidateAll(); } -// Outbound packet sending should be resilient to -// changing/disappearing base tasks. -TEST_F(ChromeInvalidationClientTest, OutboundPackets) { - SimulateInformOutboundListener(); - - notifier::FakeBaseTask fake_base_task; - client_.ChangeBaseTask(fake_base_task.AsWeakPtr()); - - SimulateInformOutboundListener(); - - { - notifier::FakeBaseTask fake_base_task2; - client_.ChangeBaseTask(fake_base_task2.AsWeakPtr()); - } - - SimulateInformOutboundListener(); -} - // TODO(akalin): Flesh out unit tests. } // namespace sync_notifier diff --git a/chrome/browser/sync/notifier/chrome_system_resources.cc b/chrome/browser/sync/notifier/chrome_system_resources.cc index 1f6703a..9d64f0d 100644 --- a/chrome/browser/sync/notifier/chrome_system_resources.cc +++ b/chrome/browser/sync/notifier/chrome_system_resources.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -13,48 +13,78 @@ #include "base/stl_util-inl.h" #include "base/string_util.h" #include "base/stringprintf.h" +#include "chrome/browser/sync/notifier/cache_invalidation_packet_handler.h" #include "chrome/browser/sync/notifier/invalidation_util.h" +#include "google/cacheinvalidation/v2/types.h" namespace sync_notifier { -ChromeSystemResources::ChromeSystemResources(StateWriter* state_writer) - : state_writer_(state_writer), - created_on_loop_(MessageLoop::current()) { - DCHECK(non_thread_safe_.CalledOnValidThread()); - CHECK(created_on_loop_); - DCHECK(state_writer_); +ChromeLogger::ChromeLogger() {} +ChromeLogger::~ChromeLogger() {} + +void ChromeLogger::Log(LogLevel level, const char* file, int line, + const char* format, ...) { + logging::LogSeverity log_severity = logging::LOG_INFO; + switch (level) { + case FINE_LEVEL: + log_severity = logging::LOG_VERBOSE; + break; + case INFO_LEVEL: + log_severity = logging::LOG_INFO; + break; + case WARNING_LEVEL: + log_severity = logging::LOG_WARNING; + break; + case SEVERE_LEVEL: + log_severity = logging::LOG_ERROR; + break; + } + // We treat LOG(INFO) as VLOG(1). + if ((log_severity >= logging::GetMinLogLevel()) && + ((log_severity != logging::LOG_INFO) || + (1 <= logging::GetVlogLevelHelper(file, ::strlen(file))))) { + va_list ap; + va_start(ap, format); + std::string result; + base::StringAppendV(&result, format, ap); + logging::LogMessage(file, line, log_severity).stream() << result; + va_end(ap); + } } -ChromeSystemResources::~ChromeSystemResources() { - DCHECK(non_thread_safe_.CalledOnValidThread()); - CHECK_EQ(created_on_loop_, MessageLoop::current()); - StopScheduler(); +ChromeScheduler::ChromeScheduler() + : created_on_loop_(MessageLoop::current()), + is_started_(false), + is_stopped_(false) { + CHECK(created_on_loop_); } -invalidation::Time ChromeSystemResources::current_time() { - DCHECK(non_thread_safe_.CalledOnValidThread()); +ChromeScheduler::~ChromeScheduler() { CHECK_EQ(created_on_loop_, MessageLoop::current()); - return base::Time::Now(); + CHECK(is_stopped_); } -void ChromeSystemResources::StartScheduler() { - DCHECK(non_thread_safe_.CalledOnValidThread()); +void ChromeScheduler::Start() { CHECK_EQ(created_on_loop_, MessageLoop::current()); + CHECK(!is_started_); + is_started_ = true; + is_stopped_ = false; scoped_runnable_method_factory_.reset( - new ScopedRunnableMethodFactory<ChromeSystemResources>(this)); + new ScopedRunnableMethodFactory<ChromeScheduler>(this)); } -void ChromeSystemResources::StopScheduler() { - DCHECK(non_thread_safe_.CalledOnValidThread()); +void ChromeScheduler::Stop() { CHECK_EQ(created_on_loop_, MessageLoop::current()); + is_stopped_ = true; + is_started_ = false; scoped_runnable_method_factory_.reset(); STLDeleteElements(&posted_tasks_); + posted_tasks_.clear(); } -void ChromeSystemResources::ScheduleWithDelay( +void ChromeScheduler::Schedule( invalidation::TimeDelta delay, invalidation::Closure* task) { - DCHECK(non_thread_safe_.CalledOnValidThread()); CHECK_EQ(created_on_loop_, MessageLoop::current()); Task* task_to_post = MakeTaskToPost(task); if (!task_to_post) { @@ -64,106 +94,190 @@ void ChromeSystemResources::ScheduleWithDelay( FROM_HERE, task_to_post, delay.InMillisecondsRoundedUp()); } -void ChromeSystemResources::ScheduleImmediately( - invalidation::Closure* task) { - DCHECK(non_thread_safe_.CalledOnValidThread()); +bool ChromeScheduler::IsRunningOnThread() { + return created_on_loop_ == MessageLoop::current(); +} + +invalidation::Time ChromeScheduler::GetCurrentTime() { CHECK_EQ(created_on_loop_, MessageLoop::current()); - Task* task_to_post = MakeTaskToPost(task); - if (!task_to_post) { - return; - } - MessageLoop::current()->PostTask(FROM_HERE, task_to_post); + return base::Time::Now(); } -// The listener thread is just our current thread (i.e., the -// notifications thread). -void ChromeSystemResources::ScheduleOnListenerThread( +Task* ChromeScheduler::MakeTaskToPost( invalidation::Closure* task) { - DCHECK(non_thread_safe_.CalledOnValidThread()); + DCHECK(invalidation::IsCallbackRepeatable(task)); CHECK_EQ(created_on_loop_, MessageLoop::current()); - ScheduleImmediately(task); + if (!scoped_runnable_method_factory_.get()) { + delete task; + return NULL; + } + posted_tasks_.insert(task); + Task* task_to_post = + scoped_runnable_method_factory_->NewRunnableMethod( + &ChromeScheduler::RunPostedTask, task); + return task_to_post; } -// 'Internal thread' means 'not the listener thread'. Since the -// listener thread is the notifications thread, always return false. -bool ChromeSystemResources::IsRunningOnInternalThread() { - DCHECK(non_thread_safe_.CalledOnValidThread()); +void ChromeScheduler::RunPostedTask(invalidation::Closure* task) { CHECK_EQ(created_on_loop_, MessageLoop::current()); - return false; + RunAndDeleteClosure(task); + posted_tasks_.erase(task); } -void ChromeSystemResources::Log( - LogLevel level, const char* file, int line, - const char* format, ...) { - DCHECK(non_thread_safe_.CalledOnValidThread()); - logging::LogSeverity log_severity = logging::LOG_INFO; - switch (level) { - case INFO_LEVEL: - log_severity = logging::LOG_INFO; - break; - case WARNING_LEVEL: - log_severity = logging::LOG_WARNING; - break; - case SEVERE_LEVEL: - log_severity = logging::LOG_ERROR; - break; - } - // We treat LOG(INFO) as VLOG(1). - if ((log_severity >= logging::GetMinLogLevel()) && - ((log_severity != logging::LOG_INFO) || - (1 <= logging::GetVlogLevelHelper(file, ::strlen(file))))) { - va_list ap; - va_start(ap, format); - std::string result; - base::StringAppendV(&result, format, ap); - logging::LogMessage(file, line, log_severity).stream() << result; - va_end(ap); - } +ChromeStorage::ChromeStorage(StateWriter* state_writer, + invalidation::Scheduler* scheduler) + : state_writer_(state_writer), + scheduler_(scheduler) { + DCHECK(state_writer_); + DCHECK(scheduler_); } -void ChromeSystemResources::RunAndDeleteStorageCallback( - invalidation::StorageCallback* callback) { - callback->Run(true); - delete callback; -} +ChromeStorage::~ChromeStorage() {} -void ChromeSystemResources::WriteState( - const invalidation::string& state, - invalidation::StorageCallback* callback) { +void ChromeStorage::WriteKey(const std::string& key, const std::string& value, + invalidation::WriteKeyCallback* done) { CHECK(state_writer_); - state_writer_->WriteState(state); + // TODO(ghc): actually write key,value associations, and don't invoke the + // callback until the operation completes. + state_writer_->WriteState(value); + cached_state_ = value; // According to the cache invalidation API folks, we can do this as // long as we make sure to clear the persistent state that we start // up the cache invalidation client with. However, we musn't do it // right away, as we may be called under a lock that the callback // uses. - ScheduleImmediately( + scheduler_->Schedule( + invalidation::Scheduler::NoDelay(), invalidation::NewPermanentCallback( - this, &ChromeSystemResources::RunAndDeleteStorageCallback, - callback)); + this, &ChromeStorage::RunAndDeleteWriteKeyCallback, + done)); } -Task* ChromeSystemResources::MakeTaskToPost( - invalidation::Closure* task) { - DCHECK(non_thread_safe_.CalledOnValidThread()); - DCHECK(invalidation::IsCallbackRepeatable(task)); - CHECK_EQ(created_on_loop_, MessageLoop::current()); - if (!scoped_runnable_method_factory_.get()) { - delete task; - return NULL; +void ChromeStorage::ReadKey(const std::string& key, + invalidation::ReadKeyCallback* done) { + scheduler_->Schedule( + invalidation::Scheduler::NoDelay(), + invalidation::NewPermanentCallback( + this, &ChromeStorage::RunAndDeleteReadKeyCallback, + done, cached_state_)); +} + +void ChromeStorage::DeleteKey(const std::string& key, + invalidation::DeleteKeyCallback* done) { + // TODO(ghc): Implement. + LOG(WARNING) << "ignoring call to DeleteKey(" << key << ", callback)"; +} + +void ChromeStorage::ReadAllKeys(invalidation::ReadAllKeysCallback* done) { + // TODO(ghc): Implement. + LOG(WARNING) << "ignoring call to ReadAllKeys(callback)"; +} + +void ChromeStorage::RunAndDeleteWriteKeyCallback( + invalidation::WriteKeyCallback* callback) { + callback->Run(invalidation::Status(invalidation::Status::SUCCESS, "")); + delete callback; +} + +void ChromeStorage::RunAndDeleteReadKeyCallback( + invalidation::ReadKeyCallback* callback, const std::string& value) { + callback->Run(std::make_pair( + invalidation::Status(invalidation::Status::SUCCESS, ""), + value)); + delete callback; +} + +ChromeNetwork::ChromeNetwork() : packet_handler_(NULL) {} + +ChromeNetwork::~ChromeNetwork() { + STLDeleteElements(&network_status_receivers_); +} + +void ChromeNetwork::SendMessage(const std::string& outgoing_message) { + if (packet_handler_) { + packet_handler_->SendMessage(outgoing_message); } - posted_tasks_.insert(task); - Task* task_to_post = - scoped_runnable_method_factory_->NewRunnableMethod( - &ChromeSystemResources::RunPostedTask, task); - return task_to_post; } -void ChromeSystemResources::RunPostedTask(invalidation::Closure* task) { - DCHECK(non_thread_safe_.CalledOnValidThread()); - CHECK_EQ(created_on_loop_, MessageLoop::current()); - RunAndDeleteClosure(task); - posted_tasks_.erase(task); +void ChromeNetwork::SetMessageReceiver( + invalidation::MessageCallback* incoming_receiver) { + incoming_receiver_.reset(incoming_receiver); +} + +void ChromeNetwork::AddNetworkStatusReceiver( + invalidation::NetworkStatusCallback* network_status_receiver) { + network_status_receivers_.push_back(network_status_receiver); +} + +void ChromeNetwork::UpdatePacketHandler( + CacheInvalidationPacketHandler* packet_handler) { + packet_handler_ = packet_handler; + if (packet_handler_ != NULL) { + packet_handler_->SetMessageReceiver( + invalidation::NewPermanentCallback( + this, &ChromeNetwork::HandleInboundMessage)); + } +} + +void ChromeNetwork::HandleInboundMessage(const std::string& incoming_message) { + if (incoming_receiver_.get()) { + incoming_receiver_->Run(incoming_message); + } +} + +ChromeSystemResources::ChromeSystemResources(StateWriter* state_writer) + : is_started_(false), + logger_(new ChromeLogger()), + internal_scheduler_(new ChromeScheduler()), + listener_scheduler_(new ChromeScheduler()), + storage_(new ChromeStorage(state_writer, internal_scheduler_.get())), + network_(new ChromeNetwork()) { +} + +ChromeSystemResources::~ChromeSystemResources() { + Stop(); +} + +void ChromeSystemResources::Start() { + internal_scheduler_->Start(); + listener_scheduler_->Start(); +} + +void ChromeSystemResources::Stop() { + internal_scheduler_->Stop(); + listener_scheduler_->Stop(); +} + +bool ChromeSystemResources::IsStarted() { + return is_started_; +} + +void ChromeSystemResources::set_platform(const std::string& platform) { + platform_ = platform; +} + +std::string ChromeSystemResources::platform() { + return platform_; +} + +ChromeLogger* ChromeSystemResources::logger() { + return logger_.get(); +} + +ChromeStorage* ChromeSystemResources::storage() { + return storage_.get(); +} + +ChromeNetwork* ChromeSystemResources::network() { + return network_.get(); +} + +ChromeScheduler* ChromeSystemResources::internal_scheduler() { + return internal_scheduler_.get(); +} + +ChromeScheduler* ChromeSystemResources::listener_scheduler() { + return listener_scheduler_.get(); } } // namespace sync_notifier diff --git a/chrome/browser/sync/notifier/chrome_system_resources.h b/chrome/browser/sync/notifier/chrome_system_resources.h index 26932c3..f034591 100644 --- a/chrome/browser/sync/notifier/chrome_system_resources.h +++ b/chrome/browser/sync/notifier/chrome_system_resources.h @@ -12,55 +12,57 @@ #include <set> #include <string> +#include <vector> #include "base/memory/scoped_ptr.h" #include "base/message_loop.h" #include "base/task.h" #include "base/threading/non_thread_safe.h" #include "chrome/browser/sync/notifier/state_writer.h" -#include "google/cacheinvalidation/invalidation-client.h" +#include "google/cacheinvalidation/v2/system-resources.h" namespace sync_notifier { -class ChromeSystemResources : public invalidation::SystemResources { - public: - explicit ChromeSystemResources(StateWriter* state_writer); +class CacheInvalidationPacketHandler; - virtual ~ChromeSystemResources(); - - // invalidation::SystemResources implementation. +class ChromeLogger : public invalidation::Logger { + public: + ChromeLogger(); - virtual invalidation::Time current_time(); + virtual ~ChromeLogger(); - virtual void StartScheduler(); + virtual void Log(LogLevel level, const char* file, int line, + const char* format, ...); +}; - virtual void StopScheduler(); +class ChromeScheduler : public invalidation::Scheduler { + public: + ChromeScheduler(); - virtual void ScheduleWithDelay(invalidation::TimeDelta delay, - invalidation::Closure* task); + virtual ~ChromeScheduler(); - virtual void ScheduleImmediately(invalidation::Closure* task); + // Start and stop the scheduler. + virtual void Start(); + virtual void Stop(); - virtual void ScheduleOnListenerThread(invalidation::Closure* task); + // Overrides. + virtual void Schedule(invalidation::TimeDelta delay, + invalidation::Closure* task); - virtual bool IsRunningOnInternalThread(); + virtual bool IsRunningOnThread(); - virtual void Log(LogLevel level, const char* file, int line, - const char* format, ...); - - virtual void WriteState(const invalidation::string& state, - invalidation::StorageCallback* callback); + virtual invalidation::Time GetCurrentTime(); private: - base::NonThreadSafe non_thread_safe_; - scoped_ptr<ScopedRunnableMethodFactory<ChromeSystemResources> > + scoped_ptr<ScopedRunnableMethodFactory<ChromeScheduler> > scoped_runnable_method_factory_; // Holds all posted tasks that have not yet been run. std::set<invalidation::Closure*> posted_tasks_; - StateWriter* state_writer_; // TODO(tim): Trying to debug bug crbug.com/64652. const MessageLoop* created_on_loop_; + bool is_started_; + bool is_stopped_; // If the scheduler has been started, inserts |task| into // |posted_tasks_| and returns a Task* to post. Otherwise, @@ -69,10 +71,95 @@ class ChromeSystemResources : public invalidation::SystemResources { // Runs the task, deletes it, and removes it from |posted_tasks_|. void RunPostedTask(invalidation::Closure* task); +}; + +class ChromeStorage : public invalidation::Storage { + public: + ChromeStorage(StateWriter* state_writer, invalidation::Scheduler* scheduler); + + virtual ~ChromeStorage(); + + void SetInitialState(const std::string& value) { + cached_state_ = value; + } + + // invalidation::Storage overrides. + virtual void WriteKey(const std::string& key, const std::string& value, + invalidation::WriteKeyCallback* done); + + virtual void ReadKey(const std::string& key, + invalidation::ReadKeyCallback* done); + + virtual void DeleteKey(const std::string& key, + invalidation::DeleteKeyCallback* done); + + virtual void ReadAllKeys(invalidation::ReadAllKeysCallback* key_callback); + + private: + // Runs the given storage callback with SUCCESS status and deletes it. + void RunAndDeleteWriteKeyCallback( + invalidation::WriteKeyCallback* callback); + + // Runs the given callback with the given value and deletes it. + void RunAndDeleteReadKeyCallback( + invalidation::ReadKeyCallback* callback, const std::string& value); + + StateWriter* state_writer_; + invalidation::Scheduler* scheduler_; + std::string cached_state_; +}; + +class ChromeNetwork : public invalidation::NetworkChannel { + public: + ChromeNetwork(); - // Runs the given storage callback with "true" and deletes it. - void RunAndDeleteStorageCallback( - invalidation::StorageCallback* callback); + virtual ~ChromeNetwork(); + + void UpdatePacketHandler(CacheInvalidationPacketHandler* packet_handler); + + // Overrides. + virtual void SendMessage(const std::string& outgoing_message); + + virtual void SetMessageReceiver( + invalidation::MessageCallback* incoming_receiver); + + virtual void AddNetworkStatusReceiver( + invalidation::NetworkStatusCallback* network_status_receiver); + + private: + void HandleInboundMessage(const std::string& incoming_message); + + CacheInvalidationPacketHandler* packet_handler_; + scoped_ptr<invalidation::MessageCallback> incoming_receiver_; + std::vector<invalidation::NetworkStatusCallback*> network_status_receivers_; +}; + +class ChromeSystemResources : public invalidation::SystemResources { + public: + explicit ChromeSystemResources(StateWriter* state_writer); + + virtual ~ChromeSystemResources(); + + // invalidation::SystemResources implementation. + virtual void Start(); + virtual void Stop(); + virtual bool IsStarted(); + virtual void set_platform(const std::string& platform); + virtual std::string platform(); + virtual ChromeLogger* logger(); + virtual ChromeStorage* storage(); + virtual ChromeNetwork* network(); + virtual ChromeScheduler* internal_scheduler(); + virtual ChromeScheduler* listener_scheduler(); + + private: + bool is_started_; + std::string platform_; + scoped_ptr<ChromeLogger> logger_; + scoped_ptr<ChromeScheduler> internal_scheduler_; + scoped_ptr<ChromeScheduler> listener_scheduler_; + scoped_ptr<ChromeStorage> storage_; + scoped_ptr<ChromeNetwork> network_; }; } // namespace sync_notifier diff --git a/chrome/browser/sync/notifier/chrome_system_resources_unittest.cc b/chrome/browser/sync/notifier/chrome_system_resources_unittest.cc index 306a8b6..d02a5ca 100644 --- a/chrome/browser/sync/notifier/chrome_system_resources_unittest.cc +++ b/chrome/browser/sync/notifier/chrome_system_resources_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -9,8 +9,9 @@ #include "base/callback.h" #include "base/message_loop.h" #include "base/tuple.h" -#include "google/cacheinvalidation/invalidation-client.h" + #include "chrome/browser/sync/notifier/state_writer.h" +#include "google/cacheinvalidation/v2/types.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -30,9 +31,9 @@ class MockClosure : public Callback0::Type { MOCK_METHOD1(RunWithParams, void(const Tuple0&)); }; -class MockStorageCallback : public Callback1<bool>::Type { +class MockStorageCallback : public Callback1<invalidation::Status>::Type { public: - MOCK_METHOD1(RunWithParams, void(const Tuple1<bool>&)); + MOCK_METHOD1(RunWithParams, void(const Tuple1<invalidation::Status>&)); }; class ChromeSystemResourcesTest : public testing::Test { @@ -47,19 +48,21 @@ class ChromeSystemResourcesTest : public testing::Test { // Owned by ScheduleImmediately. MockClosure* should_not_run = new MockClosure(); EXPECT_CALL(*should_not_run, RunWithParams(_)).Times(0); - chrome_system_resources_.ScheduleImmediately(should_not_run); + chrome_system_resources_.internal_scheduler()->Schedule( + invalidation::Scheduler::NoDelay(), should_not_run); } { // Owned by ScheduleOnListenerThread. MockClosure* should_not_run = new MockClosure(); EXPECT_CALL(*should_not_run, RunWithParams(_)).Times(0); - chrome_system_resources_.ScheduleOnListenerThread(should_not_run); + chrome_system_resources_.listener_scheduler()->Schedule( + invalidation::Scheduler::NoDelay(), should_not_run); } { // Owned by ScheduleWithDelay. MockClosure* should_not_run = new MockClosure(); EXPECT_CALL(*should_not_run, RunWithParams(_)).Times(0); - chrome_system_resources_.ScheduleWithDelay( + chrome_system_resources_.internal_scheduler()->Schedule( invalidation::TimeDelta::FromSeconds(0), should_not_run); } } @@ -76,64 +79,67 @@ class ChromeSystemResourcesTest : public testing::Test { // Make sure current_time() doesn't crash or leak. TEST_F(ChromeSystemResourcesTest, CurrentTime) { invalidation::Time current_time = - chrome_system_resources_.current_time(); + chrome_system_resources_.internal_scheduler()->GetCurrentTime(); VLOG(1) << "current_time returned: " << current_time.ToInternalValue(); } // Make sure Log() doesn't crash or leak. TEST_F(ChromeSystemResourcesTest, Log) { - chrome_system_resources_.Log(ChromeSystemResources::INFO_LEVEL, - __FILE__, __LINE__, "%s %d", - "test string", 5); + chrome_system_resources_.logger()->Log(ChromeLogger::INFO_LEVEL, + __FILE__, __LINE__, "%s %d", + "test string", 5); } TEST_F(ChromeSystemResourcesTest, ScheduleBeforeStart) { ScheduleShouldNotRun(); - chrome_system_resources_.StartScheduler(); + chrome_system_resources_.Start(); } TEST_F(ChromeSystemResourcesTest, ScheduleAfterStop) { - chrome_system_resources_.StartScheduler(); - chrome_system_resources_.StopScheduler(); + chrome_system_resources_.Start(); + chrome_system_resources_.Stop(); ScheduleShouldNotRun(); } TEST_F(ChromeSystemResourcesTest, ScheduleAndStop) { - chrome_system_resources_.StartScheduler(); + chrome_system_resources_.Start(); ScheduleShouldNotRun(); - chrome_system_resources_.StopScheduler(); + chrome_system_resources_.Stop(); } TEST_F(ChromeSystemResourcesTest, ScheduleAndDestroy) { - chrome_system_resources_.StartScheduler(); + chrome_system_resources_.Start(); ScheduleShouldNotRun(); } TEST_F(ChromeSystemResourcesTest, ScheduleImmediately) { - chrome_system_resources_.StartScheduler(); + chrome_system_resources_.Start(); // Owned by ScheduleImmediately. MockClosure* mock_closure = new MockClosure(); EXPECT_CALL(*mock_closure, RunWithParams(_)); - chrome_system_resources_.ScheduleImmediately(mock_closure); + chrome_system_resources_.internal_scheduler()->Schedule( + invalidation::Scheduler::NoDelay(), mock_closure); message_loop_.RunAllPending(); } TEST_F(ChromeSystemResourcesTest, ScheduleOnListenerThread) { - chrome_system_resources_.StartScheduler(); + chrome_system_resources_.Start(); // Owned by ScheduleOnListenerThread. MockClosure* mock_closure = new MockClosure(); EXPECT_CALL(*mock_closure, RunWithParams(_)); - chrome_system_resources_.ScheduleOnListenerThread(mock_closure); - EXPECT_FALSE(chrome_system_resources_.IsRunningOnInternalThread()); + chrome_system_resources_.listener_scheduler()->Schedule( + invalidation::Scheduler::NoDelay(), mock_closure); + EXPECT_TRUE( + chrome_system_resources_.internal_scheduler()->IsRunningOnThread()); message_loop_.RunAllPending(); } TEST_F(ChromeSystemResourcesTest, ScheduleWithZeroDelay) { - chrome_system_resources_.StartScheduler(); + chrome_system_resources_.Start(); // Owned by ScheduleWithDelay. MockClosure* mock_closure = new MockClosure(); EXPECT_CALL(*mock_closure, RunWithParams(_)); - chrome_system_resources_.ScheduleWithDelay( + chrome_system_resources_.internal_scheduler()->Schedule( invalidation::TimeDelta::FromSeconds(0), mock_closure); message_loop_.RunAllPending(); } @@ -141,16 +147,18 @@ TEST_F(ChromeSystemResourcesTest, ScheduleWithZeroDelay) { // TODO(akalin): Figure out how to test with a non-zero delay. TEST_F(ChromeSystemResourcesTest, WriteState) { - chrome_system_resources_.StartScheduler(); + chrome_system_resources_.Start(); EXPECT_CALL(mock_state_writer_, WriteState(_)); // Owned by WriteState. MockStorageCallback* mock_storage_callback = new MockStorageCallback(); - Tuple1<bool> results(false); + Tuple1<invalidation::Status> results(invalidation::Status( + invalidation::Status::PERMANENT_FAILURE, "fake-failure")); EXPECT_CALL(*mock_storage_callback, RunWithParams(_)) .WillOnce(SaveArg<0>(&results)); - chrome_system_resources_.WriteState("state", mock_storage_callback); + chrome_system_resources_.storage()->WriteKey("", "state", + mock_storage_callback); message_loop_.RunAllPending(); - EXPECT_TRUE(results.a); + EXPECT_EQ(results.a, invalidation::Status(invalidation::Status::SUCCESS, "")); } } // namespace diff --git a/chrome/browser/sync/notifier/invalidation_util.cc b/chrome/browser/sync/notifier/invalidation_util.cc index a0f16b5..e4e0ea5 100644 --- a/chrome/browser/sync/notifier/invalidation_util.cc +++ b/chrome/browser/sync/notifier/invalidation_util.cc @@ -1,8 +1,9 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/notifier/invalidation_util.h" +#include "google/cacheinvalidation/v2/types.h" #include <sstream> @@ -20,7 +21,8 @@ bool RealModelTypeToObjectId(syncable::ModelType model_type, model_type, ¬ification_type)) { return false; } - object_id->Init(invalidation::ObjectSource::CHROME_SYNC, notification_type); + object_id->Init(ipc::invalidation::ObjectSource::CHROME_SYNC, + notification_type); return true; } @@ -41,24 +43,6 @@ std::string ObjectIdToString( return ss.str(); } -std::string ObjectIdPToString( - const invalidation::ObjectIdP& object_id) { - return ObjectIdToString( - invalidation::ObjectId( - (invalidation::ObjectSource_Type) object_id.source(), - object_id.name().string_value())); -} - -std::string StatusToString( - const invalidation::Status& status) { - std::stringstream ss; - ss << "{ "; - ss << "code: " << status.code() << ", "; - ss << "description: " << status.description(); - ss << " }"; - return ss.str(); -} - std::string InvalidationToString( const invalidation::Invalidation& invalidation) { std::stringstream ss; @@ -69,27 +53,4 @@ std::string InvalidationToString( return ss.str(); } -std::string RegistrationUpdateToString( - const invalidation::RegistrationUpdate& update) { - std::stringstream ss; - ss << "{ "; - ss << "type: " << update.type() << ", "; - ss << "object_id: " << ObjectIdPToString(update.object_id()) << ", "; - ss << "version: " << update.version() << ", "; - ss << "sequence_number: " << update.sequence_number(); - ss << " }"; - return ss.str(); -} - -std::string RegistrationUpdateResultToString( - const invalidation::RegistrationUpdateResult& update_result) { - std::stringstream ss; - ss << "{ "; - ss << "operation: " - << RegistrationUpdateToString(update_result.operation()) << ", "; - ss << "status: " << StatusToString(update_result.status()); - ss << " }"; - return ss.str(); -} - } // namespace sync_notifier diff --git a/chrome/browser/sync/notifier/invalidation_util.h b/chrome/browser/sync/notifier/invalidation_util.h index 639ecdf..22fc05b 100644 --- a/chrome/browser/sync/notifier/invalidation_util.h +++ b/chrome/browser/sync/notifier/invalidation_util.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. // @@ -11,7 +11,9 @@ #include <string> #include "chrome/browser/sync/syncable/model_type.h" -#include "google/cacheinvalidation/invalidation-client.h" +#include "google/cacheinvalidation/callback.h" +#include "google/cacheinvalidation/v2/invalidation-client.h" +#include "google/cacheinvalidation/v2/types.pb.h" namespace sync_notifier { @@ -23,24 +25,11 @@ bool RealModelTypeToObjectId(syncable::ModelType model_type, bool ObjectIdToRealModelType(const invalidation::ObjectId& object_id, syncable::ModelType* model_type); -// We need to write our own protobuf-to-string functions because we -// use LITE_RUNTIME, which doesn't support DebugString(). - std::string ObjectIdToString(const invalidation::ObjectId& object_id); -std::string ObjectIdPToString(const invalidation::ObjectIdP& object_id); - -std::string StatusToString(const invalidation::Status& status); - std::string InvalidationToString( const invalidation::Invalidation& invalidation); -std::string RegistrationUpdateToString( - const invalidation::RegistrationUpdate& update); - -std::string RegistrationUpdateResultToString( - const invalidation::RegistrationUpdateResult& update_result); - } // namespace sync_notifier #endif // CHROME_BROWSER_SYNC_NOTIFIER_INVALIDATION_UTIL_H_ diff --git a/chrome/browser/sync/notifier/registration_manager.cc b/chrome/browser/sync/notifier/registration_manager.cc index 4dbc095..d9d4575 100644 --- a/chrome/browser/sync/notifier/registration_manager.cc +++ b/chrome/browser/sync/notifier/registration_manager.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -19,7 +19,7 @@ RegistrationManager::PendingRegistrationInfo::PendingRegistrationInfo() {} RegistrationManager::RegistrationStatus::RegistrationStatus() : model_type(syncable::UNSPECIFIED), registration_manager(NULL), - state(invalidation::RegistrationState_UNREGISTERED) {} + state(invalidation::InvalidationListener::UNREGISTERED) {} RegistrationManager::RegistrationStatus::~RegistrationStatus() {} @@ -82,7 +82,7 @@ void RegistrationManager::MarkRegistrationLost( syncable::ModelType model_type) { DCHECK(non_thread_safe_.CalledOnValidThread()); registration_statuses_[model_type].state = - invalidation::RegistrationState_UNREGISTERED; + invalidation::InvalidationListener::UNREGISTERED; TryRegisterType(model_type, true /* is_retry */); } @@ -223,7 +223,7 @@ void RegistrationManager::DoRegisterType(syncable::ModelType model_type) { } invalidation_client_->Register(object_id); RegistrationStatus* status = ®istration_statuses_[model_type]; - status->state = invalidation::RegistrationState_REGISTERED; + status->state = invalidation::InvalidationListener::REGISTERED; status->last_registration_request = base::Time::Now(); } @@ -236,14 +236,14 @@ void RegistrationManager::UnregisterType(syncable::ModelType model_type) { } invalidation_client_->Unregister(object_id); RegistrationStatus* status = ®istration_statuses_[model_type]; - status->state = invalidation::RegistrationState_UNREGISTERED; + status->state = invalidation::InvalidationListener::UNREGISTERED; } bool RegistrationManager::IsTypeRegistered( syncable::ModelType model_type) const { DCHECK(non_thread_safe_.CalledOnValidThread()); return registration_statuses_[model_type].state == - invalidation::RegistrationState_REGISTERED; + invalidation::InvalidationListener::REGISTERED; } } // namespace sync_notifier diff --git a/chrome/browser/sync/notifier/registration_manager.h b/chrome/browser/sync/notifier/registration_manager.h index 8111585..6e77899 100644 --- a/chrome/browser/sync/notifier/registration_manager.h +++ b/chrome/browser/sync/notifier/registration_manager.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. // @@ -16,11 +16,13 @@ #include "base/timer.h" #include "base/threading/non_thread_safe.h" #include "chrome/browser/sync/syncable/model_type.h" -// For invalidation::RegistrationState. -#include "google/cacheinvalidation/invalidation-client.h" +// For invalidation::InvalidationListener::RegistrationState. +#include "google/cacheinvalidation/v2/invalidation-listener.h" namespace sync_notifier { +using ::invalidation::InvalidationListener; + // Manages the details of registering types for invalidation. // Implements exponential backoff for repeated registration attempts // to the invalidation client. @@ -114,7 +116,7 @@ class RegistrationManager { RegistrationManager* registration_manager; // The current registration state. - invalidation::RegistrationState state; + InvalidationListener::RegistrationState state; // When we last sent a registration request. base::Time last_registration_request; // When we last tried to register. diff --git a/chrome/browser/sync/notifier/registration_manager_unittest.cc b/chrome/browser/sync/notifier/registration_manager_unittest.cc index a452d75..2e92304 100644 --- a/chrome/browser/sync/notifier/registration_manager_unittest.cc +++ b/chrome/browser/sync/notifier/registration_manager_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -14,7 +14,6 @@ #include "base/message_loop.h" #include "chrome/browser/sync/notifier/invalidation_util.h" #include "chrome/browser/sync/syncable/model_type.h" -#include "google/cacheinvalidation/invalidation-client.h" #include "testing/gtest/include/gtest/gtest.h" namespace sync_notifier { @@ -71,7 +70,9 @@ class FakeInvalidationClient : public invalidation::InvalidationClient { // invalidation::InvalidationClient implementation. - virtual void Start(const std::string& state) {} + virtual void Start() {} + virtual void Stop() {} + virtual void Acknowledge(const invalidation::AckHandle& handle) {} virtual void Register(const invalidation::ObjectId& oid) { syncable::ModelType model_type = ObjectIdToModelType(oid); @@ -79,15 +80,18 @@ class FakeInvalidationClient : public invalidation::InvalidationClient { registered_types_.insert(model_type); } + virtual void Register(const std::vector<invalidation::ObjectId>& oids) { + // Unused for now. + } + virtual void Unregister(const invalidation::ObjectId& oid) { syncable::ModelType model_type = ObjectIdToModelType(oid); EXPECT_GT(registered_types_.count(model_type), 0u); registered_types_.erase(model_type); } - virtual invalidation::NetworkEndpoint* network_endpoint() { - ADD_FAILURE(); - return NULL; + virtual void Unregister(const std::vector<invalidation::ObjectId>& oids) { + // Unused for now. } const syncable::ModelTypeSet GetRegisteredTypes() const { diff --git a/chrome/browser/sync/syncable/syncable.cc b/chrome/browser/sync/syncable/syncable.cc index 2710279..2ae8060 100644 --- a/chrome/browser/sync/syncable/syncable.cc +++ b/chrome/browser/sync/syncable/syncable.cc @@ -971,10 +971,9 @@ void Directory::set_store_birthday(const string& store_birthday) { kernel_->info_status = KERNEL_SHARE_INFO_DIRTY; } -std::string Directory::GetAndClearNotificationState() { +std::string Directory::GetNotificationState() const { ScopedKernelLock lock(this); std::string notification_state = kernel_->persisted_info.notification_state; - SetNotificationStateUnsafe(std::string()); return notification_state; } diff --git a/chrome/browser/sync/syncable/syncable.h b/chrome/browser/sync/syncable/syncable.h index f090d20..feaf6ed 100644 --- a/chrome/browser/sync/syncable/syncable.h +++ b/chrome/browser/sync/syncable/syncable.h @@ -818,7 +818,7 @@ class Directory { std::string store_birthday() const; void set_store_birthday(const std::string& store_birthday); - std::string GetAndClearNotificationState(); + std::string GetNotificationState() const; void SetNotificationState(const std::string& notification_state); // Unique to each account / client pair. diff --git a/chrome/browser/sync/syncable/syncable_unittest.cc b/chrome/browser/sync/syncable/syncable_unittest.cc index 099d01b..9d7db7d 100644 --- a/chrome/browser/sync/syncable/syncable_unittest.cc +++ b/chrome/browser/sync/syncable/syncable_unittest.cc @@ -1081,8 +1081,7 @@ TEST_F(SyncableDirectoryTest, TestShareInfo) { EXPECT_TRUE(dir_->initial_sync_ended_for_type(AUTOFILL)); EXPECT_FALSE(dir_->initial_sync_ended_for_type(BOOKMARKS)); EXPECT_EQ("Jan 31st", dir_->store_birthday()); - EXPECT_EQ("notification_state", dir_->GetAndClearNotificationState()); - EXPECT_EQ("", dir_->GetAndClearNotificationState()); + EXPECT_EQ("notification_state", dir_->GetNotificationState()); } dir_->set_store_birthday("April 10th"); dir_->SetNotificationState("notification_state2"); @@ -1092,8 +1091,7 @@ TEST_F(SyncableDirectoryTest, TestShareInfo) { EXPECT_TRUE(dir_->initial_sync_ended_for_type(AUTOFILL)); EXPECT_FALSE(dir_->initial_sync_ended_for_type(BOOKMARKS)); EXPECT_EQ("April 10th", dir_->store_birthday()); - EXPECT_EQ("notification_state2", dir_->GetAndClearNotificationState()); - EXPECT_EQ("", dir_->GetAndClearNotificationState()); + EXPECT_EQ("notification_state2", dir_->GetNotificationState()); } dir_->SetNotificationState("notification_state2"); // Restore the directory from disk. Make sure that nothing's changed. @@ -1103,8 +1101,7 @@ TEST_F(SyncableDirectoryTest, TestShareInfo) { EXPECT_TRUE(dir_->initial_sync_ended_for_type(AUTOFILL)); EXPECT_FALSE(dir_->initial_sync_ended_for_type(BOOKMARKS)); EXPECT_EQ("April 10th", dir_->store_birthday()); - EXPECT_EQ("notification_state2", dir_->GetAndClearNotificationState()); - EXPECT_EQ("", dir_->GetAndClearNotificationState()); + EXPECT_EQ("notification_state2", dir_->GetNotificationState()); } } diff --git a/third_party/cacheinvalidation/cacheinvalidation.gyp b/third_party/cacheinvalidation/cacheinvalidation.gyp index 608b8f0..0a6fc3b 100644 --- a/third_party/cacheinvalidation/cacheinvalidation.gyp +++ b/third_party/cacheinvalidation/cacheinvalidation.gyp @@ -13,7 +13,8 @@ # proto_dir_root. # TODO(akalin): Add a RULE_INPUT_DIR predefined variable to gyp so # we don't need this variable. - 'proto_dir_relpath': 'google/cacheinvalidation', + # TODO(ghc): Remove v2/ dir and move all files up a level. + 'proto_dir_relpath': 'google/cacheinvalidation/v2', # Where files generated from proto files are put. 'protoc_out_dir': '<(SHARED_INTERMEDIATE_DIR)/protoc_out', # The path to the protoc executable. @@ -26,8 +27,9 @@ 'target_name': 'cacheinvalidation_proto', 'type': 'none', 'sources': [ - '<(proto_dir_root)/<(proto_dir_relpath)/internal.proto', - '<(proto_dir_root)/<(proto_dir_relpath)/ticl_persistence.proto', + '<(proto_dir_root)/<(proto_dir_relpath)/client.proto', + '<(proto_dir_root)/<(proto_dir_relpath)/client_protocol.proto', + '<(proto_dir_root)/<(proto_dir_relpath)/client_test_internal.proto', '<(proto_dir_root)/<(proto_dir_relpath)/types.proto', ], # TODO(akalin): This block was copied from the sync_proto target @@ -63,10 +65,12 @@ 'target_name': 'cacheinvalidation_proto_cpp', 'type': 'static_library', 'sources': [ - '<(protoc_out_dir)/<(proto_dir_relpath)/internal.pb.h', - '<(protoc_out_dir)/<(proto_dir_relpath)/internal.pb.cc', - '<(protoc_out_dir)/<(proto_dir_relpath)/ticl_persistence.pb.h', - '<(protoc_out_dir)/<(proto_dir_relpath)/ticl_persistence.pb.cc', + '<(protoc_out_dir)/<(proto_dir_relpath)/client.pb.h', + '<(protoc_out_dir)/<(proto_dir_relpath)/client.pb.cc', + '<(protoc_out_dir)/<(proto_dir_relpath)/client_protocol.pb.h', + '<(protoc_out_dir)/<(proto_dir_relpath)/client_protocol.pb.cc', + '<(protoc_out_dir)/<(proto_dir_relpath)/client_test_internal.pb.h', + '<(protoc_out_dir)/<(proto_dir_relpath)/client_test_internal.pb.cc', '<(protoc_out_dir)/<(proto_dir_relpath)/types.pb.h', '<(protoc_out_dir)/<(proto_dir_relpath)/types.pb.cc', ], @@ -99,37 +103,56 @@ 'overrides/google/cacheinvalidation/compiler-specific.h', 'overrides/google/cacheinvalidation/gmock.h', 'overrides/google/cacheinvalidation/googletest.h', - 'overrides/google/cacheinvalidation/hash_map.h', - 'overrides/google/cacheinvalidation/logging.h', + 'overrides/google/cacheinvalidation/v2/logging.h', 'overrides/google/cacheinvalidation/md5.h', - 'overrides/google/cacheinvalidation/mutex.h', + 'overrides/google/cacheinvalidation/v2/mutex.h', 'overrides/google/cacheinvalidation/random.h', - 'overrides/google/cacheinvalidation/scoped_ptr.h', + 'overrides/google/cacheinvalidation/v2/scoped_ptr.h', 'overrides/google/cacheinvalidation/stl-namespace.h', - 'overrides/google/cacheinvalidation/string_util.h', - 'overrides/google/cacheinvalidation/time.h', - 'files/src/google/cacheinvalidation/invalidation-client-impl.cc', - 'files/src/google/cacheinvalidation/invalidation-client-impl.h', - 'files/src/google/cacheinvalidation/invalidation-client.cc', - 'files/src/google/cacheinvalidation/invalidation-client.h', - 'files/src/google/cacheinvalidation/invalidation-types.h', - 'files/src/google/cacheinvalidation/log-macro.h', - 'files/src/google/cacheinvalidation/network-manager.cc', - 'files/src/google/cacheinvalidation/network-manager.h', - 'files/src/google/cacheinvalidation/persistence-manager.cc', - 'files/src/google/cacheinvalidation/persistence-manager.h', - 'files/src/google/cacheinvalidation/persistence-utils.cc', - 'files/src/google/cacheinvalidation/persistence-utils.h', - 'files/src/google/cacheinvalidation/proto-converter.cc', - 'files/src/google/cacheinvalidation/proto-converter.h', - 'files/src/google/cacheinvalidation/registration-update-manager.cc', - 'files/src/google/cacheinvalidation/registration-update-manager.h', - 'files/src/google/cacheinvalidation/session-manager.cc', - 'files/src/google/cacheinvalidation/session-manager.h', - 'files/src/google/cacheinvalidation/throttle.cc', - 'files/src/google/cacheinvalidation/throttle.h', - 'files/src/google/cacheinvalidation/version-manager.cc', - 'files/src/google/cacheinvalidation/version-manager.h', + 'overrides/google/cacheinvalidation/v2/string_util.h', + 'overrides/google/cacheinvalidation/v2/time.h', + 'files/src/google/cacheinvalidation/v2/checking-invalidation-listener.cc', + 'files/src/google/cacheinvalidation/v2/checking-invalidation-listener.h', + 'files/src/google/cacheinvalidation/v2/client-protocol-namespace-fix.h', + 'files/src/google/cacheinvalidation/v2/constants.h', + 'files/src/google/cacheinvalidation/v2/constants.cc', + 'files/src/google/cacheinvalidation/v2/digest-function.h', + 'files/src/google/cacheinvalidation/v2/digest-store.h', + 'files/src/google/cacheinvalidation/v2/exponential-backoff-delay-generator.h', + 'files/src/google/cacheinvalidation/v2/exponential-backoff-delay-generator.cc', + 'files/src/google/cacheinvalidation/v2/invalidation-client-impl.cc', + 'files/src/google/cacheinvalidation/v2/invalidation-client-impl.h', + 'files/src/google/cacheinvalidation/v2/invalidation-client.h', + 'files/src/google/cacheinvalidation/v2/invalidation-client-util.h', + 'files/src/google/cacheinvalidation/v2/invalidation-listener.h', + 'files/src/google/cacheinvalidation/v2/log-macro.h', + 'files/src/google/cacheinvalidation/v2/logging.h', + 'files/src/google/cacheinvalidation/v2/mutex.h', + 'files/src/google/cacheinvalidation/v2/object-id-digest-utils.cc', + 'files/src/google/cacheinvalidation/v2/object-id-digest-utils.h', + 'files/src/google/cacheinvalidation/v2/operation-scheduler.cc', + 'files/src/google/cacheinvalidation/v2/operation-scheduler.h', + 'files/src/google/cacheinvalidation/v2/persistence-utils.cc', + 'files/src/google/cacheinvalidation/v2/persistence-utils.h', + 'files/src/google/cacheinvalidation/v2/proto-converter.cc', + 'files/src/google/cacheinvalidation/v2/proto-converter.h', + 'files/src/google/cacheinvalidation/v2/proto-helpers.h', + 'files/src/google/cacheinvalidation/v2/protocol-handler.cc', + 'files/src/google/cacheinvalidation/v2/protocol-handler.h', + 'files/src/google/cacheinvalidation/v2/registration-manager.cc', + 'files/src/google/cacheinvalidation/v2/registration-manager.h', + 'files/src/google/cacheinvalidation/v2/run-state.h', + 'files/src/google/cacheinvalidation/v2/sha1-digest-function.h', + 'files/src/google/cacheinvalidation/v2/simple-registration-store.cc', + 'files/src/google/cacheinvalidation/v2/simple-registration-store.h', + 'files/src/google/cacheinvalidation/v2/smearer.h', + 'files/src/google/cacheinvalidation/v2/statistics.cc', + 'files/src/google/cacheinvalidation/v2/statistics.h', + 'files/src/google/cacheinvalidation/v2/string_util.h', + 'files/src/google/cacheinvalidation/v2/system-resources.h', + 'files/src/google/cacheinvalidation/v2/ticl-message-validator.h', + 'files/src/google/cacheinvalidation/v2/time.h', + 'files/src/google/cacheinvalidation/v2/types.h', ], 'include_dirs': [ './overrides', @@ -155,16 +178,12 @@ ], }, # Unittests for the cache invalidation library. + # TODO(ghc): Write native tests and include them here. { 'target_name': 'cacheinvalidation_unittests', 'type': 'executable', 'sources': [ '../../base/test/run_all_unittests.cc', - 'files/src/google/cacheinvalidation/system-resources-for-test.h', - 'files/src/google/cacheinvalidation/invalidation-client-impl_test.cc', - 'files/src/google/cacheinvalidation/persistence-manager_test.cc', - 'files/src/google/cacheinvalidation/persistence-utils_test.cc', - 'files/src/google/cacheinvalidation/throttle_test.cc', ], 'dependencies': [ '../../base/base.gyp:base', diff --git a/third_party/cacheinvalidation/overrides/google/cacheinvalidation/callback.h b/third_party/cacheinvalidation/overrides/google/cacheinvalidation/callback.h index 0f42a91..cc0267a 100644 --- a/third_party/cacheinvalidation/overrides/google/cacheinvalidation/callback.h +++ b/third_party/cacheinvalidation/overrides/google/cacheinvalidation/callback.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -179,6 +179,29 @@ class ThreeArgCallbackRunner : public CallbackRunner<Tuple0> { typename internal::remove_reference<Arg3>::type arg3_; }; +template <class T, typename Arg1, typename Arg2, typename Arg3, typename Arg4> +class FourArgCallbackRunner : public CallbackRunner<Tuple0> { + public: + FourArgCallbackRunner(T* obj, void (T::*meth)(Arg1, Arg2, Arg3, Arg4), + Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) + : obj_(obj), meth_(meth), arg1_(arg1), arg2_(arg2), arg3_(arg3), + arg4_(arg4) {} + + virtual ~FourArgCallbackRunner() {} + + virtual void RunWithParams(const Tuple0& params) { + (obj_->*meth_)(arg1_, arg2_, arg3_, arg4_); + } + + private: + T* obj_; + void (T::*meth_)(Arg1, Arg2, Arg3, Arg4); + typename internal::remove_reference<Arg1>::type arg1_; + typename internal::remove_reference<Arg2>::type arg2_; + typename internal::remove_reference<Arg3>::type arg3_; + typename internal::remove_reference<Arg4>::type arg4_; +}; + // Then route the appropriate overloads of NewPermanentCallback() to // use the above. @@ -237,6 +260,19 @@ typename Callback0::Type* NewPermanentCallback( (object, method, arg1, arg2, arg3); } +template <class T1, class T2, typename Arg1, typename Arg2, typename Arg3, + typename Arg4> +typename Callback0::Type* NewPermanentCallback( + T1* object, + void (T2::*method)(Arg1, Arg2, Arg3, Arg4), + typename internal::Identity<Arg1>::type arg1, + typename internal::Identity<Arg2>::type arg2, + typename internal::Identity<Arg3>::type arg3, + typename internal::Identity<Arg4>::type arg4) { + return new FourArgCallbackRunner<T1, Arg1, Arg2, Arg3, Arg4> + (object, method, arg1, arg2, arg3, arg4); +} + } // namespace invalidation #endif // GOOGLE_CACHEINVALIDATION_CALLBACK_H_ diff --git a/third_party/cacheinvalidation/overrides/google/cacheinvalidation/v2/logging.h b/third_party/cacheinvalidation/overrides/google/cacheinvalidation/v2/logging.h new file mode 100644 index 0000000..a2f27f0 --- /dev/null +++ b/third_party/cacheinvalidation/overrides/google/cacheinvalidation/v2/logging.h @@ -0,0 +1,16 @@ +// Copyright (c) 2011 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 GOOGLE_CACHEINVALIDATION_V2_LOGGING_H_ +#define GOOGLE_CACHEINVALIDATION_V2_LOGGING_H_ + +#include "base/logging.h" + +namespace invalidation { + +using logging::LogMessage; + +} // namespace invalidation + +#endif // GOOGLE_CACHEINVALIDATION_V2_LOGGING_H_ diff --git a/third_party/cacheinvalidation/overrides/google/cacheinvalidation/v2/mutex.h b/third_party/cacheinvalidation/overrides/google/cacheinvalidation/v2/mutex.h new file mode 100644 index 0000000..7eda283 --- /dev/null +++ b/third_party/cacheinvalidation/overrides/google/cacheinvalidation/v2/mutex.h @@ -0,0 +1,26 @@ +// Copyright (c) 2011 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 GOOGLE_CACHEINVALIDATION_V2_MUTEX_H_ +#define GOOGLE_CACHEINVALIDATION_V2_MUTEX_H_ + +#include "base/logging.h" +#include "base/synchronization/lock.h" + +namespace invalidation { + +typedef base::Lock Mutex; + +class MutexLock { + public: + explicit MutexLock(Mutex* m) : auto_lock_(*m) {} + + private: + base::AutoLock auto_lock_; + DISALLOW_COPY_AND_ASSIGN(MutexLock); +}; + +} // namespace invalidation + +#endif // GOOGLE_CACHEINVALIDATION_V2_MUTEX_H_ diff --git a/third_party/cacheinvalidation/overrides/google/cacheinvalidation/v2/scoped_ptr.h b/third_party/cacheinvalidation/overrides/google/cacheinvalidation/v2/scoped_ptr.h new file mode 100644 index 0000000..80ed3cc --- /dev/null +++ b/third_party/cacheinvalidation/overrides/google/cacheinvalidation/v2/scoped_ptr.h @@ -0,0 +1,16 @@ +// Copyright (c) 2011 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 GOOGLE_CACHEINVALIDATION_V2_SCOPED_PTR_H_ +#define GOOGLE_CACHEINVALIDATION_V2_SCOPED_PTR_H_ + +#include "base/memory/scoped_ptr.h" + +namespace invalidation { + +using ::scoped_ptr; + +} // namespace invalidation + +#endif // GOOGLE_CACHEINVALIDATION_V2_SCOPED_PTR_H_ diff --git a/third_party/cacheinvalidation/overrides/google/cacheinvalidation/v2/sha1-digest-function.h b/third_party/cacheinvalidation/overrides/google/cacheinvalidation/v2/sha1-digest-function.h new file mode 100644 index 0000000..62dee55 --- /dev/null +++ b/third_party/cacheinvalidation/overrides/google/cacheinvalidation/v2/sha1-digest-function.h @@ -0,0 +1,46 @@ +// Copyright 2011 Google Inc. All Rights Reserved. +// Author: ghc@google.com (Greg Cooper) +// +// Interface to SHA1 digest computation. + +#ifndef GOOGLE_CACHEINVALIDATION_V2_SHA1_DIGEST_FUNCTION_H_ +#define GOOGLE_CACHEINVALIDATION_V2_SHA1_DIGEST_FUNCTION_H_ + +#include <string> + +#include "base/sha1.h" +#include "google/cacheinvalidation/stl-namespace.h" +#include "google/cacheinvalidation/v2/digest-function.h" + +namespace invalidation { + +using ::INVALIDATION_STL_NAMESPACE::string; + +class Sha1DigestFunction : public DigestFunction { + public: + Sha1DigestFunction() : reset_needed_(false) {} + + virtual void Reset() { + reset_needed_ = false; + buffer_.clear(); + } + + virtual void Update(const string& s) { + CHECK(!reset_needed_); + buffer_.append(s); + } + + virtual string GetDigest() { + CHECK(!reset_needed_); + reset_needed_ = true; + return base::SHA1HashString(buffer_); + } + + private: + string buffer_; + bool reset_needed_; +}; + +} // namespace invalidation + +#endif // GOOGLE_CACHEINVALIDATION_V2_SHA1_DIGEST_FUNCTION_H_ diff --git a/third_party/cacheinvalidation/overrides/google/cacheinvalidation/v2/string_util.h b/third_party/cacheinvalidation/overrides/google/cacheinvalidation/v2/string_util.h new file mode 100644 index 0000000..1b7246d --- /dev/null +++ b/third_party/cacheinvalidation/overrides/google/cacheinvalidation/v2/string_util.h @@ -0,0 +1,18 @@ +// Copyright (c) 2011 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 GOOGLE_CACHEINVALIDATION_V2_STRING_UTIL_H_ +#define GOOGLE_CACHEINVALIDATION_V2_STRING_UTIL_H_ + +#include "base/string_number_conversions.h" +#include "base/stringprintf.h" + +namespace invalidation { + +using base::IntToString; +using base::StringAppendV; + +} // namespace invalidation + +#endif // GOOGLE_CACHEINVALIDATION_V2_STRING_UTIL_H_ diff --git a/third_party/cacheinvalidation/overrides/google/cacheinvalidation/v2/time.h b/third_party/cacheinvalidation/overrides/google/cacheinvalidation/v2/time.h new file mode 100644 index 0000000..b8644f5 --- /dev/null +++ b/third_party/cacheinvalidation/overrides/google/cacheinvalidation/v2/time.h @@ -0,0 +1,16 @@ +// Copyright (c) 2011 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 GOOGLE_CACHEINVALIDATION_V2_TIME_H_ +#define GOOGLE_CACHEINVALIDATION_V2_TIME_H_ + +#include "base/time.h" + +namespace invalidation { +typedef base::Time Time; +typedef base::TimeTicks TimeTicks; +typedef base::TimeDelta TimeDelta; +} // namespace invalidation + +#endif // GOOGLE_CACHEINVALIDATION_V2_TIME_H_ |