| 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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 // has no significant state, -1 to never discard. | 50 // has no significant state, -1 to never discard. |
| 51 -1, | 51 -1, |
| 52 | 52 |
| 53 // Don't use initial delay unless the last request was an error. | 53 // Don't use initial delay unless the last request was an error. |
| 54 false, | 54 false, |
| 55 }; | 55 }; |
| 56 | 56 |
| 57 } // namespace | 57 } // namespace |
| 58 | 58 |
| 59 ChromotingHost::ChromotingHost( | 59 ChromotingHost::ChromotingHost( |
| 60 ChromotingHostContext* context, | |
| 61 SignalStrategy* signal_strategy, | 60 SignalStrategy* signal_strategy, |
| 62 DesktopEnvironmentFactory* desktop_environment_factory, | 61 DesktopEnvironmentFactory* desktop_environment_factory, |
| 63 scoped_ptr<protocol::SessionManager> session_manager) | 62 scoped_ptr<protocol::SessionManager> session_manager, |
| 64 : context_(context), | 63 scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner, |
| 65 desktop_environment_factory_(desktop_environment_factory), | 64 scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner, |
| 65 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner) |
| 66 : desktop_environment_factory_(desktop_environment_factory), |
| 66 session_manager_(session_manager.Pass()), | 67 session_manager_(session_manager.Pass()), |
| 68 capture_task_runner_(capture_task_runner), |
| 69 encode_task_runner_(encode_task_runner), |
| 70 network_task_runner_(network_task_runner), |
| 67 signal_strategy_(signal_strategy), | 71 signal_strategy_(signal_strategy), |
| 68 clients_count_(0), | 72 clients_count_(0), |
| 69 state_(kInitial), | 73 state_(kInitial), |
| 70 protocol_config_(protocol::CandidateSessionConfig::CreateDefault()), | 74 protocol_config_(protocol::CandidateSessionConfig::CreateDefault()), |
| 71 login_backoff_(&kDefaultBackoffPolicy), | 75 login_backoff_(&kDefaultBackoffPolicy), |
| 72 authenticating_client_(false), | 76 authenticating_client_(false), |
| 73 reject_authenticating_client_(false) { | 77 reject_authenticating_client_(false) { |
| 74 DCHECK(context_); | |
| 75 DCHECK(signal_strategy); | 78 DCHECK(signal_strategy); |
| 76 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 79 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 77 | 80 |
| 78 if (!desktop_environment_factory_->SupportsAudioCapture()) { | 81 if (!desktop_environment_factory_->SupportsAudioCapture()) { |
| 79 protocol::CandidateSessionConfig::DisableAudioChannel( | 82 protocol::CandidateSessionConfig::DisableAudioChannel( |
| 80 protocol_config_.get()); | 83 protocol_config_.get()); |
| 81 } | 84 } |
| 82 } | 85 } |
| 83 | 86 |
| 84 ChromotingHost::~ChromotingHost() { | 87 ChromotingHost::~ChromotingHost() { |
| 85 DCHECK(clients_.empty()); | 88 DCHECK(clients_.empty()); |
| 86 } | 89 } |
| 87 | 90 |
| 88 void ChromotingHost::Start(const std::string& xmpp_login) { | 91 void ChromotingHost::Start(const std::string& xmpp_login) { |
| 89 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 92 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 90 | 93 |
| 91 LOG(INFO) << "Starting host"; | 94 LOG(INFO) << "Starting host"; |
| 92 | 95 |
| 93 // Make sure this object is not started. | 96 // Make sure this object is not started. |
| 94 if (state_ != kInitial) | 97 if (state_ != kInitial) |
| 95 return; | 98 return; |
| 96 state_ = kStarted; | 99 state_ = kStarted; |
| 97 | 100 |
| 98 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, | 101 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, |
| 99 OnStart(xmpp_login)); | 102 OnStart(xmpp_login)); |
| 100 | 103 |
| 101 // Start the SessionManager, supplying this ChromotingHost as the listener. | 104 // Start the SessionManager, supplying this ChromotingHost as the listener. |
| 102 session_manager_->Init(signal_strategy_, this); | 105 session_manager_->Init(signal_strategy_, this); |
| 103 } | 106 } |
| 104 | 107 |
| 105 // This method is called when we need to destroy the host process. | 108 // This method is called when we need to destroy the host process. |
| 106 void ChromotingHost::Shutdown(const base::Closure& shutdown_task) { | 109 void ChromotingHost::Shutdown(const base::Closure& shutdown_task) { |
| 107 if (!context_->network_task_runner()->BelongsToCurrentThread()) { | 110 if (!network_task_runner_->BelongsToCurrentThread()) { |
| 108 context_->network_task_runner()->PostTask( | 111 network_task_runner_->PostTask( |
| 109 FROM_HERE, base::Bind(&ChromotingHost::Shutdown, this, shutdown_task)); | 112 FROM_HERE, base::Bind(&ChromotingHost::Shutdown, this, shutdown_task)); |
| 110 return; | 113 return; |
| 111 } | 114 } |
| 112 | 115 |
| 113 switch (state_) { | 116 switch (state_) { |
| 114 case kInitial: | 117 case kInitial: |
| 115 case kStopped: | 118 case kStopped: |
| 116 // Nothing to do if we are not started. | 119 // Nothing to do if we are not started. |
| 117 state_ = kStopped; | 120 state_ = kStopped; |
| 118 if (!shutdown_task.is_null()) | 121 if (!shutdown_task.is_null()) |
| 119 context_->network_task_runner()->PostTask(FROM_HERE, shutdown_task); | 122 network_task_runner_->PostTask(FROM_HERE, shutdown_task); |
| 120 break; | 123 break; |
| 121 | 124 |
| 122 case kStopping: | 125 case kStopping: |
| 123 // We are already stopping. Just save the task. | 126 // We are already stopping. Just save the task. |
| 124 if (!shutdown_task.is_null()) | 127 if (!shutdown_task.is_null()) |
| 125 shutdown_tasks_.push_back(shutdown_task); | 128 shutdown_tasks_.push_back(shutdown_task); |
| 126 break; | 129 break; |
| 127 | 130 |
| 128 case kStarted: | 131 case kStarted: |
| 129 if (!shutdown_task.is_null()) | 132 if (!shutdown_task.is_null()) |
| 130 shutdown_tasks_.push_back(shutdown_task); | 133 shutdown_tasks_.push_back(shutdown_task); |
| 131 state_ = kStopping; | 134 state_ = kStopping; |
| 132 | 135 |
| 133 // Disconnect all of the clients. | 136 // Disconnect all of the clients. |
| 134 while (!clients_.empty()) { | 137 while (!clients_.empty()) { |
| 135 clients_.front()->Disconnect(); | 138 clients_.front()->Disconnect(); |
| 136 } | 139 } |
| 137 | 140 |
| 138 // Run the remaining shutdown tasks. | 141 // Run the remaining shutdown tasks. |
| 139 if (state_ == kStopping && !clients_count_) | 142 if (state_ == kStopping && !clients_count_) |
| 140 ShutdownFinish(); | 143 ShutdownFinish(); |
| 141 | 144 |
| 142 break; | 145 break; |
| 143 } | 146 } |
| 144 } | 147 } |
| 145 | 148 |
| 146 void ChromotingHost::AddStatusObserver(HostStatusObserver* observer) { | 149 void ChromotingHost::AddStatusObserver(HostStatusObserver* observer) { |
| 147 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 150 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 148 status_observers_.AddObserver(observer); | 151 status_observers_.AddObserver(observer); |
| 149 } | 152 } |
| 150 | 153 |
| 151 void ChromotingHost::RemoveStatusObserver(HostStatusObserver* observer) { | 154 void ChromotingHost::RemoveStatusObserver(HostStatusObserver* observer) { |
| 152 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 155 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 153 status_observers_.RemoveObserver(observer); | 156 status_observers_.RemoveObserver(observer); |
| 154 } | 157 } |
| 155 | 158 |
| 156 void ChromotingHost::RejectAuthenticatingClient() { | 159 void ChromotingHost::RejectAuthenticatingClient() { |
| 157 DCHECK(authenticating_client_); | 160 DCHECK(authenticating_client_); |
| 158 reject_authenticating_client_ = true; | 161 reject_authenticating_client_ = true; |
| 159 } | 162 } |
| 160 | 163 |
| 161 void ChromotingHost::SetAuthenticatorFactory( | 164 void ChromotingHost::SetAuthenticatorFactory( |
| 162 scoped_ptr<protocol::AuthenticatorFactory> authenticator_factory) { | 165 scoped_ptr<protocol::AuthenticatorFactory> authenticator_factory) { |
| 163 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 166 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 164 session_manager_->set_authenticator_factory(authenticator_factory.Pass()); | 167 session_manager_->set_authenticator_factory(authenticator_factory.Pass()); |
| 165 } | 168 } |
| 166 | 169 |
| 167 void ChromotingHost::SetMaximumSessionDuration( | 170 void ChromotingHost::SetMaximumSessionDuration( |
| 168 const base::TimeDelta& max_session_duration) { | 171 const base::TimeDelta& max_session_duration) { |
| 169 max_session_duration_ = max_session_duration; | 172 max_session_duration_ = max_session_duration; |
| 170 } | 173 } |
| 171 | 174 |
| 172 //////////////////////////////////////////////////////////////////////////// | 175 //////////////////////////////////////////////////////////////////////////// |
| 173 // protocol::ClientSession::EventHandler implementation. | 176 // protocol::ClientSession::EventHandler implementation. |
| 174 void ChromotingHost::OnSessionAuthenticated(ClientSession* client) { | 177 void ChromotingHost::OnSessionAuthenticated(ClientSession* client) { |
| 175 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 178 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 176 | 179 |
| 177 login_backoff_.Reset(); | 180 login_backoff_.Reset(); |
| 178 | 181 |
| 179 // Disconnect all other clients. | 182 // Disconnect all other clients. |
| 180 // Iterate over a copy of the list of clients, to avoid mutating the list | 183 // Iterate over a copy of the list of clients, to avoid mutating the list |
| 181 // while iterating over it. | 184 // while iterating over it. |
| 182 ClientList clients_copy(clients_); | 185 ClientList clients_copy(clients_); |
| 183 for (ClientList::const_iterator other_client = clients_copy.begin(); | 186 for (ClientList::const_iterator other_client = clients_copy.begin(); |
| 184 other_client != clients_copy.end(); ++other_client) { | 187 other_client != clients_copy.end(); ++other_client) { |
| 185 if (other_client->get() != client) { | 188 if (other_client->get() != client) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 199 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, | 202 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, |
| 200 OnClientAuthenticated(jid)); | 203 OnClientAuthenticated(jid)); |
| 201 authenticating_client_ = false; | 204 authenticating_client_ = false; |
| 202 | 205 |
| 203 if (reject_authenticating_client_) { | 206 if (reject_authenticating_client_) { |
| 204 client->Disconnect(); | 207 client->Disconnect(); |
| 205 } | 208 } |
| 206 } | 209 } |
| 207 | 210 |
| 208 void ChromotingHost::OnSessionChannelsConnected(ClientSession* client) { | 211 void ChromotingHost::OnSessionChannelsConnected(ClientSession* client) { |
| 209 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 212 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 210 | 213 |
| 211 // Notify observers. | 214 // Notify observers. |
| 212 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, | 215 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, |
| 213 OnClientConnected(client->client_jid())); | 216 OnClientConnected(client->client_jid())); |
| 214 } | 217 } |
| 215 | 218 |
| 216 void ChromotingHost::OnSessionAuthenticationFailed(ClientSession* client) { | 219 void ChromotingHost::OnSessionAuthenticationFailed(ClientSession* client) { |
| 217 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 220 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 218 | 221 |
| 219 // Notify observers. | 222 // Notify observers. |
| 220 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, | 223 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, |
| 221 OnAccessDenied(client->client_jid())); | 224 OnAccessDenied(client->client_jid())); |
| 222 } | 225 } |
| 223 | 226 |
| 224 void ChromotingHost::OnSessionClosed(ClientSession* client) { | 227 void ChromotingHost::OnSessionClosed(ClientSession* client) { |
| 225 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 228 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 226 | 229 |
| 227 ClientList::iterator it = clients_.begin(); | 230 ClientList::iterator it = clients_.begin(); |
| 228 for (; it != clients_.end(); ++it) { | 231 for (; it != clients_.end(); ++it) { |
| 229 if (it->get() == client) { | 232 if (it->get() == client) { |
| 230 break; | 233 break; |
| 231 } | 234 } |
| 232 } | 235 } |
| 233 CHECK(it != clients_.end()); | 236 CHECK(it != clients_.end()); |
| 234 | 237 |
| 235 if (client->is_authenticated()) { | 238 if (client->is_authenticated()) { |
| 236 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, | 239 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, |
| 237 OnClientDisconnected(client->client_jid())); | 240 OnClientDisconnected(client->client_jid())); |
| 238 } | 241 } |
| 239 | 242 |
| 240 client->Stop(base::Bind(&ChromotingHost::OnClientStopped, this)); | 243 client->Stop(base::Bind(&ChromotingHost::OnClientStopped, this)); |
| 241 clients_.erase(it); | 244 clients_.erase(it); |
| 242 } | 245 } |
| 243 | 246 |
| 244 void ChromotingHost::OnSessionSequenceNumber(ClientSession* session, | 247 void ChromotingHost::OnSessionSequenceNumber(ClientSession* session, |
| 245 int64 sequence_number) { | 248 int64 sequence_number) { |
| 246 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 249 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 247 } | 250 } |
| 248 | 251 |
| 249 void ChromotingHost::OnSessionRouteChange( | 252 void ChromotingHost::OnSessionRouteChange( |
| 250 ClientSession* session, | 253 ClientSession* session, |
| 251 const std::string& channel_name, | 254 const std::string& channel_name, |
| 252 const protocol::TransportRoute& route) { | 255 const protocol::TransportRoute& route) { |
| 253 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 256 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 254 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, | 257 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, |
| 255 OnClientRouteChange(session->client_jid(), channel_name, | 258 OnClientRouteChange(session->client_jid(), channel_name, |
| 256 route)); | 259 route)); |
| 257 } | 260 } |
| 258 | 261 |
| 259 void ChromotingHost::OnClientDimensionsChanged(ClientSession* session, | 262 void ChromotingHost::OnClientDimensionsChanged(ClientSession* session, |
| 260 const SkISize& size) { | 263 const SkISize& size) { |
| 261 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 264 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 262 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, | 265 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, |
| 263 OnClientDimensionsChanged(session->client_jid(), size)); | 266 OnClientDimensionsChanged(session->client_jid(), size)); |
| 264 } | 267 } |
| 265 | 268 |
| 266 void ChromotingHost::OnSessionManagerReady() { | 269 void ChromotingHost::OnSessionManagerReady() { |
| 267 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 270 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 268 // Don't need to do anything here, just wait for incoming | 271 // Don't need to do anything here, just wait for incoming |
| 269 // connections. | 272 // connections. |
| 270 } | 273 } |
| 271 | 274 |
| 272 void ChromotingHost::OnIncomingSession( | 275 void ChromotingHost::OnIncomingSession( |
| 273 protocol::Session* session, | 276 protocol::Session* session, |
| 274 protocol::SessionManager::IncomingSessionResponse* response) { | 277 protocol::SessionManager::IncomingSessionResponse* response) { |
| 275 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 278 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 276 | 279 |
| 277 if (state_ != kStarted) { | 280 if (state_ != kStarted) { |
| 278 *response = protocol::SessionManager::DECLINE; | 281 *response = protocol::SessionManager::DECLINE; |
| 279 return; | 282 return; |
| 280 } | 283 } |
| 281 | 284 |
| 282 if (login_backoff_.ShouldRejectRequest()) { | 285 if (login_backoff_.ShouldRejectRequest()) { |
| 283 *response = protocol::SessionManager::OVERLOAD; | 286 *response = protocol::SessionManager::OVERLOAD; |
| 284 return; | 287 return; |
| 285 } | 288 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 299 } | 302 } |
| 300 | 303 |
| 301 session->set_config(config); | 304 session->set_config(config); |
| 302 | 305 |
| 303 *response = protocol::SessionManager::ACCEPT; | 306 *response = protocol::SessionManager::ACCEPT; |
| 304 | 307 |
| 305 LOG(INFO) << "Client connected: " << session->jid(); | 308 LOG(INFO) << "Client connected: " << session->jid(); |
| 306 | 309 |
| 307 // Create the desktop integration implementation for the client to use. | 310 // Create the desktop integration implementation for the client to use. |
| 308 scoped_ptr<DesktopEnvironment> desktop_environment = | 311 scoped_ptr<DesktopEnvironment> desktop_environment = |
| 309 desktop_environment_factory_->Create(context_); | 312 desktop_environment_factory_->Create(); |
| 310 | 313 |
| 311 // Create a client object. | 314 // Create a client object. |
| 312 scoped_ptr<protocol::ConnectionToClient> connection( | 315 scoped_ptr<protocol::ConnectionToClient> connection( |
| 313 new protocol::ConnectionToClient(session)); | 316 new protocol::ConnectionToClient(session)); |
| 314 scoped_refptr<ClientSession> client = new ClientSession( | 317 scoped_refptr<ClientSession> client = new ClientSession( |
| 315 this, | 318 this, |
| 316 context_->capture_task_runner(), | 319 capture_task_runner_, |
| 317 context_->encode_task_runner(), | 320 encode_task_runner_, |
| 318 context_->network_task_runner(), | 321 network_task_runner_, |
| 319 connection.Pass(), | 322 connection.Pass(), |
| 320 desktop_environment.Pass(), | 323 desktop_environment.Pass(), |
| 321 max_session_duration_); | 324 max_session_duration_); |
| 322 clients_.push_back(client); | 325 clients_.push_back(client); |
| 323 clients_count_++; | 326 clients_count_++; |
| 324 } | 327 } |
| 325 | 328 |
| 326 void ChromotingHost::set_protocol_config( | 329 void ChromotingHost::set_protocol_config( |
| 327 scoped_ptr<protocol::CandidateSessionConfig> config) { | 330 scoped_ptr<protocol::CandidateSessionConfig> config) { |
| 328 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 331 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 329 DCHECK(config.get()); | 332 DCHECK(config.get()); |
| 330 DCHECK_EQ(state_, kInitial); | 333 DCHECK_EQ(state_, kInitial); |
| 331 protocol_config_ = config.Pass(); | 334 protocol_config_ = config.Pass(); |
| 332 } | 335 } |
| 333 | 336 |
| 334 void ChromotingHost::OnLocalMouseMoved(const SkIPoint& new_pos) { | 337 void ChromotingHost::OnLocalMouseMoved(const SkIPoint& new_pos) { |
| 335 if (!context_->network_task_runner()->BelongsToCurrentThread()) { | 338 if (!network_task_runner_->BelongsToCurrentThread()) { |
| 336 context_->network_task_runner()->PostTask( | 339 network_task_runner_->PostTask( |
| 337 FROM_HERE, base::Bind(&ChromotingHost::OnLocalMouseMoved, | 340 FROM_HERE, base::Bind(&ChromotingHost::OnLocalMouseMoved, |
| 338 this, new_pos)); | 341 this, new_pos)); |
| 339 return; | 342 return; |
| 340 } | 343 } |
| 341 | 344 |
| 342 ClientList::iterator client; | 345 ClientList::iterator client; |
| 343 for (client = clients_.begin(); client != clients_.end(); ++client) { | 346 for (client = clients_.begin(); client != clients_.end(); ++client) { |
| 344 (*client)->LocalMouseMoved(new_pos); | 347 (*client)->LocalMouseMoved(new_pos); |
| 345 } | 348 } |
| 346 } | 349 } |
| 347 | 350 |
| 348 void ChromotingHost::PauseSession(bool pause) { | 351 void ChromotingHost::PauseSession(bool pause) { |
| 349 if (!context_->network_task_runner()->BelongsToCurrentThread()) { | 352 if (!network_task_runner_->BelongsToCurrentThread()) { |
| 350 context_->network_task_runner()->PostTask( | 353 network_task_runner_->PostTask( |
| 351 FROM_HERE, base::Bind(&ChromotingHost::PauseSession, this, pause)); | 354 FROM_HERE, base::Bind(&ChromotingHost::PauseSession, this, pause)); |
| 352 return; | 355 return; |
| 353 } | 356 } |
| 354 | 357 |
| 355 ClientList::iterator client; | 358 ClientList::iterator client; |
| 356 for (client = clients_.begin(); client != clients_.end(); ++client) { | 359 for (client = clients_.begin(); client != clients_.end(); ++client) { |
| 357 (*client)->SetDisableInputs(pause); | 360 (*client)->SetDisableInputs(pause); |
| 358 } | 361 } |
| 359 } | 362 } |
| 360 | 363 |
| 361 void ChromotingHost::DisconnectAllClients() { | 364 void ChromotingHost::DisconnectAllClients() { |
| 362 if (!context_->network_task_runner()->BelongsToCurrentThread()) { | 365 if (!network_task_runner_->BelongsToCurrentThread()) { |
| 363 context_->network_task_runner()->PostTask( | 366 network_task_runner_->PostTask( |
| 364 FROM_HERE, base::Bind(&ChromotingHost::DisconnectAllClients, this)); | 367 FROM_HERE, base::Bind(&ChromotingHost::DisconnectAllClients, this)); |
| 365 return; | 368 return; |
| 366 } | 369 } |
| 367 | 370 |
| 368 while (!clients_.empty()) { | 371 while (!clients_.empty()) { |
| 369 size_t size = clients_.size(); | 372 size_t size = clients_.size(); |
| 370 clients_.front()->Disconnect(); | 373 clients_.front()->Disconnect(); |
| 371 CHECK_EQ(clients_.size(), size - 1); | 374 CHECK_EQ(clients_.size(), size - 1); |
| 372 } | 375 } |
| 373 } | 376 } |
| 374 | 377 |
| 375 void ChromotingHost::SetUiStrings(const UiStrings& ui_strings) { | 378 void ChromotingHost::SetUiStrings(const UiStrings& ui_strings) { |
| 376 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 379 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 377 DCHECK_EQ(state_, kInitial); | 380 DCHECK_EQ(state_, kInitial); |
| 378 | 381 |
| 379 ui_strings_ = ui_strings; | 382 ui_strings_ = ui_strings; |
| 380 } | 383 } |
| 381 | 384 |
| 382 void ChromotingHost::OnClientStopped() { | 385 void ChromotingHost::OnClientStopped() { |
| 383 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 386 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 384 | 387 |
| 385 --clients_count_; | 388 --clients_count_; |
| 386 if (state_ == kStopping && !clients_count_) | 389 if (state_ == kStopping && !clients_count_) |
| 387 ShutdownFinish(); | 390 ShutdownFinish(); |
| 388 } | 391 } |
| 389 | 392 |
| 390 void ChromotingHost::ShutdownFinish() { | 393 void ChromotingHost::ShutdownFinish() { |
| 391 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 394 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 392 DCHECK_EQ(state_, kStopping); | 395 DCHECK_EQ(state_, kStopping); |
| 393 | 396 |
| 397 state_ = kStopped; |
| 398 |
| 394 // Destroy session manager. | 399 // Destroy session manager. |
| 395 session_manager_.reset(); | 400 session_manager_.reset(); |
| 396 | 401 |
| 397 state_ = kStopped; | 402 // Clear |desktop_environment_factory_| and |signal_strategy_| to |
| 403 // ensure we don't try to touch them after running shutdown tasks |
| 404 desktop_environment_factory_ = NULL; |
| 405 signal_strategy_ = NULL; |
| 398 | 406 |
| 399 // Keep reference to |this|, so that we don't get destroyed while | 407 // Keep reference to |this|, so that we don't get destroyed while |
| 400 // sending notifications. | 408 // sending notifications. |
| 401 scoped_refptr<ChromotingHost> self(this); | 409 scoped_refptr<ChromotingHost> self(this); |
| 402 | 410 |
| 403 // Notify observers. | 411 // Notify observers. |
| 404 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, | 412 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, |
| 405 OnShutdown()); | 413 OnShutdown()); |
| 406 | 414 |
| 407 for (std::vector<base::Closure>::iterator it = shutdown_tasks_.begin(); | 415 for (std::vector<base::Closure>::iterator it = shutdown_tasks_.begin(); |
| 408 it != shutdown_tasks_.end(); ++it) { | 416 it != shutdown_tasks_.end(); ++it) { |
| 409 it->Run(); | 417 it->Run(); |
| 410 } | 418 } |
| 411 shutdown_tasks_.clear(); | 419 shutdown_tasks_.clear(); |
| 412 } | 420 } |
| 413 | 421 |
| 414 } // namespace remoting | 422 } // namespace remoting |
| OLD | NEW |