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 |