| Index: chrome/browser/sync/notifier/listener/mediator_thread_impl.cc
|
| ===================================================================
|
| --- chrome/browser/sync/notifier/listener/mediator_thread_impl.cc (revision 0)
|
| +++ chrome/browser/sync/notifier/listener/mediator_thread_impl.cc (revision 0)
|
| @@ -0,0 +1,278 @@
|
| +// Copyright (c) 2009 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/mediator_thread_impl.h"
|
| +
|
| +#include "base/logging.h"
|
| +#include "chrome/browser/sync/engine/net/gaia_authenticator.h"
|
| +#include "chrome/browser/sync/notifier/base/async_dns_lookup.h"
|
| +#include "chrome/browser/sync/notifier/base/task_pump.h"
|
| +#include "chrome/browser/sync/notifier/communicator/connection_options.h"
|
| +#include "chrome/browser/sync/notifier/communicator/const_communicator.h"
|
| +#include "chrome/browser/sync/notifier/communicator/xmpp_connection_generator.h"
|
| +#include "chrome/browser/sync/notifier/listener/listen_task.h"
|
| +#include "chrome/browser/sync/notifier/listener/send_update_task.h"
|
| +#include "chrome/browser/sync/notifier/listener/subscribe_task.h"
|
| +#include "chrome/browser/sync/protocol/service_constants.h"
|
| +#include "chrome/browser/sync/util/pthread_helpers.h"
|
| +#include "talk/base/thread.h"
|
| +#ifdef WIN32
|
| +#include "talk/base/win32socketserver.h"
|
| +#endif
|
| +#include "talk/xmpp/xmppclient.h"
|
| +#include "talk/xmpp/xmppclientsettings.h"
|
| +
|
| +using std::string;
|
| +
|
| +namespace browser_sync {
|
| +
|
| +MediatorThreadImpl::MediatorThreadImpl() {
|
| +}
|
| +
|
| +MediatorThreadImpl::~MediatorThreadImpl() {
|
| +}
|
| +
|
| +void MediatorThreadImpl::Start() {
|
| + talk_base::Thread::Start();
|
| +}
|
| +
|
| +void MediatorThreadImpl::Run() {
|
| + NameCurrentThreadForDebugging("SyncEngine_MediatorThread");
|
| + // For win32, this sets up the win32socketserver.
|
| + // Note that it needs to dispatch windows messages
|
| + // since that is what the win32 socket server uses.
|
| +#ifdef WIN32
|
| + scoped_ptr<talk_base::SocketServer> socket_server(
|
| + new talk_base::Win32SocketServer(this));
|
| + talk_base::SocketServer* old_socket_server = socketserver();
|
| + set_socketserver(socket_server.get());
|
| +
|
| + // Since we just changed the socket server,
|
| + // ensure that any queued up messages are processed.
|
| + socket_server->WakeUp();
|
| + ::MSG message;
|
| + while (::GetMessage(&message, NULL, 0, 0)) {
|
| + ::TranslateMessage(&message);
|
| + ::DispatchMessage(&message);
|
| + if (IsStopping()) {
|
| + break;
|
| + }
|
| + }
|
| +#endif
|
| +
|
| + ProcessMessages(talk_base::kForever);
|
| +
|
| +#ifdef WIN32
|
| + set_socketserver(old_socket_server);
|
| + socket_server.reset();
|
| +#endif
|
| +}
|
| +
|
| +void MediatorThreadImpl::Login(const buzz::XmppClientSettings& settings) {
|
| + Post(this, CMD_LOGIN, new LoginData(settings));
|
| +}
|
| +
|
| +void MediatorThreadImpl::Logout() {
|
| + Post(this, CMD_DISCONNECT);
|
| + Stop();
|
| +}
|
| +
|
| +void MediatorThreadImpl::ListenForUpdates() {
|
| + Post(this, CMD_LISTEN_FOR_UPDATES);
|
| +}
|
| +
|
| +void MediatorThreadImpl::SubscribeForUpdates() {
|
| + Post(this, CMD_SUBSCRIBE_FOR_UPDATES);
|
| +}
|
| +
|
| +void MediatorThreadImpl::SendNotification() {
|
| + Post(this, CMD_SEND_NOTIFICATION);
|
| +}
|
| +
|
| +void MediatorThreadImpl::ProcessMessages(int milliseconds) {
|
| + talk_base::Thread::ProcessMessages(milliseconds);
|
| +}
|
| +
|
| +void MediatorThreadImpl::OnMessage(talk_base::Message* msg) {
|
| + scoped_ptr<LoginData> data;
|
| + switch (msg->message_id) {
|
| + case CMD_LOGIN:
|
| + DCHECK(msg->pdata);
|
| + data.reset(reinterpret_cast<LoginData*>(msg->pdata));
|
| + DoLogin(data.get());
|
| + break;
|
| + case CMD_DISCONNECT:
|
| + DoDisconnect();
|
| + break;
|
| + case CMD_LISTEN_FOR_UPDATES:
|
| + DoListenForUpdates();
|
| + break;
|
| + case CMD_SEND_NOTIFICATION:
|
| + DoSendNotification();
|
| + break;
|
| + case CMD_SUBSCRIBE_FOR_UPDATES:
|
| + DoSubscribeForUpdates();
|
| + break;
|
| + default:
|
| + LOG(ERROR) << "P2P: Someone passed a bad message to the thread.";
|
| + break;
|
| + }
|
| +}
|
| +
|
| +void MediatorThreadImpl::DoLogin(LoginData* login_data) {
|
| + LOG(INFO) << "P2P: Thread logging into talk network.";
|
| + buzz::XmppClientSettings& user_settings = login_data->user_settings;
|
| +
|
| + // Set our service id.
|
| + user_settings.set_token_service(SYNC_SERVICE_NAME);
|
| +
|
| + // Start a new pump for the login.
|
| + login_.reset();
|
| + pump_.reset(new notifier::TaskPump());
|
| +
|
| + notifier::ServerInformation server_list[2];
|
| + int server_list_count = 2;
|
| +
|
| + // The default servers know how to serve over port 443 (that's the magic)
|
| + server_list[0].server = talk_base::SocketAddress("talk.google.com",
|
| + notifier::kDefaultXmppPort,
|
| + true); // Use DNS
|
| + server_list[0].special_port_magic = true;
|
| + server_list[1].server = talk_base::SocketAddress("talkx.l.google.com",
|
| + notifier::kDefaultXmppPort,
|
| + true); // Use DNS
|
| + server_list[1].special_port_magic = true;
|
| +
|
| + // Autodetect proxy is on by default.
|
| + notifier::ConnectionOptions options;
|
| +
|
| + // Language is not used in the stanza so we default to |en|.
|
| + std::string lang = "en";
|
| + login_.reset(new notifier::Login(pump_.get(),
|
| + user_settings,
|
| + options,
|
| + lang,
|
| + server_list,
|
| + server_list_count,
|
| + // NetworkStatusDetectionTask will be
|
| + // created for you if NULL is passed in.
|
| + // It helps shorten the autoreconnect
|
| + // time after going offline and coming
|
| + // back online.
|
| + NULL,
|
| + // talk_base::FirewallManager* is NULL.
|
| + NULL,
|
| + false,
|
| + // Both the proxy and a non-proxy route
|
| + // will be attempted.
|
| + false,
|
| + // |previous_login_successful| is true
|
| + // because we have already done a
|
| + // successful gaia login at this point
|
| + // through another mechanism.
|
| + true));
|
| +
|
| + login_->SignalClientStateChange.connect(
|
| + this, &MediatorThreadImpl::OnClientStateChangeMessage);
|
| + login_->SignalLoginFailure.connect(
|
| + this, &MediatorThreadImpl::OnLoginFailureMessage);
|
| + login_->StartConnection();
|
| +}
|
| +
|
| +void MediatorThreadImpl::OnInputDebug(const char* msg, int length) {
|
| + string output(msg, length);
|
| + LOG(INFO) << "P2P: OnInputDebug:" << output << ".";
|
| +}
|
| +
|
| +void MediatorThreadImpl::OnOutputDebug(const char* msg, int length) {
|
| + string output(msg, length);
|
| + LOG(INFO) << "P2P: OnOutputDebug:" << output << ".";
|
| +}
|
| +
|
| +void MediatorThreadImpl::DoDisconnect() {
|
| + LOG(INFO) << "P2P: Thread logging out of talk network.";
|
| + login_.reset();
|
| + // Delete the old pump while on the thread to ensure that
|
| + // everything is cleaned-up in a predicatable manner.
|
| + pump_.reset();
|
| +}
|
| +
|
| +void MediatorThreadImpl::DoSubscribeForUpdates() {
|
| + SubscribeTask* subscription = new SubscribeTask(xmpp_client());
|
| + subscription->SignalStatusUpdate.connect(
|
| + this,
|
| + &MediatorThreadImpl::OnSubscriptionStateChange);
|
| + subscription->Start();
|
| +}
|
| +
|
| +void MediatorThreadImpl::DoListenForUpdates() {
|
| + ListenTask* listener = new ListenTask(xmpp_client());
|
| + listener->SignalUpdateAvailable.connect(
|
| + this,
|
| + &MediatorThreadImpl::OnUpdateListenerMessage);
|
| + listener->Start();
|
| +}
|
| +
|
| +void MediatorThreadImpl::DoSendNotification() {
|
| + SendUpdateTask* task = new SendUpdateTask(xmpp_client());
|
| + task->SignalStatusUpdate.connect(
|
| + this,
|
| + &MediatorThreadImpl::OnUpdateNotificationSent);
|
| + task->Start();
|
| +}
|
| +
|
| +void MediatorThreadImpl::OnUpdateListenerMessage() {
|
| + SignalStateChange(MSG_NOTIFICATION_RECEIVED);
|
| +}
|
| +
|
| +void MediatorThreadImpl::OnUpdateNotificationSent(bool success) {
|
| + if (success) {
|
| + SignalStateChange(MSG_NOTIFICATION_SENT);
|
| + }
|
| +}
|
| +
|
| +void MediatorThreadImpl::OnLoginFailureMessage(
|
| + const notifier::LoginFailure& failure) {
|
| + SignalStateChange(MSG_LOGGED_OUT);
|
| +}
|
| +
|
| +void MediatorThreadImpl::OnClientStateChangeMessage(
|
| + notifier::Login::ConnectionState state) {
|
| + switch (state) {
|
| + case notifier::Login::STATE_CLOSED:
|
| + SignalStateChange(MSG_LOGGED_OUT);
|
| + break;
|
| + case notifier::Login::STATE_RETRYING:
|
| + case notifier::Login::STATE_OPENING:
|
| + LOG(INFO) << "P2P: Thread trying to connect.";
|
| + // Maybe first time logon, maybe intermediate network disruption
|
| + // Assume the server went down, and lost our subscription for updates.
|
| + SignalStateChange(MSG_SUBSCRIPTION_FAILURE);
|
| + break;
|
| + case notifier::Login::STATE_OPENED:
|
| + SignalStateChange(MSG_LOGGED_IN);
|
| + break;
|
| + default:
|
| + LOG(WARNING) << "P2P: Unknown client state change.";
|
| + break;
|
| + }
|
| +}
|
| +
|
| +void MediatorThreadImpl::OnSubscriptionStateChange(bool success) {
|
| + if (success) {
|
| + SignalStateChange(MSG_SUBSCRIPTION_SUCCESS);
|
| + } else {
|
| + SignalStateChange(MSG_SUBSCRIPTION_FAILURE);
|
| + }
|
| +}
|
| +
|
| +buzz::XmppClient* MediatorThreadImpl::xmpp_client() {
|
| + if (!login_.get()) {
|
| + return NULL;
|
| + }
|
| + return login_->xmpp_client();
|
| +}
|
| +
|
| +} // namespace browser_sync
|
|
|
| Property changes on: chrome\browser\sync\notifier\listener\mediator_thread_impl.cc
|
| ___________________________________________________________________
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|