sync_listen_notifications.cc revision 72a454cd3513ac24fbdd0e0cb9ad70b86a99b801
1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string> 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector> 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/at_exit.h" 9731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/base64.h" 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/command_line.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/message_loop.h" 133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/observer_list.h" 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h" 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/task.h" 163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/weak_ptr.h" 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/notifier/cache_invalidation_packet_handler.h" 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/notifier/chrome_invalidation_client.h" 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/notifier/chrome_system_resources.h" 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/sync_constants.h" 213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "jingle/notifier/base/xmpp_connection.h" 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "jingle/notifier/listener/listen_task.h" 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "jingle/notifier/listener/notification_constants.h" 24513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "jingle/notifier/listener/notification_defines.h" 25513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "jingle/notifier/listener/send_update_task.h" 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "jingle/notifier/listener/subscribe_task.h" 273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "jingle/notifier/listener/xml_element_util.h" 2821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "net/base/cert_verifier.h" 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/ssl_config_service.h" 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/socket/client_socket_factory.h" 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "talk/base/cryptstring.h" 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "talk/base/logging.h" 33513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "talk/base/sigslot.h" 343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "talk/base/task.h" 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "talk/xmpp/jid.h" 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "talk/xmpp/xmppclientsettings.h" 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "talk/xmpp/constants.h" 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "talk/xmpp/xmppengine.h" 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This is a simple utility that logs into an XMPP server, subscribes 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// to Sync notifications, and prints out any such notifications that 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// are received. 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace { 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Main class that listens for and handles messages from the XMPP 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// client. 483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass XmppNotificationClient : public notifier::XmppConnection::Delegate { 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // An observer is notified when we are logged into XMPP or when an 513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // error occurs. 523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick class Observer { 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual ~Observer() {} 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual void OnConnect(base::WeakPtr<talk_base::Task> base_task) = 0; 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual void OnError() = 0; 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick template <class T> XmppNotificationClient(T begin, T end) { 623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (T it = begin; it != end; ++it) { 633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick observer_list_.AddObserver(*it); 643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual ~XmppNotificationClient() {} 683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Connect with the given XMPP settings and run until disconnected. 7021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen void Run(const buzz::XmppClientSettings& xmpp_client_settings, 7121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net::CertVerifier* cert_verifier) { 723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(!xmpp_connection_.get()); 733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick xmpp_connection_.reset( 7421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen new notifier::XmppConnection(xmpp_client_settings, cert_verifier, 7521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen this, NULL)); 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->Run(); 773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(!xmpp_connection_.get()); 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual void OnConnect(base::WeakPtr<talk_base::Task> base_task) { 813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick FOR_EACH_OBSERVER(Observer, observer_list_, OnConnect(base_task)); 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual void OnError(buzz::XmppEngine::Error error, int subcode, 853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const buzz::XmlElement* stream_error) { 863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick LOG(INFO) << "Error: " << error << ", subcode: " << subcode; 873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (stream_error) { 883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick LOG(INFO) << "Stream error: " 893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << notifier::XmlElementToString(*stream_error); 903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick FOR_EACH_OBSERVER(Observer, observer_list_, OnError()); 923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // This has to go before the message loop quits. 933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick xmpp_connection_.reset(); 943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MessageLoop::current()->Quit(); 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick private: 983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ObserverList<Observer> observer_list_; 993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<notifier::XmppConnection> xmpp_connection_; 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DISALLOW_COPY_AND_ASSIGN(XmppNotificationClient); 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Delegate for legacy notifications. 105513209b27ff55e2841eac0e4120199c23acce758Ben Murdochclass LegacyNotifierDelegate 106513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch : public XmppNotificationClient::Observer, 107513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch public sigslot::has_slots<> { 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 109513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch explicit LegacyNotifierDelegate(bool send_initial_update) 110513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch : send_initial_update_(send_initial_update) {} 111513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual ~LegacyNotifierDelegate() {} 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual void OnConnect(base::WeakPtr<talk_base::Task> base_task) { 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(INFO) << "Logged in"; 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<std::string> subscribed_services_list; 117513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch subscribed_services_list.push_back(browser_sync::kSyncServiceUrl); 1183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Owned by base_task. 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch notifier::SubscribeTask* subscribe_task = 1203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new notifier::SubscribeTask(base_task, subscribed_services_list); 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch subscribe_task->Start(); 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Owned by xmpp_client. 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch notifier::ListenTask* listen_task = 1243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new notifier::ListenTask(base_task); 125513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch listen_task->SignalUpdateAvailable.connect( 126513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch this, &LegacyNotifierDelegate::OnUpdateAvailable); 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch listen_task->Start(); 128513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (send_initial_update_) { 129513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Owned by xmpp_client. 130513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch notifier::SendUpdateTask* send_update_task = 131513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch new notifier::SendUpdateTask(base_task, 132513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch OutgoingNotificationData()); 133513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch send_update_task->Start(); 134513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual void OnError() {} 138513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 139513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch void OnUpdateAvailable( 140513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const IncomingNotificationData& notification_data) { 141513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch LOG(INFO) << "Notification received: " 142513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch << notification_data.service_url << " " 143513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch << notification_data.service_specific_data; 144513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 145513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 146513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch private: 147513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch bool send_initial_update_; 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The actual listener for sync notifications. 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ChromeInvalidationListener 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : public sync_notifier::ChromeInvalidationClient::Listener { 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ChromeInvalidationListener() {} 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 15672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual void OnInvalidate(syncable::ModelType model_type, 15772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const std::string& payload) { 15872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LOG(INFO) << "OnInvalidate: " 15972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen << syncable::ModelTypeToString(model_type) << " - " << payload; 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // A real implementation would respond to the invalidation. 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void OnInvalidateAll() { 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(INFO) << "InvalidateAll"; 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // A real implementation would loop over the current registered 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // data types and send notifications for those. 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(ChromeInvalidationListener); 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 173513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// Delegate for server-issued notifications. 174513209b27ff55e2841eac0e4120199c23acce758Ben Murdochclass ServerNotifierDelegate 175731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick : public XmppNotificationClient::Observer, 176731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick public sync_notifier::StateWriter { 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 178513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch explicit ServerNotifierDelegate( 179513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const std::string& server_notifier_state) 180513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch : server_notifier_state_(server_notifier_state) {} 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 182513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch virtual ~ServerNotifierDelegate() {} 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual void OnConnect(base::WeakPtr<talk_base::Task> base_task) { 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(INFO) << "Logged in"; 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(akalin): app_name should be per-client unique. 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string kAppName = "cc_sync_listen_notifications"; 18972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const std::string kAppInfo = kAppName; 19072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen chrome_invalidation_client_.Start(kAppName, kAppInfo, 19172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen server_notifier_state_, 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &chrome_invalidation_listener_, 193731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick this, base_task); 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch chrome_invalidation_client_.RegisterTypes(); 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual void OnError() { 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch chrome_invalidation_client_.Stop(); 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 201731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick virtual void WriteState(const std::string& state) { 202731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string base64_state; 203731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CHECK(base::Base64Encode(state, &base64_state)); 204731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick LOG(INFO) << "New state: " << base64_state; 205731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 206731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ChromeInvalidationListener chrome_invalidation_listener_; 209731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Opaque blob capturing the notifications state of a previous run 210731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // (i.e., the base64-decoded value of a string output by 211731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // WriteState()). 212513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch std::string server_notifier_state_; 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_notifier::ChromeInvalidationClient chrome_invalidation_client_; 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint main(int argc, char* argv[]) { 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::AtExitManager exit_manager; 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CommandLine::Init(argc, argv); 22172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen logging::InitLogging( 22272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen NULL, 22372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG, 22472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen logging::LOCK_LOG_FILE, 22572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen logging::DELETE_OLD_LOG_FILE, 22672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS); 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(akalin): Make sure that all log messages are printed to the 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // console, even on Windows (SetMinLogLevel isn't enough). 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch talk_base::LogMessage::LogToDebug(talk_base::LS_VERBOSE); 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Parse command line. 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 233513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch std::string email = command_line.GetSwitchValueASCII("email"); 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (email.empty()) { 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch printf("Usage: %s --email=foo@bar.com [--password=mypassword] " 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "[--server=talk.google.com] [--port=5222] [--allow-plain] " 237513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "[--disable-tls] [--use-ssl-tcp] [--server-notifier-state] " 238513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "[--use-legacy-notifier] " 239513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch "[--legacy-notifier-send-initial-update]\n", 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch argv[0]); 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return -1; 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 243513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch std::string password = command_line.GetSwitchValueASCII("password"); 244513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch std::string server = command_line.GetSwitchValueASCII("server"); 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (server.empty()) { 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch server = "talk.google.com"; 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 248513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch std::string port_str = command_line.GetSwitchValueASCII("port"); 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int port = 5222; 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!port_str.empty()) { 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int port_from_port_str = std::strtol(port_str.c_str(), NULL, 10); 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (port_from_port_str == 0) { 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(WARNING) << "Invalid port " << port_str << "; using default"; 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch port = port_from_port_str; 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 258513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch bool allow_plain = command_line.HasSwitch("allow-plain"); 259513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch bool disable_tls = command_line.HasSwitch("disable-tls"); 260513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch bool use_ssl_tcp = command_line.HasSwitch("use-ssl-tcp"); 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (use_ssl_tcp && (port != 443)) { 262513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch LOG(WARNING) << "--use-ssl-tcp is set but port is " << port 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << " instead of 443"; 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 265513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch std::string server_notifier_state; 266513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch std::string server_notifier_state_encoded = 267513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch command_line.GetSwitchValueASCII("server-notifier-state"); 268513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!server_notifier_state_encoded.empty() && 269513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch !base::Base64Decode(server_notifier_state_encoded, 270513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch &server_notifier_state)) { 271731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick LOG(ERROR) << "Could not decode state: " 272513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch << server_notifier_state_encoded; 273731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 274513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch bool use_legacy_notifier = command_line.HasSwitch("use-legacy-notifier"); 275513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch bool legacy_notifier_send_initial_update = 276513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch command_line.HasSwitch("legacy-notifier-send-initial-update"); 277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Build XMPP client settings. 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch buzz::XmppClientSettings xmpp_client_settings; 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch buzz::Jid jid(email); 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch xmpp_client_settings.set_user(jid.node()); 282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch xmpp_client_settings.set_resource("cc_sync_listen_notifications"); 283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch xmpp_client_settings.set_host(jid.domain()); 284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch xmpp_client_settings.set_allow_plain(allow_plain); 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch xmpp_client_settings.set_use_tls(!disable_tls); 286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (use_ssl_tcp) { 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch xmpp_client_settings.set_protocol(cricket::PROTO_SSLTCP); 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch talk_base::InsecureCryptStringImpl insecure_crypt_string; 290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch insecure_crypt_string.password() = password; 291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch xmpp_client_settings.set_pass( 292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch talk_base::CryptString(insecure_crypt_string)); 293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch talk_base::SocketAddress addr(server, port); 294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!addr.ResolveIP()) { 295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(ERROR) << "Could not resolve " << addr.ToString(); 296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return -1; 297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch xmpp_client_settings.set_server(addr); 299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 30021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net::CertVerifier cert_verifier; 301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoopForIO message_loop; 302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Connect and listen. 304513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ServerNotifierDelegate server_notifier_delegate( 305513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch server_notifier_state); 306513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch LegacyNotifierDelegate legacy_notifier_delegate( 307513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch legacy_notifier_send_initial_update); 3083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::vector<XmppNotificationClient::Observer*> observers; 309513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (use_legacy_notifier) { 3103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick observers.push_back(&legacy_notifier_delegate); 311513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } else { 312513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch observers.push_back(&server_notifier_delegate); 313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 3143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick XmppNotificationClient xmpp_notification_client( 3153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick observers.begin(), observers.end()); 31621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen xmpp_notification_client.Run(xmpp_client_settings, &cert_verifier); 317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return 0; 319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 320