Add CHECK to diagnose the crash.
[chromium-blink-merge.git] / remoting / protocol / connection_to_client.cc
blobb026ee342ce144bb8ed1be70bef94ea1f0a3d1e0
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"
7 #include "base/bind.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"
18 namespace remoting {
19 namespace protocol {
21 ConnectionToClient::ConnectionToClient(protocol::Session* session)
22 : handler_(nullptr),
23 session_(session) {
24 session_->SetEventHandler(this);
27 ConnectionToClient::~ConnectionToClient() {
30 void ConnectionToClient::SetEventHandler(EventHandler* event_handler) {
31 DCHECK(CalledOnValidThread());
32 handler_ = event_handler;
35 protocol::Session* ConnectionToClient::session() {
36 DCHECK(CalledOnValidThread());
37 return session_.get();
40 void ConnectionToClient::Disconnect() {
41 DCHECK(CalledOnValidThread());
43 CloseChannels();
45 // This should trigger OnConnectionClosed() event and this object
46 // may be destroyed as the result.
47 session_->Close();
50 void ConnectionToClient::OnEventTimestamp(int64 sequence_number) {
51 DCHECK(CalledOnValidThread());
52 handler_->OnEventTimestamp(this, sequence_number);
55 VideoStub* ConnectionToClient::video_stub() {
56 DCHECK(CalledOnValidThread());
57 return video_dispatcher_.get();
60 AudioStub* ConnectionToClient::audio_stub() {
61 DCHECK(CalledOnValidThread());
62 return audio_writer_.get();
65 // Return pointer to ClientStub.
66 ClientStub* ConnectionToClient::client_stub() {
67 DCHECK(CalledOnValidThread());
68 return control_dispatcher_.get();
71 void ConnectionToClient::set_clipboard_stub(
72 protocol::ClipboardStub* clipboard_stub) {
73 DCHECK(CalledOnValidThread());
74 control_dispatcher_->set_clipboard_stub(clipboard_stub);
77 void ConnectionToClient::set_host_stub(protocol::HostStub* host_stub) {
78 DCHECK(CalledOnValidThread());
79 control_dispatcher_->set_host_stub(host_stub);
82 void ConnectionToClient::set_input_stub(protocol::InputStub* input_stub) {
83 DCHECK(CalledOnValidThread());
84 event_dispatcher_->set_input_stub(input_stub);
87 void ConnectionToClient::set_video_feedback_stub(
88 VideoFeedbackStub* video_feedback_stub) {
89 DCHECK(CalledOnValidThread());
90 video_dispatcher_->set_video_feedback_stub(video_feedback_stub);
93 void ConnectionToClient::OnSessionStateChange(Session::State state) {
94 DCHECK(CalledOnValidThread());
96 DCHECK(handler_);
97 switch(state) {
98 case Session::INITIALIZING:
99 case Session::CONNECTING:
100 case Session::ACCEPTING:
101 case Session::CONNECTED:
102 // Don't care about these events.
103 break;
104 case Session::AUTHENTICATING:
105 handler_->OnConnectionAuthenticating(this);
106 break;
107 case Session::AUTHENTICATED:
108 // Initialize channels.
109 control_dispatcher_.reset(new HostControlDispatcher());
110 control_dispatcher_->Init(session_.get(),
111 session_->config().control_config(), this);
113 event_dispatcher_.reset(new HostEventDispatcher());
114 event_dispatcher_->Init(session_.get(), session_->config().event_config(),
115 this);
116 event_dispatcher_->set_event_timestamp_callback(base::Bind(
117 &ConnectionToClient::OnEventTimestamp, base::Unretained(this)));
119 video_dispatcher_.reset(new HostVideoDispatcher());
120 video_dispatcher_->Init(session_.get(), session_->config().video_config(),
121 this);
123 audio_writer_ = AudioWriter::Create(session_->config());
124 if (audio_writer_.get()) {
125 audio_writer_->Init(session_.get(), session_->config().audio_config(),
126 this);
129 // Notify the handler after initializing the channels, so that
130 // ClientSession can get a client clipboard stub.
131 handler_->OnConnectionAuthenticated(this);
132 break;
134 case Session::CLOSED:
135 Close(OK);
136 break;
138 case Session::FAILED:
139 Close(session_->error());
140 break;
144 void ConnectionToClient::OnSessionRouteChange(
145 const std::string& channel_name,
146 const TransportRoute& route) {
147 handler_->OnRouteChange(this, channel_name, route);
150 void ConnectionToClient::OnChannelInitialized(
151 ChannelDispatcherBase* channel_dispatcher) {
152 DCHECK(CalledOnValidThread());
154 NotifyIfChannelsReady();
157 void ConnectionToClient::OnChannelError(
158 ChannelDispatcherBase* channel_dispatcher,
159 ErrorCode error) {
160 DCHECK(CalledOnValidThread());
162 LOG(ERROR) << "Failed to connect channel "
163 << channel_dispatcher->channel_name();
164 Close(CHANNEL_CONNECTION_ERROR);
167 void ConnectionToClient::NotifyIfChannelsReady() {
168 DCHECK(CalledOnValidThread());
170 if (!control_dispatcher_ || !control_dispatcher_->is_connected())
171 return;
172 if (!event_dispatcher_ || !event_dispatcher_->is_connected())
173 return;
174 if (!video_dispatcher_ || !video_dispatcher_->is_connected())
175 return;
176 if ((!audio_writer_ || !audio_writer_->is_connected()) &&
177 session_->config().is_audio_enabled()) {
178 return;
180 handler_->OnConnectionChannelsConnected(this);
183 void ConnectionToClient::Close(ErrorCode error) {
184 CloseChannels();
185 handler_->OnConnectionClosed(this, error);
188 void ConnectionToClient::CloseChannels() {
189 control_dispatcher_.reset();
190 event_dispatcher_.reset();
191 video_dispatcher_.reset();
192 audio_writer_.reset();
195 } // namespace protocol
196 } // namespace remoting