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

Unified Diff: remoting/host/chromoting_host.cc

Issue 6711033: A new authenticated connection evicts an old one. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remove redundant member of HostMessageDispatcher. Created 9 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: remoting/host/chromoting_host.cc
diff --git a/remoting/host/chromoting_host.cc b/remoting/host/chromoting_host.cc
index df778482af73b31d566b5892ca39328ba9e5b60d..bfdd988589db1a4a902734e8bfe298f5680c0ad6 100644
--- a/remoting/host/chromoting_host.cc
+++ b/remoting/host/chromoting_host.cc
@@ -57,7 +57,6 @@ ChromotingHost::ChromotingHost(ChromotingHostContext* context,
state_(kInitial),
protocol_config_(protocol::CandidateSessionConfig::CreateDefault()) {
DCHECK(desktop_environment_.get());
- desktop_environment_->set_event_handler(this);
}
ChromotingHost::~ChromotingHost() {
@@ -140,9 +139,9 @@ void ChromotingHost::Shutdown() {
recorder_->RemoveAllConnections();
}
- // Disconnect the client.
- if (connection_) {
- connection_->Disconnect();
+ // Disconnect the clients.
+ for (size_t i = 0; i < clients_.size(); i++) {
+ clients_[i]->Disconnect();
}
awong 2011/03/22 15:11:56 Do we care to call clients_.clear() here to drop a
simonmorris 2011/03/23 10:35:20 Added clients_.clear() .
// Stop the heartbeat sender.
@@ -172,42 +171,33 @@ void ChromotingHost::Shutdown() {
// This method is called when a client connects.
void ChromotingHost::OnClientConnected(ConnectionToClient* connection) {
DCHECK_EQ(context_->main_message_loop(), MessageLoop::current());
-
- // Create a new RecordSession if there was none.
- if (!recorder_.get()) {
- // Then we create a ScreenRecorder passing the message loops that
- // it should run on.
- DCHECK(desktop_environment_->capturer());
-
- Encoder* encoder = CreateEncoder(connection->session()->config());
-
- recorder_ = new ScreenRecorder(context_->main_message_loop(),
- context_->encode_message_loop(),
- context_->network_message_loop(),
- desktop_environment_->capturer(),
- encoder);
- }
-
- // Immediately add the connection and start the session.
- recorder_->AddConnection(connection);
}
void ChromotingHost::OnClientDisconnected(ConnectionToClient* connection) {
DCHECK_EQ(context_->main_message_loop(), MessageLoop::current());
// Remove the connection from the session manager and stop the session.
- // TODO(hclam): Stop only if the last connection disconnected.
Sergey Ulanov 2011/03/22 23:19:14 I don't think we can remove this TODO yet. Recorde
simonmorris 2011/03/23 10:35:20 Done.
if (recorder_.get()) {
recorder_->RemoveConnection(connection);
- recorder_->Stop(NULL);
- recorder_ = NULL;
+ // If the client is authenticated, then it was the only reason for running
+ // the recorder.
awong 2011/03/22 15:11:56 Not completely sure what this means: "the only
simonmorris 2011/03/23 10:35:20 Clarified comment. I don't think that scenario ca
+ if (connection->client_authenticated()) {
+ recorder_->Stop(NULL);
+ recorder_ = NULL;
+ }
}
// Close the connection to connection just to be safe.
connection->Disconnect();
// Also remove reference to ConnectionToClient from this object.
- connection_ = NULL;
+ std::vector<scoped_refptr<ClientSession> >::iterator it;
+ for (it = clients_.begin(); it != clients_.end(); ++it) {
+ if (it->get()->connection() == connection) {
+ clients_.erase(it);
+ break;
+ }
+ }
}
////////////////////////////////////////////////////////////////////////////
@@ -287,8 +277,7 @@ void ChromotingHost::OnNewClientSession(
protocol::Session* session,
protocol::SessionManager::IncomingSessionResponse* response) {
base::AutoLock auto_lock(lock_);
- // TODO(hclam): Allow multiple clients to connect to the host.
- if (connection_.get() || state_ != kStarted) {
+ if (state_ != kStarted) {
*response = protocol::SessionManager::DECLINE;
return;
}
@@ -323,12 +312,20 @@ void ChromotingHost::OnNewClientSession(
VLOG(1) << "Client connected: " << session->jid();
- // If we accept the connected then create a connection object.
- connection_ = new ConnectionToClient(context_->network_message_loop(),
- this,
- desktop_environment_.get(),
- desktop_environment_->input_stub());
- connection_->Init(session);
+ // We accept the connection, so create a connection object.
+ ConnectionToClient* connection = new ConnectionToClient(
+ context_->network_message_loop(),
+ this,
+ NULL,
awong 2011/03/22 15:11:56 Is this parameter ever non-NULL now?
simonmorris 2011/03/23 10:35:20 Only in unit tests, and it's better to be more con
+ desktop_environment_->input_stub());
+
+ // Create a client object.
+ ClientSession* client = new ClientSession(this, connection);
+ connection->set_host_stub(client);
+
+ connection->Init(session);
+
+ clients_.push_back(client);
}
void ChromotingHost::set_protocol_config(
@@ -338,10 +335,6 @@ void ChromotingHost::set_protocol_config(
protocol_config_.reset(config);
}
-protocol::HostStub* ChromotingHost::host_stub() const {
- return desktop_environment_.get();
-}
-
void ChromotingHost::OnServerClosed() {
// Don't need to do anything here.
}
@@ -371,34 +364,68 @@ std::string ChromotingHost::GenerateHostAuthToken(
return encoded_client_token;
}
-void ChromotingHost::LocalLoginSucceeded() {
+void ChromotingHost::LocalLoginSucceeded(
+ scoped_refptr<ConnectionToClient> connection) {
if (MessageLoop::current() != context_->main_message_loop()) {
context_->main_message_loop()->PostTask(
FROM_HERE,
- NewRunnableMethod(this, &ChromotingHost::LocalLoginSucceeded));
+ NewRunnableMethod(this,
+ &ChromotingHost::LocalLoginSucceeded,
+ connection));
return;
}
protocol::LocalLoginStatus* status = new protocol::LocalLoginStatus();
status->set_success(true);
- connection_->client_stub()->BeginSessionResponse(
+ connection->client_stub()->BeginSessionResponse(
status, new DeleteTask<protocol::LocalLoginStatus>(status));
- connection_->OnClientAuthenticated();
+ connection->OnClientAuthenticated();
+
+ // Disconnect all other clients.
+ std::vector<scoped_refptr<ClientSession> > clients_copy(clients_);
awong 2011/03/22 15:11:56 Add a note for why we need to copy |clients_|.
simonmorris 2011/03/23 10:35:20 Done.
+ std::vector<scoped_refptr<ClientSession> >::const_iterator client;
+ for (client = clients_copy.begin(); client != clients_copy.end(); client++) {
+ ConnectionToClient* connection_other = client->get()->connection();
+ if (connection_other != connection) {
+ OnClientDisconnected(connection_other);
+ }
+ }
+ // Those disconnections should have killed the screen recorder.
+ DCHECK(recorder_.get() == NULL);
awong 2011/03/22 15:11:56 This should be a hard requirement right? I would
simonmorris 2011/03/23 10:35:20 Done.
+
+ // Create a new RecordSession if there was none.
+ if (!recorder_.get()) {
+ // Then we create a ScreenRecorder passing the message loops that
+ // it should run on.
+ DCHECK(desktop_environment_->capturer());
awong 2011/03/22 15:11:56 It's not obvious why we're checking for the existe
simonmorris 2011/03/23 10:35:20 A comment elsewhere suggests that this test is a r
+
+ Encoder* encoder = CreateEncoder(connection->session()->config());
+
+ recorder_ = new ScreenRecorder(context_->main_message_loop(),
+ context_->encode_message_loop(),
+ context_->network_message_loop(),
+ desktop_environment_->capturer(),
+ encoder);
+ }
+
+ // Immediately add the connection and start the session.
+ recorder_->AddConnection(connection);
recorder_->Start();
}
-void ChromotingHost::LocalLoginFailed() {
+void ChromotingHost::LocalLoginFailed(
+ scoped_refptr<ConnectionToClient> connection) {
if (MessageLoop::current() != context_->main_message_loop()) {
context_->main_message_loop()->PostTask(
FROM_HERE,
- NewRunnableMethod(this, &ChromotingHost::LocalLoginFailed));
+ NewRunnableMethod(this, &ChromotingHost::LocalLoginFailed, connection));
return;
}
protocol::LocalLoginStatus* status = new protocol::LocalLoginStatus();
status->set_success(false);
- connection_->client_stub()->BeginSessionResponse(
+ connection->client_stub()->BeginSessionResponse(
status, new DeleteTask<protocol::LocalLoginStatus>(status));
}

Powered by Google App Engine
This is Rietveld 408576698