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

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: rebased 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
« no previous file with comments | « remoting/host/chromoting_host.h ('k') | remoting/host/chromoting_host_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 // Notify observers.
103 if (started_) {
104 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, OnShutdown());
105 }
96 } 106 }
97 107
98 void ChromotingHost::Start(const std::string& xmpp_login) { 108 void ChromotingHost::Start(const std::string& xmpp_login) {
99 DCHECK(network_task_runner_->BelongsToCurrentThread()); 109 DCHECK(CalledOnValidThread());
110 DCHECK(!started_);
100 111
101 LOG(INFO) << "Starting host"; 112 LOG(INFO) << "Starting host";
102 113 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_, 114 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_,
109 OnStart(xmpp_login)); 115 OnStart(xmpp_login));
110 116
111 // Start the SessionManager, supplying this ChromotingHost as the listener. 117 // Start the SessionManager, supplying this ChromotingHost as the listener.
112 session_manager_->Init(signal_strategy_, this); 118 session_manager_->Init(signal_strategy_, this);
113 } 119 }
114 120
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) { 121 void ChromotingHost::AddStatusObserver(HostStatusObserver* observer) {
157 DCHECK(network_task_runner_->BelongsToCurrentThread()); 122 DCHECK(CalledOnValidThread());
158 status_observers_.AddObserver(observer); 123 status_observers_.AddObserver(observer);
159 } 124 }
160 125
161 void ChromotingHost::RemoveStatusObserver(HostStatusObserver* observer) { 126 void ChromotingHost::RemoveStatusObserver(HostStatusObserver* observer) {
162 DCHECK(network_task_runner_->BelongsToCurrentThread()); 127 DCHECK(CalledOnValidThread());
163 status_observers_.RemoveObserver(observer); 128 status_observers_.RemoveObserver(observer);
164 } 129 }
165 130
166 void ChromotingHost::RejectAuthenticatingClient() { 131 void ChromotingHost::RejectAuthenticatingClient() {
167 DCHECK(authenticating_client_); 132 DCHECK(authenticating_client_);
168 reject_authenticating_client_ = true; 133 reject_authenticating_client_ = true;
169 } 134 }
170 135
171 void ChromotingHost::SetAuthenticatorFactory( 136 void ChromotingHost::SetAuthenticatorFactory(
172 scoped_ptr<protocol::AuthenticatorFactory> authenticator_factory) { 137 scoped_ptr<protocol::AuthenticatorFactory> authenticator_factory) {
173 DCHECK(network_task_runner_->BelongsToCurrentThread()); 138 DCHECK(CalledOnValidThread());
174 session_manager_->set_authenticator_factory(authenticator_factory.Pass()); 139 session_manager_->set_authenticator_factory(authenticator_factory.Pass());
175 } 140 }
176 141
177 void ChromotingHost::SetMaximumSessionDuration( 142 void ChromotingHost::SetMaximumSessionDuration(
178 const base::TimeDelta& max_session_duration) { 143 const base::TimeDelta& max_session_duration) {
179 max_session_duration_ = max_session_duration; 144 max_session_duration_ = max_session_duration;
180 } 145 }
181 146
182 //////////////////////////////////////////////////////////////////////////// 147 ////////////////////////////////////////////////////////////////////////////
183 // protocol::ClientSession::EventHandler implementation. 148 // protocol::ClientSession::EventHandler implementation.
184 void ChromotingHost::OnSessionAuthenticated(ClientSession* client) { 149 void ChromotingHost::OnSessionAuthenticated(ClientSession* client) {
185 DCHECK(network_task_runner_->BelongsToCurrentThread()); 150 DCHECK(CalledOnValidThread());
186 151
187 login_backoff_.Reset(); 152 login_backoff_.Reset();
188 153
189 // Disconnect all other clients. |it| should be advanced before Disconnect() 154 // Disconnect all other clients. |it| should be advanced before Disconnect()
190 // is called to avoid it becoming invalid when the client is removed from 155 // is called to avoid it becoming invalid when the client is removed from
191 // the list. 156 // the list.
192 ClientList::iterator it = clients_.begin(); 157 ClientList::iterator it = clients_.begin();
193 while (it != clients_.end()) { 158 while (it != clients_.end()) {
194 ClientSession* other_client = *it++; 159 ClientSession* other_client = *it++;
195 if (other_client != client) 160 if (other_client != client)
(...skipping 12 matching lines...) Expand all
208 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, 173 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_,
209 OnClientAuthenticated(jid)); 174 OnClientAuthenticated(jid));
210 authenticating_client_ = false; 175 authenticating_client_ = false;
211 176
212 if (reject_authenticating_client_) { 177 if (reject_authenticating_client_) {
213 client->DisconnectSession(); 178 client->DisconnectSession();
214 } 179 }
215 } 180 }
216 181
217 void ChromotingHost::OnSessionChannelsConnected(ClientSession* client) { 182 void ChromotingHost::OnSessionChannelsConnected(ClientSession* client) {
218 DCHECK(network_task_runner_->BelongsToCurrentThread()); 183 DCHECK(CalledOnValidThread());
219 184
220 // Notify observers. 185 // Notify observers.
221 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, 186 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_,
222 OnClientConnected(client->client_jid())); 187 OnClientConnected(client->client_jid()));
223 } 188 }
224 189
225 void ChromotingHost::OnSessionAuthenticationFailed(ClientSession* client) { 190 void ChromotingHost::OnSessionAuthenticationFailed(ClientSession* client) {
226 DCHECK(network_task_runner_->BelongsToCurrentThread()); 191 DCHECK(CalledOnValidThread());
227 192
228 // Notify observers. 193 // Notify observers.
229 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, 194 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_,
230 OnAccessDenied(client->client_jid())); 195 OnAccessDenied(client->client_jid()));
231 } 196 }
232 197
233 void ChromotingHost::OnSessionClosed(ClientSession* client) { 198 void ChromotingHost::OnSessionClosed(ClientSession* client) {
234 DCHECK(network_task_runner_->BelongsToCurrentThread()); 199 DCHECK(CalledOnValidThread());
235 200
236 ClientList::iterator it = std::find(clients_.begin(), clients_.end(), client); 201 ClientList::iterator it = std::find(clients_.begin(), clients_.end(), client);
237 CHECK(it != clients_.end()); 202 CHECK(it != clients_.end());
238 203
239 if (client->is_authenticated()) { 204 if (client->is_authenticated()) {
240 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, 205 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_,
241 OnClientDisconnected(client->client_jid())); 206 OnClientDisconnected(client->client_jid()));
242 } 207 }
243 208
244 clients_.erase(it); 209 clients_.erase(it);
245 delete client; 210 delete client;
246
247 if (state_ == kStopping && clients_.empty())
248 ShutdownFinish();
249 } 211 }
250 212
251 void ChromotingHost::OnSessionSequenceNumber(ClientSession* session, 213 void ChromotingHost::OnSessionSequenceNumber(ClientSession* session,
252 int64 sequence_number) { 214 int64 sequence_number) {
253 DCHECK(network_task_runner_->BelongsToCurrentThread()); 215 DCHECK(CalledOnValidThread());
254 } 216 }
255 217
256 void ChromotingHost::OnSessionRouteChange( 218 void ChromotingHost::OnSessionRouteChange(
257 ClientSession* session, 219 ClientSession* session,
258 const std::string& channel_name, 220 const std::string& channel_name,
259 const protocol::TransportRoute& route) { 221 const protocol::TransportRoute& route) {
260 DCHECK(network_task_runner_->BelongsToCurrentThread()); 222 DCHECK(CalledOnValidThread());
261 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, 223 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_,
262 OnClientRouteChange(session->client_jid(), channel_name, 224 OnClientRouteChange(session->client_jid(), channel_name,
263 route)); 225 route));
264 } 226 }
265 227
266 void ChromotingHost::OnSessionManagerReady() { 228 void ChromotingHost::OnSessionManagerReady() {
267 DCHECK(network_task_runner_->BelongsToCurrentThread()); 229 DCHECK(CalledOnValidThread());
268 // Don't need to do anything here, just wait for incoming 230 // Don't need to do anything here, just wait for incoming
269 // connections. 231 // connections.
270 } 232 }
271 233
272 void ChromotingHost::OnIncomingSession( 234 void ChromotingHost::OnIncomingSession(
273 protocol::Session* session, 235 protocol::Session* session,
274 protocol::SessionManager::IncomingSessionResponse* response) { 236 protocol::SessionManager::IncomingSessionResponse* response) {
275 DCHECK(network_task_runner_->BelongsToCurrentThread()); 237 DCHECK(CalledOnValidThread());
276 238
277 if (state_ != kStarted) { 239 if (!started_) {
278 *response = protocol::SessionManager::DECLINE; 240 *response = protocol::SessionManager::DECLINE;
279 return; 241 return;
280 } 242 }
281 243
282 if (login_backoff_.ShouldRejectRequest()) { 244 if (login_backoff_.ShouldRejectRequest()) {
283 *response = protocol::SessionManager::OVERLOAD; 245 *response = protocol::SessionManager::OVERLOAD;
284 return; 246 return;
285 } 247 }
286 248
287 // We treat each incoming connection as a failure to authenticate, 249 // We treat each incoming connection as a failure to authenticate,
(...skipping 28 matching lines...) Expand all
316 network_task_runner_, 278 network_task_runner_,
317 ui_task_runner_, 279 ui_task_runner_,
318 connection.Pass(), 280 connection.Pass(),
319 desktop_environment_factory_, 281 desktop_environment_factory_,
320 max_session_duration_); 282 max_session_duration_);
321 clients_.push_back(client); 283 clients_.push_back(client);
322 } 284 }
323 285
324 void ChromotingHost::set_protocol_config( 286 void ChromotingHost::set_protocol_config(
325 scoped_ptr<protocol::CandidateSessionConfig> config) { 287 scoped_ptr<protocol::CandidateSessionConfig> config) {
326 DCHECK(network_task_runner_->BelongsToCurrentThread()); 288 DCHECK(CalledOnValidThread());
327 DCHECK(config.get()); 289 DCHECK(config.get());
328 DCHECK_EQ(state_, kInitial); 290 DCHECK(!started_);
329 protocol_config_ = config.Pass(); 291 protocol_config_ = config.Pass();
330 } 292 }
331 293
332 void ChromotingHost::DisconnectAllClients() { 294 void ChromotingHost::DisconnectAllClients() {
333 if (!network_task_runner_->BelongsToCurrentThread()) { 295 DCHECK(CalledOnValidThread());
334 network_task_runner_->PostTask(
335 FROM_HERE, base::Bind(&ChromotingHost::DisconnectAllClients, this));
336 return;
337 }
338 296
339 while (!clients_.empty()) { 297 while (!clients_.empty()) {
340 size_t size = clients_.size(); 298 size_t size = clients_.size();
341 clients_.front()->DisconnectSession(); 299 clients_.front()->DisconnectSession();
342 CHECK_EQ(clients_.size(), size - 1); 300 CHECK_EQ(clients_.size(), size - 1);
343 } 301 }
344 } 302 }
345 303
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 304 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/chromoting_host.h ('k') | remoting/host/chromoting_host_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698