diff options
author | garykac@chromium.org <garykac@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-04 22:44:41 +0000 |
---|---|---|
committer | garykac@chromium.org <garykac@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-04 22:44:41 +0000 |
commit | d11535a810717cd12a32a1a98080b2029c838547 (patch) | |
tree | bfb4ef1af1d49e6db34c932af52e3dd143f67f67 /remoting/protocol | |
parent | d5805b3d99d2d2b3774416cc754221a63a714ad2 (diff) | |
download | chromium_src-d11535a810717cd12a32a1a98080b2029c838547.zip chromium_src-d11535a810717cd12a32a1a98080b2029c838547.tar.gz chromium_src-d11535a810717cd12a32a1a98080b2029c838547.tar.bz2 |
Chromoting: Rename HostConnection to ConnectionToHost
BUG=none
TEST=build chrome, chromoting
Review URL: http://codereview.chromium.org/4457002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@65121 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/protocol')
-rw-r--r-- | remoting/protocol/connection_to_host.h | 63 | ||||
-rw-r--r-- | remoting/protocol/jingle_connection_to_host.cc | 178 | ||||
-rw-r--r-- | remoting/protocol/jingle_connection_to_host.h | 107 |
3 files changed, 348 insertions, 0 deletions
diff --git a/remoting/protocol/connection_to_host.h b/remoting/protocol/connection_to_host.h new file mode 100644 index 0000000..7905c18 --- /dev/null +++ b/remoting/protocol/connection_to_host.h @@ -0,0 +1,63 @@ +// 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 REMOTING_PROTOCOL_CONNECTION_TO_HOST_H_ +#define REMOTING_PROTOCOL_CONNECTION_TO_HOST_H_ + +#include "base/ref_counted.h" +#include "base/scoped_ptr.h" +#include "remoting/proto/internal.pb.h" +#include "remoting/protocol/message_decoder.h" + +namespace remoting { + +struct ClientConfig; + +namespace protocol { + +class VideoStub; + +class ConnectionToHost { + public: + class HostEventCallback { + public: + virtual ~HostEventCallback() {} + + // Handles an event received by the protocol::ConnectionToHost. Ownership of + // the message is passed to the callee. + virtual void HandleMessage(ConnectionToHost* conn, + ChromotingHostMessage* message) = 0; + + // Called when the network connection is opened. + virtual void OnConnectionOpened(ConnectionToHost* conn) = 0; + + // Called when the network connection is closed. + virtual void OnConnectionClosed(ConnectionToHost* conn) = 0; + + // Called when the network connection has failed. + virtual void OnConnectionFailed(ConnectionToHost* conn) = 0; + }; + + virtual ~ConnectionToHost() {} + + // TODO(ajwong): We need to generalize this API. + virtual void Connect(const ClientConfig& config, + HostEventCallback* event_callback, + VideoStub* video_stub) = 0; + virtual void Disconnect() = 0; + + // Send an input event to the host. + virtual void SendEvent(const ChromotingClientMessage& msg) = 0; + + protected: + ConnectionToHost() {} + + private: + DISALLOW_COPY_AND_ASSIGN(ConnectionToHost); +}; + +} // namespace protocol +} // namespace remoting + +#endif // REMOTING_PROTOCOL_CONNECTION_TO_HOST_H_ diff --git a/remoting/protocol/jingle_connection_to_host.cc b/remoting/protocol/jingle_connection_to_host.cc new file mode 100644 index 0000000..e76184e --- /dev/null +++ b/remoting/protocol/jingle_connection_to_host.cc @@ -0,0 +1,178 @@ +// 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 "remoting/protocol/jingle_connection_to_host.h" + +#include "base/callback.h" +#include "base/message_loop.h" +#include "remoting/base/constants.h" +// TODO(hclam): Remove this header once MessageDispatcher is used. +#include "remoting/base/multiple_array_input_stream.h" +#include "remoting/client/client_config.h" +#include "remoting/jingle_glue/jingle_thread.h" +#include "remoting/protocol/jingle_session_manager.h" +#include "remoting/protocol/video_reader.h" +#include "remoting/protocol/video_stub.h" +#include "remoting/protocol/util.h" + +namespace remoting { +namespace protocol { + +JingleConnectionToHost::JingleConnectionToHost(ClientContext* context) + : context_(context), + event_callback_(NULL) { +} + +JingleConnectionToHost::~JingleConnectionToHost() { +} + +void JingleConnectionToHost::Connect(const ClientConfig& config, + HostEventCallback* event_callback, + VideoStub* video_stub) { + event_callback_ = event_callback; + video_stub_ = video_stub; + + // Initialize |jingle_client_|. + jingle_client_ = new JingleClient(context_->jingle_thread()); + jingle_client_->Init(config.username, config.auth_token, + kChromotingTokenServiceName, this); + + // Save jid of the host. The actual connection is created later after + // |jingle_client_| is connected. + host_jid_ = config.host_jid; +} + +void JingleConnectionToHost::Disconnect() { + if (MessageLoop::current() != message_loop()) { + message_loop()->PostTask( + FROM_HERE, NewRunnableMethod(this, + &JingleConnectionToHost::Disconnect)); + return; + } + + control_reader_.Close(); + event_writer_.Close(); + video_reader_->Close(); + + if (session_) { + session_->Close( + NewRunnableMethod(this, &JingleConnectionToHost::OnDisconnected)); + } else { + OnDisconnected(); + } +} + +void JingleConnectionToHost::OnControlMessage(ChromotingHostMessage* msg) { + event_callback_->HandleMessage(this, msg); +} + +void JingleConnectionToHost::InitSession() { + DCHECK_EQ(message_loop(), MessageLoop::current()); + + // Initialize chromotocol |session_manager_|. + protocol::JingleSessionManager* session_manager = + new protocol::JingleSessionManager(context_->jingle_thread()); + // TODO(ajwong): Make this a command switch when we're more stable. + session_manager->set_allow_local_ips(true); + session_manager->Init( + jingle_client_->GetFullJid(), + jingle_client_->session_manager(), + NewCallback(this, &JingleConnectionToHost::OnNewSession)); + session_manager_ = session_manager; + + CandidateChromotocolConfig* candidate_config = + CandidateChromotocolConfig::CreateDefault(); + // TODO(sergeyu): Set resolution in the |candidate_config| to the desired + // resolution. + + // Initialize |session_|. + session_ = session_manager_->Connect( + host_jid_, candidate_config, + NewCallback(this, &JingleConnectionToHost::OnSessionStateChange)); +} + +void JingleConnectionToHost::OnDisconnected() { + session_ = NULL; + + if (session_manager_) { + session_manager_->Close( + NewRunnableMethod(this, &JingleConnectionToHost::OnServerClosed)); + } else { + OnServerClosed(); + } +} + +void JingleConnectionToHost::OnServerClosed() { + session_manager_ = NULL; + if (jingle_client_) { + jingle_client_->Close(); + jingle_client_ = NULL; + } +} + +void JingleConnectionToHost::SendEvent(const ChromotingClientMessage& msg) { + // This drops the message if we are not connected yet. + event_writer_.SendMessage(msg); +} + +// JingleClient::Callback interface. +void JingleConnectionToHost::OnStateChange(JingleClient* client, + JingleClient::State state) { + DCHECK_EQ(message_loop(), MessageLoop::current()); + DCHECK(client); + DCHECK(event_callback_); + + if (state == JingleClient::CONNECTED) { + VLOG(1) << "Connected as: " << client->GetFullJid(); + InitSession(); + } else if (state == JingleClient::CLOSED) { + VLOG(1) << "Connection closed."; + event_callback_->OnConnectionClosed(this); + } +} + +void JingleConnectionToHost::OnNewSession(protocol::Session* session, + protocol::SessionManager::IncomingSessionResponse* response) { + DCHECK_EQ(message_loop(), MessageLoop::current()); + // Client always rejects incoming sessions. + *response = protocol::SessionManager::DECLINE; +} + +void JingleConnectionToHost::OnSessionStateChange( + protocol::Session::State state) { + DCHECK_EQ(message_loop(), MessageLoop::current()); + DCHECK(event_callback_); + + switch (state) { + case protocol::Session::FAILED: + event_callback_->OnConnectionFailed(this); + break; + + case protocol::Session::CLOSED: + event_callback_->OnConnectionClosed(this); + break; + + case protocol::Session::CONNECTED: + // Initialize reader and writer. + control_reader_.Init<ChromotingHostMessage>( + session_->control_channel(), + NewCallback(this, &JingleConnectionToHost::OnControlMessage)); + event_writer_.Init(session_->event_channel()); + video_reader_.reset(VideoReader::Create(session_->config())); + video_reader_->Init(session_, video_stub_); + event_callback_->OnConnectionOpened(this); + break; + + default: + // Ignore the other states by default. + break; + } +} + +MessageLoop* JingleConnectionToHost::message_loop() { + return context_->jingle_thread()->message_loop(); +} + +} // namespace protocol +} // namespace remoting diff --git a/remoting/protocol/jingle_connection_to_host.h b/remoting/protocol/jingle_connection_to_host.h new file mode 100644 index 0000000..931b5b3 --- /dev/null +++ b/remoting/protocol/jingle_connection_to_host.h @@ -0,0 +1,107 @@ +// 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. + +// JingleConnectionToHost implements the ConnectionToHost interface using +// libjingle as the transport protocol. +// +// Much of this class focuses on translating JingleClient and +// ChromotingConnection callbacks into ConnectionToHost::HostEventCallback +// messages. +// +// The public API of this class is designed to be asynchronous, and thread +// safe for invocation from other threads. +// +// Internally though, all work delegeated to the |network_thread| given +// during construction. Any event handlers running on the |network_thread| +// should not block. + +#ifndef REMOTING_PROTOCOL_JINGLE_CONNECTION_TO_HOST_H_ +#define REMOTING_PROTOCOL_JINGLE_CONNECTION_TO_HOST_H_ + +#include "base/ref_counted.h" +#include "base/scoped_ptr.h" +#include "base/task.h" +#include "remoting/client/client_context.h" +#include "remoting/jingle_glue/jingle_client.h" +#include "remoting/protocol/connection_to_host.h" +#include "remoting/protocol/message_reader.h" +#include "remoting/protocol/session.h" +#include "remoting/protocol/session_manager.h" +#include "remoting/protocol/stream_writer.h" + +class MessageLoop; + +namespace remoting { +namespace protocol { + +class VideoReader; +class VideoStub; + +class JingleConnectionToHost : public ConnectionToHost, + public JingleClient::Callback { + public: + explicit JingleConnectionToHost(ClientContext* context); + virtual ~JingleConnectionToHost(); + + virtual void Connect(const ClientConfig& config, + HostEventCallback* event_callback, + VideoStub* video_stub); + virtual void Disconnect(); + + virtual void SendEvent(const ChromotingClientMessage& msg); + + // JingleClient::Callback interface. + virtual void OnStateChange(JingleClient* client, JingleClient::State state); + + // Callback for chromotocol SessionManager. + void OnNewSession( + protocol::Session* connection, + protocol::SessionManager::IncomingSessionResponse* response); + + // Callback for chromotocol Session. + void OnSessionStateChange(protocol::Session::State state); + + private: + // The message loop for the jingle thread this object works on. + MessageLoop* message_loop(); + + // Called on the jingle thread after we've successfully to XMPP server. Starts + // P2P connection to the host. + void InitSession(); + + // Callback for |control_reader_|. + void OnControlMessage(ChromotingHostMessage* msg); + + // Callback for |video_reader_|. + void OnVideoPacket(VideoPacket* packet); + + // Used by Disconnect() to disconnect chromoting connection, stop chromoting + // server, and then disconnect XMPP connection. + void OnDisconnected(); + void OnServerClosed(); + + ClientContext* context_; + + scoped_refptr<JingleClient> jingle_client_; + scoped_refptr<protocol::SessionManager> session_manager_; + scoped_refptr<protocol::Session> session_; + + MessageReader control_reader_; + EventStreamWriter event_writer_; + scoped_ptr<VideoReader> video_reader_; + + HostEventCallback* event_callback_; + VideoStub* video_stub_; + + std::string host_jid_; + + DISALLOW_COPY_AND_ASSIGN(JingleConnectionToHost); +}; + +} // namespace protocol +} // namespace remoting + +DISABLE_RUNNABLE_METHOD_REFCOUNT(remoting::protocol::JingleConnectionToHost); + +#endif // REMOTING_PROTOCOL_JINGLE_CONNECTION_TO_HOST_H_ |