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

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

Issue 13466014: Made the ChromotingHost class not ref-counted. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: CR feedback. Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "remoting/host/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 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) 69 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner)
70 : desktop_environment_factory_(desktop_environment_factory), 70 : desktop_environment_factory_(desktop_environment_factory),
71 session_manager_(session_manager.Pass()), 71 session_manager_(session_manager.Pass()),
72 audio_task_runner_(audio_task_runner), 72 audio_task_runner_(audio_task_runner),
73 input_task_runner_(input_task_runner), 73 input_task_runner_(input_task_runner),
74 video_capture_task_runner_(video_capture_task_runner), 74 video_capture_task_runner_(video_capture_task_runner),
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 started_(false),
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(CalledOnValidThread());
96
97 // Disconnect all of the clients.
98 while (!clients_.empty()) {
99 clients_.front()->DisconnectSession();
100 }
101
102 // Destroy session manager.
Wez 2013/04/09 01:08:21 nit: Why does this need destroying explicitly rath
alexeypa (please no reviews) 2013/04/12 18:22:26 Done.
103 session_manager_.reset();
104
105 // Clear |desktop_environment_factory_| and |signal_strategy_| to
106 // ensure we don't try to touch them after running shutdown tasks
Wez 2013/04/09 01:08:21 Is there any risk of that, if we're being deleted?
alexeypa (please no reviews) 2013/04/12 18:22:26 Done.
107 desktop_environment_factory_ = NULL;
108 signal_strategy_ = NULL;
109
110 // Notify observers.
111 if (started_) {
112 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, OnShutdown());
113 }
96 } 114 }
97 115
98 void ChromotingHost::Start(const std::string& xmpp_login) { 116 void ChromotingHost::Start(const std::string& xmpp_login) {
99 DCHECK(network_task_runner_->BelongsToCurrentThread()); 117 DCHECK(CalledOnValidThread());
118 DCHECK(!started_);
100 119
101 LOG(INFO) << "Starting host"; 120 LOG(INFO) << "Starting host";
102 121 started_ = true;
103 // Make sure this object is not started.
104 if (state_ != kInitial)
105 return;
106 state_ = kStarted;
107
108 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, 122 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_,
109 OnStart(xmpp_login)); 123 OnStart(xmpp_login));
110 124
111 // Start the SessionManager, supplying this ChromotingHost as the listener. 125 // Start the SessionManager, supplying this ChromotingHost as the listener.
112 session_manager_->Init(signal_strategy_, this); 126 session_manager_->Init(signal_strategy_, this);
113 } 127 }
114 128
115 // This method is called when we need to destroy the host process.
116 void ChromotingHost::Shutdown(const base::Closure& shutdown_task) {
117 if (!network_task_runner_->BelongsToCurrentThread()) {
118 network_task_runner_->PostTask(
119 FROM_HERE, base::Bind(&ChromotingHost::Shutdown, this, shutdown_task));
120 return;
121 }
122
123 switch (state_) {
124 case kInitial:
125 case kStopped:
126 // Nothing to do if we are not started.
127 state_ = kStopped;
128 if (!shutdown_task.is_null())
129 network_task_runner_->PostTask(FROM_HERE, shutdown_task);
130 break;
131
132 case kStopping:
133 // We are already stopping. Just save the task.
134 if (!shutdown_task.is_null())
135 shutdown_tasks_.push_back(shutdown_task);
136 break;
137
138 case kStarted:
139 if (!shutdown_task.is_null())
140 shutdown_tasks_.push_back(shutdown_task);
141 state_ = kStopping;
142
143 // Disconnect all of the clients.
144 while (!clients_.empty()) {
145 clients_.front()->DisconnectSession();
146 }
147
148 // Run the remaining shutdown tasks.
149 if (state_ == kStopping)
150 ShutdownFinish();
151
152 break;
153 }
154 }
155
156 void ChromotingHost::AddStatusObserver(HostStatusObserver* observer) { 129 void ChromotingHost::AddStatusObserver(HostStatusObserver* observer) {
157 DCHECK(network_task_runner_->BelongsToCurrentThread()); 130 DCHECK(CalledOnValidThread());
158 status_observers_.AddObserver(observer); 131 status_observers_.AddObserver(observer);
159 } 132 }
160 133
161 void ChromotingHost::RemoveStatusObserver(HostStatusObserver* observer) { 134 void ChromotingHost::RemoveStatusObserver(HostStatusObserver* observer) {
162 DCHECK(network_task_runner_->BelongsToCurrentThread()); 135 DCHECK(CalledOnValidThread());
163 status_observers_.RemoveObserver(observer); 136 status_observers_.RemoveObserver(observer);
164 } 137 }
165 138
166 void ChromotingHost::RejectAuthenticatingClient() { 139 void ChromotingHost::RejectAuthenticatingClient() {
167 DCHECK(authenticating_client_); 140 DCHECK(authenticating_client_);
168 reject_authenticating_client_ = true; 141 reject_authenticating_client_ = true;
169 } 142 }
170 143
171 void ChromotingHost::SetAuthenticatorFactory( 144 void ChromotingHost::SetAuthenticatorFactory(
172 scoped_ptr<protocol::AuthenticatorFactory> authenticator_factory) { 145 scoped_ptr<protocol::AuthenticatorFactory> authenticator_factory) {
173 DCHECK(network_task_runner_->BelongsToCurrentThread()); 146 DCHECK(CalledOnValidThread());
174 session_manager_->set_authenticator_factory(authenticator_factory.Pass()); 147 session_manager_->set_authenticator_factory(authenticator_factory.Pass());
175 } 148 }
176 149
177 void ChromotingHost::SetMaximumSessionDuration( 150 void ChromotingHost::SetMaximumSessionDuration(
178 const base::TimeDelta& max_session_duration) { 151 const base::TimeDelta& max_session_duration) {
179 max_session_duration_ = max_session_duration; 152 max_session_duration_ = max_session_duration;
180 } 153 }
181 154
182 //////////////////////////////////////////////////////////////////////////// 155 ////////////////////////////////////////////////////////////////////////////
183 // protocol::ClientSession::EventHandler implementation. 156 // protocol::ClientSession::EventHandler implementation.
184 void ChromotingHost::OnSessionAuthenticated(ClientSession* client) { 157 void ChromotingHost::OnSessionAuthenticated(ClientSession* client) {
185 DCHECK(network_task_runner_->BelongsToCurrentThread()); 158 DCHECK(CalledOnValidThread());
186 159
187 login_backoff_.Reset(); 160 login_backoff_.Reset();
188 161
189 // Disconnect all other clients. |it| should be advanced before Disconnect() 162 // Disconnect all other clients. |it| should be advanced before Disconnect()
190 // is called to avoid it becoming invalid when the client is removed from 163 // is called to avoid it becoming invalid when the client is removed from
191 // the list. 164 // the list.
192 ClientList::iterator it = clients_.begin(); 165 ClientList::iterator it = clients_.begin();
193 while (it != clients_.end()) { 166 while (it != clients_.end()) {
194 ClientSession* other_client = *it++; 167 ClientSession* other_client = *it++;
195 if (other_client != client) 168 if (other_client != client)
(...skipping 12 matching lines...) Expand all
208 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, 181 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_,
209 OnClientAuthenticated(jid)); 182 OnClientAuthenticated(jid));
210 authenticating_client_ = false; 183 authenticating_client_ = false;
211 184
212 if (reject_authenticating_client_) { 185 if (reject_authenticating_client_) {
213 client->DisconnectSession(); 186 client->DisconnectSession();
214 } 187 }
215 } 188 }
216 189
217 void ChromotingHost::OnSessionChannelsConnected(ClientSession* client) { 190 void ChromotingHost::OnSessionChannelsConnected(ClientSession* client) {
218 DCHECK(network_task_runner_->BelongsToCurrentThread()); 191 DCHECK(CalledOnValidThread());
219 192
220 // Notify observers. 193 // Notify observers.
221 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, 194 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_,
222 OnClientConnected(client->client_jid())); 195 OnClientConnected(client->client_jid()));
223 } 196 }
224 197
225 void ChromotingHost::OnSessionAuthenticationFailed(ClientSession* client) { 198 void ChromotingHost::OnSessionAuthenticationFailed(ClientSession* client) {
226 DCHECK(network_task_runner_->BelongsToCurrentThread()); 199 DCHECK(CalledOnValidThread());
227 200
228 // Notify observers. 201 // Notify observers.
229 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, 202 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_,
230 OnAccessDenied(client->client_jid())); 203 OnAccessDenied(client->client_jid()));
231 } 204 }
232 205
233 void ChromotingHost::OnSessionClosed(ClientSession* client) { 206 void ChromotingHost::OnSessionClosed(ClientSession* client) {
234 DCHECK(network_task_runner_->BelongsToCurrentThread()); 207 DCHECK(CalledOnValidThread());
235 208
236 ClientList::iterator it = std::find(clients_.begin(), clients_.end(), client); 209 ClientList::iterator it = std::find(clients_.begin(), clients_.end(), client);
237 CHECK(it != clients_.end()); 210 CHECK(it != clients_.end());
238 211
239 if (client->is_authenticated()) { 212 if (client->is_authenticated()) {
240 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, 213 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_,
241 OnClientDisconnected(client->client_jid())); 214 OnClientDisconnected(client->client_jid()));
242 } 215 }
243 216
244 clients_.erase(it); 217 clients_.erase(it);
245 delete client; 218 delete client;
246
247 if (state_ == kStopping && clients_.empty())
248 ShutdownFinish();
249 } 219 }
250 220
251 void ChromotingHost::OnSessionSequenceNumber(ClientSession* session, 221 void ChromotingHost::OnSessionSequenceNumber(ClientSession* session,
252 int64 sequence_number) { 222 int64 sequence_number) {
253 DCHECK(network_task_runner_->BelongsToCurrentThread()); 223 DCHECK(CalledOnValidThread());
254 } 224 }
255 225
256 void ChromotingHost::OnSessionRouteChange( 226 void ChromotingHost::OnSessionRouteChange(
257 ClientSession* session, 227 ClientSession* session,
258 const std::string& channel_name, 228 const std::string& channel_name,
259 const protocol::TransportRoute& route) { 229 const protocol::TransportRoute& route) {
260 DCHECK(network_task_runner_->BelongsToCurrentThread()); 230 DCHECK(CalledOnValidThread());
261 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, 231 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_,
262 OnClientRouteChange(session->client_jid(), channel_name, 232 OnClientRouteChange(session->client_jid(), channel_name,
263 route)); 233 route));
264 } 234 }
265 235
266 void ChromotingHost::OnSessionManagerReady() { 236 void ChromotingHost::OnSessionManagerReady() {
267 DCHECK(network_task_runner_->BelongsToCurrentThread()); 237 DCHECK(CalledOnValidThread());
268 // Don't need to do anything here, just wait for incoming 238 // Don't need to do anything here, just wait for incoming
269 // connections. 239 // connections.
270 } 240 }
271 241
272 void ChromotingHost::OnIncomingSession( 242 void ChromotingHost::OnIncomingSession(
273 protocol::Session* session, 243 protocol::Session* session,
274 protocol::SessionManager::IncomingSessionResponse* response) { 244 protocol::SessionManager::IncomingSessionResponse* response) {
275 DCHECK(network_task_runner_->BelongsToCurrentThread()); 245 DCHECK(CalledOnValidThread());
276 246
277 if (state_ != kStarted) { 247 if (!started_) {
278 *response = protocol::SessionManager::DECLINE; 248 *response = protocol::SessionManager::DECLINE;
279 return; 249 return;
280 } 250 }
281 251
282 if (login_backoff_.ShouldRejectRequest()) { 252 if (login_backoff_.ShouldRejectRequest()) {
283 *response = protocol::SessionManager::OVERLOAD; 253 *response = protocol::SessionManager::OVERLOAD;
284 return; 254 return;
285 } 255 }
286 256
287 // We treat each incoming connection as a failure to authenticate, 257 // We treat each incoming connection as a failure to authenticate,
(...skipping 28 matching lines...) Expand all
316 network_task_runner_, 286 network_task_runner_,
317 ui_task_runner_, 287 ui_task_runner_,
318 connection.Pass(), 288 connection.Pass(),
319 desktop_environment_factory_, 289 desktop_environment_factory_,
320 max_session_duration_); 290 max_session_duration_);
321 clients_.push_back(client); 291 clients_.push_back(client);
322 } 292 }
323 293
324 void ChromotingHost::set_protocol_config( 294 void ChromotingHost::set_protocol_config(
325 scoped_ptr<protocol::CandidateSessionConfig> config) { 295 scoped_ptr<protocol::CandidateSessionConfig> config) {
326 DCHECK(network_task_runner_->BelongsToCurrentThread()); 296 DCHECK(CalledOnValidThread());
327 DCHECK(config.get()); 297 DCHECK(config.get());
328 DCHECK_EQ(state_, kInitial); 298 DCHECK(!started_);
329 protocol_config_ = config.Pass(); 299 protocol_config_ = config.Pass();
330 } 300 }
331 301
332 void ChromotingHost::DisconnectAllClients() { 302 void ChromotingHost::DisconnectAllClients() {
333 if (!network_task_runner_->BelongsToCurrentThread()) { 303 DCHECK(CalledOnValidThread());
334 network_task_runner_->PostTask(
335 FROM_HERE, base::Bind(&ChromotingHost::DisconnectAllClients, this));
336 return;
337 }
338 304
339 while (!clients_.empty()) { 305 while (!clients_.empty()) {
340 size_t size = clients_.size(); 306 size_t size = clients_.size();
341 clients_.front()->DisconnectSession(); 307 clients_.front()->DisconnectSession();
342 CHECK_EQ(clients_.size(), size - 1); 308 CHECK_EQ(clients_.size(), size - 1);
343 } 309 }
344 } 310 }
345 311
346 void ChromotingHost::ShutdownFinish() {
347 DCHECK(network_task_runner_->BelongsToCurrentThread());
348 DCHECK_EQ(state_, kStopping);
349
350 state_ = kStopped;
351
352 // Destroy session manager.
353 session_manager_.reset();
354
355 // Clear |desktop_environment_factory_| and |signal_strategy_| to
356 // ensure we don't try to touch them after running shutdown tasks
357 desktop_environment_factory_ = NULL;
358 signal_strategy_ = NULL;
359
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.
365 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_,
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
374 weak_factory_.InvalidateWeakPtrs();
375 }
376
377 } // namespace remoting 312 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698