OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "remoting/host/client_session.h" | 5 #include "remoting/host/client_session.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/message_loop_proxy.h" | 9 #include "base/message_loop_proxy.h" |
10 #include "media/video/capture/screen/screen_capturer.h" | 10 #include "media/video/capture/screen/screen_capturer.h" |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 if (client_resolution.IsValid()) | 117 if (client_resolution.IsValid()) |
118 screen_controls_->SetScreenResolution(client_resolution); | 118 screen_controls_->SetScreenResolution(client_resolution); |
119 } | 119 } |
120 | 120 |
121 void ClientSession::ControlVideo(const protocol::VideoControl& video_control) { | 121 void ClientSession::ControlVideo(const protocol::VideoControl& video_control) { |
122 DCHECK(CalledOnValidThread()); | 122 DCHECK(CalledOnValidThread()); |
123 | 123 |
124 if (video_control.has_enable()) { | 124 if (video_control.has_enable()) { |
125 VLOG(1) << "Received VideoControl (enable=" | 125 VLOG(1) << "Received VideoControl (enable=" |
126 << video_control.enable() << ")"; | 126 << video_control.enable() << ")"; |
127 if (video_scheduler_) | 127 video_scheduler_->Pause(!video_control.enable()); |
128 video_scheduler_->Pause(!video_control.enable()); | |
129 } | 128 } |
130 } | 129 } |
131 | 130 |
132 void ClientSession::ControlAudio(const protocol::AudioControl& audio_control) { | 131 void ClientSession::ControlAudio(const protocol::AudioControl& audio_control) { |
133 DCHECK(CalledOnValidThread()); | 132 DCHECK(CalledOnValidThread()); |
134 | 133 |
135 if (audio_control.has_enable()) { | 134 if (audio_control.has_enable()) { |
136 VLOG(1) << "Received AudioControl (enable=" | 135 VLOG(1) << "Received AudioControl (enable=" |
137 << audio_control.enable() << ")"; | 136 << audio_control.enable() << ")"; |
138 if (audio_scheduler_) | 137 if (audio_scheduler_) |
(...skipping 19 matching lines...) Expand all Loading... |
158 } | 157 } |
159 | 158 |
160 client_capabilities_ = make_scoped_ptr(new std::string()); | 159 client_capabilities_ = make_scoped_ptr(new std::string()); |
161 if (capabilities.has_capabilities()) | 160 if (capabilities.has_capabilities()) |
162 *client_capabilities_ = capabilities.capabilities(); | 161 *client_capabilities_ = capabilities.capabilities(); |
163 | 162 |
164 VLOG(1) << "Client capabilities: " << *client_capabilities_; | 163 VLOG(1) << "Client capabilities: " << *client_capabilities_; |
165 | 164 |
166 // Calculate the set of capabilities enabled by both client and host and | 165 // Calculate the set of capabilities enabled by both client and host and |
167 // pass it to the desktop environment if it is available. | 166 // pass it to the desktop environment if it is available. |
168 if (desktop_environment_) { | 167 desktop_environment_->SetCapabilities( |
169 desktop_environment_->SetCapabilities( | 168 IntersectCapabilities(*client_capabilities_, host_capabilities_)); |
170 IntersectCapabilities(*client_capabilities_, host_capabilities_)); | |
171 } | |
172 } | 169 } |
173 | 170 |
174 void ClientSession::OnConnectionAuthenticated( | 171 void ClientSession::OnConnectionAuthenticated( |
175 protocol::ConnectionToClient* connection) { | 172 protocol::ConnectionToClient* connection) { |
176 DCHECK(CalledOnValidThread()); | 173 DCHECK(CalledOnValidThread()); |
177 DCHECK_EQ(connection_.get(), connection); | 174 DCHECK_EQ(connection_.get(), connection); |
| 175 DCHECK(!audio_scheduler_); |
178 DCHECK(!desktop_environment_); | 176 DCHECK(!desktop_environment_); |
| 177 DCHECK(!input_injector_); |
| 178 DCHECK(!screen_controls_); |
| 179 DCHECK(!video_scheduler_); |
179 | 180 |
180 auth_input_filter_.set_enabled(true); | 181 auth_input_filter_.set_enabled(true); |
181 auth_clipboard_filter_.set_enabled(true); | 182 auth_clipboard_filter_.set_enabled(true); |
182 | 183 |
183 clipboard_echo_filter_.set_client_stub(connection_->client_stub()); | 184 clipboard_echo_filter_.set_client_stub(connection_->client_stub()); |
184 mouse_clamping_filter_.set_video_stub(connection_->video_stub()); | 185 mouse_clamping_filter_.set_video_stub(connection_->video_stub()); |
185 | 186 |
186 if (max_duration_ > base::TimeDelta()) { | 187 if (max_duration_ > base::TimeDelta()) { |
187 // TODO(simonmorris): Let Disconnect() tell the client that the | 188 // TODO(simonmorris): Let Disconnect() tell the client that the |
188 // disconnection was caused by the session exceeding its maximum duration. | 189 // disconnection was caused by the session exceeding its maximum duration. |
189 max_duration_timer_.Start(FROM_HERE, max_duration_, | 190 max_duration_timer_.Start(FROM_HERE, max_duration_, |
190 this, &ClientSession::DisconnectSession); | 191 this, &ClientSession::DisconnectSession); |
191 } | 192 } |
192 | 193 |
193 // The session may be destroyed as the result result of this call, so it must | 194 // Disconnect the session if the connection was rejected by the host. |
194 // be the last in this method. | 195 if (!event_handler_->OnSessionAuthenticated(this)) { |
195 event_handler_->OnSessionAuthenticated(this); | 196 DisconnectSession(); |
196 } | 197 return; |
197 | 198 } |
198 void ClientSession::OnConnectionChannelsConnected( | |
199 protocol::ConnectionToClient* connection) { | |
200 DCHECK(CalledOnValidThread()); | |
201 DCHECK_EQ(connection_.get(), connection); | |
202 DCHECK(!audio_scheduler_); | |
203 DCHECK(!input_injector_); | |
204 DCHECK(!screen_controls_); | |
205 DCHECK(!video_scheduler_); | |
206 | 199 |
207 // Create the desktop environment. | 200 // Create the desktop environment. |
208 desktop_environment_ = | 201 desktop_environment_ = |
209 desktop_environment_factory_->Create(control_factory_.GetWeakPtr()); | 202 desktop_environment_factory_->Create(control_factory_.GetWeakPtr()); |
210 host_capabilities_ = desktop_environment_->GetCapabilities(); | 203 host_capabilities_ = desktop_environment_->GetCapabilities(); |
211 | 204 |
212 // Negotiate capabilities with the client. | 205 // Ignore protocol::Capabilities messages from the client if it does not |
213 if (connection_->session()->config().SupportsCapabilities()) { | 206 // support any capabilities. |
214 VLOG(1) << "Host capabilities: " << host_capabilities_; | 207 if (!connection_->session()->config().SupportsCapabilities()) { |
215 | |
216 protocol::Capabilities capabilities; | |
217 capabilities.set_capabilities(host_capabilities_); | |
218 connection_->client_stub()->SetCapabilities(capabilities); | |
219 | |
220 // |client_capabilities_| could have been received before all channels were | |
221 // connected. Process them now. | |
222 if (client_capabilities_) { | |
223 desktop_environment_->SetCapabilities( | |
224 IntersectCapabilities(*client_capabilities_, host_capabilities_)); | |
225 } | |
226 } else { | |
227 VLOG(1) << "The client does not support any capabilities."; | 208 VLOG(1) << "The client does not support any capabilities."; |
228 | 209 |
229 client_capabilities_ = make_scoped_ptr(new std::string()); | 210 client_capabilities_ = make_scoped_ptr(new std::string()); |
230 desktop_environment_->SetCapabilities(*client_capabilities_); | 211 desktop_environment_->SetCapabilities(*client_capabilities_); |
231 } | 212 } |
232 | 213 |
233 // Create the object that controls the screen resolution. | 214 // Create the object that controls the screen resolution. |
234 screen_controls_ = desktop_environment_->CreateScreenControls(); | 215 screen_controls_ = desktop_environment_->CreateScreenControls(); |
235 | 216 |
236 // Create and start the event executor. | 217 // Create the event executor. |
237 input_injector_ = desktop_environment_->CreateInputInjector(); | 218 input_injector_ = desktop_environment_->CreateInputInjector(); |
238 input_injector_->Start(CreateClipboardProxy()); | |
239 | 219 |
240 // Connect the host clipboard and input stubs. | 220 // Connect the host clipboard and input stubs. |
241 host_input_filter_.set_input_stub(input_injector_.get()); | 221 host_input_filter_.set_input_stub(input_injector_.get()); |
242 clipboard_echo_filter_.set_host_stub(input_injector_.get()); | 222 clipboard_echo_filter_.set_host_stub(input_injector_.get()); |
243 | 223 |
244 SetDisableInputs(false); | |
245 | |
246 // Create a VideoEncoder based on the session's video channel configuration. | 224 // Create a VideoEncoder based on the session's video channel configuration. |
247 scoped_ptr<VideoEncoder> video_encoder = | 225 scoped_ptr<VideoEncoder> video_encoder = |
248 CreateVideoEncoder(connection_->session()->config()); | 226 CreateVideoEncoder(connection_->session()->config()); |
249 | 227 |
250 // Create a VideoScheduler to pump frames from the capturer to the client. | 228 // Create a VideoScheduler to pump frames from the capturer to the client. |
251 video_scheduler_ = VideoScheduler::Create( | 229 video_scheduler_ = new VideoScheduler( |
252 video_capture_task_runner_, | 230 video_capture_task_runner_, |
253 video_encode_task_runner_, | 231 video_encode_task_runner_, |
254 network_task_runner_, | 232 network_task_runner_, |
255 desktop_environment_->CreateVideoCapturer(), | 233 desktop_environment_->CreateVideoCapturer(), |
256 video_encoder.Pass(), | 234 video_encoder.Pass(), |
257 connection_->client_stub(), | 235 connection_->client_stub(), |
258 &mouse_clamping_filter_); | 236 &mouse_clamping_filter_); |
259 | 237 |
260 // Create an AudioScheduler if audio is enabled, to pump audio samples. | 238 // Create an AudioScheduler if audio is enabled, to pump audio samples. |
261 if (connection_->session()->config().is_audio_enabled()) { | 239 if (connection_->session()->config().is_audio_enabled()) { |
262 scoped_ptr<AudioEncoder> audio_encoder = | 240 scoped_ptr<AudioEncoder> audio_encoder = |
263 CreateAudioEncoder(connection_->session()->config()); | 241 CreateAudioEncoder(connection_->session()->config()); |
264 audio_scheduler_ = AudioScheduler::Create( | 242 audio_scheduler_ = new AudioScheduler( |
265 audio_task_runner_, | 243 audio_task_runner_, |
266 network_task_runner_, | 244 network_task_runner_, |
267 desktop_environment_->CreateAudioCapturer(), | 245 desktop_environment_->CreateAudioCapturer(), |
268 audio_encoder.Pass(), | 246 audio_encoder.Pass(), |
269 connection_->audio_stub()); | 247 connection_->audio_stub()); |
270 } | 248 } |
| 249 } |
| 250 |
| 251 void ClientSession::OnConnectionChannelsConnected( |
| 252 protocol::ConnectionToClient* connection) { |
| 253 DCHECK(CalledOnValidThread()); |
| 254 DCHECK_EQ(connection_.get(), connection); |
| 255 |
| 256 // Negotiate capabilities with the client. |
| 257 if (connection_->session()->config().SupportsCapabilities()) { |
| 258 VLOG(1) << "Host capabilities: " << host_capabilities_; |
| 259 |
| 260 protocol::Capabilities capabilities; |
| 261 capabilities.set_capabilities(host_capabilities_); |
| 262 connection_->client_stub()->SetCapabilities(capabilities); |
| 263 } |
| 264 |
| 265 // Start the event executor. |
| 266 input_injector_->Start(CreateClipboardProxy()); |
| 267 SetDisableInputs(false); |
| 268 |
| 269 // Start capturing the screen. |
| 270 video_scheduler_->Start(); |
| 271 |
| 272 // Start recording audio. |
| 273 if (connection_->session()->config().is_audio_enabled()) |
| 274 audio_scheduler_->Start(); |
271 | 275 |
272 // Notify the event handler that all our channels are now connected. | 276 // Notify the event handler that all our channels are now connected. |
273 event_handler_->OnSessionChannelsConnected(this); | 277 event_handler_->OnSessionChannelsConnected(this); |
274 } | 278 } |
275 | 279 |
276 void ClientSession::OnConnectionClosed( | 280 void ClientSession::OnConnectionClosed( |
277 protocol::ConnectionToClient* connection, | 281 protocol::ConnectionToClient* connection, |
278 protocol::ErrorCode error) { | 282 protocol::ErrorCode error) { |
279 DCHECK(CalledOnValidThread()); | 283 DCHECK(CalledOnValidThread()); |
280 DCHECK_EQ(connection_.get(), connection); | 284 DCHECK_EQ(connection_.get(), connection); |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 return scoped_ptr<AudioEncoder>(new AudioEncoderSpeex()); | 406 return scoped_ptr<AudioEncoder>(new AudioEncoderSpeex()); |
403 } else if (audio_config.codec == protocol::ChannelConfig::CODEC_OPUS) { | 407 } else if (audio_config.codec == protocol::ChannelConfig::CODEC_OPUS) { |
404 return scoped_ptr<AudioEncoder>(new AudioEncoderOpus()); | 408 return scoped_ptr<AudioEncoder>(new AudioEncoderOpus()); |
405 } | 409 } |
406 | 410 |
407 NOTIMPLEMENTED(); | 411 NOTIMPLEMENTED(); |
408 return scoped_ptr<AudioEncoder>(NULL); | 412 return scoped_ptr<AudioEncoder>(NULL); |
409 } | 413 } |
410 | 414 |
411 } // namespace remoting | 415 } // namespace remoting |
OLD | NEW |