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 "base/message_loop/message_loop_proxy.h"
10 #include "net/base/io_buffer.h"
11 #include "remoting/protocol/clipboard_stub.h"
12 #include "remoting/protocol/host_control_dispatcher.h"
13 #include "remoting/protocol/host_event_dispatcher.h"
14 #include "remoting/protocol/host_stub.h"
15 #include "remoting/protocol/host_video_dispatcher.h"
16 #include "remoting/protocol/input_stub.h"
21 ConnectionToClient::ConnectionToClient(protocol::Session
* session
)
23 clipboard_stub_(NULL
),
27 session_
->SetEventHandler(this);
30 ConnectionToClient::~ConnectionToClient() {
33 void ConnectionToClient::SetEventHandler(EventHandler
* event_handler
) {
34 DCHECK(CalledOnValidThread());
35 handler_
= event_handler
;
38 protocol::Session
* ConnectionToClient::session() {
39 DCHECK(CalledOnValidThread());
40 return session_
.get();
43 void ConnectionToClient::Disconnect() {
44 DCHECK(CalledOnValidThread());
48 // This should trigger OnConnectionClosed() event and this object
49 // may be destroyed as the result.
53 void ConnectionToClient::UpdateSequenceNumber(int64 sequence_number
) {
54 DCHECK(CalledOnValidThread());
55 handler_
->OnSequenceNumberUpdated(this, sequence_number
);
58 VideoStub
* ConnectionToClient::video_stub() {
59 DCHECK(CalledOnValidThread());
60 return video_dispatcher_
.get();
63 AudioStub
* ConnectionToClient::audio_stub() {
64 DCHECK(CalledOnValidThread());
65 return audio_writer_
.get();
68 // Return pointer to ClientStub.
69 ClientStub
* ConnectionToClient::client_stub() {
70 DCHECK(CalledOnValidThread());
71 return control_dispatcher_
.get();
74 void ConnectionToClient::set_clipboard_stub(
75 protocol::ClipboardStub
* clipboard_stub
) {
76 DCHECK(CalledOnValidThread());
77 clipboard_stub_
= clipboard_stub
;
80 ClipboardStub
* ConnectionToClient::clipboard_stub() {
81 DCHECK(CalledOnValidThread());
82 return clipboard_stub_
;
85 void ConnectionToClient::set_host_stub(protocol::HostStub
* host_stub
) {
86 DCHECK(CalledOnValidThread());
87 host_stub_
= host_stub
;
90 HostStub
* ConnectionToClient::host_stub() {
91 DCHECK(CalledOnValidThread());
95 void ConnectionToClient::set_input_stub(protocol::InputStub
* input_stub
) {
96 DCHECK(CalledOnValidThread());
97 input_stub_
= input_stub
;
100 InputStub
* ConnectionToClient::input_stub() {
101 DCHECK(CalledOnValidThread());
105 void ConnectionToClient::OnSessionStateChange(Session::State state
) {
106 DCHECK(CalledOnValidThread());
110 case Session::INITIALIZING
:
111 case Session::CONNECTING
:
112 case Session::ACCEPTING
:
113 case Session::CONNECTED
:
114 // Don't care about these events.
116 case Session::AUTHENTICATING
:
117 handler_
->OnConnectionAuthenticating(this);
119 case Session::AUTHENTICATED
:
120 // Initialize channels.
121 control_dispatcher_
.reset(new HostControlDispatcher());
122 control_dispatcher_
->Init(
123 session_
.get(), session_
->config().control_config(),
124 base::Bind(&ConnectionToClient::OnChannelInitialized
,
125 base::Unretained(this)));
126 control_dispatcher_
->set_clipboard_stub(clipboard_stub_
);
127 control_dispatcher_
->set_host_stub(host_stub_
);
129 event_dispatcher_
.reset(new HostEventDispatcher());
130 event_dispatcher_
->Init(
131 session_
.get(), session_
->config().event_config(),
132 base::Bind(&ConnectionToClient::OnChannelInitialized
,
133 base::Unretained(this)));
134 event_dispatcher_
->set_input_stub(input_stub_
);
135 event_dispatcher_
->set_sequence_number_callback(base::Bind(
136 &ConnectionToClient::UpdateSequenceNumber
, base::Unretained(this)));
138 video_dispatcher_
.reset(new HostVideoDispatcher());
139 video_dispatcher_
->Init(
140 session_
.get(), session_
->config().video_config(),
141 base::Bind(&ConnectionToClient::OnChannelInitialized
,
142 base::Unretained(this)));
144 audio_writer_
= AudioWriter::Create(session_
->config());
145 if (audio_writer_
.get()) {
147 session_
.get(), session_
->config().audio_config(),
148 base::Bind(&ConnectionToClient::OnChannelInitialized
,
149 base::Unretained(this)));
152 // Notify the handler after initializing the channels, so that
153 // ClientSession can get a client clipboard stub.
154 handler_
->OnConnectionAuthenticated(this);
157 case Session::CLOSED
:
161 case Session::FAILED
:
162 Close(session_
->error());
167 void ConnectionToClient::OnSessionRouteChange(
168 const std::string
& channel_name
,
169 const TransportRoute
& route
) {
170 handler_
->OnRouteChange(this, channel_name
, route
);
173 void ConnectionToClient::OnChannelInitialized(bool successful
) {
174 DCHECK(CalledOnValidThread());
177 LOG(ERROR
) << "Failed to connect a channel";
178 Close(CHANNEL_CONNECTION_ERROR
);
182 NotifyIfChannelsReady();
185 void ConnectionToClient::NotifyIfChannelsReady() {
186 DCHECK(CalledOnValidThread());
188 if (!control_dispatcher_
.get() || !control_dispatcher_
->is_connected())
190 if (!event_dispatcher_
.get() || !event_dispatcher_
->is_connected())
192 if (!video_dispatcher_
.get() || !video_dispatcher_
->is_connected())
194 if ((!audio_writer_
.get() || !audio_writer_
->is_connected()) &&
195 session_
->config().is_audio_enabled()) {
198 handler_
->OnConnectionChannelsConnected(this);
201 void ConnectionToClient::Close(ErrorCode error
) {
203 handler_
->OnConnectionClosed(this, error
);
206 void ConnectionToClient::CloseChannels() {
207 control_dispatcher_
.reset();
208 event_dispatcher_
.reset();
209 video_dispatcher_
.reset();
210 audio_writer_
.reset();
213 } // namespace protocol
214 } // namespace remoting