1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "remoting/protocol/connection_to_client.h"
8 #include "base/location.h"
9 #include "net/base/io_buffer.h"
10 #include "remoting/protocol/clipboard_stub.h"
11 #include "remoting/protocol/host_control_dispatcher.h"
12 #include "remoting/protocol/host_event_dispatcher.h"
13 #include "remoting/protocol/host_stub.h"
14 #include "remoting/protocol/host_video_dispatcher.h"
15 #include "remoting/protocol/input_stub.h"
20 ConnectionToClient::ConnectionToClient(protocol::Session
* session
)
23 session_
->SetEventHandler(this);
26 ConnectionToClient::~ConnectionToClient() {
29 void ConnectionToClient::SetEventHandler(EventHandler
* event_handler
) {
30 DCHECK(CalledOnValidThread());
31 handler_
= event_handler
;
34 protocol::Session
* ConnectionToClient::session() {
35 DCHECK(CalledOnValidThread());
36 return session_
.get();
39 void ConnectionToClient::Disconnect() {
40 DCHECK(CalledOnValidThread());
44 // This should trigger OnConnectionClosed() event and this object
45 // may be destroyed as the result.
49 void ConnectionToClient::OnEventTimestamp(int64 sequence_number
) {
50 DCHECK(CalledOnValidThread());
51 handler_
->OnEventTimestamp(this, sequence_number
);
54 VideoStub
* ConnectionToClient::video_stub() {
55 DCHECK(CalledOnValidThread());
56 return video_dispatcher_
.get();
59 AudioStub
* ConnectionToClient::audio_stub() {
60 DCHECK(CalledOnValidThread());
61 return audio_writer_
.get();
64 // Return pointer to ClientStub.
65 ClientStub
* ConnectionToClient::client_stub() {
66 DCHECK(CalledOnValidThread());
67 return control_dispatcher_
.get();
70 void ConnectionToClient::set_clipboard_stub(
71 protocol::ClipboardStub
* clipboard_stub
) {
72 DCHECK(CalledOnValidThread());
73 control_dispatcher_
->set_clipboard_stub(clipboard_stub
);
76 void ConnectionToClient::set_host_stub(protocol::HostStub
* host_stub
) {
77 DCHECK(CalledOnValidThread());
78 control_dispatcher_
->set_host_stub(host_stub
);
81 void ConnectionToClient::set_input_stub(protocol::InputStub
* input_stub
) {
82 DCHECK(CalledOnValidThread());
83 event_dispatcher_
->set_input_stub(input_stub
);
86 void ConnectionToClient::set_video_feedback_stub(
87 VideoFeedbackStub
* video_feedback_stub
) {
88 DCHECK(CalledOnValidThread());
89 video_dispatcher_
->set_video_feedback_stub(video_feedback_stub
);
92 void ConnectionToClient::OnSessionStateChange(Session::State state
) {
93 DCHECK(CalledOnValidThread());
97 case Session::INITIALIZING
:
98 case Session::CONNECTING
:
99 case Session::ACCEPTING
:
100 case Session::CONNECTED
:
101 // Don't care about these events.
103 case Session::AUTHENTICATING
:
104 handler_
->OnConnectionAuthenticating(this);
106 case Session::AUTHENTICATED
:
107 // Initialize channels.
108 control_dispatcher_
.reset(new HostControlDispatcher());
109 control_dispatcher_
->Init(session_
.get(),
110 session_
->config().control_config(), this);
112 event_dispatcher_
.reset(new HostEventDispatcher());
113 event_dispatcher_
->Init(session_
.get(), session_
->config().event_config(),
115 event_dispatcher_
->set_event_timestamp_callback(base::Bind(
116 &ConnectionToClient::OnEventTimestamp
, base::Unretained(this)));
118 video_dispatcher_
.reset(new HostVideoDispatcher());
119 video_dispatcher_
->Init(session_
.get(), session_
->config().video_config(),
122 audio_writer_
= AudioWriter::Create(session_
->config());
123 if (audio_writer_
.get()) {
124 audio_writer_
->Init(session_
.get(), session_
->config().audio_config(),
128 // Notify the handler after initializing the channels, so that
129 // ClientSession can get a client clipboard stub.
130 handler_
->OnConnectionAuthenticated(this);
133 case Session::CLOSED
:
137 case Session::FAILED
:
138 Close(session_
->error());
143 void ConnectionToClient::OnSessionRouteChange(
144 const std::string
& channel_name
,
145 const TransportRoute
& route
) {
146 handler_
->OnRouteChange(this, channel_name
, route
);
149 void ConnectionToClient::OnChannelInitialized(
150 ChannelDispatcherBase
* channel_dispatcher
) {
151 DCHECK(CalledOnValidThread());
153 NotifyIfChannelsReady();
156 void ConnectionToClient::OnChannelError(
157 ChannelDispatcherBase
* channel_dispatcher
,
159 DCHECK(CalledOnValidThread());
161 LOG(ERROR
) << "Failed to connect channel "
162 << channel_dispatcher
->channel_name();
163 Close(CHANNEL_CONNECTION_ERROR
);
166 void ConnectionToClient::NotifyIfChannelsReady() {
167 DCHECK(CalledOnValidThread());
169 if (!control_dispatcher_
|| !control_dispatcher_
->is_connected())
171 if (!event_dispatcher_
|| !event_dispatcher_
->is_connected())
173 if (!video_dispatcher_
|| !video_dispatcher_
->is_connected())
175 if ((!audio_writer_
|| !audio_writer_
->is_connected()) &&
176 session_
->config().is_audio_enabled()) {
179 handler_
->OnConnectionChannelsConnected(this);
182 void ConnectionToClient::Close(ErrorCode error
) {
184 handler_
->OnConnectionClosed(this, error
);
187 void ConnectionToClient::CloseChannels() {
188 control_dispatcher_
.reset();
189 event_dispatcher_
.reset();
190 video_dispatcher_
.reset();
191 audio_writer_
.reset();
194 } // namespace protocol
195 } // namespace remoting