| 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 //////////////////////////////////////////////////////////////////////////// | 159 //////////////////////////////////////////////////////////////////////////// |
| 160 // protocol::ClientSession::EventHandler implementation. | 160 // protocol::ClientSession::EventHandler implementation. |
| 161 void ChromotingHost::OnSessionAuthenticated(ClientSession* client) { | 161 void ChromotingHost::OnSessionAuthenticated(ClientSession* client) { |
| 162 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); | 162 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 163 | 163 |
| 164 login_backoff_.Reset(); | 164 login_backoff_.Reset(); |
| 165 | 165 |
| 166 // Disconnect all other clients. | 166 // Disconnect all other clients. |
| 167 // Iterate over a copy of the list of clients, to avoid mutating the list | 167 // Iterate over a copy of the list of clients, to avoid mutating the list |
| 168 // while iterating over it. | 168 // while iterating over it. |
| 169 ClientList clients_copy(clients_); | 169 ClientList clients_copy(clients_); |
| 170 for (ClientList::const_iterator other_client = clients_copy.begin(); | 170 for (ClientList::const_iterator other_client = clients_copy.begin(); |
| 171 other_client != clients_copy.end(); ++other_client) { | 171 other_client != clients_copy.end(); ++other_client) { |
| 172 if ((*other_client) != client) { | 172 if ((*other_client) != client) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 187 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, | 187 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, |
| 188 OnClientAuthenticated(jid)); | 188 OnClientAuthenticated(jid)); |
| 189 authenticating_client_ = false; | 189 authenticating_client_ = false; |
| 190 | 190 |
| 191 if (reject_authenticating_client_) { | 191 if (reject_authenticating_client_) { |
| 192 client->Disconnect(); | 192 client->Disconnect(); |
| 193 } | 193 } |
| 194 } | 194 } |
| 195 | 195 |
| 196 void ChromotingHost::OnSessionChannelsConnected(ClientSession* client) { | 196 void ChromotingHost::OnSessionChannelsConnected(ClientSession* client) { |
| 197 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); | 197 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 198 | 198 |
| 199 // Then we create a ScreenRecorder passing the message loops that | 199 // Then we create a ScreenRecorder passing the message loops that |
| 200 // it should run on. | 200 // it should run on. |
| 201 Encoder* encoder = CreateEncoder(client->connection()->session()->config()); | 201 Encoder* encoder = CreateEncoder(client->connection()->session()->config()); |
| 202 | 202 |
| 203 recorder_ = new ScreenRecorder(context_->main_message_loop(), | 203 recorder_ = new ScreenRecorder(context_->main_task_runner(), |
| 204 context_->encode_message_loop(), | 204 context_->encode_task_runner(), |
| 205 context_->network_message_loop(), | 205 context_->network_task_runner(), |
| 206 desktop_environment_->capturer(), | 206 desktop_environment_->capturer(), |
| 207 encoder); | 207 encoder); |
| 208 | 208 |
| 209 // Immediately add the connection and start the session. | 209 // Immediately add the connection and start the session. |
| 210 recorder_->AddConnection(client->connection()); | 210 recorder_->AddConnection(client->connection()); |
| 211 recorder_->Start(); | 211 recorder_->Start(); |
| 212 desktop_environment_->OnSessionStarted(client->CreateClipboardProxy()); | 212 desktop_environment_->OnSessionStarted(client->CreateClipboardProxy()); |
| 213 | 213 |
| 214 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, | 214 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, |
| 215 OnClientConnected(client->client_jid())); | 215 OnClientConnected(client->client_jid())); |
| 216 } | 216 } |
| 217 | 217 |
| 218 void ChromotingHost::OnSessionAuthenticationFailed(ClientSession* client) { | 218 void ChromotingHost::OnSessionAuthenticationFailed(ClientSession* client) { |
| 219 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); | 219 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 220 | 220 |
| 221 // Notify observers. | 221 // Notify observers. |
| 222 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, | 222 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, |
| 223 OnAccessDenied(client->client_jid())); | 223 OnAccessDenied(client->client_jid())); |
| 224 } | 224 } |
| 225 | 225 |
| 226 void ChromotingHost::OnSessionClosed(ClientSession* client) { | 226 void ChromotingHost::OnSessionClosed(ClientSession* client) { |
| 227 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); | 227 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 228 | 228 |
| 229 scoped_ptr<ClientSession> client_destroyer(client); | 229 scoped_ptr<ClientSession> client_destroyer(client); |
| 230 | 230 |
| 231 ClientList::iterator it = std::find(clients_.begin(), clients_.end(), client); | 231 ClientList::iterator it = std::find(clients_.begin(), clients_.end(), client); |
| 232 CHECK(it != clients_.end()); | 232 CHECK(it != clients_.end()); |
| 233 clients_.erase(it); | 233 clients_.erase(it); |
| 234 | 234 |
| 235 if (recorder_.get()) { | 235 if (recorder_.get()) { |
| 236 recorder_->RemoveConnection(client->connection()); | 236 recorder_->RemoveConnection(client->connection()); |
| 237 } | 237 } |
| 238 | 238 |
| 239 if (client->is_authenticated()) { | 239 if (client->is_authenticated()) { |
| 240 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, | 240 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, |
| 241 OnClientDisconnected(client->client_jid())); | 241 OnClientDisconnected(client->client_jid())); |
| 242 | 242 |
| 243 // TODO(sergeyu): This teardown logic belongs to ClientSession | 243 // TODO(sergeyu): This teardown logic belongs to ClientSession |
| 244 // class. It should start/stop screen recorder or tell the host | 244 // class. It should start/stop screen recorder or tell the host |
| 245 // when to do it. | 245 // when to do it. |
| 246 if (recorder_.get()) { | 246 if (recorder_.get()) { |
| 247 // Currently we don't allow more than one simultaneous connection, | 247 // Currently we don't allow more than one simultaneous connection, |
| 248 // so we need to shutdown recorder when a client disconnects. | 248 // so we need to shutdown recorder when a client disconnects. |
| 249 StopScreenRecorder(); | 249 StopScreenRecorder(); |
| 250 } | 250 } |
| 251 desktop_environment_->OnSessionFinished(); | 251 desktop_environment_->OnSessionFinished(); |
| 252 } | 252 } |
| 253 } | 253 } |
| 254 | 254 |
| 255 void ChromotingHost::OnSessionSequenceNumber(ClientSession* session, | 255 void ChromotingHost::OnSessionSequenceNumber(ClientSession* session, |
| 256 int64 sequence_number) { | 256 int64 sequence_number) { |
| 257 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); | 257 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 258 if (recorder_.get()) | 258 if (recorder_.get()) |
| 259 recorder_->UpdateSequenceNumber(sequence_number); | 259 recorder_->UpdateSequenceNumber(sequence_number); |
| 260 } | 260 } |
| 261 | 261 |
| 262 void ChromotingHost::OnSessionRouteChange( | 262 void ChromotingHost::OnSessionRouteChange( |
| 263 ClientSession* session, | 263 ClientSession* session, |
| 264 const std::string& channel_name, | 264 const std::string& channel_name, |
| 265 const protocol::TransportRoute& route) { | 265 const protocol::TransportRoute& route) { |
| 266 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); | 266 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 267 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, | 267 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, |
| 268 OnClientRouteChange(session->client_jid(), channel_name, | 268 OnClientRouteChange(session->client_jid(), channel_name, |
| 269 route)); | 269 route)); |
| 270 } | 270 } |
| 271 | 271 |
| 272 void ChromotingHost::OnSessionManagerReady() { | 272 void ChromotingHost::OnSessionManagerReady() { |
| 273 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); | 273 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 274 // Don't need to do anything here, just wait for incoming | 274 // Don't need to do anything here, just wait for incoming |
| 275 // connections. | 275 // connections. |
| 276 } | 276 } |
| 277 | 277 |
| 278 void ChromotingHost::OnIncomingSession( | 278 void ChromotingHost::OnIncomingSession( |
| 279 protocol::Session* session, | 279 protocol::Session* session, |
| 280 protocol::SessionManager::IncomingSessionResponse* response) { | 280 protocol::SessionManager::IncomingSessionResponse* response) { |
| 281 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); | 281 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 282 | 282 |
| 283 if (state_ != kStarted) { | 283 if (state_ != kStarted) { |
| 284 *response = protocol::SessionManager::DECLINE; | 284 *response = protocol::SessionManager::DECLINE; |
| 285 return; | 285 return; |
| 286 } | 286 } |
| 287 | 287 |
| 288 if (login_backoff_.ShouldRejectRequest()) { | 288 if (login_backoff_.ShouldRejectRequest()) { |
| 289 *response = protocol::SessionManager::OVERLOAD; | 289 *response = protocol::SessionManager::OVERLOAD; |
| 290 return; | 290 return; |
| 291 } | 291 } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 314 scoped_ptr<protocol::ConnectionToClient> connection( | 314 scoped_ptr<protocol::ConnectionToClient> connection( |
| 315 new protocol::ConnectionToClient(session)); | 315 new protocol::ConnectionToClient(session)); |
| 316 ClientSession* client = new ClientSession( | 316 ClientSession* client = new ClientSession( |
| 317 this, connection.Pass(), desktop_environment_->event_executor(), | 317 this, connection.Pass(), desktop_environment_->event_executor(), |
| 318 desktop_environment_->capturer()); | 318 desktop_environment_->capturer()); |
| 319 clients_.push_back(client); | 319 clients_.push_back(client); |
| 320 } | 320 } |
| 321 | 321 |
| 322 void ChromotingHost::set_protocol_config( | 322 void ChromotingHost::set_protocol_config( |
| 323 protocol::CandidateSessionConfig* config) { | 323 protocol::CandidateSessionConfig* config) { |
| 324 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); | 324 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 325 DCHECK(config); | 325 DCHECK(config); |
| 326 DCHECK_EQ(state_, kInitial); | 326 DCHECK_EQ(state_, kInitial); |
| 327 protocol_config_.reset(config); | 327 protocol_config_.reset(config); |
| 328 } | 328 } |
| 329 | 329 |
| 330 void ChromotingHost::OnLocalMouseMoved(const SkIPoint& new_pos) { | 330 void ChromotingHost::OnLocalMouseMoved(const SkIPoint& new_pos) { |
| 331 if (!context_->network_message_loop()->BelongsToCurrentThread()) { | 331 if (!context_->network_task_runner()->BelongsToCurrentThread()) { |
| 332 context_->network_message_loop()->PostTask( | 332 context_->network_task_runner()->PostTask( |
| 333 FROM_HERE, base::Bind(&ChromotingHost::OnLocalMouseMoved, | 333 FROM_HERE, base::Bind(&ChromotingHost::OnLocalMouseMoved, |
| 334 this, new_pos)); | 334 this, new_pos)); |
| 335 return; | 335 return; |
| 336 } | 336 } |
| 337 | 337 |
| 338 ClientList::iterator client; | 338 ClientList::iterator client; |
| 339 for (client = clients_.begin(); client != clients_.end(); ++client) { | 339 for (client = clients_.begin(); client != clients_.end(); ++client) { |
| 340 (*client)->LocalMouseMoved(new_pos); | 340 (*client)->LocalMouseMoved(new_pos); |
| 341 } | 341 } |
| 342 } | 342 } |
| 343 | 343 |
| 344 void ChromotingHost::PauseSession(bool pause) { | 344 void ChromotingHost::PauseSession(bool pause) { |
| 345 if (!context_->network_message_loop()->BelongsToCurrentThread()) { | 345 if (!context_->network_task_runner()->BelongsToCurrentThread()) { |
| 346 context_->network_message_loop()->PostTask( | 346 context_->network_task_runner()->PostTask( |
| 347 FROM_HERE, base::Bind(&ChromotingHost::PauseSession, this, pause)); | 347 FROM_HERE, base::Bind(&ChromotingHost::PauseSession, this, pause)); |
| 348 return; | 348 return; |
| 349 } | 349 } |
| 350 | 350 |
| 351 ClientList::iterator client; | 351 ClientList::iterator client; |
| 352 for (client = clients_.begin(); client != clients_.end(); ++client) { | 352 for (client = clients_.begin(); client != clients_.end(); ++client) { |
| 353 (*client)->SetDisableInputs(pause); | 353 (*client)->SetDisableInputs(pause); |
| 354 } | 354 } |
| 355 } | 355 } |
| 356 | 356 |
| 357 void ChromotingHost::DisconnectAllClients() { | 357 void ChromotingHost::DisconnectAllClients() { |
| 358 if (!context_->network_message_loop()->BelongsToCurrentThread()) { | 358 if (!context_->network_task_runner()->BelongsToCurrentThread()) { |
| 359 context_->network_message_loop()->PostTask( | 359 context_->network_task_runner()->PostTask( |
| 360 FROM_HERE, base::Bind(&ChromotingHost::DisconnectAllClients, this)); | 360 FROM_HERE, base::Bind(&ChromotingHost::DisconnectAllClients, this)); |
| 361 return; | 361 return; |
| 362 } | 362 } |
| 363 | 363 |
| 364 while (!clients_.empty()) { | 364 while (!clients_.empty()) { |
| 365 size_t size = clients_.size(); | 365 size_t size = clients_.size(); |
| 366 clients_.front()->Disconnect(); | 366 clients_.front()->Disconnect(); |
| 367 CHECK_EQ(clients_.size(), size - 1); | 367 CHECK_EQ(clients_.size(), size - 1); |
| 368 } | 368 } |
| 369 } | 369 } |
| 370 | 370 |
| 371 void ChromotingHost::SetUiStrings(const UiStrings& ui_strings) { | 371 void ChromotingHost::SetUiStrings(const UiStrings& ui_strings) { |
| 372 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); | 372 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 373 DCHECK_EQ(state_, kInitial); | 373 DCHECK_EQ(state_, kInitial); |
| 374 | 374 |
| 375 ui_strings_ = ui_strings; | 375 ui_strings_ = ui_strings; |
| 376 } | 376 } |
| 377 | 377 |
| 378 // TODO(sergeyu): Move this to SessionManager? | 378 // TODO(sergeyu): Move this to SessionManager? |
| 379 // static | 379 // static |
| 380 Encoder* ChromotingHost::CreateEncoder(const protocol::SessionConfig& config) { | 380 Encoder* ChromotingHost::CreateEncoder(const protocol::SessionConfig& config) { |
| 381 const protocol::ChannelConfig& video_config = config.video_config(); | 381 const protocol::ChannelConfig& video_config = config.video_config(); |
| 382 | 382 |
| 383 if (video_config.codec == protocol::ChannelConfig::CODEC_VERBATIM) { | 383 if (video_config.codec == protocol::ChannelConfig::CODEC_VERBATIM) { |
| 384 return EncoderRowBased::CreateVerbatimEncoder(); | 384 return EncoderRowBased::CreateVerbatimEncoder(); |
| 385 } else if (video_config.codec == protocol::ChannelConfig::CODEC_ZIP) { | 385 } else if (video_config.codec == protocol::ChannelConfig::CODEC_ZIP) { |
| 386 return EncoderRowBased::CreateZlibEncoder(); | 386 return EncoderRowBased::CreateZlibEncoder(); |
| 387 } else if (video_config.codec == protocol::ChannelConfig::CODEC_VP8) { | 387 } else if (video_config.codec == protocol::ChannelConfig::CODEC_VP8) { |
| 388 return new remoting::EncoderVp8(); | 388 return new remoting::EncoderVp8(); |
| 389 } | 389 } |
| 390 | 390 |
| 391 return NULL; | 391 return NULL; |
| 392 } | 392 } |
| 393 | 393 |
| 394 void ChromotingHost::StopScreenRecorder() { | 394 void ChromotingHost::StopScreenRecorder() { |
| 395 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); | 395 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 396 DCHECK(recorder_.get()); | 396 DCHECK(recorder_.get()); |
| 397 | 397 |
| 398 ++stopping_recorders_; | 398 ++stopping_recorders_; |
| 399 scoped_refptr<ScreenRecorder> recorder = recorder_; | 399 scoped_refptr<ScreenRecorder> recorder = recorder_; |
| 400 recorder_ = NULL; | 400 recorder_ = NULL; |
| 401 recorder->Stop(base::Bind(&ChromotingHost::OnScreenRecorderStopped, this)); | 401 recorder->Stop(base::Bind(&ChromotingHost::OnScreenRecorderStopped, this)); |
| 402 } | 402 } |
| 403 | 403 |
| 404 void ChromotingHost::OnScreenRecorderStopped() { | 404 void ChromotingHost::OnScreenRecorderStopped() { |
| 405 if (!context_->network_message_loop()->BelongsToCurrentThread()) { | 405 if (!context_->network_task_runner()->BelongsToCurrentThread()) { |
| 406 context_->network_message_loop()->PostTask( | 406 context_->network_task_runner()->PostTask( |
| 407 FROM_HERE, base::Bind(&ChromotingHost::OnScreenRecorderStopped, this)); | 407 FROM_HERE, base::Bind(&ChromotingHost::OnScreenRecorderStopped, this)); |
| 408 return; | 408 return; |
| 409 } | 409 } |
| 410 | 410 |
| 411 --stopping_recorders_; | 411 --stopping_recorders_; |
| 412 DCHECK_GE(stopping_recorders_, 0); | 412 DCHECK_GE(stopping_recorders_, 0); |
| 413 | 413 |
| 414 if (!stopping_recorders_ && state_ == kStopping) | 414 if (!stopping_recorders_ && state_ == kStopping) |
| 415 ShutdownFinish(); | 415 ShutdownFinish(); |
| 416 } | 416 } |
| 417 | 417 |
| 418 void ChromotingHost::ShutdownFinish() { | 418 void ChromotingHost::ShutdownFinish() { |
| 419 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); | 419 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 420 DCHECK(!stopping_recorders_); | 420 DCHECK(!stopping_recorders_); |
| 421 | 421 |
| 422 state_ = kStopped; | 422 state_ = kStopped; |
| 423 | 423 |
| 424 // Keep reference to |this|, so that we don't get destroyed while | 424 // Keep reference to |this|, so that we don't get destroyed while |
| 425 // sending notifications. | 425 // sending notifications. |
| 426 scoped_refptr<ChromotingHost> self(this); | 426 scoped_refptr<ChromotingHost> self(this); |
| 427 | 427 |
| 428 // Notify observers. | 428 // Notify observers. |
| 429 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, | 429 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, |
| 430 OnShutdown()); | 430 OnShutdown()); |
| 431 | 431 |
| 432 for (std::vector<base::Closure>::iterator it = shutdown_tasks_.begin(); | 432 for (std::vector<base::Closure>::iterator it = shutdown_tasks_.begin(); |
| 433 it != shutdown_tasks_.end(); ++it) { | 433 it != shutdown_tasks_.end(); ++it) { |
| 434 it->Run(); | 434 it->Run(); |
| 435 } | 435 } |
| 436 shutdown_tasks_.clear(); | 436 shutdown_tasks_.clear(); |
| 437 } | 437 } |
| 438 | 438 |
| 439 } // namespace remoting | 439 } // namespace remoting |
| OLD | NEW |