OLD | NEW |
---|---|
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 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
293 // Provide the Access Code as shared secret for SSL channel authentication. | 293 // Provide the Access Code as shared secret for SSL channel authentication. |
294 session->set_shared_secret(access_code_); | 294 session->set_shared_secret(access_code_); |
295 | 295 |
296 *response = protocol::SessionManager::ACCEPT; | 296 *response = protocol::SessionManager::ACCEPT; |
297 | 297 |
298 LOG(INFO) << "Client connected: " << session->jid(); | 298 LOG(INFO) << "Client connected: " << session->jid(); |
299 | 299 |
300 // We accept the connection, so create a connection object. | 300 // We accept the connection, so create a connection object. |
301 ConnectionToClient* connection = new ConnectionToClient( | 301 ConnectionToClient* connection = new ConnectionToClient( |
302 context_->network_message_loop(), this); | 302 context_->network_message_loop(), this); |
303 connection->Init(session); | |
Wez
2011/09/12 22:40:44
Why did this move?
Sergey Ulanov
2011/09/12 22:53:22
Because ClientSession constructor now needs to acc
| |
303 | 304 |
304 // Create a client object. | 305 // Create a client object. |
305 ClientSession* client = new ClientSession( | 306 ClientSession* client = new ClientSession( |
306 this, | 307 this, |
307 UserAuthenticator::Create(), | 308 UserAuthenticator::Create(), |
308 connection, | 309 connection, |
309 desktop_environment_->event_executor()); | 310 desktop_environment_->event_executor()); |
310 connection->set_host_stub(client); | 311 connection->set_host_stub(client); |
311 connection->set_input_stub(client); | 312 connection->set_input_stub(client); |
312 | 313 |
313 connection->Init(session); | |
314 | |
315 clients_.push_back(client); | 314 clients_.push_back(client); |
316 } | 315 } |
317 | 316 |
318 void ChromotingHost::set_protocol_config( | 317 void ChromotingHost::set_protocol_config( |
319 protocol::CandidateSessionConfig* config) { | 318 protocol::CandidateSessionConfig* config) { |
320 DCHECK(config_.get()); | 319 DCHECK(config_.get()); |
321 DCHECK_EQ(state_, kInitial); | 320 DCHECK_EQ(state_, kInitial); |
322 protocol_config_.reset(config); | 321 protocol_config_.reset(config); |
323 } | 322 } |
324 | 323 |
(...skipping 29 matching lines...) Expand all Loading... | |
354 DCHECK_EQ(context_->main_message_loop(), MessageLoop::current()); | 353 DCHECK_EQ(context_->main_message_loop(), MessageLoop::current()); |
355 DCHECK_EQ(state_, kInitial); | 354 DCHECK_EQ(state_, kInitial); |
356 | 355 |
357 ui_strings_ = ui_strings; | 356 ui_strings_ = ui_strings; |
358 } | 357 } |
359 | 358 |
360 void ChromotingHost::OnClientDisconnected(ConnectionToClient* connection) { | 359 void ChromotingHost::OnClientDisconnected(ConnectionToClient* connection) { |
361 DCHECK_EQ(context_->main_message_loop(), MessageLoop::current()); | 360 DCHECK_EQ(context_->main_message_loop(), MessageLoop::current()); |
362 | 361 |
363 // Find the client session corresponding to the given connection. | 362 // Find the client session corresponding to the given connection. |
364 ClientList::iterator client; | 363 ClientList::iterator it; |
365 for (client = clients_.begin(); client != clients_.end(); ++client) { | 364 for (it = clients_.begin(); it != clients_.end(); ++it) { |
366 if (client->get()->connection() == connection) | 365 if (it->get()->connection() == connection) |
367 break; | 366 break; |
368 } | 367 } |
369 if (client == clients_.end()) | 368 if (it == clients_.end()) |
370 return; | 369 return; |
371 | 370 |
371 scoped_refptr<ClientSession> client = *it; | |
372 | |
373 clients_.erase(it); | |
374 | |
372 // Remove the connection from the session manager and stop the session. | 375 // Remove the connection from the session manager and stop the session. |
373 // TODO(hclam): Stop only if the last connection disconnected. | |
374 if (recorder_.get()) { | 376 if (recorder_.get()) { |
375 recorder_->RemoveConnection(connection); | 377 recorder_->RemoveConnection(connection); |
376 // The recorder only exists to serve the unique authenticated client. | |
377 // If that client has disconnected, then we can kill the recorder. | |
378 if (client->get()->authenticated()) | |
379 StopScreenRecorder(); | |
380 } | 378 } |
381 | 379 |
382 // Close the connection to client just to be safe. | 380 // Close the connection to client just to be safe. |
383 connection->Disconnect(); | 381 connection->Disconnect(); |
384 | 382 |
385 // Also remove reference to ConnectionToClient from this object. | 383 if (client->authenticated()) { |
386 int old_authenticated_clients = AuthenticatedClientsCount(); | |
387 clients_.erase(client); | |
388 | |
389 // Notify the observers of the change, if any. | |
390 int authenticated_clients = AuthenticatedClientsCount(); | |
391 if (old_authenticated_clients != authenticated_clients) { | |
392 for (StatusObserverList::iterator it = status_observers_.begin(); | 384 for (StatusObserverList::iterator it = status_observers_.begin(); |
393 it != status_observers_.end(); ++it) { | 385 it != status_observers_.end(); ++it) { |
394 (*it)->OnClientDisconnected(connection); | 386 (*it)->OnClientDisconnected(client->client_jid()); |
395 } | 387 } |
396 } | 388 } |
397 | 389 |
398 // Disable the "curtain" if there are no more active clients. | 390 // Disable the "curtain" if there are no more active clients. |
Wez
2011/09/12 22:40:44
Update this comment.
Sergey Ulanov
2011/09/12 22:53:22
Done.
| |
399 if (AuthenticatedClientsCount() == 0) { | 391 if (AuthenticatedClientsCount() == 0) { |
392 if (recorder_.get()) { | |
393 // The recorder only exists to serve the unique authenticated client. | |
394 // If that client has disconnected, then we can kill the recorder. | |
Wez
2011/09/12 22:40:44
Simpler to say "If there are no authenticated clie
Sergey Ulanov
2011/09/12 22:53:22
Done.
| |
395 if (client->authenticated()) | |
396 StopScreenRecorder(); | |
397 } | |
398 | |
400 EnableCurtainMode(false); | 399 EnableCurtainMode(false); |
401 if (is_it2me_) { | 400 if (is_it2me_) { |
402 desktop_environment_->OnLastDisconnect(); | 401 desktop_environment_->OnLastDisconnect(); |
403 } | 402 } |
404 } | 403 } |
405 } | 404 } |
406 | 405 |
407 // TODO(sergeyu): Move this to SessionManager? | 406 // TODO(sergeyu): Move this to SessionManager? |
408 Encoder* ChromotingHost::CreateEncoder(const protocol::SessionConfig& config) { | 407 Encoder* ChromotingHost::CreateEncoder(const protocol::SessionConfig& config) { |
409 const protocol::ChannelConfig& video_config = config.video_config(); | 408 const protocol::ChannelConfig& video_config = config.video_config(); |
(...skipping 30 matching lines...) Expand all Loading... | |
440 // about proper crash recovery and daemon mode. | 439 // about proper crash recovery and daemon mode. |
441 // TODO(wez): CurtainMode shouldn't be driven directly by ChromotingHost. | 440 // TODO(wez): CurtainMode shouldn't be driven directly by ChromotingHost. |
442 if (is_it2me_ || enable == is_curtained_) | 441 if (is_it2me_ || enable == is_curtained_) |
443 return; | 442 return; |
444 desktop_environment_->curtain()->EnableCurtainMode(enable); | 443 desktop_environment_->curtain()->EnableCurtainMode(enable); |
445 is_curtained_ = enable; | 444 is_curtained_ = enable; |
446 } | 445 } |
447 | 446 |
448 void ChromotingHost::LocalLoginSucceeded( | 447 void ChromotingHost::LocalLoginSucceeded( |
449 scoped_refptr<ConnectionToClient> connection) { | 448 scoped_refptr<ConnectionToClient> connection) { |
450 if (MessageLoop::current() != context_->main_message_loop()) { | 449 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); |
451 context_->main_message_loop()->PostTask( | 450 |
452 FROM_HERE, base::Bind(&ChromotingHost::LocalLoginSucceeded, this, | 451 context_->main_message_loop()->PostTask( |
453 connection)); | 452 FROM_HERE, base::Bind(&ChromotingHost::AddAuthenticatedClient, |
454 return; | 453 this, connection, connection->session()->config(), |
455 } | 454 connection->session()->jid())); |
455 } | |
456 | |
457 void ChromotingHost::AddAuthenticatedClient( | |
458 scoped_refptr<ConnectionToClient> connection, | |
459 const protocol::SessionConfig& config, | |
460 const std::string& jid) { | |
461 DCHECK_EQ(context_->main_message_loop(), MessageLoop::current()); | |
456 | 462 |
457 protocol::LocalLoginStatus* status = new protocol::LocalLoginStatus(); | 463 protocol::LocalLoginStatus* status = new protocol::LocalLoginStatus(); |
458 status->set_success(true); | 464 status->set_success(true); |
459 connection->client_stub()->BeginSessionResponse( | 465 connection->client_stub()->BeginSessionResponse( |
460 status, new DeleteTask<protocol::LocalLoginStatus>(status)); | 466 status, new DeleteTask<protocol::LocalLoginStatus>(status)); |
461 | 467 |
462 // Disconnect all other clients. | 468 // Disconnect all other clients. |
463 // Iterate over a copy of the list of clients, to avoid mutating the list | 469 // Iterate over a copy of the list of clients, to avoid mutating the list |
464 // while iterating over it. | 470 // while iterating over it. |
465 ClientList clients_copy(clients_); | 471 ClientList clients_copy(clients_); |
466 for (ClientList::const_iterator client = clients_copy.begin(); | 472 for (ClientList::const_iterator client = clients_copy.begin(); |
467 client != clients_copy.end(); client++) { | 473 client != clients_copy.end(); client++) { |
468 ConnectionToClient* connection_other = client->get()->connection(); | 474 ConnectionToClient* connection_other = client->get()->connection(); |
469 if (connection_other != connection) { | 475 if (connection_other != connection) { |
470 OnClientDisconnected(connection_other); | 476 OnClientDisconnected(connection_other); |
471 } | 477 } |
472 } | 478 } |
473 // Those disconnections should have killed the screen recorder. | 479 // Those disconnections should have killed the screen recorder. |
474 CHECK(recorder_.get() == NULL); | 480 CHECK(recorder_.get() == NULL); |
475 | 481 |
476 // Create a new RecordSession if there was none. | 482 // Create a new RecordSession if there was none. |
477 if (!recorder_.get()) { | 483 if (!recorder_.get()) { |
478 // Then we create a ScreenRecorder passing the message loops that | 484 // Then we create a ScreenRecorder passing the message loops that |
479 // it should run on. | 485 // it should run on. |
480 Encoder* encoder = CreateEncoder(connection->session()->config()); | 486 Encoder* encoder = CreateEncoder(config); |
481 | 487 |
482 recorder_ = new ScreenRecorder(context_->main_message_loop(), | 488 recorder_ = new ScreenRecorder(context_->main_message_loop(), |
483 context_->encode_message_loop(), | 489 context_->encode_message_loop(), |
484 context_->network_message_loop(), | 490 context_->network_message_loop(), |
485 desktop_environment_->capturer(), | 491 desktop_environment_->capturer(), |
486 encoder); | 492 encoder); |
487 } | 493 } |
488 | 494 |
489 // Immediately add the connection and start the session. | 495 // Immediately add the connection and start the session. |
490 recorder_->AddConnection(connection); | 496 recorder_->AddConnection(connection); |
491 recorder_->Start(); | 497 recorder_->Start(); |
492 // Notify observers that there is at least one authenticated client. | 498 // Notify observers that there is at least one authenticated client. |
493 for (StatusObserverList::iterator it = status_observers_.begin(); | 499 for (StatusObserverList::iterator it = status_observers_.begin(); |
494 it != status_observers_.end(); ++it) { | 500 it != status_observers_.end(); ++it) { |
495 (*it)->OnClientAuthenticated(connection); | 501 (*it)->OnClientAuthenticated(jid); |
496 } | 502 } |
497 // TODO(jamiewalch): Tidy up actions to be taken on connect/disconnect, | 503 // TODO(jamiewalch): Tidy up actions to be taken on connect/disconnect, |
498 // including closing the connection on failure of a critical operation. | 504 // including closing the connection on failure of a critical operation. |
499 EnableCurtainMode(true); | 505 EnableCurtainMode(true); |
500 if (is_it2me_) { | 506 if (is_it2me_) { |
501 std::string username = connection->session()->jid(); | 507 std::string username = jid; |
502 size_t pos = username.find('/'); | 508 size_t pos = username.find('/'); |
503 if (pos != std::string::npos) | 509 if (pos != std::string::npos) |
504 username.replace(pos, std::string::npos, ""); | 510 username.replace(pos, std::string::npos, ""); |
505 desktop_environment_->OnConnect(username); | 511 desktop_environment_->OnConnect(username); |
506 } | 512 } |
507 } | 513 } |
508 | 514 |
509 void ChromotingHost::LocalLoginFailed( | 515 void ChromotingHost::LocalLoginFailed( |
510 scoped_refptr<ConnectionToClient> connection) { | 516 scoped_refptr<ConnectionToClient> connection) { |
511 if (MessageLoop::current() != context_->main_message_loop()) { | 517 if (MessageLoop::current() != context_->main_message_loop()) { |
(...skipping 12 matching lines...) Expand all Loading... | |
524 void ChromotingHost::ProcessPreAuthentication( | 530 void ChromotingHost::ProcessPreAuthentication( |
525 const scoped_refptr<ConnectionToClient>& connection) { | 531 const scoped_refptr<ConnectionToClient>& connection) { |
526 DCHECK_EQ(context_->main_message_loop(), MessageLoop::current()); | 532 DCHECK_EQ(context_->main_message_loop(), MessageLoop::current()); |
527 // Find the client session corresponding to the given connection. | 533 // Find the client session corresponding to the given connection. |
528 ClientList::iterator client; | 534 ClientList::iterator client; |
529 for (client = clients_.begin(); client != clients_.end(); ++client) { | 535 for (client = clients_.begin(); client != clients_.end(); ++client) { |
530 if (client->get()->connection() == connection) | 536 if (client->get()->connection() == connection) |
531 break; | 537 break; |
532 } | 538 } |
533 CHECK(client != clients_.end()); | 539 CHECK(client != clients_.end()); |
534 client->get()->OnAuthorizationComplete(true); | 540 |
541 context_->network_message_loop()->PostTask( | |
542 FROM_HERE, base::Bind(&ClientSession::OnAuthorizationComplete, | |
543 client->get(), true)); | |
535 } | 544 } |
536 | 545 |
537 void ChromotingHost::StopScreenRecorder() { | 546 void ChromotingHost::StopScreenRecorder() { |
538 DCHECK(MessageLoop::current() == context_->main_message_loop()); | 547 DCHECK(MessageLoop::current() == context_->main_message_loop()); |
539 DCHECK(recorder_.get()); | 548 DCHECK(recorder_.get()); |
540 | 549 |
541 ++stopping_recorders_; | 550 ++stopping_recorders_; |
542 recorder_->Stop(base::Bind(&ChromotingHost::OnScreenRecorderStopped, this)); | 551 recorder_->Stop(base::Bind(&ChromotingHost::OnScreenRecorderStopped, this)); |
543 recorder_ = NULL; | 552 recorder_ = NULL; |
544 } | 553 } |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
628 | 637 |
629 for (std::vector<Task*>::iterator it = shutdown_tasks_.begin(); | 638 for (std::vector<Task*>::iterator it = shutdown_tasks_.begin(); |
630 it != shutdown_tasks_.end(); ++it) { | 639 it != shutdown_tasks_.end(); ++it) { |
631 (*it)->Run(); | 640 (*it)->Run(); |
632 delete *it; | 641 delete *it; |
633 } | 642 } |
634 shutdown_tasks_.clear(); | 643 shutdown_tasks_.clear(); |
635 } | 644 } |
636 | 645 |
637 } // namespace remoting | 646 } // namespace remoting |
OLD | NEW |