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

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

Issue 7867019: Access Session::config() and Session::jid() on the correct thread only. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: - Created 9 years, 3 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) 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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698