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 <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/callback.h" | 10 #include "base/callback.h" |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
75 video_encode_task_runner_(video_encode_task_runner), | 75 video_encode_task_runner_(video_encode_task_runner), |
76 network_task_runner_(network_task_runner), | 76 network_task_runner_(network_task_runner), |
77 ui_task_runner_(ui_task_runner), | 77 ui_task_runner_(ui_task_runner), |
78 signal_strategy_(signal_strategy), | 78 signal_strategy_(signal_strategy), |
79 state_(kInitial), | 79 state_(kInitial), |
80 protocol_config_(protocol::CandidateSessionConfig::CreateDefault()), | 80 protocol_config_(protocol::CandidateSessionConfig::CreateDefault()), |
81 login_backoff_(&kDefaultBackoffPolicy), | 81 login_backoff_(&kDefaultBackoffPolicy), |
82 authenticating_client_(false), | 82 authenticating_client_(false), |
83 reject_authenticating_client_(false), | 83 reject_authenticating_client_(false), |
84 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { | 84 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { |
85 DCHECK(network_task_runner_->BelongsToCurrentThread()); | |
85 DCHECK(signal_strategy); | 86 DCHECK(signal_strategy); |
86 DCHECK(network_task_runner_->BelongsToCurrentThread()); | |
87 | 87 |
88 if (!desktop_environment_factory_->SupportsAudioCapture()) { | 88 if (!desktop_environment_factory_->SupportsAudioCapture()) { |
89 protocol::CandidateSessionConfig::DisableAudioChannel( | 89 protocol::CandidateSessionConfig::DisableAudioChannel( |
90 protocol_config_.get()); | 90 protocol_config_.get()); |
91 } | 91 } |
92 } | 92 } |
93 | 93 |
94 ChromotingHost::~ChromotingHost() { | 94 ChromotingHost::~ChromotingHost() { |
95 DCHECK(clients_.empty()); | 95 DCHECK(clients_.empty()); |
96 } | 96 } |
97 | 97 |
98 void ChromotingHost::Start(const std::string& xmpp_login) { | 98 void ChromotingHost::Start(const std::string& xmpp_login) { |
99 DCHECK(network_task_runner_->BelongsToCurrentThread()); | 99 DCHECK(CalledOnValidThread()); |
Wez
2013/04/02 19:58:33
Can we also DCHECK that Start() is only called fro
alexeypa (please no reviews)
2013/04/08 23:28:17
Done.
| |
100 | 100 |
101 LOG(INFO) << "Starting host"; | 101 LOG(INFO) << "Starting host"; |
102 | 102 |
103 // Make sure this object is not started. | 103 // Make sure this object is not started. |
104 if (state_ != kInitial) | 104 if (state_ != kInitial) |
105 return; | 105 return; |
106 state_ = kStarted; | 106 state_ = kStarted; |
107 | 107 |
108 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, | 108 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, |
109 OnStart(xmpp_login)); | 109 OnStart(xmpp_login)); |
110 | 110 |
111 // Start the SessionManager, supplying this ChromotingHost as the listener. | 111 // Start the SessionManager, supplying this ChromotingHost as the listener. |
112 session_manager_->Init(signal_strategy_, this); | 112 session_manager_->Init(signal_strategy_, this); |
113 } | 113 } |
114 | 114 |
115 // This method is called when we need to destroy the host process. | 115 // This method is called when we need to destroy the host process. |
116 void ChromotingHost::Shutdown(const base::Closure& shutdown_task) { | 116 void ChromotingHost::Shutdown() { |
117 if (!network_task_runner_->BelongsToCurrentThread()) { | 117 DCHECK(CalledOnValidThread()); |
Wez
2013/04/02 19:58:33
nit: Can we also DCHECK that Shutdown is never cal
alexeypa (please no reviews)
2013/04/08 23:28:17
Done.
| |
118 network_task_runner_->PostTask( | |
119 FROM_HERE, base::Bind(&ChromotingHost::Shutdown, this, shutdown_task)); | |
120 return; | |
121 } | |
122 | 118 |
123 switch (state_) { | 119 switch (state_) { |
124 case kInitial: | 120 case kInitial: |
125 case kStopped: | 121 case kStopped: |
126 // Nothing to do if we are not started. | 122 // Nothing to do if we are not started. |
127 state_ = kStopped; | 123 state_ = kStopped; |
128 if (!shutdown_task.is_null()) | |
129 network_task_runner_->PostTask(FROM_HERE, shutdown_task); | |
130 break; | 124 break; |
131 | 125 |
132 case kStopping: | 126 case kStopping: |
133 // We are already stopping. Just save the task. | 127 // We are already stopping. |
134 if (!shutdown_task.is_null()) | |
135 shutdown_tasks_.push_back(shutdown_task); | |
136 break; | 128 break; |
137 | 129 |
138 case kStarted: | 130 case kStarted: |
139 if (!shutdown_task.is_null()) | |
140 shutdown_tasks_.push_back(shutdown_task); | |
141 state_ = kStopping; | 131 state_ = kStopping; |
142 | 132 |
143 // Disconnect all of the clients. | 133 // Disconnect all of the clients. |
144 while (!clients_.empty()) { | 134 while (!clients_.empty()) { |
145 clients_.front()->DisconnectSession(); | 135 clients_.front()->DisconnectSession(); |
146 } | 136 } |
147 | 137 |
148 // Run the remaining shutdown tasks. | 138 // Run the remaining shutdown tasks. |
149 if (state_ == kStopping) | 139 if (state_ == kStopping) { |
Wez
2013/04/02 19:58:33
How can we ever end up not in the kStopping state
alexeypa (please no reviews)
2013/04/08 23:28:17
Done.
| |
140 state_ = kStopped; | |
150 ShutdownFinish(); | 141 ShutdownFinish(); |
142 } | |
151 | 143 |
152 break; | 144 break; |
153 } | 145 } |
154 } | 146 } |
155 | 147 |
156 void ChromotingHost::AddStatusObserver(HostStatusObserver* observer) { | 148 void ChromotingHost::AddStatusObserver(HostStatusObserver* observer) { |
157 DCHECK(network_task_runner_->BelongsToCurrentThread()); | 149 DCHECK(CalledOnValidThread()); |
158 status_observers_.AddObserver(observer); | 150 status_observers_.AddObserver(observer); |
159 } | 151 } |
160 | 152 |
161 void ChromotingHost::RemoveStatusObserver(HostStatusObserver* observer) { | 153 void ChromotingHost::RemoveStatusObserver(HostStatusObserver* observer) { |
162 DCHECK(network_task_runner_->BelongsToCurrentThread()); | 154 DCHECK(CalledOnValidThread()); |
163 status_observers_.RemoveObserver(observer); | 155 status_observers_.RemoveObserver(observer); |
164 } | 156 } |
165 | 157 |
166 void ChromotingHost::RejectAuthenticatingClient() { | 158 void ChromotingHost::RejectAuthenticatingClient() { |
167 DCHECK(authenticating_client_); | 159 DCHECK(authenticating_client_); |
168 reject_authenticating_client_ = true; | 160 reject_authenticating_client_ = true; |
169 } | 161 } |
170 | 162 |
171 void ChromotingHost::SetAuthenticatorFactory( | 163 void ChromotingHost::SetAuthenticatorFactory( |
172 scoped_ptr<protocol::AuthenticatorFactory> authenticator_factory) { | 164 scoped_ptr<protocol::AuthenticatorFactory> authenticator_factory) { |
173 DCHECK(network_task_runner_->BelongsToCurrentThread()); | 165 DCHECK(CalledOnValidThread()); |
174 session_manager_->set_authenticator_factory(authenticator_factory.Pass()); | 166 session_manager_->set_authenticator_factory(authenticator_factory.Pass()); |
175 } | 167 } |
176 | 168 |
177 void ChromotingHost::SetMaximumSessionDuration( | 169 void ChromotingHost::SetMaximumSessionDuration( |
178 const base::TimeDelta& max_session_duration) { | 170 const base::TimeDelta& max_session_duration) { |
179 max_session_duration_ = max_session_duration; | 171 max_session_duration_ = max_session_duration; |
180 } | 172 } |
181 | 173 |
182 //////////////////////////////////////////////////////////////////////////// | 174 //////////////////////////////////////////////////////////////////////////// |
183 // protocol::ClientSession::EventHandler implementation. | 175 // protocol::ClientSession::EventHandler implementation. |
184 void ChromotingHost::OnSessionAuthenticated(ClientSession* client) { | 176 void ChromotingHost::OnSessionAuthenticated(ClientSession* client) { |
185 DCHECK(network_task_runner_->BelongsToCurrentThread()); | 177 DCHECK(CalledOnValidThread()); |
186 | 178 |
187 login_backoff_.Reset(); | 179 login_backoff_.Reset(); |
188 | 180 |
189 // Disconnect all other clients. |it| should be advanced before Disconnect() | 181 // Disconnect all other clients. |it| should be advanced before Disconnect() |
190 // is called to avoid it becoming invalid when the client is removed from | 182 // is called to avoid it becoming invalid when the client is removed from |
191 // the list. | 183 // the list. |
192 ClientList::iterator it = clients_.begin(); | 184 ClientList::iterator it = clients_.begin(); |
193 while (it != clients_.end()) { | 185 while (it != clients_.end()) { |
194 ClientSession* other_client = *it++; | 186 ClientSession* other_client = *it++; |
195 if (other_client != client) | 187 if (other_client != client) |
(...skipping 12 matching lines...) Expand all Loading... | |
208 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, | 200 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, |
209 OnClientAuthenticated(jid)); | 201 OnClientAuthenticated(jid)); |
210 authenticating_client_ = false; | 202 authenticating_client_ = false; |
211 | 203 |
212 if (reject_authenticating_client_) { | 204 if (reject_authenticating_client_) { |
213 client->DisconnectSession(); | 205 client->DisconnectSession(); |
214 } | 206 } |
215 } | 207 } |
216 | 208 |
217 void ChromotingHost::OnSessionChannelsConnected(ClientSession* client) { | 209 void ChromotingHost::OnSessionChannelsConnected(ClientSession* client) { |
218 DCHECK(network_task_runner_->BelongsToCurrentThread()); | 210 DCHECK(CalledOnValidThread()); |
219 | 211 |
220 // Notify observers. | 212 // Notify observers. |
221 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, | 213 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, |
222 OnClientConnected(client->client_jid())); | 214 OnClientConnected(client->client_jid())); |
223 } | 215 } |
224 | 216 |
225 void ChromotingHost::OnSessionAuthenticationFailed(ClientSession* client) { | 217 void ChromotingHost::OnSessionAuthenticationFailed(ClientSession* client) { |
226 DCHECK(network_task_runner_->BelongsToCurrentThread()); | 218 DCHECK(CalledOnValidThread()); |
227 | 219 |
228 // Notify observers. | 220 // Notify observers. |
229 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, | 221 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, |
230 OnAccessDenied(client->client_jid())); | 222 OnAccessDenied(client->client_jid())); |
231 } | 223 } |
232 | 224 |
233 void ChromotingHost::OnSessionClosed(ClientSession* client) { | 225 void ChromotingHost::OnSessionClosed(ClientSession* client) { |
234 DCHECK(network_task_runner_->BelongsToCurrentThread()); | 226 DCHECK(CalledOnValidThread()); |
235 | 227 |
236 ClientList::iterator it = std::find(clients_.begin(), clients_.end(), client); | 228 ClientList::iterator it = std::find(clients_.begin(), clients_.end(), client); |
237 CHECK(it != clients_.end()); | 229 CHECK(it != clients_.end()); |
238 | 230 |
239 if (client->is_authenticated()) { | 231 if (client->is_authenticated()) { |
240 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, | 232 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, |
241 OnClientDisconnected(client->client_jid())); | 233 OnClientDisconnected(client->client_jid())); |
242 } | 234 } |
243 | 235 |
244 clients_.erase(it); | 236 clients_.erase(it); |
245 delete client; | 237 delete client; |
246 | |
247 if (state_ == kStopping && clients_.empty()) | |
248 ShutdownFinish(); | |
249 } | 238 } |
250 | 239 |
251 void ChromotingHost::OnSessionSequenceNumber(ClientSession* session, | 240 void ChromotingHost::OnSessionSequenceNumber(ClientSession* session, |
252 int64 sequence_number) { | 241 int64 sequence_number) { |
253 DCHECK(network_task_runner_->BelongsToCurrentThread()); | 242 DCHECK(CalledOnValidThread()); |
254 } | 243 } |
255 | 244 |
256 void ChromotingHost::OnSessionRouteChange( | 245 void ChromotingHost::OnSessionRouteChange( |
257 ClientSession* session, | 246 ClientSession* session, |
258 const std::string& channel_name, | 247 const std::string& channel_name, |
259 const protocol::TransportRoute& route) { | 248 const protocol::TransportRoute& route) { |
260 DCHECK(network_task_runner_->BelongsToCurrentThread()); | 249 DCHECK(CalledOnValidThread()); |
261 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, | 250 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, |
262 OnClientRouteChange(session->client_jid(), channel_name, | 251 OnClientRouteChange(session->client_jid(), channel_name, |
263 route)); | 252 route)); |
264 } | 253 } |
265 | 254 |
266 void ChromotingHost::OnSessionManagerReady() { | 255 void ChromotingHost::OnSessionManagerReady() { |
267 DCHECK(network_task_runner_->BelongsToCurrentThread()); | 256 DCHECK(CalledOnValidThread()); |
268 // Don't need to do anything here, just wait for incoming | 257 // Don't need to do anything here, just wait for incoming |
269 // connections. | 258 // connections. |
270 } | 259 } |
271 | 260 |
272 void ChromotingHost::OnIncomingSession( | 261 void ChromotingHost::OnIncomingSession( |
273 protocol::Session* session, | 262 protocol::Session* session, |
274 protocol::SessionManager::IncomingSessionResponse* response) { | 263 protocol::SessionManager::IncomingSessionResponse* response) { |
275 DCHECK(network_task_runner_->BelongsToCurrentThread()); | 264 DCHECK(CalledOnValidThread()); |
276 | 265 |
277 if (state_ != kStarted) { | 266 if (state_ != kStarted) { |
278 *response = protocol::SessionManager::DECLINE; | 267 *response = protocol::SessionManager::DECLINE; |
279 return; | 268 return; |
280 } | 269 } |
281 | 270 |
282 if (login_backoff_.ShouldRejectRequest()) { | 271 if (login_backoff_.ShouldRejectRequest()) { |
283 *response = protocol::SessionManager::OVERLOAD; | 272 *response = protocol::SessionManager::OVERLOAD; |
284 return; | 273 return; |
285 } | 274 } |
(...skipping 30 matching lines...) Expand all Loading... | |
316 network_task_runner_, | 305 network_task_runner_, |
317 ui_task_runner_, | 306 ui_task_runner_, |
318 connection.Pass(), | 307 connection.Pass(), |
319 desktop_environment_factory_, | 308 desktop_environment_factory_, |
320 max_session_duration_); | 309 max_session_duration_); |
321 clients_.push_back(client); | 310 clients_.push_back(client); |
322 } | 311 } |
323 | 312 |
324 void ChromotingHost::set_protocol_config( | 313 void ChromotingHost::set_protocol_config( |
325 scoped_ptr<protocol::CandidateSessionConfig> config) { | 314 scoped_ptr<protocol::CandidateSessionConfig> config) { |
326 DCHECK(network_task_runner_->BelongsToCurrentThread()); | 315 DCHECK(CalledOnValidThread()); |
327 DCHECK(config.get()); | 316 DCHECK(config.get()); |
328 DCHECK_EQ(state_, kInitial); | 317 DCHECK_EQ(state_, kInitial); |
329 protocol_config_ = config.Pass(); | 318 protocol_config_ = config.Pass(); |
330 } | 319 } |
331 | 320 |
332 void ChromotingHost::DisconnectAllClients() { | 321 void ChromotingHost::DisconnectAllClients() { |
333 if (!network_task_runner_->BelongsToCurrentThread()) { | 322 DCHECK(CalledOnValidThread()); |
334 network_task_runner_->PostTask( | |
335 FROM_HERE, base::Bind(&ChromotingHost::DisconnectAllClients, this)); | |
336 return; | |
337 } | |
338 | 323 |
339 while (!clients_.empty()) { | 324 while (!clients_.empty()) { |
340 size_t size = clients_.size(); | 325 size_t size = clients_.size(); |
341 clients_.front()->DisconnectSession(); | 326 clients_.front()->DisconnectSession(); |
342 CHECK_EQ(clients_.size(), size - 1); | 327 CHECK_EQ(clients_.size(), size - 1); |
343 } | 328 } |
344 } | 329 } |
345 | 330 |
346 void ChromotingHost::ShutdownFinish() { | 331 void ChromotingHost::ShutdownFinish() { |
347 DCHECK(network_task_runner_->BelongsToCurrentThread()); | 332 DCHECK(CalledOnValidThread()); |
348 DCHECK_EQ(state_, kStopping); | |
349 | |
350 state_ = kStopped; | |
351 | 333 |
352 // Destroy session manager. | 334 // Destroy session manager. |
353 session_manager_.reset(); | 335 session_manager_.reset(); |
354 | 336 |
355 // Clear |desktop_environment_factory_| and |signal_strategy_| to | 337 // Clear |desktop_environment_factory_| and |signal_strategy_| to |
356 // ensure we don't try to touch them after running shutdown tasks | 338 // ensure we don't try to touch them after running shutdown tasks |
357 desktop_environment_factory_ = NULL; | 339 desktop_environment_factory_ = NULL; |
358 signal_strategy_ = NULL; | 340 signal_strategy_ = NULL; |
359 | 341 |
360 // Keep reference to |this|, so that we don't get destroyed while | |
361 // sending notifications. | |
362 scoped_refptr<ChromotingHost> self(this); | |
363 | |
364 // Notify observers. | 342 // Notify observers. |
365 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, | 343 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, OnShutdown()); |
366 OnShutdown()); | |
367 | |
368 for (std::vector<base::Closure>::iterator it = shutdown_tasks_.begin(); | |
369 it != shutdown_tasks_.end(); ++it) { | |
370 it->Run(); | |
371 } | |
372 shutdown_tasks_.clear(); | |
373 | 344 |
374 weak_factory_.InvalidateWeakPtrs(); | 345 weak_factory_.InvalidateWeakPtrs(); |
375 } | 346 } |
376 | 347 |
377 } // namespace remoting | 348 } // namespace remoting |
OLD | NEW |