summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/sync/engine/auth_watcher_unittest.cc3
-rwxr-xr-xchrome/browser/sync/engine/syncapi.cc15
-rwxr-xr-xchrome/browser/sync/engine/syncapi.h4
-rw-r--r--chrome/browser/sync/glue/sync_backend_host.cc45
-rw-r--r--chrome/browser/sync/glue/sync_backend_host.h56
-rw-r--r--chrome/browser/sync/notification_method.cc49
-rw-r--r--chrome/browser/sync/notification_method.h53
-rw-r--r--chrome/browser/sync/notifier/listener/listen_task.cc30
-rw-r--r--chrome/browser/sync/notifier/listener/listen_task.h5
-rw-r--r--chrome/browser/sync/notifier/listener/mediator_thread.h12
-rw-r--r--chrome/browser/sync/notifier/listener/mediator_thread_impl.cc15
-rw-r--r--chrome/browser/sync/notifier/listener/mediator_thread_impl.h3
-rw-r--r--chrome/browser/sync/notifier/listener/mediator_thread_mock.h3
-rw-r--r--chrome/browser/sync/notifier/listener/notification_constants.cc17
-rw-r--r--chrome/browser/sync/notifier/listener/notification_constants.h20
-rw-r--r--chrome/browser/sync/notifier/listener/send_update_task.cc106
-rw-r--r--chrome/browser/sync/notifier/listener/send_update_task.h23
-rw-r--r--chrome/browser/sync/notifier/listener/send_update_task_unittest.cc132
-rw-r--r--chrome/browser/sync/notifier/listener/subscribe_task.cc83
-rw-r--r--chrome/browser/sync/notifier/listener/subscribe_task.h23
-rw-r--r--chrome/browser/sync/notifier/listener/subscribe_task_unittest.cc116
-rw-r--r--chrome/browser/sync/notifier/listener/talk_mediator_impl.cc4
-rw-r--r--chrome/browser/sync/notifier/listener/talk_mediator_impl.h3
-rw-r--r--chrome/browser/sync/notifier/listener/talk_mediator_unittest.cc3
-rw-r--r--chrome/browser/sync/notifier/listener/xml_element_util.cc51
-rw-r--r--chrome/browser/sync/notifier/listener/xml_element_util.h29
-rw-r--r--chrome/browser/sync/notifier/listener/xml_element_util_unittest.cc59
-rw-r--r--chrome/browser/sync/profile_sync_service.cc12
-rw-r--r--chrome/browser/sync/profile_sync_service.h4
-rw-r--r--chrome/browser/sync/profile_sync_service_unittest.cc3
-rwxr-xr-xchrome/chrome.gyp4
-rwxr-xr-xchrome/chrome_browser.gypi2
-rwxr-xr-xchrome/chrome_tests.gypi3
-rw-r--r--chrome/common/chrome_switches.cc3
-rw-r--r--chrome/common/chrome_switches.h1
35 files changed, 898 insertions, 96 deletions
diff --git a/chrome/browser/sync/engine/auth_watcher_unittest.cc b/chrome/browser/sync/engine/auth_watcher_unittest.cc
index 0e02f70..8de43e0 100644
--- a/chrome/browser/sync/engine/auth_watcher_unittest.cc
+++ b/chrome/browser/sync/engine/auth_watcher_unittest.cc
@@ -89,7 +89,8 @@ class AuthWatcherTest : public testing::Test {
FilePath user_settings_path = temp_dir_.path().Append(kUserSettingsDB);
user_settings_->Init(user_settings_path);
gaia_auth_ = new GaiaAuthMockForAuthWatcher();
- talk_mediator_.reset(new TalkMediatorImpl());
+ talk_mediator_.reset(new TalkMediatorImpl(
+ browser_sync::kDefaultNotificationMethod));
auth_watcher_ = new AuthWatcher(metadb_.manager(), connection_.get(),
allstatus_.get(), kTestUserAgent, kTestServiceId, kTestGaiaURL,
user_settings_.get(), gaia_auth_, talk_mediator_.get());
diff --git a/chrome/browser/sync/engine/syncapi.cc b/chrome/browser/sync/engine/syncapi.cc
index 4ae26a2..0fa7362 100755
--- a/chrome/browser/sync/engine/syncapi.cc
+++ b/chrome/browser/sync/engine/syncapi.cc
@@ -918,7 +918,8 @@ class SyncManager::SyncInternal {
bool attempt_last_user_authentication,
bool invalidate_last_user_auth_token,
const char* user_agent,
- const std::string& lsid);
+ const std::string& lsid,
+ browser_sync::NotificationMethod notification_method);
// Tell sync engine to submit credentials to GAIA for verification and start
// the syncing process on success. Successful GAIA authentication will kick
@@ -1159,7 +1160,8 @@ bool SyncManager::Init(const FilePath& database_location,
bool attempt_last_user_authentication,
bool invalidate_last_user_auth_token,
const char* user_agent,
- const char* lsid) {
+ const char* lsid,
+ browser_sync::NotificationMethod notification_method) {
DCHECK(post_factory);
string server_string(sync_server_and_path);
@@ -1175,7 +1177,8 @@ bool SyncManager::Init(const FilePath& database_location,
attempt_last_user_authentication,
invalidate_last_user_auth_token,
user_agent,
- lsid);
+ lsid,
+ notification_method);
}
void SyncManager::Authenticate(const char* username, const char* password,
@@ -1201,8 +1204,8 @@ bool SyncManager::SyncInternal::Init(
bool attempt_last_user_authentication,
bool invalidate_last_user_auth_token,
const char* user_agent,
- const std::string& lsid) {
-
+ const std::string& lsid,
+ browser_sync::NotificationMethod notification_method) {
// Set up UserSettings, creating the db if necessary. We need this to
// instantiate a URLFactory to give to the Syncer.
FilePath settings_db_file =
@@ -1254,7 +1257,7 @@ bool SyncManager::SyncInternal::Init(
const char* service_id = gaia_service_id ?
gaia_service_id : SYNC_SERVICE_NAME;
- talk_mediator_.reset(new TalkMediatorImpl());
+ talk_mediator_.reset(new TalkMediatorImpl(notification_method));
allstatus()->WatchTalkMediator(talk_mediator());
BridgedGaiaAuthenticator* gaia_auth = new BridgedGaiaAuthenticator(
diff --git a/chrome/browser/sync/engine/syncapi.h b/chrome/browser/sync/engine/syncapi.h
index 96b869b..5307f7b 100755
--- a/chrome/browser/sync/engine/syncapi.h
+++ b/chrome/browser/sync/engine/syncapi.h
@@ -46,6 +46,7 @@
#include "base/scoped_ptr.h"
#include "build/build_config.h"
#include "chrome/browser/google_service_auth_error.h"
+#include "chrome/browser/sync/notification_method.h"
#include "chrome/browser/sync/syncable/model_type.h"
#include "googleurl/src/gurl.h"
@@ -592,7 +593,8 @@ class SyncManager {
bool attempt_last_user_authentication,
bool invalidate_last_user_auth_token,
const char* user_agent,
- const char* lsid);
+ const char* lsid,
+ browser_sync::NotificationMethod notification_method);
// Returns the username last used for a successful authentication.
// Returns empty if there is no such username.
diff --git a/chrome/browser/sync/glue/sync_backend_host.cc b/chrome/browser/sync/glue/sync_backend_host.cc
index 7206b1c..c72567a 100644
--- a/chrome/browser/sync/glue/sync_backend_host.cc
+++ b/chrome/browser/sync/glue/sync_backend_host.cc
@@ -44,7 +44,8 @@ void SyncBackendHost::Initialize(
URLRequestContextGetter* baseline_context_getter,
const std::string& lsid,
bool delete_sync_data_folder,
- bool invalidate_sync_login) {
+ bool invalidate_sync_login,
+ NotificationMethod notification_method) {
if (!core_thread_.Start())
return;
@@ -64,12 +65,14 @@ void SyncBackendHost::Initialize(
core_thread_.message_loop()->PostTask(FROM_HERE,
NewRunnableMethod(core_.get(), &SyncBackendHost::Core::DoInitialize,
- sync_service_url, true,
- new HttpBridgeFactory(baseline_context_getter),
- new HttpBridgeFactory(baseline_context_getter),
- lsid,
- delete_sync_data_folder,
- invalidate_sync_login));
+ Core::DoInitializeOptions(
+ sync_service_url, true,
+ new HttpBridgeFactory(baseline_context_getter),
+ new HttpBridgeFactory(baseline_context_getter),
+ lsid,
+ delete_sync_data_folder,
+ invalidate_sync_login,
+ notification_method)));
}
void SyncBackendHost::Authenticate(const std::string& username,
@@ -232,19 +235,12 @@ std::string MakeUserAgentForSyncapi() {
return user_agent;
}
-void SyncBackendHost::Core::DoInitialize(
- const GURL& service_url,
- bool attempt_last_user_authentication,
- sync_api::HttpPostProviderFactory* http_provider_factory,
- sync_api::HttpPostProviderFactory* auth_http_provider_factory,
- const std::string& lsid,
- bool delete_sync_data_folder,
- bool invalidate_sync_login) {
+void SyncBackendHost::Core::DoInitialize(const DoInitializeOptions& options) {
DCHECK(MessageLoop::current() == host_->core_thread_.message_loop());
// Blow away the partial or corrupt sync data folder before doing any more
// initialization, if necessary.
- if (delete_sync_data_folder)
+ if (options.delete_sync_data_folder)
DeleteSyncDataFolder();
// Make sure that the directory exists before initializing the backend.
@@ -255,18 +251,19 @@ void SyncBackendHost::Core::DoInitialize(
syncapi_->SetObserver(this);
const FilePath& path_str = host_->sync_data_folder_path();
success = syncapi_->Init(path_str,
- (service_url.host() + service_url.path()).c_str(),
- service_url.EffectiveIntPort(),
+ (options.service_url.host() + options.service_url.path()).c_str(),
+ options.service_url.EffectiveIntPort(),
kGaiaServiceId,
kGaiaSourceForChrome,
- service_url.SchemeIsSecure(),
- http_provider_factory,
- auth_http_provider_factory,
+ options.service_url.SchemeIsSecure(),
+ options.http_bridge_factory,
+ options.auth_http_bridge_factory,
host_, // ModelSafeWorkerRegistrar.
- attempt_last_user_authentication,
- invalidate_sync_login,
+ options.attempt_last_user_authentication,
+ options.invalidate_sync_login,
MakeUserAgentForSyncapi().c_str(),
- lsid.c_str());
+ options.lsid.c_str(),
+ options.notification_method);
DCHECK(success) << "Syncapi initialization failed!";
}
diff --git a/chrome/browser/sync/glue/sync_backend_host.h b/chrome/browser/sync/glue/sync_backend_host.h
index c7c145b..fe832c5 100644
--- a/chrome/browser/sync/glue/sync_backend_host.h
+++ b/chrome/browser/sync/glue/sync_backend_host.h
@@ -17,6 +17,7 @@
#include "base/timer.h"
#include "chrome/browser/google_service_auth_error.h"
#include "chrome/browser/net/url_request_context_getter.h"
+#include "chrome/browser/sync/notification_method.h"
#include "chrome/browser/sync/engine/syncapi.h"
#include "chrome/browser/sync/engine/model_safe_worker.h"
#include "chrome/browser/sync/glue/ui_model_worker.h"
@@ -82,7 +83,8 @@ class SyncBackendHost : public browser_sync::ModelSafeWorkerRegistrar {
URLRequestContextGetter* baseline_context_getter,
const std::string& lsid,
bool delete_sync_data_folder,
- bool invalidate_sync_login);
+ bool invalidate_sync_login,
+ NotificationMethod notification_method);
// Called on |frontend_loop_| to kick off asynchronous authentication.
void Authenticate(const std::string& username, const std::string& password,
@@ -133,7 +135,8 @@ class SyncBackendHost : public browser_sync::ModelSafeWorkerRegistrar {
void InitializeForTestMode(const std::wstring& test_user,
sync_api::HttpPostProviderFactory* factory,
sync_api::HttpPostProviderFactory* auth_factory,
- bool delete_sync_data_folder) {
+ bool delete_sync_data_folder,
+ NotificationMethod notification_method) {
if (!core_thread_.Start())
return;
registrar_.workers[GROUP_UI] = new UIModelWorker(frontend_loop_);
@@ -145,7 +148,8 @@ class SyncBackendHost : public browser_sync::ModelSafeWorkerRegistrar {
test_user,
factory,
auth_factory,
- delete_sync_data_folder));
+ delete_sync_data_folder,
+ notification_method));
}
#endif
@@ -167,6 +171,35 @@ class SyncBackendHost : public browser_sync::ModelSafeWorkerRegistrar {
virtual void OnInitializationComplete();
virtual void OnAuthError(const GoogleServiceAuthError& auth_error);
+ struct DoInitializeOptions {
+ DoInitializeOptions(
+ const GURL& service_url,
+ bool attempt_last_user_authentication,
+ sync_api::HttpPostProviderFactory* http_bridge_factory,
+ sync_api::HttpPostProviderFactory* auth_http_bridge_factory,
+ const std::string& lsid,
+ bool delete_sync_data_folder,
+ bool invalidate_sync_login,
+ NotificationMethod notification_method)
+ : service_url(service_url),
+ attempt_last_user_authentication(attempt_last_user_authentication),
+ http_bridge_factory(http_bridge_factory),
+ auth_http_bridge_factory(auth_http_bridge_factory),
+ lsid(lsid),
+ delete_sync_data_folder(delete_sync_data_folder),
+ invalidate_sync_login(invalidate_sync_login),
+ notification_method(notification_method) {}
+
+ GURL service_url;
+ bool attempt_last_user_authentication;
+ sync_api::HttpPostProviderFactory* http_bridge_factory;
+ sync_api::HttpPostProviderFactory* auth_http_bridge_factory;
+ std::string lsid;
+ bool delete_sync_data_folder;
+ bool invalidate_sync_login;
+ NotificationMethod notification_method;
+ };
+
// Note:
//
// The Do* methods are the various entry points from our SyncBackendHost.
@@ -175,13 +208,7 @@ class SyncBackendHost : public browser_sync::ModelSafeWorkerRegistrar {
//
// Called on the SyncBackendHost core_thread_ to perform initialization
// of the syncapi on behalf of SyncBackendHost::Initialize.
- void DoInitialize(const GURL& service_url,
- bool attempt_last_user_authentication,
- sync_api::HttpPostProviderFactory* http_bridge_factory,
- sync_api::HttpPostProviderFactory* auth_http_bridge_factory,
- const std::string& lsid,
- bool delete_sync_data_folder,
- bool invalidate_sync_login);
+ void DoInitialize(const DoInitializeOptions& options);
// Called on our SyncBackendHost's core_thread_ to perform authentication
// on behalf of SyncBackendHost::Authenticate.
@@ -218,9 +245,12 @@ class SyncBackendHost : public browser_sync::ModelSafeWorkerRegistrar {
void DoInitializeForTest(const std::wstring& test_user,
sync_api::HttpPostProviderFactory* factory,
sync_api::HttpPostProviderFactory* auth_factory,
- bool delete_sync_data_folder) {
- DoInitialize(GURL(), false, factory, auth_factory, std::string(),
- delete_sync_data_folder, false);
+ bool delete_sync_data_folder,
+ NotificationMethod notification_method) {
+ DoInitialize(
+ DoInitializeOptions(GURL(), false, factory, auth_factory,
+ std::string(), delete_sync_data_folder, false,
+ notification_method));
syncapi_->SetupForTestMode(test_user);
}
#endif
diff --git a/chrome/browser/sync/notification_method.cc b/chrome/browser/sync/notification_method.cc
new file mode 100644
index 0000000..28f6c15
--- /dev/null
+++ b/chrome/browser/sync/notification_method.cc
@@ -0,0 +1,49 @@
+// Copyright (c) 2010 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/notification_method.h"
+
+#include "base/logging.h"
+
+namespace browser_sync {
+
+// TODO(akalin): Eventually change this to NOTIFICATION_TRANSITIONAL,
+// then NOTIFICATION_NEW.
+const NotificationMethod kDefaultNotificationMethod = NOTIFICATION_LEGACY;
+
+std::string NotificationMethodToString(
+ NotificationMethod notification_method) {
+ switch (notification_method) {
+ case NOTIFICATION_LEGACY:
+ return "NOTIFICATION_LEGACY";
+ break;
+ case NOTIFICATION_TRANSITIONAL:
+ return "NOTIFICATION_TRANSITIONAL";
+ break;
+ case NOTIFICATION_NEW:
+ return "NOTIFICATION_NEW";
+ break;
+ default:
+ LOG(WARNING) << "Unknown value for notification method: "
+ << notification_method;
+ break;
+ }
+ return "<unknown notification method>";
+}
+
+NotificationMethod StringToNotificationMethod(const std::string& str) {
+ if (str == "legacy") {
+ return NOTIFICATION_LEGACY;
+ } else if (str == "transitional") {
+ return NOTIFICATION_TRANSITIONAL;
+ } else if (str == "new") {
+ return NOTIFICATION_NEW;
+ }
+ LOG(WARNING) << "Unknown notification method \"" << str
+ << "\"; using method "
+ << NotificationMethodToString(kDefaultNotificationMethod);
+ return kDefaultNotificationMethod;
+}
+
+} // namespace browser_sync
diff --git a/chrome/browser/sync/notification_method.h b/chrome/browser/sync/notification_method.h
new file mode 100644
index 0000000..569f8d2
--- /dev/null
+++ b/chrome/browser/sync/notification_method.h
@@ -0,0 +1,53 @@
+// Copyright (c) 2010 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_NOTIFICATION_METHOD_H_
+#define CHROME_BROWSER_SYNC_NOTIFICATION_METHOD_H_
+
+#include <string>
+
+namespace browser_sync {
+
+// This is the matrix for the interaction between clients with
+// different notification methods:
+//
+// Listen
+// L T N
+// +-------+
+// L | E E E |
+// Send T | Y Y Y |
+// N | E Y Y |
+// +-------+
+//
+// 'Y' means a client listening with the column notification method
+// will receive notifications from a client sending with the row
+// notification method. 'E' means means that the notification will be
+// an empty one, which may be dropped by the server in the future.
+
+enum NotificationMethod {
+ // Old, broken notification method. Works only if notification
+ // servers don't drop empty notifications.
+ NOTIFICATION_LEGACY,
+ // Compatible with new notifications. Also compatible with legacy
+ // notifications if the notification servers don't drop empty
+ // notifications.
+ NOTIFICATION_TRANSITIONAL,
+ // New, ideal notification method. Compatible only with
+ // transitional notifications.
+ NOTIFICATION_NEW,
+};
+
+extern const NotificationMethod kDefaultNotificationMethod;
+
+std::string NotificationMethodToString(
+ NotificationMethod notification_method);
+
+// If the given string is not one of "legacy", "transitional", or
+// "new", returns kDefaultNotificationMethod.
+NotificationMethod StringToNotificationMethod(const std::string& str);
+
+} // namespace browser_sync
+
+#endif // CHROME_BROWSER_SYNC_NOTIFICATION_METHOD_H_
+
diff --git a/chrome/browser/sync/notifier/listener/listen_task.cc b/chrome/browser/sync/notifier/listener/listen_task.cc
index 70fd081..48468a8 100644
--- a/chrome/browser/sync/notifier/listener/listen_task.cc
+++ b/chrome/browser/sync/notifier/listener/listen_task.cc
@@ -5,7 +5,9 @@
#include "chrome/browser/sync/notifier/listener/listen_task.h"
#include "base/logging.h"
-#include "base/string_util.h"
+#include "chrome/browser/sync/notification_method.h"
+#include "chrome/browser/sync/notifier/listener/notification_constants.h"
+#include "chrome/browser/sync/notifier/listener/xml_element_util.h"
#include "talk/base/task.h"
#include "talk/xmllite/qname.h"
#include "talk/xmllite/xmlelement.h"
@@ -15,8 +17,9 @@
namespace browser_sync {
-ListenTask::ListenTask(Task* parent)
- : buzz::XmppTask(parent, buzz::XmppEngine::HL_TYPE) {
+ListenTask::ListenTask(Task* parent, NotificationMethod notification_method)
+ : buzz::XmppTask(parent, buzz::XmppEngine::HL_TYPE),
+ notification_method_(notification_method) {
}
ListenTask::~ListenTask() {
@@ -33,7 +36,7 @@ int ListenTask::ProcessResponse() {
if (stanza == NULL) {
return STATE_BLOCKED;
}
- // Acknowledge receipt of the notificaiton to the buzz server.
+ // Acknowledge receipt of the notification to the buzz server.
scoped_ptr<buzz::XmlElement> response_stanza(MakeIqResult(stanza));
SendStanza(response_stanza.get());
@@ -43,6 +46,9 @@ int ListenTask::ProcessResponse() {
}
bool ListenTask::HandleStanza(const buzz::XmlElement* stanza) {
+ LOG(INFO) << "P2P: Stanza received: " << XmlElementToString(*stanza);
+ // TODO(akalin): Do more verification on stanza depending on
+ // notification_method_.
if (IsValidNotification(stanza)) {
QueueStanza(stanza);
return true;
@@ -51,8 +57,8 @@ bool ListenTask::HandleStanza(const buzz::XmlElement* stanza) {
}
bool ListenTask::IsValidNotification(const buzz::XmlElement* stanza) {
- static const std::string kNSNotifier("google:notifier");
- static const buzz::QName kQnNotifierGetAll(true, kNSNotifier, "getAll");
+ static const buzz::QName kQnNotifierGetAll(
+ true, kNotifierNamespace, "getAll");
// An update notificaiton has the following form.
// <cli:iq from="{bare_jid}" to="{full_jid}"
// id="#" type="set" xmlns:cli="jabber:client">
@@ -60,14 +66,10 @@ bool ListenTask::IsValidNotification(const buzz::XmlElement* stanza) {
// <Timestamp long="#" xmlns=""/>
// </not:getAll>
// </cli:iq>
- if (MatchRequestIq(stanza, buzz::STR_SET, kQnNotifierGetAll) &&
- !base::strcasecmp(stanza->Attr(buzz::QN_TO).c_str(),
- GetClient()->jid().Str().c_str()) &&
- !base::strcasecmp(stanza->Attr(buzz::QN_FROM).c_str(),
- GetClient()->jid().BareJid().Str().c_str())) {
- return true;
- }
- return false;
+ return
+ (MatchRequestIq(stanza, buzz::STR_SET, kQnNotifierGetAll) &&
+ (stanza->Attr(buzz::QN_TO) == GetClient()->jid().Str()) &&
+ (stanza->Attr(buzz::QN_FROM) == GetClient()->jid().BareJid().Str()));
}
} // namespace browser_sync
diff --git a/chrome/browser/sync/notifier/listener/listen_task.h b/chrome/browser/sync/notifier/listener/listen_task.h
index f8b32ce89..8f5bcd3 100644
--- a/chrome/browser/sync/notifier/listener/listen_task.h
+++ b/chrome/browser/sync/notifier/listener/listen_task.h
@@ -12,6 +12,7 @@
#ifndef CHROME_BROWSER_SYNC_NOTIFIER_LISTENER_LISTEN_TASK_H_
#define CHROME_BROWSER_SYNC_NOTIFIER_LISTENER_LISTEN_TASK_H_
+#include "chrome/browser/sync/notification_method.h"
#include "talk/xmpp/xmpptask.h"
namespace buzz {
@@ -23,7 +24,7 @@ namespace browser_sync {
class ListenTask : public buzz::XmppTask {
public:
- explicit ListenTask(Task* parent);
+ ListenTask(Task* parent, NotificationMethod notification_method);
virtual ~ListenTask();
// Overriden from buzz::XmppTask.
@@ -39,6 +40,8 @@ class ListenTask : public buzz::XmppTask {
// this notification came from our own Jid().
bool IsValidNotification(const buzz::XmlElement* stanza);
+ NotificationMethod notification_method_;
+
DISALLOW_COPY_AND_ASSIGN(ListenTask);
};
diff --git a/chrome/browser/sync/notifier/listener/mediator_thread.h b/chrome/browser/sync/notifier/listener/mediator_thread.h
index 1e6d89a..66682929 100644
--- a/chrome/browser/sync/notifier/listener/mediator_thread.h
+++ b/chrome/browser/sync/notifier/listener/mediator_thread.h
@@ -8,6 +8,8 @@
#ifndef CHROME_BROWSER_SYNC_NOTIFIER_LISTENER_MEDIATOR_THREAD_H_
#define CHROME_BROWSER_SYNC_NOTIFIER_LISTENER_MEDIATOR_THREAD_H_
+#include "base/logging.h"
+#include "chrome/browser/sync/notification_method.h"
#include "talk/xmpp/xmppclientsettings.h"
namespace browser_sync {
@@ -23,7 +25,6 @@ class MediatorThread {
MSG_NOTIFICATION_SENT
};
- MediatorThread() {}
virtual ~MediatorThread() {}
virtual void Login(const buzz::XmppClientSettings& settings) = 0;
@@ -35,6 +36,15 @@ class MediatorThread {
// Connect to this for messages about talk events.
sigslot::signal1<MediatorMessage> SignalStateChange;
+
+ protected:
+ explicit MediatorThread(NotificationMethod notification_method)
+ : notification_method_(notification_method) {}
+
+ const NotificationMethod notification_method_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MediatorThread);
};
} // namespace browser_sync
diff --git a/chrome/browser/sync/notifier/listener/mediator_thread_impl.cc b/chrome/browser/sync/notifier/listener/mediator_thread_impl.cc
index d688b7e..a6df235 100644
--- a/chrome/browser/sync/notifier/listener/mediator_thread_impl.cc
+++ b/chrome/browser/sync/notifier/listener/mediator_thread_impl.cc
@@ -28,8 +28,9 @@ using std::string;
namespace browser_sync {
-MediatorThreadImpl::MediatorThreadImpl() {
-}
+MediatorThreadImpl::MediatorThreadImpl(
+ NotificationMethod notification_method)
+ : MediatorThread(notification_method) {}
MediatorThreadImpl::~MediatorThreadImpl() {
}
@@ -43,6 +44,9 @@ void MediatorThreadImpl::Run() {
// For win32, this sets up the win32socketserver. Note that it needs to
// dispatch windows messages since that is what the win32 socket server uses.
+ LOG(INFO) << "Running mediator thread with notification method "
+ << NotificationMethodToString(notification_method_);
+
MessageLoop message_loop;
#if defined(OS_WIN)
scoped_ptr<talk_base::SocketServer> socket_server(
@@ -211,7 +215,8 @@ void MediatorThreadImpl::DoSubscribeForUpdates() {
if (!client) {
return;
}
- SubscribeTask* subscription = new SubscribeTask(client);
+ SubscribeTask* subscription =
+ new SubscribeTask(client, notification_method_);
subscription->SignalStatusUpdate.connect(
this,
&MediatorThreadImpl::OnSubscriptionStateChange);
@@ -224,7 +229,7 @@ void MediatorThreadImpl::DoListenForUpdates() {
if (!client) {
return;
}
- ListenTask* listener = new ListenTask(client);
+ ListenTask* listener = new ListenTask(client, notification_method_);
listener->SignalUpdateAvailable.connect(
this,
&MediatorThreadImpl::OnUpdateListenerMessage);
@@ -237,7 +242,7 @@ void MediatorThreadImpl::DoSendNotification() {
if (!client) {
return;
}
- SendUpdateTask* task = new SendUpdateTask(client);
+ SendUpdateTask* task = new SendUpdateTask(client, notification_method_);
task->SignalStatusUpdate.connect(
this,
&MediatorThreadImpl::OnUpdateNotificationSent);
diff --git a/chrome/browser/sync/notifier/listener/mediator_thread_impl.h b/chrome/browser/sync/notifier/listener/mediator_thread_impl.h
index a31da53..f8cf359 100644
--- a/chrome/browser/sync/notifier/listener/mediator_thread_impl.h
+++ b/chrome/browser/sync/notifier/listener/mediator_thread_impl.h
@@ -20,6 +20,7 @@
#ifndef CHROME_BROWSER_SYNC_NOTIFIER_LISTENER_MEDIATOR_THREAD_IMPL_H_
#define CHROME_BROWSER_SYNC_NOTIFIER_LISTENER_MEDIATOR_THREAD_IMPL_H_
+#include "base/logging.h"
#include "base/scoped_ptr.h"
#include "chrome/browser/sync/notifier/communicator/login.h"
#include "chrome/browser/sync/notifier/communicator/login_failure.h"
@@ -67,7 +68,7 @@ class MediatorThreadImpl
public talk_base::MessageHandler,
public talk_base::Thread {
public:
- MediatorThreadImpl();
+ explicit MediatorThreadImpl(NotificationMethod notification_method);
virtual ~MediatorThreadImpl();
// Start the thread.
diff --git a/chrome/browser/sync/notifier/listener/mediator_thread_mock.h b/chrome/browser/sync/notifier/listener/mediator_thread_mock.h
index dea8a8e..ee5fde6 100644
--- a/chrome/browser/sync/notifier/listener/mediator_thread_mock.h
+++ b/chrome/browser/sync/notifier/listener/mediator_thread_mock.h
@@ -10,13 +10,14 @@
#define CHROME_BROWSER_SYNC_NOTIFIER_LISTENER_MEDIATOR_THREAD_MOCK_H_
#include "chrome/browser/sync/notifier/listener/mediator_thread.h"
+#include "chrome/browser/sync/notification_method.h"
#include "talk/xmpp/xmppclientsettings.h"
namespace browser_sync {
class MockMediatorThread : public MediatorThread {
public:
- MockMediatorThread() {
+ MockMediatorThread() : MediatorThread(kDefaultNotificationMethod) {
Reset();
}
~MockMediatorThread() {}
diff --git a/chrome/browser/sync/notifier/listener/notification_constants.cc b/chrome/browser/sync/notifier/listener/notification_constants.cc
new file mode 100644
index 0000000..bd253e5
--- /dev/null
+++ b/chrome/browser/sync/notifier/listener/notification_constants.cc
@@ -0,0 +1,17 @@
+// Copyright (c) 2010 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/listener/notification_constants.h"
+
+namespace browser_sync {
+
+const char kNotifierNamespace[] = "google:notifier";
+const char kSyncLegacyServiceUrl[] = "google:notifier";
+const char kSyncServiceUrl[] = "http://www.google.com/chrome/sync";
+const char kSyncLegacyServiceId[] = "notification";
+const char kSyncServiceId[] = "sync-ping";
+const int kSyncPriority = 200;
+const char kSyncServiceSpecificData[] = "sync-ping-p2p";
+
+} // namespace browser_sync
diff --git a/chrome/browser/sync/notifier/listener/notification_constants.h b/chrome/browser/sync/notifier/listener/notification_constants.h
new file mode 100644
index 0000000..afb40d2
--- /dev/null
+++ b/chrome/browser/sync/notifier/listener/notification_constants.h
@@ -0,0 +1,20 @@
+// Copyright (c) 2010 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_NOTIFIER_LISTENER_NOTIFICATION_CONSTANTS_H_
+#define CHROME_BROWSER_SYNC_NOTIFIER_LISTENER_NOTIFICATION_CONSTANTS_H_
+
+namespace browser_sync {
+
+extern const char kNotifierNamespace[];
+extern const char kSyncLegacyServiceUrl[];
+extern const char kSyncServiceUrl[];
+extern const char kSyncLegacyServiceId[];
+extern const char kSyncServiceId[];
+extern const int kSyncPriority;
+extern const char kSyncServiceSpecificData[];
+
+} // namespace browser_sync
+
+#endif // CHROME_BROWSER_SYNC_NOTIFIER_LISTENER_NOTIFICATION_CONSTANTS_H_
diff --git a/chrome/browser/sync/notifier/listener/send_update_task.cc b/chrome/browser/sync/notifier/listener/send_update_task.cc
index 835b226..6204310 100644
--- a/chrome/browser/sync/notifier/listener/send_update_task.cc
+++ b/chrome/browser/sync/notifier/listener/send_update_task.cc
@@ -4,16 +4,22 @@
#include "chrome/browser/sync/notifier/listener/send_update_task.h"
+#include <string>
+
#include "base/logging.h"
#include "base/scoped_ptr.h"
+#include "chrome/browser/sync/notifier/listener/notification_constants.h"
+#include "chrome/browser/sync/notifier/listener/xml_element_util.h"
#include "talk/xmllite/qname.h"
#include "talk/xmpp/xmppclient.h"
#include "talk/xmpp/xmppconstants.h"
namespace browser_sync {
-SendUpdateTask::SendUpdateTask(Task* parent)
- : XmppTask(parent, buzz::XmppEngine::HL_SINGLE) { // Watch for one reply.
+SendUpdateTask::SendUpdateTask(Task* parent,
+ NotificationMethod notification_method)
+ : XmppTask(parent, buzz::XmppEngine::HL_SINGLE), // Watch for one reply.
+ notification_method_(notification_method) {
}
SendUpdateTask::~SendUpdateTask() {
@@ -28,9 +34,17 @@ bool SendUpdateTask::HandleStanza(const buzz::XmlElement* stanza) {
int SendUpdateTask::ProcessStart() {
LOG(INFO) << "P2P: Notification task started.";
- scoped_ptr<buzz::XmlElement> stanza(NewUpdateMessage());
+ scoped_ptr<buzz::XmlElement> stanza(
+ MakeUpdateMessage(notification_method_,
+ GetClient()->jid().BareJid(), task_id()));
+ LOG(INFO) << "P2P: Notification stanza: "
+ << XmlElementToString(*stanza.get());
+
if (SendStanza(stanza.get()) != buzz::XMPP_RETURN_OK) {
// TODO(brg) : Retry on error.
+ // TODO(akalin): Or maybe immediately return STATE_ERROR and let
+ // retries happen a higher level. In any case, STATE_ERROR should
+ // eventually be returned.
SignalStatusUpdate(false);
return STATE_DONE;
}
@@ -43,6 +57,7 @@ int SendUpdateTask::ProcessResponse() {
if (stanza == NULL) {
return STATE_BLOCKED;
}
+ LOG(INFO) << "P2P: Notification response: " << XmlElementToString(*stanza);
if (stanza->HasAttr(buzz::QN_TYPE) &&
stanza->Attr(buzz::QN_TYPE) == buzz::STR_RESULT) {
// Notify listeners of success.
@@ -53,12 +68,32 @@ int SendUpdateTask::ProcessResponse() {
// An error response was received.
// TODO(brg) : Error handling.
SignalStatusUpdate(false);
+ // TODO(akalin): This should be STATE_ERROR.
return STATE_DONE;
}
-buzz::XmlElement* SendUpdateTask::NewUpdateMessage() {
- static const std::string kNSNotifier = "google:notifier";
- static const buzz::QName kQnNotifierSet(true, kNSNotifier, "set");
+buzz::XmlElement* SendUpdateTask::MakeUpdateMessage(
+ NotificationMethod notification_method,
+ const buzz::Jid& to_jid_bare, const std::string& task_id) {
+ switch (notification_method) {
+ case NOTIFICATION_LEGACY:
+ return MakeLegacyUpdateMessage(to_jid_bare, task_id);
+ case NOTIFICATION_TRANSITIONAL:
+ return MakeNonLegacyUpdateMessage(true, to_jid_bare, task_id);
+ case NOTIFICATION_NEW:
+ return MakeNonLegacyUpdateMessage(false, to_jid_bare, task_id);
+ }
+ NOTREACHED();
+ return NULL;
+}
+
+// TODO(akalin): Remove this once we get all clients on at least
+// NOTIFICATION_TRANSITIONAL.
+
+buzz::XmlElement* SendUpdateTask::MakeLegacyUpdateMessage(
+ const buzz::Jid& to_jid_bare, const std::string& task_id) {
+ DCHECK(to_jid_bare.IsBare());
+ static const buzz::QName kQnNotifierSet(true, kNotifierNamespace, "set");
static const buzz::QName kQnId(true, buzz::STR_EMPTY, "Id");
static const buzz::QName kQnServiceUrl(true, buzz::STR_EMPTY, "ServiceUrl");
static const buzz::QName kQnData(true, buzz::STR_EMPTY, "data");
@@ -74,8 +109,7 @@ buzz::XmlElement* SendUpdateTask::NewUpdateMessage() {
// </Id>
// </set>
// </iq>
- buzz::XmlElement* stanza =
- MakeIq(buzz::STR_GET, GetClient()->jid().BareJid(), task_id());
+ buzz::XmlElement* stanza = MakeIq(buzz::STR_GET, to_jid_bare, task_id);
buzz::XmlElement* notifier_set = new buzz::XmlElement(kQnNotifierSet, true);
stanza->AddElement(notifier_set);
@@ -83,13 +117,65 @@ buzz::XmlElement* SendUpdateTask::NewUpdateMessage() {
notifier_set->AddElement(id);
buzz::XmlElement* service_url = new buzz::XmlElement(kQnServiceUrl, true);
- service_url->AddAttr(kQnData, kNSNotifier);
+ service_url->AddAttr(kQnData, kSyncLegacyServiceUrl);
id->AddElement(service_url);
buzz::XmlElement* service_id = new buzz::XmlElement(kQnServiceId, true);
- service_id->AddAttr(kQnData, "notification");
+ service_id->AddAttr(kQnData, kSyncLegacyServiceId);
id->AddElement(service_id);
return stanza;
}
+// TODO(akalin): Remove the is_transitional switch once we get all
+// clients on at least NOTIFICATION_NEW.
+
+buzz::XmlElement* SendUpdateTask::MakeNonLegacyUpdateMessage(
+ bool is_transitional,
+ const buzz::Jid& to_jid_bare, const std::string& task_id) {
+ DCHECK(to_jid_bare.IsBare());
+ static const buzz::QName kQnNotifierSet(true, kNotifierNamespace, "set");
+ static const buzz::QName kQnId(true, buzz::STR_EMPTY, "Id");
+ static const buzz::QName kQnContent(true, buzz::STR_EMPTY, "Content");
+
+ // Create our update stanza. In the future this may include the revision id,
+ // but at the moment simply does a p2p ping. The message is constructed as:
+ // <iq type='get' from='{fullJid}' to='{bareJid}' id='{#}'>
+ // <gn:set xmlns:gn="google:notifier" xmlns="">
+ // <Id>
+ // <ServiceUrl data="http://www.google.com/chrome/sync" />
+ // <ServiceId data="sync-ping" />
+ // </Id>
+ // <Content>
+ // <Priority int="200" />
+ // <!-- If is_transitional is not set, the bool value is "true". -->
+ // <RequireSubscription bool="false" />
+ // <!-- If is_transitional is set, this is omitted. -->
+ // <ServiceSpecificData data="sync-ping-p2p" />
+ // <WriteToCacheOnly bool="true" />
+ // </Content>
+ // </set>
+ // </iq>
+ buzz::XmlElement* iq = MakeIq(buzz::STR_GET, to_jid_bare, task_id);
+ buzz::XmlElement* set = new buzz::XmlElement(kQnNotifierSet, true);
+ buzz::XmlElement* id = new buzz::XmlElement(kQnId, true);
+ buzz::XmlElement* content = new buzz::XmlElement(kQnContent, true);
+ iq->AddElement(set);
+ set->AddElement(id);
+ set->AddElement(content);
+
+ id->AddElement(MakeStringXmlElement("ServiceUrl", kSyncServiceUrl));
+ id->AddElement(MakeStringXmlElement("ServiceId", kSyncServiceId));
+
+ content->AddElement(MakeIntXmlElement("Priority", kSyncPriority));
+ content->AddElement(
+ MakeBoolXmlElement("RequireSubscription", !is_transitional));
+ if (!is_transitional) {
+ content->AddElement(
+ MakeStringXmlElement("ServiceSpecificData", kSyncServiceSpecificData));
+ }
+ content->AddElement(MakeBoolXmlElement("WriteToCacheOnly", true));
+
+ return iq;
+}
+
} // namespace browser_sync
diff --git a/chrome/browser/sync/notifier/listener/send_update_task.h b/chrome/browser/sync/notifier/listener/send_update_task.h
index de4a518..ae422af 100644
--- a/chrome/browser/sync/notifier/listener/send_update_task.h
+++ b/chrome/browser/sync/notifier/listener/send_update_task.h
@@ -7,14 +7,18 @@
#ifndef CHROME_BROWSER_SYNC_NOTIFIER_LISTENER_SEND_UPDATE_TASK_H_
#define CHROME_BROWSER_SYNC_NOTIFIER_LISTENER_SEND_UPDATE_TASK_H_
+#include <string>
+
+#include "chrome/browser/sync/notification_method.h"
#include "talk/xmllite/xmlelement.h"
#include "talk/xmpp/xmpptask.h"
+#include "testing/gtest/include/gtest/gtest_prod.h"
namespace browser_sync {
class SendUpdateTask : public buzz::XmppTask {
public:
- explicit SendUpdateTask(Task* parent);
+ SendUpdateTask(Task* parent, NotificationMethod notification_method);
virtual ~SendUpdateTask();
// Overridden from buzz::XmppTask.
@@ -27,7 +31,22 @@ class SendUpdateTask : public buzz::XmppTask {
private:
// Allocates and constructs an buzz::XmlElement containing the update stanza.
- buzz::XmlElement* NewUpdateMessage();
+ static buzz::XmlElement* MakeUpdateMessage(
+ NotificationMethod notification_method,
+ const buzz::Jid& to_jid_bare, const std::string& task_id);
+
+ static buzz::XmlElement* MakeLegacyUpdateMessage(
+ const buzz::Jid& to_jid_bare, const std::string& task_id);
+
+ static buzz::XmlElement* MakeNonLegacyUpdateMessage(
+ bool is_transitional,
+ const buzz::Jid& to_jid_bare, const std::string& task_id);
+
+ NotificationMethod notification_method_;
+
+ FRIEND_TEST(SendUpdateTaskTest, MakeUpdateMessage);
+ FRIEND_TEST(SendUpdateTaskTest, MakeLegacyUpdateMessage);
+ FRIEND_TEST(SendUpdateTaskTest, MakeNonLegacyUpdateMessage);
DISALLOW_COPY_AND_ASSIGN(SendUpdateTask);
};
diff --git a/chrome/browser/sync/notifier/listener/send_update_task_unittest.cc b/chrome/browser/sync/notifier/listener/send_update_task_unittest.cc
new file mode 100644
index 0000000..50dd379
--- /dev/null
+++ b/chrome/browser/sync/notifier/listener/send_update_task_unittest.cc
@@ -0,0 +1,132 @@
+// Copyright (c) 2010 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/listener/send_update_task.h"
+
+#include "base/logging.h"
+#include "base/scoped_ptr.h"
+#include "base/string_util.h"
+#include "chrome/browser/sync/notification_method.h"
+#include "chrome/browser/sync/notifier/listener/xml_element_util.h"
+#include "talk/xmpp/jid.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace buzz {
+class XmlElement;
+}
+
+namespace browser_sync {
+
+class SendUpdateTaskTest : public testing::Test {
+ public:
+ SendUpdateTaskTest() : to_jid_bare_("to@jid.com"), task_id_("taskid") {
+ EXPECT_EQ(to_jid_bare_.Str(), to_jid_bare_.BareJid().Str());
+ }
+
+ protected:
+ const buzz::Jid to_jid_bare_;
+ const std::string task_id_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SendUpdateTaskTest);
+};
+
+TEST_F(SendUpdateTaskTest, MakeLegacyUpdateMessage) {
+ scoped_ptr<buzz::XmlElement> message(
+ SendUpdateTask::MakeLegacyUpdateMessage(to_jid_bare_, task_id_));
+ const std::string expected_xml_string =
+ StringPrintf(
+ "<cli:iq type=\"get\" to=\"%s\" id=\"%s\" "
+ "xmlns:cli=\"jabber:client\">"
+ "<set xmlns=\"google:notifier\">"
+ "<Id xmlns=\"\">"
+ "<ServiceUrl xmlns=\"\" data=\"google:notifier\"/>"
+ "<ServiceId xmlns=\"\" data=\"notification\"/>"
+ "</Id>"
+ "</set>"
+ "</cli:iq>",
+ to_jid_bare_.Str().c_str(), task_id_.c_str());
+ EXPECT_EQ(expected_xml_string, XmlElementToString(*message));
+}
+
+TEST_F(SendUpdateTaskTest, MakeNonLegacyUpdateMessage) {
+ scoped_ptr<buzz::XmlElement> new_message(
+ SendUpdateTask::MakeNonLegacyUpdateMessage(false, to_jid_bare_,
+ task_id_));
+ const std::string expected_new_xml_string =
+ StringPrintf(
+ "<cli:iq type=\"get\" to=\"%s\" id=\"%s\" "
+ "xmlns:cli=\"jabber:client\">"
+ "<set xmlns=\"google:notifier\">"
+ "<Id xmlns=\"\">"
+ "<ServiceUrl xmlns=\"\" "
+ "data=\"http://www.google.com/chrome/sync\"/>"
+ "<ServiceId xmlns=\"\" data=\"sync-ping\"/>"
+ "</Id>"
+ "<Content xmlns=\"\">"
+ "<Priority xmlns=\"\" int=\"200\"/>"
+ "<RequireSubscription xmlns=\"\" bool=\"true\"/>"
+ "<ServiceSpecificData xmlns=\"\" "
+ "data=\"sync-ping-p2p\"/>"
+ "<WriteToCacheOnly xmlns=\"\" bool=\"true\"/>"
+ "</Content>"
+ "</set>"
+ "</cli:iq>",
+ to_jid_bare_.Str().c_str(), task_id_.c_str());
+ EXPECT_EQ(expected_new_xml_string, XmlElementToString(*new_message));
+
+ scoped_ptr<buzz::XmlElement> transitional_message(
+ SendUpdateTask::MakeNonLegacyUpdateMessage(true, to_jid_bare_,
+ task_id_));
+ const std::string expected_transitional_xml_string =
+ StringPrintf(
+ "<cli:iq type=\"get\" to=\"%s\" id=\"%s\" "
+ "xmlns:cli=\"jabber:client\">"
+ "<set xmlns=\"google:notifier\">"
+ "<Id xmlns=\"\">"
+ "<ServiceUrl xmlns=\"\" "
+ "data=\"http://www.google.com/chrome/sync\"/>"
+ "<ServiceId xmlns=\"\" data=\"sync-ping\"/>"
+ "</Id>"
+ "<Content xmlns=\"\">"
+ "<Priority xmlns=\"\" int=\"200\"/>"
+ "<RequireSubscription xmlns=\"\" bool=\"false\"/>"
+ "<WriteToCacheOnly xmlns=\"\" bool=\"true\"/>"
+ "</Content>"
+ "</set>"
+ "</cli:iq>",
+ to_jid_bare_.Str().c_str(), task_id_.c_str());
+ EXPECT_EQ(expected_transitional_xml_string,
+ XmlElementToString(*transitional_message));
+}
+
+TEST_F(SendUpdateTaskTest, MakeUpdateMessage) {
+ scoped_ptr<buzz::XmlElement> expected_legacy_message(
+ SendUpdateTask::MakeLegacyUpdateMessage(to_jid_bare_, task_id_));
+ scoped_ptr<buzz::XmlElement> legacy_message(
+ SendUpdateTask::MakeUpdateMessage(NOTIFICATION_LEGACY,
+ to_jid_bare_, task_id_));
+ EXPECT_EQ(XmlElementToString(*expected_legacy_message),
+ XmlElementToString(*legacy_message));
+
+ scoped_ptr<buzz::XmlElement> expected_transitional_message(
+ SendUpdateTask::MakeNonLegacyUpdateMessage(true,
+ to_jid_bare_, task_id_));
+ scoped_ptr<buzz::XmlElement> transitional_message(
+ SendUpdateTask::MakeUpdateMessage(NOTIFICATION_TRANSITIONAL,
+ to_jid_bare_, task_id_));
+ EXPECT_EQ(XmlElementToString(*expected_transitional_message),
+ XmlElementToString(*transitional_message));
+
+ scoped_ptr<buzz::XmlElement> expected_new_message(
+ SendUpdateTask::MakeNonLegacyUpdateMessage(false,
+ to_jid_bare_, task_id_));
+ scoped_ptr<buzz::XmlElement> new_message(
+ SendUpdateTask::MakeUpdateMessage(NOTIFICATION_NEW,
+ to_jid_bare_, task_id_));
+ EXPECT_EQ(XmlElementToString(*expected_new_message),
+ XmlElementToString(*new_message));
+}
+
+} // namespace browser_sync
diff --git a/chrome/browser/sync/notifier/listener/subscribe_task.cc b/chrome/browser/sync/notifier/listener/subscribe_task.cc
index 9fb828b..e0f0bf9 100644
--- a/chrome/browser/sync/notifier/listener/subscribe_task.cc
+++ b/chrome/browser/sync/notifier/listener/subscribe_task.cc
@@ -7,6 +7,8 @@
#include <string>
#include "base/logging.h"
+#include "chrome/browser/sync/notifier/listener/notification_constants.h"
+#include "chrome/browser/sync/notifier/listener/xml_element_util.h"
#include "talk/base/task.h"
#include "talk/xmllite/qname.h"
#include "talk/xmllite/xmlelement.h"
@@ -16,8 +18,10 @@
namespace browser_sync {
-SubscribeTask::SubscribeTask(Task* parent)
- : XmppTask(parent, buzz::XmppEngine::HL_SINGLE) {
+SubscribeTask::SubscribeTask(Task* parent,
+ NotificationMethod notification_method)
+ : XmppTask(parent, buzz::XmppEngine::HL_SINGLE),
+ notification_method_(notification_method) {
}
SubscribeTask::~SubscribeTask() {
@@ -32,10 +36,15 @@ bool SubscribeTask::HandleStanza(const buzz::XmlElement* stanza) {
int SubscribeTask::ProcessStart() {
LOG(INFO) << "P2P: Subscription task started.";
- scoped_ptr<buzz::XmlElement> iq_stanza(NewSubscriptionMessage());
+ scoped_ptr<buzz::XmlElement> iq_stanza(
+ MakeSubscriptionMessage(notification_method_,
+ GetClient()->jid().BareJid(), task_id()));
+ LOG(INFO) << "P2P: Subscription stanza: "
+ << XmlElementToString(*iq_stanza.get());
if (SendStanza(iq_stanza.get()) != buzz::XMPP_RETURN_OK) {
SignalStatusUpdate(false);
+ // TODO(akalin): This should be STATE_ERROR.
return STATE_DONE;
}
return STATE_RESPONSE;
@@ -47,6 +56,7 @@ int SubscribeTask::ProcessResponse() {
if (stanza == NULL) {
return STATE_BLOCKED;
}
+ LOG(INFO) << "P2P: Subscription response: " << XmlElementToString(*stanza);
// We've receieved a response to our subscription request.
if (stanza->HasAttr(buzz::QN_TYPE) &&
stanza->Attr(buzz::QN_TYPE) == buzz::STR_RESULT) {
@@ -56,25 +66,47 @@ int SubscribeTask::ProcessResponse() {
// An error response was received.
// TODO(brg) : Error handling.
SignalStatusUpdate(false);
+ // TODO(akalin): This should be STATE_ERROR.
return STATE_DONE;
}
-buzz::XmlElement* SubscribeTask::NewSubscriptionMessage() {
- static const buzz::QName kQnNotifierGetAll(true, "google:notifier", "getAll");
+buzz::XmlElement* SubscribeTask::MakeSubscriptionMessage(
+ NotificationMethod notification_method,
+ const buzz::Jid& to_jid_bare, const std::string& task_id) {
+ switch (notification_method) {
+ case NOTIFICATION_LEGACY:
+ return MakeLegacySubscriptionMessage(to_jid_bare, task_id);
+ case NOTIFICATION_TRANSITIONAL:
+ return MakeNonLegacySubscriptionMessage(true, to_jid_bare, task_id);
+ case NOTIFICATION_NEW:
+ return MakeNonLegacySubscriptionMessage(false, to_jid_bare, task_id);
+ }
+ NOTREACHED();
+ return NULL;
+}
+
+// TODO(akalin): Remove this once we get all clients on at least
+// NOTIFICATION_TRANSITIONAL.
+
+buzz::XmlElement* SubscribeTask::MakeLegacySubscriptionMessage(
+ const buzz::Jid& to_jid_bare, const std::string& task_id) {
+ DCHECK(to_jid_bare.IsBare());
+ static const buzz::QName kQnNotifierGetAll(
+ true, kNotifierNamespace, "getAll");
static const buzz::QName kQnNotifierClientActive(true,
buzz::STR_EMPTY,
"ClientActive");
static const buzz::QName kQnBool(true, buzz::STR_EMPTY, "bool");
static const std::string kTrueString("true");
- // Create the subscription stanza using the notificaitons protocol.
+ // Create the subscription stanza using the notifications protocol.
// <iq type='get' from='{fullJid}' to='{bareJid}' id='{#}'>
// <gn:getAll xmlns:gn='google:notifier' xmlns=''>
// <ClientActive bool='true'/>
// </gn:getAll>
// </iq>
buzz::XmlElement* get_all_request =
- MakeIq(buzz::STR_GET, GetClient()->jid().BareJid(), task_id());
+ MakeIq(buzz::STR_GET, to_jid_bare, task_id);
buzz::XmlElement* notifier_get =
new buzz::XmlElement(kQnNotifierGetAll, true);
@@ -88,4 +120,41 @@ buzz::XmlElement* SubscribeTask::NewSubscriptionMessage() {
return get_all_request;
}
+// TODO(akalin): Remove the is_transitional switch once we get all
+// clients on at least NOTIFICATION_NEW.
+
+buzz::XmlElement* SubscribeTask::MakeNonLegacySubscriptionMessage(
+ bool is_transitional, const buzz::Jid& to_jid_bare,
+ const std::string& task_id) {
+ DCHECK(to_jid_bare.IsBare());
+ static const buzz::QName kQnNotifierGetAll(
+ true, kNotifierNamespace, "getAll");
+
+ // Create the subscription stanza using the notifications protocol.
+ // <iq type='get' from='{fullJid}' to='{bareJid}' id='{#}'>
+ // <gn:getAll xmlns:gn="google:notifier" xmlns="">
+ // <ClientActive bool="true" />
+ // <!-- present only if is_transitional is set -->
+ // <SubscribedServiceUrl data="google:notifier">
+ // <SubscribedServiceUrl data="http://www.google.com/chrome/sync">
+ // <FilterNonSubscribed bool="true" />
+ // </gn:getAll>
+ // </iq>
+
+ buzz::XmlElement* iq = MakeIq(buzz::STR_GET, to_jid_bare, task_id);
+ buzz::XmlElement* get_all = new buzz::XmlElement(kQnNotifierGetAll, true);
+ iq->AddElement(get_all);
+
+ get_all->AddElement(MakeBoolXmlElement("ClientActive", true));
+ if (is_transitional) {
+ get_all->AddElement(
+ MakeStringXmlElement("SubscribedServiceUrl", kSyncLegacyServiceUrl));
+ }
+ get_all->AddElement(
+ MakeStringXmlElement("SubscribedServiceUrl", kSyncServiceUrl));
+ get_all->AddElement(MakeBoolXmlElement("FilterNonSubscribed", true));
+
+ return iq;
+}
+
} // namespace browser_sync
diff --git a/chrome/browser/sync/notifier/listener/subscribe_task.h b/chrome/browser/sync/notifier/listener/subscribe_task.h
index 793694e..dbef8d6 100644
--- a/chrome/browser/sync/notifier/listener/subscribe_task.h
+++ b/chrome/browser/sync/notifier/listener/subscribe_task.h
@@ -9,14 +9,18 @@
#ifndef CHROME_BROWSER_SYNC_NOTIFIER_LISTENER_SUBSCRIBE_TASK_H_
#define CHROME_BROWSER_SYNC_NOTIFIER_LISTENER_SUBSCRIBE_TASK_H_
+#include <string>
+
+#include "chrome/browser/sync/notification_method.h"
#include "talk/xmllite/xmlelement.h"
#include "talk/xmpp/xmpptask.h"
+#include "testing/gtest/include/gtest/gtest_prod.h"
namespace browser_sync {
class SubscribeTask : public buzz::XmppTask {
public:
- explicit SubscribeTask(Task* parent);
+ SubscribeTask(Task* parent, NotificationMethod notification_method);
virtual ~SubscribeTask();
// Overridden from XmppTask.
@@ -29,7 +33,22 @@ class SubscribeTask : public buzz::XmppTask {
private:
// Assembles an Xmpp stanza which can be sent to subscribe to notifications.
- buzz::XmlElement* NewSubscriptionMessage();
+ static buzz::XmlElement* MakeSubscriptionMessage(
+ NotificationMethod notification_method,
+ const buzz::Jid& to_jid_bare, const std::string& task_id);
+
+ static buzz::XmlElement* MakeLegacySubscriptionMessage(
+ const buzz::Jid& to_jid_bare, const std::string& task_id);
+
+ static buzz::XmlElement* MakeNonLegacySubscriptionMessage(
+ bool is_transitional,
+ const buzz::Jid& to_jid_bare, const std::string& task_id);
+
+ NotificationMethod notification_method_;
+
+ FRIEND_TEST(SubscribeTaskTest, MakeLegacySubscriptionMessage);
+ FRIEND_TEST(SubscribeTaskTest, MakeNonLegacySubscriptionMessage);
+ FRIEND_TEST(SubscribeTaskTest, MakeSubscriptionMessage);
DISALLOW_COPY_AND_ASSIGN(SubscribeTask);
};
diff --git a/chrome/browser/sync/notifier/listener/subscribe_task_unittest.cc b/chrome/browser/sync/notifier/listener/subscribe_task_unittest.cc
new file mode 100644
index 0000000..21bffc2
--- /dev/null
+++ b/chrome/browser/sync/notifier/listener/subscribe_task_unittest.cc
@@ -0,0 +1,116 @@
+// Copyright (c) 2010 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/listener/subscribe_task.h"
+
+#include "base/logging.h"
+#include "base/scoped_ptr.h"
+#include "base/string_util.h"
+#include "chrome/browser/sync/notification_method.h"
+#include "chrome/browser/sync/notifier/listener/xml_element_util.h"
+#include "talk/xmpp/jid.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace buzz {
+class XmlElement;
+}
+
+namespace browser_sync {
+
+class SubscribeTaskTest : public testing::Test {
+ public:
+ SubscribeTaskTest() : to_jid_bare_("to@jid.com"), task_id_("taskid") {
+ EXPECT_EQ(to_jid_bare_.Str(), to_jid_bare_.BareJid().Str());
+ }
+
+ protected:
+ const buzz::Jid to_jid_bare_;
+ const std::string task_id_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SubscribeTaskTest);
+};
+
+TEST_F(SubscribeTaskTest, MakeLegacySubscriptionMessage) {
+ scoped_ptr<buzz::XmlElement> message(
+ SubscribeTask::MakeLegacySubscriptionMessage(to_jid_bare_, task_id_));
+ const std::string expected_xml_string =
+ StringPrintf(
+ "<cli:iq type=\"get\" to=\"%s\" id=\"%s\" "
+ "xmlns:cli=\"jabber:client\">"
+ "<getAll xmlns=\"google:notifier\">"
+ "<ClientActive xmlns=\"\" bool=\"true\"/>"
+ "</getAll>"
+ "</cli:iq>",
+ to_jid_bare_.Str().c_str(), task_id_.c_str());
+ EXPECT_EQ(expected_xml_string, XmlElementToString(*message));
+}
+
+TEST_F(SubscribeTaskTest, MakeNonLegacySubscriptionMessage) {
+ scoped_ptr<buzz::XmlElement> new_message(
+ SubscribeTask::MakeNonLegacySubscriptionMessage(false, to_jid_bare_,
+ task_id_));
+ const std::string expected_new_xml_string =
+ StringPrintf(
+ "<cli:iq type=\"get\" to=\"%s\" id=\"%s\" "
+ "xmlns:cli=\"jabber:client\">"
+ "<getAll xmlns=\"google:notifier\">"
+ "<ClientActive xmlns=\"\" bool=\"true\"/>"
+ "<SubscribedServiceUrl "
+ "xmlns=\"\" data=\"http://www.google.com/chrome/sync\"/>"
+ "<FilterNonSubscribed xmlns=\"\" bool=\"true\"/>"
+ "</getAll>"
+ "</cli:iq>",
+ to_jid_bare_.Str().c_str(), task_id_.c_str());
+ EXPECT_EQ(expected_new_xml_string, XmlElementToString(*new_message));
+
+ scoped_ptr<buzz::XmlElement> transitional_message(
+ SubscribeTask::MakeNonLegacySubscriptionMessage(true, to_jid_bare_,
+ task_id_));
+ const std::string expected_transitional_xml_string =
+ StringPrintf(
+ "<cli:iq type=\"get\" to=\"%s\" id=\"%s\" "
+ "xmlns:cli=\"jabber:client\">"
+ "<getAll xmlns=\"google:notifier\">"
+ "<ClientActive xmlns=\"\" bool=\"true\"/>"
+ "<SubscribedServiceUrl xmlns=\"\" data=\"google:notifier\"/>"
+ "<SubscribedServiceUrl "
+ "xmlns=\"\" data=\"http://www.google.com/chrome/sync\"/>"
+ "<FilterNonSubscribed xmlns=\"\" bool=\"true\"/>"
+ "</getAll>"
+ "</cli:iq>",
+ to_jid_bare_.Str().c_str(), task_id_.c_str());
+ EXPECT_EQ(expected_transitional_xml_string,
+ XmlElementToString(*transitional_message));
+}
+
+TEST_F(SubscribeTaskTest, MakeSubscriptionMessage) {
+ scoped_ptr<buzz::XmlElement> expected_legacy_message(
+ SubscribeTask::MakeLegacySubscriptionMessage(to_jid_bare_, task_id_));
+ scoped_ptr<buzz::XmlElement> legacy_message(
+ SubscribeTask::MakeSubscriptionMessage(NOTIFICATION_LEGACY,
+ to_jid_bare_, task_id_));
+ EXPECT_EQ(XmlElementToString(*expected_legacy_message),
+ XmlElementToString(*legacy_message));
+
+ scoped_ptr<buzz::XmlElement> expected_transitional_message(
+ SubscribeTask::MakeNonLegacySubscriptionMessage(true,
+ to_jid_bare_, task_id_));
+ scoped_ptr<buzz::XmlElement> transitional_message(
+ SubscribeTask::MakeSubscriptionMessage(NOTIFICATION_TRANSITIONAL,
+ to_jid_bare_, task_id_));
+ EXPECT_EQ(XmlElementToString(*expected_transitional_message),
+ XmlElementToString(*transitional_message));
+
+ scoped_ptr<buzz::XmlElement> expected_new_message(
+ SubscribeTask::MakeNonLegacySubscriptionMessage(false,
+ to_jid_bare_, task_id_));
+ scoped_ptr<buzz::XmlElement> new_message(
+ SubscribeTask::MakeSubscriptionMessage(NOTIFICATION_NEW,
+ to_jid_bare_, task_id_));
+ EXPECT_EQ(XmlElementToString(*expected_new_message),
+ XmlElementToString(*new_message));
+}
+
+} // namespace browser_sync
diff --git a/chrome/browser/sync/notifier/listener/talk_mediator_impl.cc b/chrome/browser/sync/notifier/listener/talk_mediator_impl.cc
index a147e66..f8506fe 100644
--- a/chrome/browser/sync/notifier/listener/talk_mediator_impl.cc
+++ b/chrome/browser/sync/notifier/listener/talk_mediator_impl.cc
@@ -41,8 +41,8 @@ class SslInitializationSingleton {
DISALLOW_COPY_AND_ASSIGN(SslInitializationSingleton);
};
-TalkMediatorImpl::TalkMediatorImpl()
- : mediator_thread_(new MediatorThreadImpl()) {
+TalkMediatorImpl::TalkMediatorImpl(NotificationMethod notification_method)
+ : mediator_thread_(new MediatorThreadImpl(notification_method)) {
// Ensure the SSL library is initialized.
SslInitializationSingleton::GetInstance()->RegisterClient();
diff --git a/chrome/browser/sync/notifier/listener/talk_mediator_impl.h b/chrome/browser/sync/notifier/listener/talk_mediator_impl.h
index 922624e..6b9ce20 100644
--- a/chrome/browser/sync/notifier/listener/talk_mediator_impl.h
+++ b/chrome/browser/sync/notifier/listener/talk_mediator_impl.h
@@ -14,6 +14,7 @@
#include "base/lock.h"
#include "base/scoped_ptr.h"
#include "chrome/browser/sync/engine/auth_watcher.h"
+#include "chrome/browser/sync/notification_method.h"
#include "chrome/browser/sync/notifier/listener/mediator_thread.h"
#include "chrome/browser/sync/notifier/listener/talk_mediator.h"
#include "talk/xmpp/xmppclientsettings.h"
@@ -31,7 +32,7 @@ class TalkMediatorImpl
: public TalkMediator,
public sigslot::has_slots<> {
public:
- TalkMediatorImpl();
+ explicit TalkMediatorImpl(NotificationMethod notification_method);
explicit TalkMediatorImpl(MediatorThread* thread);
virtual ~TalkMediatorImpl();
diff --git a/chrome/browser/sync/notifier/listener/talk_mediator_unittest.cc b/chrome/browser/sync/notifier/listener/talk_mediator_unittest.cc
index 280a8a9..4c37eba 100644
--- a/chrome/browser/sync/notifier/listener/talk_mediator_unittest.cc
+++ b/chrome/browser/sync/notifier/listener/talk_mediator_unittest.cc
@@ -36,7 +36,8 @@ class TalkMediatorImplTest : public testing::Test {
TEST_F(TalkMediatorImplTest, ConstructionOfTheClass) {
// Constructing a single talk mediator enables SSL through the singleton.
- scoped_ptr<TalkMediatorImpl> talk1(new TalkMediatorImpl());
+ scoped_ptr<TalkMediatorImpl> talk1(new TalkMediatorImpl(
+ browser_sync::kDefaultNotificationMethod));
talk1.reset(NULL);
}
diff --git a/chrome/browser/sync/notifier/listener/xml_element_util.cc b/chrome/browser/sync/notifier/listener/xml_element_util.cc
new file mode 100644
index 0000000..a00f899
--- /dev/null
+++ b/chrome/browser/sync/notifier/listener/xml_element_util.cc
@@ -0,0 +1,51 @@
+// Copyright (c) 2010 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/listener/xml_element_util.h"
+
+#include <sstream>
+#include <string>
+
+#include "base/string_util.h"
+#include "talk/xmllite/qname.h"
+#include "talk/xmllite/xmlconstants.h"
+#include "talk/xmllite/xmlelement.h"
+#include "talk/xmllite/xmlprinter.h"
+
+namespace browser_sync {
+
+std::string XmlElementToString(const buzz::XmlElement& xml_element) {
+ std::ostringstream xml_stream;
+ buzz::XmlPrinter::PrintXml(&xml_stream, &xml_element);
+ return xml_stream.str();
+}
+
+buzz::XmlElement* MakeBoolXmlElement(const char* name, bool value) {
+ const buzz::QName elementQName(true, buzz::STR_EMPTY, name);
+ const buzz::QName boolAttrQName(true, buzz::STR_EMPTY, "bool");
+ buzz::XmlElement* bool_xml_element =
+ new buzz::XmlElement(elementQName, true);
+ bool_xml_element->AddAttr(boolAttrQName, value ? "true" : "false");
+ return bool_xml_element;
+}
+
+buzz::XmlElement* MakeIntXmlElement(const char* name, int value) {
+ const buzz::QName elementQName(true, buzz::STR_EMPTY, name);
+ const buzz::QName intAttrQName(true, buzz::STR_EMPTY, "int");
+ buzz::XmlElement* int_xml_element =
+ new buzz::XmlElement(elementQName, true);
+ int_xml_element->AddAttr(intAttrQName, IntToString(value));
+ return int_xml_element;
+}
+
+buzz::XmlElement* MakeStringXmlElement(const char* name, const char* value) {
+ const buzz::QName elementQName(true, buzz::STR_EMPTY, name);
+ const buzz::QName dataAttrQName(true, buzz::STR_EMPTY, "data");
+ buzz::XmlElement* data_xml_element =
+ new buzz::XmlElement(elementQName, true);
+ data_xml_element->AddAttr(dataAttrQName, value);
+ return data_xml_element;
+}
+
+} // namespace browser_sync
diff --git a/chrome/browser/sync/notifier/listener/xml_element_util.h b/chrome/browser/sync/notifier/listener/xml_element_util.h
new file mode 100644
index 0000000..cfd0d05
--- /dev/null
+++ b/chrome/browser/sync/notifier/listener/xml_element_util.h
@@ -0,0 +1,29 @@
+// Copyright (c) 2010 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_NOTIFIER_LISTENER_XML_ELEMENT_UTIL_H_
+#define CHROME_BROWSER_SYNC_NOTIFIER_LISTENER_XML_ELEMENT_UTIL_H_
+
+#include <string>
+
+namespace buzz {
+class XmlElement;
+}
+
+namespace browser_sync {
+
+std::string XmlElementToString(const buzz::XmlElement& xml_element);
+
+// The functions below are helpful for building notifications-related
+// XML stanzas.
+
+buzz::XmlElement* MakeBoolXmlElement(const char* name, bool value);
+
+buzz::XmlElement* MakeIntXmlElement(const char* name, int value);
+
+buzz::XmlElement* MakeStringXmlElement(const char* name, const char* value);
+
+} // namespace browser_sync
+
+#endif // CHROME_BROWSER_SYNC_NOTIFIER_LISTENER_XML_ELEMENT_UTIL_H_
diff --git a/chrome/browser/sync/notifier/listener/xml_element_util_unittest.cc b/chrome/browser/sync/notifier/listener/xml_element_util_unittest.cc
new file mode 100644
index 0000000..7faf073
--- /dev/null
+++ b/chrome/browser/sync/notifier/listener/xml_element_util_unittest.cc
@@ -0,0 +1,59 @@
+// Copyright (c) 2010 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/listener/xml_element_util.h"
+
+#include <sstream>
+#include <string>
+
+#include "base/logging.h"
+#include "base/scoped_ptr.h"
+#include "talk/xmllite/qname.h"
+#include "talk/xmllite/xmlelement.h"
+#include "talk/xmllite/xmlprinter.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace buzz {
+class XmlElement;
+}
+
+namespace browser_sync {
+namespace {
+
+class XmlElementUtilTest : public testing::Test {};
+
+TEST_F(XmlElementUtilTest, XmlElementToString) {
+ const buzz::QName kQName(true, "namespace", "element");
+ const buzz::XmlElement kXmlElement(kQName, true);
+ std::ostringstream expected_xml_stream;
+ buzz::XmlPrinter::PrintXml(&expected_xml_stream, &kXmlElement);
+ EXPECT_EQ(expected_xml_stream.str(), XmlElementToString(kXmlElement));
+}
+
+TEST_F(XmlElementUtilTest, MakeBoolXmlElement) {
+ scoped_ptr<buzz::XmlElement> foo_false(
+ MakeBoolXmlElement("foo", false));
+ EXPECT_EQ("<foo xmlns=\"\" bool=\"false\"/>", XmlElementToString(*foo_false));
+
+ scoped_ptr<buzz::XmlElement> bar_true(
+ MakeBoolXmlElement("bar", true));
+ EXPECT_EQ("<bar xmlns=\"\" bool=\"true\"/>", XmlElementToString(*bar_true));
+}
+
+TEST_F(XmlElementUtilTest, MakeIntXmlElement) {
+ scoped_ptr<buzz::XmlElement> int_xml_element(
+ MakeIntXmlElement("foo", 35));
+ EXPECT_EQ("<foo xmlns=\"\" int=\"35\"/>",
+ XmlElementToString(*int_xml_element));
+}
+
+TEST_F(XmlElementUtilTest, MakeStringXmlElement) {
+ scoped_ptr<buzz::XmlElement> string_xml_element(
+ MakeStringXmlElement("foo", "bar"));
+ EXPECT_EQ("<foo xmlns=\"\" data=\"bar\"/>",
+ XmlElementToString(*string_xml_element));
+}
+
+} // namespace
+} // namespace browser_sync
diff --git a/chrome/browser/sync/profile_sync_service.cc b/chrome/browser/sync/profile_sync_service.cc
index df65f79..c6baf7f 100644
--- a/chrome/browser/sync/profile_sync_service.cc
+++ b/chrome/browser/sync/profile_sync_service.cc
@@ -42,7 +42,8 @@ ProfileSyncService::ProfileSyncService(Profile* profile)
expecting_first_run_auth_needed_event_(false),
is_auth_in_progress_(false),
ALLOW_THIS_IN_INITIALIZER_LIST(wizard_(this)),
- unrecoverable_error_detected_(false) {
+ unrecoverable_error_detected_(false),
+ notification_method_(browser_sync::kDefaultNotificationMethod) {
}
ProfileSyncService::~ProfileSyncService() {
@@ -93,6 +94,13 @@ void ProfileSyncService::InitSettings() {
}
}
}
+
+ if (command_line.HasSwitch(switches::kSyncNotificationMethod)) {
+ const std::string notification_method_str(
+ command_line.GetSwitchValueASCII(switches::kSyncNotificationMethod));
+ notification_method_ =
+ browser_sync::StringToNotificationMethod(notification_method_str);
+ }
}
void ProfileSyncService::RegisterPreferences() {
@@ -143,7 +151,7 @@ void ProfileSyncService::InitializeBackend(bool delete_sync_data_folder) {
#endif
backend_->Initialize(sync_service_url_, profile_->GetRequestContext(),
GetLsidForAuthBootstraping(), delete_sync_data_folder,
- invalidate_sync_login);
+ invalidate_sync_login, notification_method_);
}
void ProfileSyncService::StartUp() {
diff --git a/chrome/browser/sync/profile_sync_service.h b/chrome/browser/sync/profile_sync_service.h
index 0c1f8ae..349e819f 100644
--- a/chrome/browser/sync/profile_sync_service.h
+++ b/chrome/browser/sync/profile_sync_service.h
@@ -16,6 +16,7 @@
#include "chrome/browser/profile.h"
#include "chrome/browser/sync/glue/data_type_controller.h" // For StartResult.
#include "chrome/browser/sync/glue/sync_backend_host.h"
+#include "chrome/browser/sync/notification_method.h"
#include "chrome/browser/sync/sync_setup_wizard.h"
#include "chrome/browser/sync/syncable/model_type.h"
#include "googleurl/src/gurl.h"
@@ -321,6 +322,9 @@ class ProfileSyncService : public browser_sync::SyncFrontend,
// doing any work that might corrupt things further.
bool unrecoverable_error_detected_;
+ // Which peer-to-peer notification method to use.
+ browser_sync::NotificationMethod notification_method_;
+
ObserverList<Observer> observers_;
DISALLOW_COPY_AND_ASSIGN(ProfileSyncService);
diff --git a/chrome/browser/sync/profile_sync_service_unittest.cc b/chrome/browser/sync/profile_sync_service_unittest.cc
index 584b77d..2e54c5b 100644
--- a/chrome/browser/sync/profile_sync_service_unittest.cc
+++ b/chrome/browser/sync/profile_sync_service_unittest.cc
@@ -20,6 +20,7 @@
#include "chrome/browser/sync/glue/bookmark_model_associator.h"
#include "chrome/browser/sync/glue/model_associator.h"
#include "chrome/browser/sync/glue/sync_backend_host.h"
+#include "chrome/browser/sync/notification_method.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/sync/profile_sync_factory.h"
#include "chrome/common/chrome_switches.h"
@@ -131,7 +132,7 @@ class TestProfileSyncService : public ProfileSyncService {
TestHttpBridgeFactory* factory = new TestHttpBridgeFactory();
TestHttpBridgeFactory* factory2 = new TestHttpBridgeFactory();
backend()->InitializeForTestMode(L"testuser", factory, factory2,
- delete_sync_data_folder);
+ delete_sync_data_folder, browser_sync::kDefaultNotificationMethod);
// The SyncBackend posts a task to the current loop when initialization
// completes.
MessageLoop::current()->Run();
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index f06dd1a..e2199b8 100755
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -801,6 +801,8 @@
'browser/sync/notifier/listener/mediator_thread_impl.cc',
'browser/sync/notifier/listener/mediator_thread_impl.h',
'browser/sync/notifier/listener/mediator_thread_mock.h',
+ 'browser/sync/notifier/listener/notification_constants.cc',
+ 'browser/sync/notifier/listener/notification_constants.h',
'browser/sync/notifier/listener/send_update_task.cc',
'browser/sync/notifier/listener/send_update_task.h',
'browser/sync/notifier/listener/subscribe_task.cc',
@@ -808,6 +810,8 @@
'browser/sync/notifier/listener/talk_mediator.h',
'browser/sync/notifier/listener/talk_mediator_impl.cc',
'browser/sync/notifier/listener/talk_mediator_impl.h',
+ 'browser/sync/notifier/listener/xml_element_util.cc',
+ 'browser/sync/notifier/listener/xml_element_util.h',
],
'include_dirs': [
'..',
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 0149981..d049ab4 100755
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -1685,6 +1685,8 @@
'browser/sync/glue/sync_backend_host.h',
'browser/sync/glue/ui_model_worker.cc',
'browser/sync/glue/ui_model_worker.h',
+ 'browser/sync/notification_method.h',
+ 'browser/sync/notification_method.cc',
'browser/sync/profile_sync_service.cc',
'browser/sync/profile_sync_service.h',
'browser/sync/profile_sync_factory.h',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 04a4491..fea4898 100755
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -1465,6 +1465,9 @@
'browser/sync/glue/change_processor_mock.h',
'browser/sync/notifier/base/mac/network_status_detector_task_mac_unittest.cc',
'browser/sync/notifier/listener/talk_mediator_unittest.cc',
+ 'browser/sync/notifier/listener/send_update_task_unittest.cc',
+ 'browser/sync/notifier/listener/subscribe_task_unittest.cc',
+ 'browser/sync/notifier/listener/xml_element_util_unittest.cc',
'browser/sync/profile_sync_factory_mock.cc',
'browser/sync/profile_sync_factory_mock.h',
'browser/sync/sessions/status_controller_unittest.cc',
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index c4b45b2..eba0a6e 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -604,6 +604,9 @@ const char kStartMaximized[] = "start-maximized";
// Override the default server used for profile sync.
const char kSyncServiceURL[] = "sync-url";
+// Override the default notification method for sync.
+const char kSyncNotificationMethod[] = "sync-notification-method";
+
// Use the SyncerThread implementation that matches up with the old pthread
// impl semantics, but using Chrome synchronization primitives. The only
// difference between this and the default is that we now have no timeout on
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index 5676bf3..0cd2873 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -176,6 +176,7 @@ extern const char kSimpleDataSource[];
extern const char kSingleProcess[];
extern const char kStartMaximized[];
extern const char kSyncServiceURL[];
+extern const char kSyncNotificationMethod[];
extern const char kSyncerThreadTimedStop[];
extern const char kTabCountToLoadOnSessionRestore[];
extern const char kTestName[];