Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(114)

Side by Side Diff: remoting/host/client_session.cc

Issue 10920019: [Chromoting] Refactoring DesktopEnvironment and moving screen/audio recorders to ClientSession. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "remoting/base/encoder.h"
11 #include "remoting/base/encoder_row_based.h"
12 #include "remoting/base/encoder_vp8.h"
13 #include "remoting/codec/audio_encoder.h"
14 #include "remoting/codec/audio_encoder_verbatim.h"
15 #include "remoting/host/audio_capturer.h"
16 #include "remoting/host/audio_scheduler.h"
17 #include "remoting/host/desktop_environment.h"
18 #include "remoting/host/event_executor.h"
19 #include "remoting/host/screen_recorder.h"
10 #include "remoting/host/video_frame_capturer.h" 20 #include "remoting/host/video_frame_capturer.h"
11 #include "remoting/proto/control.pb.h" 21 #include "remoting/proto/control.pb.h"
12 #include "remoting/proto/event.pb.h" 22 #include "remoting/proto/event.pb.h"
13 #include "remoting/protocol/client_stub.h" 23 #include "remoting/protocol/client_stub.h"
14 #include "remoting/protocol/clipboard_thread_proxy.h" 24 #include "remoting/protocol/clipboard_thread_proxy.h"
15 25
16 namespace remoting { 26 namespace remoting {
17 27
18 ClientSession::ClientSession( 28 ClientSession::ClientSession(
19 EventHandler* event_handler, 29 EventHandler* event_handler,
30 scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner,
31 scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner,
32 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner,
20 scoped_ptr<protocol::ConnectionToClient> connection, 33 scoped_ptr<protocol::ConnectionToClient> connection,
21 protocol::ClipboardStub* host_clipboard_stub, 34 scoped_ptr<DesktopEnvironment> desktop_environment,
22 protocol::InputStub* host_input_stub,
23 VideoFrameCapturer* capturer,
24 const base::TimeDelta& max_duration) 35 const base::TimeDelta& max_duration)
25 : event_handler_(event_handler), 36 : event_handler_(event_handler),
26 connection_(connection.Pass()), 37 connection_(connection.Pass()),
38 desktop_environment_(desktop_environment.Pass()),
27 client_jid_(connection_->session()->jid()), 39 client_jid_(connection_->session()->jid()),
28 is_authenticated_(false), 40 is_authenticated_(false),
29 host_clipboard_stub_(host_clipboard_stub), 41 host_clipboard_stub_(desktop_environment_->event_executor()),
30 host_input_stub_(host_input_stub), 42 host_input_stub_(desktop_environment_->event_executor()),
31 input_tracker_(host_input_stub_), 43 input_tracker_(host_input_stub_),
32 remote_input_filter_(&input_tracker_), 44 remote_input_filter_(&input_tracker_),
33 mouse_input_filter_(&remote_input_filter_), 45 mouse_input_filter_(&remote_input_filter_),
34 client_clipboard_factory_(clipboard_echo_filter_.client_filter()), 46 client_clipboard_factory_(clipboard_echo_filter_.client_filter()),
35 capturer_(capturer), 47 capturer_(desktop_environment_->video_capturer()),
36 max_duration_(max_duration) { 48 max_duration_(max_duration),
49 capture_task_runner_(capture_task_runner),
50 encode_task_runner_(encode_task_runner),
51 network_task_runner_(network_task_runner),
52 active_recorders_(0) {
37 connection_->SetEventHandler(this); 53 connection_->SetEventHandler(this);
38 54
39 // TODO(sergeyu): Currently ConnectionToClient expects stubs to be 55 // TODO(sergeyu): Currently ConnectionToClient expects stubs to be
40 // set before channels are connected. Make it possible to set stubs 56 // set before channels are connected. Make it possible to set stubs
41 // later and set them only when connection is authenticated. 57 // later and set them only when connection is authenticated.
42 connection_->set_clipboard_stub(&auth_clipboard_filter_); 58 connection_->set_clipboard_stub(&auth_clipboard_filter_);
43 connection_->set_host_stub(this); 59 connection_->set_host_stub(this);
44 connection_->set_input_stub(this); 60 connection_->set_input_stub(this);
45 clipboard_echo_filter_.set_host_stub(host_clipboard_stub_); 61 clipboard_echo_filter_.set_host_stub(host_clipboard_stub_);
46 } 62 }
47 63
48 ClientSession::~ClientSession() { 64 ClientSession::~ClientSession() {
65 DCHECK(desktop_environment_.get() == NULL);
49 } 66 }
50 67
51 void ClientSession::InjectKeyEvent(const protocol::KeyEvent& event) { 68 void ClientSession::InjectKeyEvent(const protocol::KeyEvent& event) {
52 DCHECK(CalledOnValidThread()); 69 DCHECK(CalledOnValidThread());
53 auth_input_filter_.InjectKeyEvent(event); 70 auth_input_filter_.InjectKeyEvent(event);
54 } 71 }
55 72
56 void ClientSession::InjectMouseEvent(const protocol::MouseEvent& event) { 73 void ClientSession::InjectMouseEvent(const protocol::MouseEvent& event) {
57 DCHECK(CalledOnValidThread()); 74 DCHECK(CalledOnValidThread());
58 75
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 } 117 }
101 118
102 event_handler_->OnSessionAuthenticated(this); 119 event_handler_->OnSessionAuthenticated(this);
103 } 120 }
104 121
105 void ClientSession::OnConnectionChannelsConnected( 122 void ClientSession::OnConnectionChannelsConnected(
106 protocol::ConnectionToClient* connection) { 123 protocol::ConnectionToClient* connection) {
107 DCHECK(CalledOnValidThread()); 124 DCHECK(CalledOnValidThread());
108 DCHECK_EQ(connection_.get(), connection); 125 DCHECK_EQ(connection_.get(), connection);
109 SetDisableInputs(false); 126 SetDisableInputs(false);
127
128 // Then we create a ScreenRecorder passing the message loops that
Wez 2012/08/31 18:18:02 nit: Drop "Then we".
alexeypa (please no reviews) 2012/08/31 23:13:30 Done.
129 // it should run on.
130 Encoder* encoder = CreateEncoder(connection_->session()->config());
131 video_recorder_ = new ScreenRecorder(
132 capture_task_runner_,
133 encode_task_runner_,
134 network_task_runner_,
135 desktop_environment_->video_capturer(),
136 encoder);
137 ++active_recorders_;
138
139 if (connection_->session()->config().is_audio_enabled()) {
140 scoped_ptr<AudioEncoder> audio_encoder =
141 CreateAudioEncoder(connection_->session()->config());
142 audio_scheduler_ = new AudioScheduler(
143 capture_task_runner_,
144 network_task_runner_,
145 desktop_environment_->audio_capturer(),
146 audio_encoder.Pass(),
147 connection_->audio_stub());
148 ++active_recorders_;
149 }
150
151 // Immediately add the connection and start the session.
Wez 2012/08/31 18:18:02 nit: Suggest just "Start the session."
alexeypa (please no reviews) 2012/08/31 23:13:30 Done.
152 video_recorder_->AddConnection(connection_.get());
153 video_recorder_->Start();
154 desktop_environment_->Start(CreateClipboardProxy());
155
110 event_handler_->OnSessionChannelsConnected(this); 156 event_handler_->OnSessionChannelsConnected(this);
111 } 157 }
112 158
113 void ClientSession::OnConnectionClosed( 159 void ClientSession::OnConnectionClosed(
114 protocol::ConnectionToClient* connection, 160 protocol::ConnectionToClient* connection,
115 protocol::ErrorCode error) { 161 protocol::ErrorCode error) {
116 DCHECK(CalledOnValidThread()); 162 DCHECK(CalledOnValidThread());
117 DCHECK_EQ(connection_.get(), connection); 163 DCHECK_EQ(connection_.get(), connection);
118 if (!is_authenticated_) 164 if (!is_authenticated_)
119 event_handler_->OnSessionAuthenticationFailed(this); 165 event_handler_->OnSessionAuthenticationFailed(this);
120 auth_input_filter_.set_input_stub(NULL); 166 auth_input_filter_.set_input_stub(NULL);
121 auth_clipboard_filter_.set_clipboard_stub(NULL); 167 auth_clipboard_filter_.set_clipboard_stub(NULL);
122 168
123 // Ensure that any pressed keys or buttons are released. 169 // Ensure that any pressed keys or buttons are released.
124 input_tracker_.ReleaseAll(); 170 input_tracker_.ReleaseAll();
125 171
126 // TODO(sergeyu): Log failure reason? 172 // TODO(sergeyu): Log failure reason?
127 event_handler_->OnSessionClosed(this); 173 event_handler_->OnSessionClosed(this);
128 } 174 }
129 175
130 void ClientSession::OnSequenceNumberUpdated( 176 void ClientSession::OnSequenceNumberUpdated(
131 protocol::ConnectionToClient* connection, int64 sequence_number) { 177 protocol::ConnectionToClient* connection, int64 sequence_number) {
132 DCHECK(CalledOnValidThread()); 178 DCHECK(CalledOnValidThread());
133 DCHECK_EQ(connection_.get(), connection); 179 DCHECK_EQ(connection_.get(), connection);
180
181 if (video_recorder_.get())
182 video_recorder_->UpdateSequenceNumber(sequence_number);
183
134 event_handler_->OnSessionSequenceNumber(this, sequence_number); 184 event_handler_->OnSessionSequenceNumber(this, sequence_number);
135 } 185 }
136 186
137 void ClientSession::OnRouteChange( 187 void ClientSession::OnRouteChange(
138 protocol::ConnectionToClient* connection, 188 protocol::ConnectionToClient* connection,
139 const std::string& channel_name, 189 const std::string& channel_name,
140 const protocol::TransportRoute& route) { 190 const protocol::TransportRoute& route) {
141 DCHECK(CalledOnValidThread()); 191 DCHECK(CalledOnValidThread());
142 DCHECK_EQ(connection_.get(), connection); 192 DCHECK_EQ(connection_.get(), connection);
143 event_handler_->OnSessionRouteChange(this, channel_name, route); 193 event_handler_->OnSessionRouteChange(this, channel_name, route);
144 } 194 }
145 195
146 void ClientSession::Disconnect() { 196 void ClientSession::Disconnect() {
147 DCHECK(CalledOnValidThread()); 197 DCHECK(CalledOnValidThread());
148 DCHECK(connection_.get()); 198 DCHECK(connection_.get());
149 199
150 max_duration_timer_.Stop(); 200 max_duration_timer_.Stop();
151 // This triggers OnConnectionClosed(), and the session may be destroyed 201 // This triggers OnConnectionClosed(), and the session may be destroyed
152 // as the result, so this call must be the last in this method. 202 // as the result, so this call must be the last in this method.
153 connection_->Disconnect(); 203 connection_->Disconnect();
154 } 204 }
155 205
206 void ClientSession::StopAndDelete() {
207 DCHECK(CalledOnValidThread());
208
209 if (audio_scheduler_.get()) {
210 audio_scheduler_->OnClientDisconnected();
211 StopAudioScheduler();
212 }
213
214 if (video_recorder_.get()) {
215 video_recorder_->RemoveConnection(connection_.get());
216 StopScreenRecorder();
217 }
218
219 if (!active_recorders_) {
220 desktop_environment_.release()->StopAndDelete();
221 delete this;
222 }
223 }
224
156 void ClientSession::LocalMouseMoved(const SkIPoint& mouse_pos) { 225 void ClientSession::LocalMouseMoved(const SkIPoint& mouse_pos) {
157 DCHECK(CalledOnValidThread()); 226 DCHECK(CalledOnValidThread());
158 remote_input_filter_.LocalMouseMoved(mouse_pos); 227 remote_input_filter_.LocalMouseMoved(mouse_pos);
159 } 228 }
160 229
161 void ClientSession::SetDisableInputs(bool disable_inputs) { 230 void ClientSession::SetDisableInputs(bool disable_inputs) {
162 DCHECK(CalledOnValidThread()); 231 DCHECK(CalledOnValidThread());
163 232
164 if (disable_inputs) { 233 if (disable_inputs) {
165 disable_input_filter_.set_input_stub(NULL); 234 disable_input_filter_.set_input_stub(NULL);
166 disable_clipboard_filter_.set_clipboard_stub(NULL); 235 disable_clipboard_filter_.set_clipboard_stub(NULL);
167 input_tracker_.ReleaseAll(); 236 input_tracker_.ReleaseAll();
168 } else { 237 } else {
169 disable_input_filter_.set_input_stub(&mouse_input_filter_); 238 disable_input_filter_.set_input_stub(&mouse_input_filter_);
170 disable_clipboard_filter_.set_clipboard_stub( 239 disable_clipboard_filter_.set_clipboard_stub(
171 clipboard_echo_filter_.host_filter()); 240 clipboard_echo_filter_.host_filter());
172 } 241 }
173 } 242 }
174 243
175 scoped_ptr<protocol::ClipboardStub> ClientSession::CreateClipboardProxy() { 244 scoped_ptr<protocol::ClipboardStub> ClientSession::CreateClipboardProxy() {
176 DCHECK(CalledOnValidThread()); 245 DCHECK(CalledOnValidThread());
177 246
178 return scoped_ptr<protocol::ClipboardStub>( 247 return scoped_ptr<protocol::ClipboardStub>(
179 new protocol::ClipboardThreadProxy( 248 new protocol::ClipboardThreadProxy(
180 client_clipboard_factory_.GetWeakPtr(), 249 client_clipboard_factory_.GetWeakPtr(),
181 base::MessageLoopProxy::current())); 250 base::MessageLoopProxy::current()));
182 } 251 }
183 252
253 // TODO(sergeyu): Move this to SessionManager?
254 // static
255 Encoder* ClientSession::CreateEncoder(const protocol::SessionConfig& config) {
256 const protocol::ChannelConfig& video_config = config.video_config();
257
258 if (video_config.codec == protocol::ChannelConfig::CODEC_VERBATIM) {
259 return EncoderRowBased::CreateVerbatimEncoder();
260 } else if (video_config.codec == protocol::ChannelConfig::CODEC_ZIP) {
261 return EncoderRowBased::CreateZlibEncoder();
262 } else if (video_config.codec == protocol::ChannelConfig::CODEC_VP8) {
263 return new remoting::EncoderVp8();
264 }
265
266 return NULL;
267 }
268
269 // static
270 scoped_ptr<AudioEncoder> ClientSession::CreateAudioEncoder(
271 const protocol::SessionConfig& config) {
272 const protocol::ChannelConfig& audio_config = config.audio_config();
273
274 if (audio_config.codec == protocol::ChannelConfig::CODEC_VERBATIM) {
275 return scoped_ptr<AudioEncoder>(new AudioEncoderVerbatim());
276 }
277
278 NOTIMPLEMENTED();
279 return scoped_ptr<AudioEncoder>(NULL);
280 }
281
282 void ClientSession::OnRecorderStopped() {
283 if (!network_task_runner_->BelongsToCurrentThread()) {
284 network_task_runner_->PostTask(
285 FROM_HERE, base::Bind(&ClientSession::OnRecorderStopped,
286 base::Unretained(this)));
287 return;
288 }
289
290 --active_recorders_;
291 DCHECK_GE(active_recorders_, 0);
292
293 StopAndDelete();
294 }
295
296 void ClientSession::StopAudioScheduler() {
297 DCHECK(CalledOnValidThread());
298 DCHECK(audio_scheduler_.get());
299
300 scoped_refptr<AudioScheduler> audio_scheduler = audio_scheduler_;
301 audio_scheduler_ = NULL;
302 audio_scheduler->Stop(base::Bind(&ClientSession::OnRecorderStopped,
303 base::Unretained(this)));
304 }
305
306 void ClientSession::StopScreenRecorder() {
307 DCHECK(CalledOnValidThread());
308 DCHECK(video_recorder_.get());
309
310 scoped_refptr<ScreenRecorder> video_recorder = video_recorder_;
311 video_recorder_ = NULL;
312 video_recorder->Stop(base::Bind(&ClientSession::OnRecorderStopped,
313 base::Unretained(this)));
314 }
315
184 } // namespace remoting 316 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698