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

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

Issue 8476018: Move ConnectionToClient::EventHandler from ChromotingHost to ClientSession (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merged Created 9 years, 1 month 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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 } 123 }
124 if (!shutdown_task.is_null()) 124 if (!shutdown_task.is_null())
125 shutdown_tasks_.push_back(shutdown_task); 125 shutdown_tasks_.push_back(shutdown_task);
126 if (state_ == kStopping) 126 if (state_ == kStopping)
127 return; 127 return;
128 state_ = kStopping; 128 state_ = kStopping;
129 } 129 }
130 130
131 // Disconnect all of the clients, implicitly stopping the ScreenRecorder. 131 // Disconnect all of the clients, implicitly stopping the ScreenRecorder.
132 while (!clients_.empty()) { 132 while (!clients_.empty()) {
133 OnClientDisconnected(clients_.front()->connection()); 133 scoped_refptr<ClientSession> client = clients_.front();
134 client->Disconnect();
135 OnClientDisconnected(client);
134 } 136 }
135 137
136 ShutdownNetwork(); 138 ShutdownNetwork();
137 } 139 }
138 140
139 void ChromotingHost::AddStatusObserver(HostStatusObserver* observer) { 141 void ChromotingHost::AddStatusObserver(HostStatusObserver* observer) {
140 DCHECK_EQ(state_, kInitial); 142 DCHECK_EQ(state_, kInitial);
141 status_observers_.push_back(observer); 143 status_observers_.push_back(observer);
142 } 144 }
143 145
144 //////////////////////////////////////////////////////////////////////////// 146 ////////////////////////////////////////////////////////////////////////////
145 // protocol::ConnectionToClient::EventHandler implementations 147 // protocol::ClientSession::EventHandler implementation.
146 void ChromotingHost::OnConnectionOpened(ConnectionToClient* connection) { 148 void ChromotingHost::OnSessionAuthenticated(ClientSession* client) {
147 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); 149 DCHECK(context_->network_message_loop()->BelongsToCurrentThread());
148 VLOG(1) << "Connection to client established."; 150 protocol::Session* session = client->connection()->session();
149 context_->main_message_loop()->PostTask( 151 context_->main_message_loop()->PostTask(
150 FROM_HERE, base::Bind(&ChromotingHost::ProcessPreAuthentication, this, 152 FROM_HERE, base::Bind(&ChromotingHost::AddAuthenticatedClient,
151 make_scoped_refptr(connection))); 153 this, make_scoped_refptr(client),
154 session->config(), session->jid()));
152 } 155 }
153 156
154 void ChromotingHost::OnConnectionClosed(ConnectionToClient* connection) { 157 void ChromotingHost::OnSessionClosed(ClientSession* client) {
155 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); 158 DCHECK(context_->network_message_loop()->BelongsToCurrentThread());
156 159
157 VLOG(1) << "Connection to client closed."; 160 VLOG(1) << "Connection to client closed.";
158 context_->main_message_loop()->PostTask( 161 context_->main_message_loop()->PostTask(
159 FROM_HERE, base::Bind(&ChromotingHost::OnClientDisconnected, this, 162 FROM_HERE, base::Bind(&ChromotingHost::OnClientDisconnected, this,
160 make_scoped_refptr(connection))); 163 make_scoped_refptr(client)));
161 } 164 }
162 165
163 void ChromotingHost::OnConnectionFailed(ConnectionToClient* connection) { 166 void ChromotingHost::OnSessionSequenceNumber(ClientSession* session,
164 DCHECK(context_->network_message_loop()->BelongsToCurrentThread());
165
166 LOG(ERROR) << "Connection failed unexpectedly.";
167 context_->main_message_loop()->PostTask(
168 FROM_HERE, base::Bind(&ChromotingHost::OnClientDisconnected, this,
169 make_scoped_refptr(connection)));
170 }
171
172 void ChromotingHost::OnSequenceNumberUpdated(ConnectionToClient* connection,
173 int64 sequence_number) { 167 int64 sequence_number) {
174 // Update the sequence number in ScreenRecorder. 168 // Update the sequence number in ScreenRecorder.
175 if (MessageLoop::current() != context_->main_message_loop()) { 169 if (MessageLoop::current() != context_->main_message_loop()) {
176 context_->main_message_loop()->PostTask( 170 context_->main_message_loop()->PostTask(
177 FROM_HERE, base::Bind(&ChromotingHost::OnSequenceNumberUpdated, this, 171 FROM_HERE, base::Bind(&ChromotingHost::OnSessionSequenceNumber, this,
178 make_scoped_refptr(connection), sequence_number)); 172 make_scoped_refptr(session), sequence_number));
179 return; 173 return;
180 } 174 }
181 175
182 if (recorder_.get()) 176 if (recorder_.get())
183 recorder_->UpdateSequenceNumber(sequence_number); 177 recorder_->UpdateSequenceNumber(sequence_number);
184 } 178 }
185 179
186 //////////////////////////////////////////////////////////////////////////// 180 ////////////////////////////////////////////////////////////////////////////
187 // SignalStrategy::StatusObserver implementations 181 // SignalStrategy::StatusObserver implementations
188 void ChromotingHost::OnStateChange( 182 void ChromotingHost::OnStateChange(
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 session->set_receiver_token( 279 session->set_receiver_token(
286 GenerateHostAuthToken(session->initiator_token())); 280 GenerateHostAuthToken(session->initiator_token()));
287 281
288 // Provide the Access Code as shared secret for SSL channel authentication. 282 // Provide the Access Code as shared secret for SSL channel authentication.
289 session->set_shared_secret(access_code_); 283 session->set_shared_secret(access_code_);
290 284
291 *response = protocol::SessionManager::ACCEPT; 285 *response = protocol::SessionManager::ACCEPT;
292 286
293 LOG(INFO) << "Client connected: " << session->jid(); 287 LOG(INFO) << "Client connected: " << session->jid();
294 288
295 // We accept the connection, so create a connection object.
296 ConnectionToClient* connection = new ConnectionToClient(
297 context_->network_message_loop(), this);
298 connection->Init(session);
299
300 // Create a client object. 289 // Create a client object.
290 scoped_refptr<protocol::ConnectionToClient> connection =
291 new protocol::ConnectionToClient(context_->network_message_loop(),
292 session);
301 ClientSession* client = new ClientSession( 293 ClientSession* client = new ClientSession(
302 this, 294 this, connection,
303 connection,
304 desktop_environment_->event_executor(), 295 desktop_environment_->event_executor(),
305 desktop_environment_->capturer()); 296 desktop_environment_->capturer());
306 connection->set_host_stub(client);
307 connection->set_input_stub(client);
308 297
309 clients_.push_back(client); 298 clients_.push_back(client);
310 } 299 }
311 300
312 void ChromotingHost::set_protocol_config( 301 void ChromotingHost::set_protocol_config(
313 protocol::CandidateSessionConfig* config) { 302 protocol::CandidateSessionConfig* config) {
314 DCHECK(config_.get()); 303 DCHECK(config_.get());
315 DCHECK_EQ(state_, kInitial); 304 DCHECK_EQ(state_, kInitial);
316 protocol_config_.reset(config); 305 protocol_config_.reset(config);
317 } 306 }
(...skipping 23 matching lines...) Expand all
341 desktop_environment_->OnPause(pause); 330 desktop_environment_->OnPause(pause);
342 } 331 }
343 332
344 void ChromotingHost::SetUiStrings(const UiStrings& ui_strings) { 333 void ChromotingHost::SetUiStrings(const UiStrings& ui_strings) {
345 DCHECK_EQ(context_->main_message_loop(), MessageLoop::current()); 334 DCHECK_EQ(context_->main_message_loop(), MessageLoop::current());
346 DCHECK_EQ(state_, kInitial); 335 DCHECK_EQ(state_, kInitial);
347 336
348 ui_strings_ = ui_strings; 337 ui_strings_ = ui_strings;
349 } 338 }
350 339
351 void ChromotingHost::OnClientDisconnected(ConnectionToClient* connection) { 340 void ChromotingHost::OnClientDisconnected(ClientSession* client) {
352 DCHECK_EQ(context_->main_message_loop(), MessageLoop::current()); 341 DCHECK_EQ(context_->main_message_loop(), MessageLoop::current());
353 342
354 // Find the client session corresponding to the given connection. 343 scoped_refptr<ClientSession> client_ref = client;
344
355 ClientList::iterator it; 345 ClientList::iterator it;
356 for (it = clients_.begin(); it != clients_.end(); ++it) { 346 for (it = clients_.begin(); it != clients_.end(); ++it) {
357 if (it->get()->connection() == connection) 347 if (it->get() == client)
358 break; 348 break;
359 } 349 }
360 if (it == clients_.end())
361 return;
362
363 scoped_refptr<ClientSession> client = *it;
364
365 clients_.erase(it); 350 clients_.erase(it);
366 351
367 if (recorder_.get()) { 352 if (recorder_.get()) {
368 recorder_->RemoveConnection(connection); 353 recorder_->RemoveConnection(client->connection());
369 } 354 }
370 355
371 // Close the connection to client just to be safe.
372 // TODO(garykac): This should be removed when we revisit our shutdown and
373 // disconnect code. This should only need to be done in
374 // ClientSession::Disconnect().
375 connection->Disconnect();
376
377 for (StatusObserverList::iterator it = status_observers_.begin(); 356 for (StatusObserverList::iterator it = status_observers_.begin();
378 it != status_observers_.end(); ++it) { 357 it != status_observers_.end(); ++it) {
379 (*it)->OnClientDisconnected(client->client_jid()); 358 (*it)->OnClientDisconnected(client->client_jid());
380 } 359 }
381 360
382 if (AuthenticatedClientsCount() == 0) { 361 if (AuthenticatedClientsCount() == 0) {
383 if (recorder_.get()) { 362 if (recorder_.get()) {
384 // Stop the recorder if there are no more clients. 363 // Stop the recorder if there are no more clients.
385 StopScreenRecorder(); 364 StopScreenRecorder();
386 } 365 }
387 366
388 // Disable the "curtain" if there are no more active clients. 367 // Disable the "curtain" if there are no more active clients.
389 EnableCurtainMode(false); 368 EnableCurtainMode(false);
390 if (is_it2me_) { 369 desktop_environment_->OnLastDisconnect();
391 desktop_environment_->OnLastDisconnect();
392 }
393 } 370 }
394
395 client->OnDisconnected();
396 } 371 }
397 372
398 // TODO(sergeyu): Move this to SessionManager? 373 // TODO(sergeyu): Move this to SessionManager?
399 Encoder* ChromotingHost::CreateEncoder(const protocol::SessionConfig& config) { 374 Encoder* ChromotingHost::CreateEncoder(const protocol::SessionConfig& config) {
400 const protocol::ChannelConfig& video_config = config.video_config(); 375 const protocol::ChannelConfig& video_config = config.video_config();
401 376
402 if (video_config.codec == protocol::ChannelConfig::CODEC_VERBATIM) { 377 if (video_config.codec == protocol::ChannelConfig::CODEC_VERBATIM) {
403 return EncoderRowBased::CreateVerbatimEncoder(); 378 return EncoderRowBased::CreateVerbatimEncoder();
404 } else if (video_config.codec == protocol::ChannelConfig::CODEC_ZIP) { 379 } else if (video_config.codec == protocol::ChannelConfig::CODEC_ZIP) {
405 return EncoderRowBased::CreateZlibEncoder(); 380 return EncoderRowBased::CreateZlibEncoder();
(...skipping 23 matching lines...) Expand all
429 void ChromotingHost::EnableCurtainMode(bool enable) { 404 void ChromotingHost::EnableCurtainMode(bool enable) {
430 // TODO(jamiewalch): This will need to be more sophisticated when we think 405 // TODO(jamiewalch): This will need to be more sophisticated when we think
431 // about proper crash recovery and daemon mode. 406 // about proper crash recovery and daemon mode.
432 // TODO(wez): CurtainMode shouldn't be driven directly by ChromotingHost. 407 // TODO(wez): CurtainMode shouldn't be driven directly by ChromotingHost.
433 if (is_it2me_ || enable == is_curtained_) 408 if (is_it2me_ || enable == is_curtained_)
434 return; 409 return;
435 desktop_environment_->curtain()->EnableCurtainMode(enable); 410 desktop_environment_->curtain()->EnableCurtainMode(enable);
436 is_curtained_ = enable; 411 is_curtained_ = enable;
437 } 412 }
438 413
439 void ChromotingHost::OnAuthenticationComplete(
440 scoped_refptr<ConnectionToClient> connection) {
441 DCHECK(context_->network_message_loop()->BelongsToCurrentThread());
442
443 context_->main_message_loop()->PostTask(
444 FROM_HERE, base::Bind(&ChromotingHost::AddAuthenticatedClient,
445 this, connection, connection->session()->config(),
446 connection->session()->jid()));
447 }
448
449 void ChromotingHost::AddAuthenticatedClient( 414 void ChromotingHost::AddAuthenticatedClient(
450 scoped_refptr<ConnectionToClient> connection, 415 ClientSession* client,
451 const protocol::SessionConfig& config, 416 const protocol::SessionConfig& config,
452 const std::string& jid) { 417 const std::string& jid) {
453 DCHECK_EQ(context_->main_message_loop(), MessageLoop::current()); 418 DCHECK_EQ(context_->main_message_loop(), MessageLoop::current());
454 419
455 // Disconnect all other clients. 420 // Disconnect all other clients.
456 // Iterate over a copy of the list of clients, to avoid mutating the list 421 // Iterate over a copy of the list of clients, to avoid mutating the list
457 // while iterating over it. 422 // while iterating over it.
458 ClientList clients_copy(clients_); 423 ClientList clients_copy(clients_);
459 for (ClientList::const_iterator client = clients_copy.begin(); 424 for (ClientList::const_iterator other_client = clients_copy.begin();
460 client != clients_copy.end(); client++) { 425 other_client != clients_copy.end(); ++other_client) {
461 ConnectionToClient* connection_other = client->get()->connection(); 426 if ((*other_client) != client) {
462 if (connection_other != connection) { 427 (*other_client)->Disconnect();
463 OnClientDisconnected(connection_other); 428 OnClientDisconnected(*other_client);
464 } 429 }
465 } 430 }
431
466 // Those disconnections should have killed the screen recorder. 432 // Those disconnections should have killed the screen recorder.
467 CHECK(recorder_.get() == NULL); 433 CHECK(recorder_.get() == NULL);
468 434
469 // Create a new RecordSession if there was none. 435 // Create a new RecordSession if there was none.
470 if (!recorder_.get()) { 436 if (!recorder_.get()) {
471 // Then we create a ScreenRecorder passing the message loops that 437 // Then we create a ScreenRecorder passing the message loops that
472 // it should run on. 438 // it should run on.
473 Encoder* encoder = CreateEncoder(config); 439 Encoder* encoder = CreateEncoder(config);
474 440
475 recorder_ = new ScreenRecorder(context_->main_message_loop(), 441 recorder_ = new ScreenRecorder(context_->main_message_loop(),
476 context_->encode_message_loop(), 442 context_->encode_message_loop(),
477 context_->network_message_loop(), 443 context_->network_message_loop(),
478 desktop_environment_->capturer(), 444 desktop_environment_->capturer(),
479 encoder); 445 encoder);
480 } 446 }
481 447
482 // Immediately add the connection and start the session. 448 // Immediately add the connection and start the session.
483 recorder_->AddConnection(connection); 449 recorder_->AddConnection(client->connection());
484 recorder_->Start(); 450 recorder_->Start();
485 // Notify observers that there is at least one authenticated client. 451 // Notify observers that there is at least one authenticated client.
486 for (StatusObserverList::iterator it = status_observers_.begin(); 452 for (StatusObserverList::iterator it = status_observers_.begin();
487 it != status_observers_.end(); ++it) { 453 it != status_observers_.end(); ++it) {
488 (*it)->OnClientAuthenticated(jid); 454 (*it)->OnClientAuthenticated(jid);
489 } 455 }
490 // TODO(jamiewalch): Tidy up actions to be taken on connect/disconnect, 456 // TODO(jamiewalch): Tidy up actions to be taken on connect/disconnect,
491 // including closing the connection on failure of a critical operation. 457 // including closing the connection on failure of a critical operation.
492 EnableCurtainMode(true); 458 EnableCurtainMode(true);
493 if (is_it2me_) { 459 if (is_it2me_) {
494 std::string username = jid; 460 std::string username = jid;
495 size_t pos = username.find('/'); 461 size_t pos = username.find('/');
496 if (pos != std::string::npos) 462 if (pos != std::string::npos)
497 username.replace(pos, std::string::npos, ""); 463 username.replace(pos, std::string::npos, "");
498 desktop_environment_->OnConnect(username); 464 desktop_environment_->OnConnect(username);
499 } 465 }
500 } 466 }
501 467
502 void ChromotingHost::ProcessPreAuthentication(
503 const scoped_refptr<ConnectionToClient>& connection) {
504 DCHECK_EQ(context_->main_message_loop(), MessageLoop::current());
505 // Find the client session corresponding to the given connection.
506 ClientList::iterator client;
507 for (client = clients_.begin(); client != clients_.end(); ++client) {
508 if (client->get()->connection() == connection)
509 break;
510 }
511 CHECK(client != clients_.end());
512
513 context_->network_message_loop()->PostTask(
514 FROM_HERE, base::Bind(&ClientSession::OnAuthenticationComplete,
515 client->get()));
516 }
517
518 void ChromotingHost::StopScreenRecorder() { 468 void ChromotingHost::StopScreenRecorder() {
519 DCHECK(MessageLoop::current() == context_->main_message_loop()); 469 DCHECK(MessageLoop::current() == context_->main_message_loop());
520 DCHECK(recorder_.get()); 470 DCHECK(recorder_.get());
521 471
522 ++stopping_recorders_; 472 ++stopping_recorders_;
523 recorder_->Stop(base::Bind(&ChromotingHost::OnScreenRecorderStopped, this)); 473 recorder_->Stop(base::Bind(&ChromotingHost::OnScreenRecorderStopped, this));
524 recorder_ = NULL; 474 recorder_ = NULL;
525 } 475 }
526 476
527 void ChromotingHost::OnScreenRecorderStopped() { 477 void ChromotingHost::OnScreenRecorderStopped() {
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 } 558 }
609 559
610 for (std::vector<base::Closure>::iterator it = shutdown_tasks_.begin(); 560 for (std::vector<base::Closure>::iterator it = shutdown_tasks_.begin();
611 it != shutdown_tasks_.end(); ++it) { 561 it != shutdown_tasks_.end(); ++it) {
612 it->Run(); 562 it->Run();
613 } 563 }
614 shutdown_tasks_.clear(); 564 shutdown_tasks_.clear();
615 } 565 }
616 566
617 } // namespace remoting 567 } // 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