Chromium Code Reviews| 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_); | |
| 231 } | 211 } |
| 232 | 212 |
| 233 // Create the object that controls the screen resolution. | 213 // Create the object that controls the screen resolution. |
| 234 screen_controls_ = desktop_environment_->CreateScreenControls(); | 214 screen_controls_ = desktop_environment_->CreateScreenControls(); |
| 235 | 215 |
| 236 // Create and start the event executor. | 216 // Create the event executor. |
| 237 input_injector_ = desktop_environment_->CreateInputInjector(); | 217 input_injector_ = desktop_environment_->CreateInputInjector(); |
|
Wez
2013/04/30 13:48:39
nit: You don't really need to do this at this poin
alexeypa (please no reviews)
2013/04/30 18:16:20
Yes, but it allows the host to create the event ex
| |
| 238 input_injector_->Start(CreateClipboardProxy()); | |
| 239 | 218 |
| 240 // Connect the host clipboard and input stubs. | 219 // Connect the host clipboard and input stubs. |
| 241 host_input_filter_.set_input_stub(input_injector_.get()); | 220 host_input_filter_.set_input_stub(input_injector_.get()); |
| 242 clipboard_echo_filter_.set_host_stub(input_injector_.get()); | 221 clipboard_echo_filter_.set_host_stub(input_injector_.get()); |
| 243 | 222 |
| 244 SetDisableInputs(false); | |
| 245 | |
| 246 // Create a VideoEncoder based on the session's video channel configuration. | 223 // Create a VideoEncoder based on the session's video channel configuration. |
| 247 scoped_ptr<VideoEncoder> video_encoder = | 224 scoped_ptr<VideoEncoder> video_encoder = |
| 248 CreateVideoEncoder(connection_->session()->config()); | 225 CreateVideoEncoder(connection_->session()->config()); |
| 249 | 226 |
| 250 // Create a VideoScheduler to pump frames from the capturer to the client. | 227 // Create a VideoScheduler to pump frames from the capturer to the client. |
| 251 video_scheduler_ = VideoScheduler::Create( | 228 video_scheduler_ = new VideoScheduler( |
| 252 video_capture_task_runner_, | 229 video_capture_task_runner_, |
| 253 video_encode_task_runner_, | 230 video_encode_task_runner_, |
| 254 network_task_runner_, | 231 network_task_runner_, |
| 255 desktop_environment_->CreateVideoCapturer(), | 232 desktop_environment_->CreateVideoCapturer(), |
| 256 video_encoder.Pass(), | 233 video_encoder.Pass(), |
| 257 connection_->client_stub(), | 234 connection_->client_stub(), |
| 258 &mouse_clamping_filter_); | 235 &mouse_clamping_filter_); |
| 259 | 236 |
| 260 // Create an AudioScheduler if audio is enabled, to pump audio samples. | 237 // Create an AudioScheduler if audio is enabled, to pump audio samples. |
| 261 if (connection_->session()->config().is_audio_enabled()) { | 238 if (connection_->session()->config().is_audio_enabled()) { |
| 262 scoped_ptr<AudioEncoder> audio_encoder = | 239 scoped_ptr<AudioEncoder> audio_encoder = |
| 263 CreateAudioEncoder(connection_->session()->config()); | 240 CreateAudioEncoder(connection_->session()->config()); |
| 264 audio_scheduler_ = AudioScheduler::Create( | 241 audio_scheduler_ = new AudioScheduler( |
| 265 audio_task_runner_, | 242 audio_task_runner_, |
| 266 network_task_runner_, | 243 network_task_runner_, |
| 267 desktop_environment_->CreateAudioCapturer(), | 244 desktop_environment_->CreateAudioCapturer(), |
| 268 audio_encoder.Pass(), | 245 audio_encoder.Pass(), |
| 269 connection_->audio_stub()); | 246 connection_->audio_stub()); |
| 270 } | 247 } |
| 248 } | |
| 249 | |
| 250 void ClientSession::OnConnectionChannelsConnected( | |
| 251 protocol::ConnectionToClient* connection) { | |
| 252 DCHECK(CalledOnValidThread()); | |
| 253 DCHECK_EQ(connection_.get(), connection); | |
| 254 DCHECK(desktop_environment_); | |
| 255 DCHECK(input_injector_); | |
| 256 DCHECK(video_scheduler_); | |
|
Sergey Ulanov
2013/04/30 17:19:26
nit: Many of these dchecks are not necessary - sco
alexeypa (please no reviews)
2013/04/30 18:16:20
Done.
| |
| 257 | |
| 258 // Negotiate capabilities with the client. | |
| 259 if (connection_->session()->config().SupportsCapabilities()) { | |
| 260 VLOG(1) << "Host capabilities: " << host_capabilities_; | |
| 261 | |
| 262 protocol::Capabilities capabilities; | |
| 263 capabilities.set_capabilities(host_capabilities_); | |
| 264 connection_->client_stub()->SetCapabilities(capabilities); | |
| 265 } | |
| 266 | |
| 267 // |client_capabilities_| could have been received before all channels were | |
| 268 // connected. Process them now. | |
| 269 if (client_capabilities_) { | |
| 270 desktop_environment_->SetCapabilities( | |
|
Sergey Ulanov
2013/04/30 17:19:26
Do you need this here? ClientSession::SetCapabilit
alexeypa (please no reviews)
2013/04/30 18:16:20
Done.
| |
| 271 IntersectCapabilities(*client_capabilities_, host_capabilities_)); | |
| 272 } | |
| 273 | |
| 274 // Start the event executor. | |
| 275 input_injector_->Start(CreateClipboardProxy()); | |
| 276 SetDisableInputs(false); | |
| 277 | |
| 278 // Start capturing the screen. | |
| 279 video_scheduler_->Start(); | |
| 280 | |
| 281 // Start recording audio. | |
| 282 if (connection_->session()->config().is_audio_enabled()) | |
| 283 audio_scheduler_->Start(); | |
| 271 | 284 |
| 272 // Notify the event handler that all our channels are now connected. | 285 // Notify the event handler that all our channels are now connected. |
| 273 event_handler_->OnSessionChannelsConnected(this); | 286 event_handler_->OnSessionChannelsConnected(this); |
| 274 } | 287 } |
| 275 | 288 |
| 276 void ClientSession::OnConnectionClosed( | 289 void ClientSession::OnConnectionClosed( |
| 277 protocol::ConnectionToClient* connection, | 290 protocol::ConnectionToClient* connection, |
| 278 protocol::ErrorCode error) { | 291 protocol::ErrorCode error) { |
| 279 DCHECK(CalledOnValidThread()); | 292 DCHECK(CalledOnValidThread()); |
| 280 DCHECK_EQ(connection_.get(), connection); | 293 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()); | 415 return scoped_ptr<AudioEncoder>(new AudioEncoderSpeex()); |
| 403 } else if (audio_config.codec == protocol::ChannelConfig::CODEC_OPUS) { | 416 } else if (audio_config.codec == protocol::ChannelConfig::CODEC_OPUS) { |
| 404 return scoped_ptr<AudioEncoder>(new AudioEncoderOpus()); | 417 return scoped_ptr<AudioEncoder>(new AudioEncoderOpus()); |
| 405 } | 418 } |
| 406 | 419 |
| 407 NOTIMPLEMENTED(); | 420 NOTIMPLEMENTED(); |
| 408 return scoped_ptr<AudioEncoder>(NULL); | 421 return scoped_ptr<AudioEncoder>(NULL); |
| 409 } | 422 } |
| 410 | 423 |
| 411 } // namespace remoting | 424 } // namespace remoting |
| OLD | NEW |