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/chromoting_host.h" | 5 #include "remoting/host/chromoting_host.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/callback.h" | 8 #include "base/callback.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/message_loop_proxy.h" | 10 #include "base/message_loop_proxy.h" |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 signal_strategy_(signal_strategy), | 70 signal_strategy_(signal_strategy), |
71 stopping_recorders_(0), | 71 stopping_recorders_(0), |
72 state_(kInitial), | 72 state_(kInitial), |
73 protocol_config_(protocol::CandidateSessionConfig::CreateDefault()), | 73 protocol_config_(protocol::CandidateSessionConfig::CreateDefault()), |
74 login_backoff_(&kDefaultBackoffPolicy), | 74 login_backoff_(&kDefaultBackoffPolicy), |
75 authenticating_client_(false), | 75 authenticating_client_(false), |
76 reject_authenticating_client_(false) { | 76 reject_authenticating_client_(false) { |
77 DCHECK(context_); | 77 DCHECK(context_); |
78 DCHECK(signal_strategy); | 78 DCHECK(signal_strategy); |
79 DCHECK(desktop_environment_); | 79 DCHECK(desktop_environment_); |
80 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); | 80 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
81 } | 81 } |
82 | 82 |
83 ChromotingHost::~ChromotingHost() { | 83 ChromotingHost::~ChromotingHost() { |
84 DCHECK(clients_.empty()); | 84 DCHECK(clients_.empty()); |
85 } | 85 } |
86 | 86 |
87 void ChromotingHost::Start() { | 87 void ChromotingHost::Start() { |
88 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); | 88 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
89 | 89 |
90 LOG(INFO) << "Starting host"; | 90 LOG(INFO) << "Starting host"; |
91 | 91 |
92 // Make sure this object is not started. | 92 // Make sure this object is not started. |
93 if (state_ != kInitial) | 93 if (state_ != kInitial) |
94 return; | 94 return; |
95 state_ = kStarted; | 95 state_ = kStarted; |
96 | 96 |
97 // Start the SessionManager, supplying this ChromotingHost as the listener. | 97 // Start the SessionManager, supplying this ChromotingHost as the listener. |
98 session_manager_->Init(signal_strategy_, this); | 98 session_manager_->Init(signal_strategy_, this); |
99 } | 99 } |
100 | 100 |
101 // This method is called when we need to destroy the host process. | 101 // This method is called when we need to destroy the host process. |
102 void ChromotingHost::Shutdown(const base::Closure& shutdown_task) { | 102 void ChromotingHost::Shutdown(const base::Closure& shutdown_task) { |
103 if (!context_->network_message_loop()->BelongsToCurrentThread()) { | 103 if (!context_->network_task_runner()->BelongsToCurrentThread()) { |
104 context_->network_message_loop()->PostTask( | 104 context_->network_task_runner()->PostTask( |
105 FROM_HERE, base::Bind(&ChromotingHost::Shutdown, this, shutdown_task)); | 105 FROM_HERE, base::Bind(&ChromotingHost::Shutdown, this, shutdown_task)); |
106 return; | 106 return; |
107 } | 107 } |
108 | 108 |
109 // No-op if this object is not started yet. | 109 // No-op if this object is not started yet. |
110 if (state_ == kInitial || state_ == kStopped) { | 110 if (state_ == kInitial || state_ == kStopped) { |
111 // Nothing to do if we are not started. | 111 // Nothing to do if we are not started. |
112 state_ = kStopped; | 112 state_ = kStopped; |
113 context_->network_message_loop()->PostTask(FROM_HERE, shutdown_task); | 113 context_->network_task_runner()->PostTask(FROM_HERE, shutdown_task); |
114 return; | 114 return; |
115 } | 115 } |
116 if (!shutdown_task.is_null()) | 116 if (!shutdown_task.is_null()) |
117 shutdown_tasks_.push_back(shutdown_task); | 117 shutdown_tasks_.push_back(shutdown_task); |
118 if (state_ == kStopping) | 118 if (state_ == kStopping) |
119 return; | 119 return; |
120 state_ = kStopping; | 120 state_ = kStopping; |
121 | 121 |
122 // Disconnect all of the clients, implicitly stopping the ScreenRecorder. | 122 // Disconnect all of the clients, implicitly stopping the ScreenRecorder. |
123 while (!clients_.empty()) { | 123 while (!clients_.empty()) { |
124 clients_.front()->Disconnect(); | 124 clients_.front()->Disconnect(); |
125 } | 125 } |
126 | 126 |
127 // Destroy session manager. | 127 // Destroy session manager. |
128 session_manager_.reset(); | 128 session_manager_.reset(); |
129 | 129 |
130 // Stop screen recorder | 130 // Stop screen recorder |
131 if (recorder_.get()) { | 131 if (recorder_.get()) { |
132 StopScreenRecorder(); | 132 StopScreenRecorder(); |
133 } else if (!stopping_recorders_) { | 133 } else if (!stopping_recorders_) { |
134 ShutdownFinish(); | 134 ShutdownFinish(); |
135 } | 135 } |
136 } | 136 } |
137 | 137 |
138 void ChromotingHost::AddStatusObserver(HostStatusObserver* observer) { | 138 void ChromotingHost::AddStatusObserver(HostStatusObserver* observer) { |
139 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); | 139 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
140 status_observers_.AddObserver(observer); | 140 status_observers_.AddObserver(observer); |
141 } | 141 } |
142 | 142 |
143 void ChromotingHost::RemoveStatusObserver(HostStatusObserver* observer) { | 143 void ChromotingHost::RemoveStatusObserver(HostStatusObserver* observer) { |
144 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); | 144 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
145 status_observers_.RemoveObserver(observer); | 145 status_observers_.RemoveObserver(observer); |
146 } | 146 } |
147 | 147 |
148 void ChromotingHost::RejectAuthenticatingClient() { | 148 void ChromotingHost::RejectAuthenticatingClient() { |
149 DCHECK(authenticating_client_); | 149 DCHECK(authenticating_client_); |
150 reject_authenticating_client_ = true; | 150 reject_authenticating_client_ = true; |
151 } | 151 } |
152 | 152 |
153 void ChromotingHost::SetAuthenticatorFactory( | 153 void ChromotingHost::SetAuthenticatorFactory( |
154 scoped_ptr<protocol::AuthenticatorFactory> authenticator_factory) { | 154 scoped_ptr<protocol::AuthenticatorFactory> authenticator_factory) { |
155 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); | 155 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
156 session_manager_->set_authenticator_factory(authenticator_factory.Pass()); | 156 session_manager_->set_authenticator_factory(authenticator_factory.Pass()); |
157 } | 157 } |
158 | 158 |
159 void ChromotingHost::SetMaximumSessionDuration( | 159 void ChromotingHost::SetMaximumSessionDuration( |
160 const base::TimeDelta& max_session_duration) { | 160 const base::TimeDelta& max_session_duration) { |
161 max_session_duration_ = max_session_duration; | 161 max_session_duration_ = max_session_duration; |
162 } | 162 } |
163 | 163 |
164 //////////////////////////////////////////////////////////////////////////// | 164 //////////////////////////////////////////////////////////////////////////// |
165 // protocol::ClientSession::EventHandler implementation. | 165 // protocol::ClientSession::EventHandler implementation. |
166 void ChromotingHost::OnSessionAuthenticated(ClientSession* client) { | 166 void ChromotingHost::OnSessionAuthenticated(ClientSession* client) { |
167 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); | 167 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
168 | 168 |
169 login_backoff_.Reset(); | 169 login_backoff_.Reset(); |
170 | 170 |
171 // Disconnect all other clients. | 171 // Disconnect all other clients. |
172 // Iterate over a copy of the list of clients, to avoid mutating the list | 172 // Iterate over a copy of the list of clients, to avoid mutating the list |
173 // while iterating over it. | 173 // while iterating over it. |
174 ClientList clients_copy(clients_); | 174 ClientList clients_copy(clients_); |
175 for (ClientList::const_iterator other_client = clients_copy.begin(); | 175 for (ClientList::const_iterator other_client = clients_copy.begin(); |
176 other_client != clients_copy.end(); ++other_client) { | 176 other_client != clients_copy.end(); ++other_client) { |
177 if ((*other_client) != client) { | 177 if ((*other_client) != client) { |
(...skipping 14 matching lines...) Expand all Loading... |
192 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, | 192 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, |
193 OnClientAuthenticated(jid)); | 193 OnClientAuthenticated(jid)); |
194 authenticating_client_ = false; | 194 authenticating_client_ = false; |
195 | 195 |
196 if (reject_authenticating_client_) { | 196 if (reject_authenticating_client_) { |
197 client->Disconnect(); | 197 client->Disconnect(); |
198 } | 198 } |
199 } | 199 } |
200 | 200 |
201 void ChromotingHost::OnSessionChannelsConnected(ClientSession* client) { | 201 void ChromotingHost::OnSessionChannelsConnected(ClientSession* client) { |
202 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); | 202 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
203 | 203 |
204 // Then we create a ScreenRecorder passing the message loops that | 204 // Then we create a ScreenRecorder passing the message loops that |
205 // it should run on. | 205 // it should run on. |
206 Encoder* encoder = CreateEncoder(client->connection()->session()->config()); | 206 Encoder* encoder = CreateEncoder(client->connection()->session()->config()); |
207 | 207 |
208 recorder_ = new ScreenRecorder(context_->main_message_loop(), | 208 recorder_ = new ScreenRecorder(context_->capture_task_runner(), |
209 context_->encode_message_loop(), | 209 context_->encode_task_runner(), |
210 context_->network_message_loop(), | 210 context_->network_task_runner(), |
211 desktop_environment_->capturer(), | 211 desktop_environment_->capturer(), |
212 encoder); | 212 encoder); |
213 | 213 |
214 // Immediately add the connection and start the session. | 214 // Immediately add the connection and start the session. |
215 recorder_->AddConnection(client->connection()); | 215 recorder_->AddConnection(client->connection()); |
216 recorder_->Start(); | 216 recorder_->Start(); |
217 desktop_environment_->OnSessionStarted(client->CreateClipboardProxy()); | 217 desktop_environment_->OnSessionStarted(client->CreateClipboardProxy()); |
218 | 218 |
219 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, | 219 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, |
220 OnClientConnected(client->client_jid())); | 220 OnClientConnected(client->client_jid())); |
221 } | 221 } |
222 | 222 |
223 void ChromotingHost::OnSessionAuthenticationFailed(ClientSession* client) { | 223 void ChromotingHost::OnSessionAuthenticationFailed(ClientSession* client) { |
224 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); | 224 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
225 | 225 |
226 // Notify observers. | 226 // Notify observers. |
227 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, | 227 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, |
228 OnAccessDenied(client->client_jid())); | 228 OnAccessDenied(client->client_jid())); |
229 } | 229 } |
230 | 230 |
231 void ChromotingHost::OnSessionClosed(ClientSession* client) { | 231 void ChromotingHost::OnSessionClosed(ClientSession* client) { |
232 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); | 232 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
233 | 233 |
234 scoped_ptr<ClientSession> client_destroyer(client); | 234 scoped_ptr<ClientSession> client_destroyer(client); |
235 | 235 |
236 ClientList::iterator it = std::find(clients_.begin(), clients_.end(), client); | 236 ClientList::iterator it = std::find(clients_.begin(), clients_.end(), client); |
237 CHECK(it != clients_.end()); | 237 CHECK(it != clients_.end()); |
238 clients_.erase(it); | 238 clients_.erase(it); |
239 | 239 |
240 if (recorder_.get()) { | 240 if (recorder_.get()) { |
241 recorder_->RemoveConnection(client->connection()); | 241 recorder_->RemoveConnection(client->connection()); |
242 } | 242 } |
243 | 243 |
244 if (client->is_authenticated()) { | 244 if (client->is_authenticated()) { |
245 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, | 245 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, |
246 OnClientDisconnected(client->client_jid())); | 246 OnClientDisconnected(client->client_jid())); |
247 | 247 |
248 // TODO(sergeyu): This teardown logic belongs to ClientSession | 248 // TODO(sergeyu): This teardown logic belongs to ClientSession |
249 // class. It should start/stop screen recorder or tell the host | 249 // class. It should start/stop screen recorder or tell the host |
250 // when to do it. | 250 // when to do it. |
251 if (recorder_.get()) { | 251 if (recorder_.get()) { |
252 // Currently we don't allow more than one simultaneous connection, | 252 // Currently we don't allow more than one simultaneous connection, |
253 // so we need to shutdown recorder when a client disconnects. | 253 // so we need to shutdown recorder when a client disconnects. |
254 StopScreenRecorder(); | 254 StopScreenRecorder(); |
255 } | 255 } |
256 desktop_environment_->OnSessionFinished(); | 256 desktop_environment_->OnSessionFinished(); |
257 } | 257 } |
258 } | 258 } |
259 | 259 |
260 void ChromotingHost::OnSessionSequenceNumber(ClientSession* session, | 260 void ChromotingHost::OnSessionSequenceNumber(ClientSession* session, |
261 int64 sequence_number) { | 261 int64 sequence_number) { |
262 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); | 262 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
263 if (recorder_.get()) | 263 if (recorder_.get()) |
264 recorder_->UpdateSequenceNumber(sequence_number); | 264 recorder_->UpdateSequenceNumber(sequence_number); |
265 } | 265 } |
266 | 266 |
267 void ChromotingHost::OnSessionRouteChange( | 267 void ChromotingHost::OnSessionRouteChange( |
268 ClientSession* session, | 268 ClientSession* session, |
269 const std::string& channel_name, | 269 const std::string& channel_name, |
270 const protocol::TransportRoute& route) { | 270 const protocol::TransportRoute& route) { |
271 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); | 271 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
272 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, | 272 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, |
273 OnClientRouteChange(session->client_jid(), channel_name, | 273 OnClientRouteChange(session->client_jid(), channel_name, |
274 route)); | 274 route)); |
275 } | 275 } |
276 | 276 |
277 void ChromotingHost::OnSessionManagerReady() { | 277 void ChromotingHost::OnSessionManagerReady() { |
278 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); | 278 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
279 // Don't need to do anything here, just wait for incoming | 279 // Don't need to do anything here, just wait for incoming |
280 // connections. | 280 // connections. |
281 } | 281 } |
282 | 282 |
283 void ChromotingHost::OnIncomingSession( | 283 void ChromotingHost::OnIncomingSession( |
284 protocol::Session* session, | 284 protocol::Session* session, |
285 protocol::SessionManager::IncomingSessionResponse* response) { | 285 protocol::SessionManager::IncomingSessionResponse* response) { |
286 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); | 286 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
287 | 287 |
288 if (state_ != kStarted) { | 288 if (state_ != kStarted) { |
289 *response = protocol::SessionManager::DECLINE; | 289 *response = protocol::SessionManager::DECLINE; |
290 return; | 290 return; |
291 } | 291 } |
292 | 292 |
293 if (login_backoff_.ShouldRejectRequest()) { | 293 if (login_backoff_.ShouldRejectRequest()) { |
294 *response = protocol::SessionManager::OVERLOAD; | 294 *response = protocol::SessionManager::OVERLOAD; |
295 return; | 295 return; |
296 } | 296 } |
(...skipping 22 matching lines...) Expand all Loading... |
319 scoped_ptr<protocol::ConnectionToClient> connection( | 319 scoped_ptr<protocol::ConnectionToClient> connection( |
320 new protocol::ConnectionToClient(session)); | 320 new protocol::ConnectionToClient(session)); |
321 ClientSession* client = new ClientSession( | 321 ClientSession* client = new ClientSession( |
322 this, connection.Pass(), desktop_environment_->event_executor(), | 322 this, connection.Pass(), desktop_environment_->event_executor(), |
323 desktop_environment_->capturer(), max_session_duration_); | 323 desktop_environment_->capturer(), max_session_duration_); |
324 clients_.push_back(client); | 324 clients_.push_back(client); |
325 } | 325 } |
326 | 326 |
327 void ChromotingHost::set_protocol_config( | 327 void ChromotingHost::set_protocol_config( |
328 protocol::CandidateSessionConfig* config) { | 328 protocol::CandidateSessionConfig* config) { |
329 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); | 329 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
330 DCHECK(config); | 330 DCHECK(config); |
331 DCHECK_EQ(state_, kInitial); | 331 DCHECK_EQ(state_, kInitial); |
332 protocol_config_.reset(config); | 332 protocol_config_.reset(config); |
333 } | 333 } |
334 | 334 |
335 void ChromotingHost::OnLocalMouseMoved(const SkIPoint& new_pos) { | 335 void ChromotingHost::OnLocalMouseMoved(const SkIPoint& new_pos) { |
336 if (!context_->network_message_loop()->BelongsToCurrentThread()) { | 336 if (!context_->network_task_runner()->BelongsToCurrentThread()) { |
337 context_->network_message_loop()->PostTask( | 337 context_->network_task_runner()->PostTask( |
338 FROM_HERE, base::Bind(&ChromotingHost::OnLocalMouseMoved, | 338 FROM_HERE, base::Bind(&ChromotingHost::OnLocalMouseMoved, |
339 this, new_pos)); | 339 this, new_pos)); |
340 return; | 340 return; |
341 } | 341 } |
342 | 342 |
343 ClientList::iterator client; | 343 ClientList::iterator client; |
344 for (client = clients_.begin(); client != clients_.end(); ++client) { | 344 for (client = clients_.begin(); client != clients_.end(); ++client) { |
345 (*client)->LocalMouseMoved(new_pos); | 345 (*client)->LocalMouseMoved(new_pos); |
346 } | 346 } |
347 } | 347 } |
348 | 348 |
349 void ChromotingHost::PauseSession(bool pause) { | 349 void ChromotingHost::PauseSession(bool pause) { |
350 if (!context_->network_message_loop()->BelongsToCurrentThread()) { | 350 if (!context_->network_task_runner()->BelongsToCurrentThread()) { |
351 context_->network_message_loop()->PostTask( | 351 context_->network_task_runner()->PostTask( |
352 FROM_HERE, base::Bind(&ChromotingHost::PauseSession, this, pause)); | 352 FROM_HERE, base::Bind(&ChromotingHost::PauseSession, this, pause)); |
353 return; | 353 return; |
354 } | 354 } |
355 | 355 |
356 ClientList::iterator client; | 356 ClientList::iterator client; |
357 for (client = clients_.begin(); client != clients_.end(); ++client) { | 357 for (client = clients_.begin(); client != clients_.end(); ++client) { |
358 (*client)->SetDisableInputs(pause); | 358 (*client)->SetDisableInputs(pause); |
359 } | 359 } |
360 } | 360 } |
361 | 361 |
362 void ChromotingHost::DisconnectAllClients() { | 362 void ChromotingHost::DisconnectAllClients() { |
363 if (!context_->network_message_loop()->BelongsToCurrentThread()) { | 363 if (!context_->network_task_runner()->BelongsToCurrentThread()) { |
364 context_->network_message_loop()->PostTask( | 364 context_->network_task_runner()->PostTask( |
365 FROM_HERE, base::Bind(&ChromotingHost::DisconnectAllClients, this)); | 365 FROM_HERE, base::Bind(&ChromotingHost::DisconnectAllClients, this)); |
366 return; | 366 return; |
367 } | 367 } |
368 | 368 |
369 while (!clients_.empty()) { | 369 while (!clients_.empty()) { |
370 size_t size = clients_.size(); | 370 size_t size = clients_.size(); |
371 clients_.front()->Disconnect(); | 371 clients_.front()->Disconnect(); |
372 CHECK_EQ(clients_.size(), size - 1); | 372 CHECK_EQ(clients_.size(), size - 1); |
373 } | 373 } |
374 } | 374 } |
375 | 375 |
376 void ChromotingHost::SetUiStrings(const UiStrings& ui_strings) { | 376 void ChromotingHost::SetUiStrings(const UiStrings& ui_strings) { |
377 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); | 377 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
378 DCHECK_EQ(state_, kInitial); | 378 DCHECK_EQ(state_, kInitial); |
379 | 379 |
380 ui_strings_ = ui_strings; | 380 ui_strings_ = ui_strings; |
381 } | 381 } |
382 | 382 |
383 // TODO(sergeyu): Move this to SessionManager? | 383 // TODO(sergeyu): Move this to SessionManager? |
384 // static | 384 // static |
385 Encoder* ChromotingHost::CreateEncoder(const protocol::SessionConfig& config) { | 385 Encoder* ChromotingHost::CreateEncoder(const protocol::SessionConfig& config) { |
386 const protocol::ChannelConfig& video_config = config.video_config(); | 386 const protocol::ChannelConfig& video_config = config.video_config(); |
387 | 387 |
388 if (video_config.codec == protocol::ChannelConfig::CODEC_VERBATIM) { | 388 if (video_config.codec == protocol::ChannelConfig::CODEC_VERBATIM) { |
389 return EncoderRowBased::CreateVerbatimEncoder(); | 389 return EncoderRowBased::CreateVerbatimEncoder(); |
390 } else if (video_config.codec == protocol::ChannelConfig::CODEC_ZIP) { | 390 } else if (video_config.codec == protocol::ChannelConfig::CODEC_ZIP) { |
391 return EncoderRowBased::CreateZlibEncoder(); | 391 return EncoderRowBased::CreateZlibEncoder(); |
392 } else if (video_config.codec == protocol::ChannelConfig::CODEC_VP8) { | 392 } else if (video_config.codec == protocol::ChannelConfig::CODEC_VP8) { |
393 return new remoting::EncoderVp8(); | 393 return new remoting::EncoderVp8(); |
394 } | 394 } |
395 | 395 |
396 return NULL; | 396 return NULL; |
397 } | 397 } |
398 | 398 |
399 void ChromotingHost::StopScreenRecorder() { | 399 void ChromotingHost::StopScreenRecorder() { |
400 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); | 400 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
401 DCHECK(recorder_.get()); | 401 DCHECK(recorder_.get()); |
402 | 402 |
403 ++stopping_recorders_; | 403 ++stopping_recorders_; |
404 scoped_refptr<ScreenRecorder> recorder = recorder_; | 404 scoped_refptr<ScreenRecorder> recorder = recorder_; |
405 recorder_ = NULL; | 405 recorder_ = NULL; |
406 recorder->Stop(base::Bind(&ChromotingHost::OnScreenRecorderStopped, this)); | 406 recorder->Stop(base::Bind(&ChromotingHost::OnScreenRecorderStopped, this)); |
407 } | 407 } |
408 | 408 |
409 void ChromotingHost::OnScreenRecorderStopped() { | 409 void ChromotingHost::OnScreenRecorderStopped() { |
410 if (!context_->network_message_loop()->BelongsToCurrentThread()) { | 410 if (!context_->network_task_runner()->BelongsToCurrentThread()) { |
411 context_->network_message_loop()->PostTask( | 411 context_->network_task_runner()->PostTask( |
412 FROM_HERE, base::Bind(&ChromotingHost::OnScreenRecorderStopped, this)); | 412 FROM_HERE, base::Bind(&ChromotingHost::OnScreenRecorderStopped, this)); |
413 return; | 413 return; |
414 } | 414 } |
415 | 415 |
416 --stopping_recorders_; | 416 --stopping_recorders_; |
417 DCHECK_GE(stopping_recorders_, 0); | 417 DCHECK_GE(stopping_recorders_, 0); |
418 | 418 |
419 if (!stopping_recorders_ && state_ == kStopping) | 419 if (!stopping_recorders_ && state_ == kStopping) |
420 ShutdownFinish(); | 420 ShutdownFinish(); |
421 } | 421 } |
422 | 422 |
423 void ChromotingHost::ShutdownFinish() { | 423 void ChromotingHost::ShutdownFinish() { |
424 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); | 424 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
425 DCHECK(!stopping_recorders_); | 425 DCHECK(!stopping_recorders_); |
426 | 426 |
427 state_ = kStopped; | 427 state_ = kStopped; |
428 | 428 |
429 // Keep reference to |this|, so that we don't get destroyed while | 429 // Keep reference to |this|, so that we don't get destroyed while |
430 // sending notifications. | 430 // sending notifications. |
431 scoped_refptr<ChromotingHost> self(this); | 431 scoped_refptr<ChromotingHost> self(this); |
432 | 432 |
433 // Notify observers. | 433 // Notify observers. |
434 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, | 434 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, |
435 OnShutdown()); | 435 OnShutdown()); |
436 | 436 |
437 for (std::vector<base::Closure>::iterator it = shutdown_tasks_.begin(); | 437 for (std::vector<base::Closure>::iterator it = shutdown_tasks_.begin(); |
438 it != shutdown_tasks_.end(); ++it) { | 438 it != shutdown_tasks_.end(); ++it) { |
439 it->Run(); | 439 it->Run(); |
440 } | 440 } |
441 shutdown_tasks_.clear(); | 441 shutdown_tasks_.clear(); |
442 } | 442 } |
443 | 443 |
444 } // namespace remoting | 444 } // namespace remoting |
OLD | NEW |