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

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: 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
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) 124 if (shutdown_task)
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::OnSessionFailed(ClientSession* client) {
164 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); 167 DCHECK(context_->network_message_loop()->BelongsToCurrentThread());
165 168
166 LOG(ERROR) << "Connection failed unexpectedly."; 169 LOG(ERROR) << "Connection failed unexpectedly.";
167 context_->main_message_loop()->PostTask( 170 context_->main_message_loop()->PostTask(
168 FROM_HERE, base::Bind(&ChromotingHost::OnClientDisconnected, this, 171 FROM_HERE, base::Bind(&ChromotingHost::OnClientDisconnected, this,
169 make_scoped_refptr(connection))); 172 make_scoped_refptr(client)));
170 } 173 }
171 174
172 void ChromotingHost::OnSequenceNumberUpdated(ConnectionToClient* connection, 175 void ChromotingHost::OnSessionSequenceNumber(ClientSession* session,
173 int64 sequence_number) { 176 int64 sequence_number) {
174 // Update the sequence number in ScreenRecorder. 177 // Update the sequence number in ScreenRecorder.
175 if (MessageLoop::current() != context_->main_message_loop()) { 178 if (MessageLoop::current() != context_->main_message_loop()) {
176 context_->main_message_loop()->PostTask( 179 context_->main_message_loop()->PostTask(
177 FROM_HERE, base::Bind(&ChromotingHost::OnSequenceNumberUpdated, this, 180 FROM_HERE, base::Bind(&ChromotingHost::OnSessionSequenceNumber, this,
178 make_scoped_refptr(connection), sequence_number)); 181 make_scoped_refptr(session), sequence_number));
179 return; 182 return;
180 } 183 }
181 184
182 if (recorder_.get()) 185 if (recorder_.get())
183 recorder_->UpdateSequenceNumber(sequence_number); 186 recorder_->UpdateSequenceNumber(sequence_number);
184 } 187 }
185 188
186 //////////////////////////////////////////////////////////////////////////// 189 ////////////////////////////////////////////////////////////////////////////
187 // SignalStrategy::StatusObserver implementations 190 // SignalStrategy::StatusObserver implementations
188 void ChromotingHost::OnStateChange( 191 void ChromotingHost::OnStateChange(
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 session->set_receiver_token( 288 session->set_receiver_token(
286 GenerateHostAuthToken(session->initiator_token())); 289 GenerateHostAuthToken(session->initiator_token()));
287 290
288 // Provide the Access Code as shared secret for SSL channel authentication. 291 // Provide the Access Code as shared secret for SSL channel authentication.
289 session->set_shared_secret(access_code_); 292 session->set_shared_secret(access_code_);
290 293
291 *response = protocol::SessionManager::ACCEPT; 294 *response = protocol::SessionManager::ACCEPT;
292 295
293 LOG(INFO) << "Client connected: " << session->jid(); 296 LOG(INFO) << "Client connected: " << session->jid();
294 297
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. 298 // Create a client object.
299 scoped_refptr<protocol::ConnectionToClient> connection =
300 new protocol::ConnectionToClient(context_->network_message_loop(),
301 session);
301 ClientSession* client = new ClientSession( 302 ClientSession* client = new ClientSession(
302 this, 303 this, connection,
303 connection,
304 desktop_environment_->event_executor(), 304 desktop_environment_->event_executor(),
305 desktop_environment_->capturer()); 305 desktop_environment_->capturer());
306 connection->set_host_stub(client);
307 connection->set_input_stub(client);
308 306
309 clients_.push_back(client); 307 clients_.push_back(client);
310 } 308 }
311 309
312 void ChromotingHost::set_protocol_config( 310 void ChromotingHost::set_protocol_config(
313 protocol::CandidateSessionConfig* config) { 311 protocol::CandidateSessionConfig* config) {
314 DCHECK(config_.get()); 312 DCHECK(config_.get());
315 DCHECK_EQ(state_, kInitial); 313 DCHECK_EQ(state_, kInitial);
316 protocol_config_.reset(config); 314 protocol_config_.reset(config);
317 } 315 }
(...skipping 26 matching lines...) Expand all
344 desktop_environment_->OnPause(pause); 342 desktop_environment_->OnPause(pause);
345 } 343 }
346 344
347 void ChromotingHost::SetUiStrings(const UiStrings& ui_strings) { 345 void ChromotingHost::SetUiStrings(const UiStrings& ui_strings) {
348 DCHECK_EQ(context_->main_message_loop(), MessageLoop::current()); 346 DCHECK_EQ(context_->main_message_loop(), MessageLoop::current());
349 DCHECK_EQ(state_, kInitial); 347 DCHECK_EQ(state_, kInitial);
350 348
351 ui_strings_ = ui_strings; 349 ui_strings_ = ui_strings;
352 } 350 }
353 351
354 void ChromotingHost::OnClientDisconnected(ConnectionToClient* connection) { 352 void ChromotingHost::OnClientDisconnected(ClientSession* client) {
355 DCHECK_EQ(context_->main_message_loop(), MessageLoop::current()); 353 DCHECK_EQ(context_->main_message_loop(), MessageLoop::current());
356 354
357 // Find the client session corresponding to the given connection. 355 scoped_refptr<ClientSession> client_ref = client;
356
358 ClientList::iterator it; 357 ClientList::iterator it;
359 for (it = clients_.begin(); it != clients_.end(); ++it) { 358 for (it = clients_.begin(); it != clients_.end(); ++it) {
360 if (it->get()->connection() == connection) 359 if (it->get() == client)
361 break; 360 break;
362 } 361 }
363 if (it == clients_.end())
364 return;
365
366 scoped_refptr<ClientSession> client = *it;
367
368 clients_.erase(it); 362 clients_.erase(it);
369 363
370 if (recorder_.get()) { 364 if (recorder_.get()) {
371 recorder_->RemoveConnection(connection); 365 recorder_->RemoveConnection(client->connection());
372 } 366 }
373 367
374 // Close the connection to client just to be safe.
375 // TODO(garykac): This should be removed when we revisit our shutdown and
376 // disconnect code. This should only need to be done in
377 // ClientSession::Disconnect().
378 connection->Disconnect();
379
380 for (StatusObserverList::iterator it = status_observers_.begin(); 368 for (StatusObserverList::iterator it = status_observers_.begin();
381 it != status_observers_.end(); ++it) { 369 it != status_observers_.end(); ++it) {
382 (*it)->OnClientDisconnected(client->client_jid()); 370 (*it)->OnClientDisconnected(client->client_jid());
383 } 371 }
384 372
385 if (AuthenticatedClientsCount() == 0) { 373 if (AuthenticatedClientsCount() == 0) {
386 if (recorder_.get()) { 374 if (recorder_.get()) {
387 // Stop the recorder if there are no more clients. 375 // Stop the recorder if there are no more clients.
388 StopScreenRecorder(); 376 StopScreenRecorder();
389 } 377 }
390 378
391 // Disable the "curtain" if there are no more active clients. 379 // Disable the "curtain" if there are no more active clients.
392 EnableCurtainMode(false); 380 EnableCurtainMode(false);
393 if (is_it2me_) { 381 desktop_environment_->OnLastDisconnect();
394 desktop_environment_->OnLastDisconnect();
395 }
396 } 382 }
397
398 client->OnDisconnected();
399 } 383 }
400 384
401 // TODO(sergeyu): Move this to SessionManager? 385 // TODO(sergeyu): Move this to SessionManager?
402 Encoder* ChromotingHost::CreateEncoder(const protocol::SessionConfig& config) { 386 Encoder* ChromotingHost::CreateEncoder(const protocol::SessionConfig& config) {
403 const protocol::ChannelConfig& video_config = config.video_config(); 387 const protocol::ChannelConfig& video_config = config.video_config();
404 388
405 if (video_config.codec == protocol::ChannelConfig::CODEC_VERBATIM) { 389 if (video_config.codec == protocol::ChannelConfig::CODEC_VERBATIM) {
406 return EncoderRowBased::CreateVerbatimEncoder(); 390 return EncoderRowBased::CreateVerbatimEncoder();
407 } else if (video_config.codec == protocol::ChannelConfig::CODEC_ZIP) { 391 } else if (video_config.codec == protocol::ChannelConfig::CODEC_ZIP) {
408 return EncoderRowBased::CreateZlibEncoder(); 392 return EncoderRowBased::CreateZlibEncoder();
(...skipping 23 matching lines...) Expand all
432 void ChromotingHost::EnableCurtainMode(bool enable) { 416 void ChromotingHost::EnableCurtainMode(bool enable) {
433 // TODO(jamiewalch): This will need to be more sophisticated when we think 417 // TODO(jamiewalch): This will need to be more sophisticated when we think
434 // about proper crash recovery and daemon mode. 418 // about proper crash recovery and daemon mode.
435 // TODO(wez): CurtainMode shouldn't be driven directly by ChromotingHost. 419 // TODO(wez): CurtainMode shouldn't be driven directly by ChromotingHost.
436 if (is_it2me_ || enable == is_curtained_) 420 if (is_it2me_ || enable == is_curtained_)
437 return; 421 return;
438 desktop_environment_->curtain()->EnableCurtainMode(enable); 422 desktop_environment_->curtain()->EnableCurtainMode(enable);
439 is_curtained_ = enable; 423 is_curtained_ = enable;
440 } 424 }
441 425
442 void ChromotingHost::OnAuthenticationComplete(
443 scoped_refptr<ConnectionToClient> connection) {
444 DCHECK(context_->network_message_loop()->BelongsToCurrentThread());
445
446 context_->main_message_loop()->PostTask(
447 FROM_HERE, base::Bind(&ChromotingHost::AddAuthenticatedClient,
448 this, connection, connection->session()->config(),
449 connection->session()->jid()));
450 }
451
452 void ChromotingHost::AddAuthenticatedClient( 426 void ChromotingHost::AddAuthenticatedClient(
453 scoped_refptr<ConnectionToClient> connection, 427 ClientSession* client,
454 const protocol::SessionConfig& config, 428 const protocol::SessionConfig& config,
455 const std::string& jid) { 429 const std::string& jid) {
456 DCHECK_EQ(context_->main_message_loop(), MessageLoop::current()); 430 DCHECK_EQ(context_->main_message_loop(), MessageLoop::current());
457 431
458 // Disconnect all other clients. 432 // Disconnect all other clients.
459 // Iterate over a copy of the list of clients, to avoid mutating the list 433 // Iterate over a copy of the list of clients, to avoid mutating the list
460 // while iterating over it. 434 // while iterating over it.
461 ClientList clients_copy(clients_); 435 ClientList clients_copy(clients_);
462 for (ClientList::const_iterator client = clients_copy.begin(); 436 for (ClientList::const_iterator other_client = clients_copy.begin();
463 client != clients_copy.end(); client++) { 437 other_client != clients_copy.end(); ++other_client) {
464 ConnectionToClient* connection_other = client->get()->connection(); 438 if ((*other_client) != client) {
465 if (connection_other != connection) { 439 (*other_client)->Disconnect();
466 OnClientDisconnected(connection_other); 440 OnClientDisconnected(*other_client);
467 } 441 }
468 } 442 }
443
469 // Those disconnections should have killed the screen recorder. 444 // Those disconnections should have killed the screen recorder.
470 CHECK(recorder_.get() == NULL); 445 CHECK(recorder_.get() == NULL);
471 446
472 // Create a new RecordSession if there was none. 447 // Create a new RecordSession if there was none.
473 if (!recorder_.get()) { 448 if (!recorder_.get()) {
474 // Then we create a ScreenRecorder passing the message loops that 449 // Then we create a ScreenRecorder passing the message loops that
475 // it should run on. 450 // it should run on.
476 Encoder* encoder = CreateEncoder(config); 451 Encoder* encoder = CreateEncoder(config);
477 452
478 recorder_ = new ScreenRecorder(context_->main_message_loop(), 453 recorder_ = new ScreenRecorder(context_->main_message_loop(),
479 context_->encode_message_loop(), 454 context_->encode_message_loop(),
480 context_->network_message_loop(), 455 context_->network_message_loop(),
481 desktop_environment_->capturer(), 456 desktop_environment_->capturer(),
482 encoder); 457 encoder);
483 } 458 }
484 459
485 // Immediately add the connection and start the session. 460 // Immediately add the connection and start the session.
486 recorder_->AddConnection(connection); 461 recorder_->AddConnection(client->connection());
487 recorder_->Start(); 462 recorder_->Start();
488 // Notify observers that there is at least one authenticated client. 463 // Notify observers that there is at least one authenticated client.
489 for (StatusObserverList::iterator it = status_observers_.begin(); 464 for (StatusObserverList::iterator it = status_observers_.begin();
490 it != status_observers_.end(); ++it) { 465 it != status_observers_.end(); ++it) {
491 (*it)->OnClientAuthenticated(jid); 466 (*it)->OnClientAuthenticated(jid);
492 } 467 }
493 // TODO(jamiewalch): Tidy up actions to be taken on connect/disconnect, 468 // TODO(jamiewalch): Tidy up actions to be taken on connect/disconnect,
494 // including closing the connection on failure of a critical operation. 469 // including closing the connection on failure of a critical operation.
495 EnableCurtainMode(true); 470 EnableCurtainMode(true);
496 if (is_it2me_) { 471 if (is_it2me_) {
497 std::string username = jid; 472 std::string username = jid;
498 size_t pos = username.find('/'); 473 size_t pos = username.find('/');
499 if (pos != std::string::npos) 474 if (pos != std::string::npos)
500 username.replace(pos, std::string::npos, ""); 475 username.replace(pos, std::string::npos, "");
501 desktop_environment_->OnConnect(username); 476 desktop_environment_->OnConnect(username);
502 } 477 }
503 } 478 }
504 479
505 void ChromotingHost::ProcessPreAuthentication(
506 const scoped_refptr<ConnectionToClient>& connection) {
507 DCHECK_EQ(context_->main_message_loop(), MessageLoop::current());
508 // Find the client session corresponding to the given connection.
509 ClientList::iterator client;
510 for (client = clients_.begin(); client != clients_.end(); ++client) {
511 if (client->get()->connection() == connection)
512 break;
513 }
514 CHECK(client != clients_.end());
515
516 context_->network_message_loop()->PostTask(
517 FROM_HERE, base::Bind(&ClientSession::OnAuthenticationComplete,
518 client->get()));
519 }
520
521 void ChromotingHost::StopScreenRecorder() { 480 void ChromotingHost::StopScreenRecorder() {
522 DCHECK(MessageLoop::current() == context_->main_message_loop()); 481 DCHECK(MessageLoop::current() == context_->main_message_loop());
523 DCHECK(recorder_.get()); 482 DCHECK(recorder_.get());
524 483
525 ++stopping_recorders_; 484 ++stopping_recorders_;
526 recorder_->Stop(base::Bind(&ChromotingHost::OnScreenRecorderStopped, this)); 485 recorder_->Stop(base::Bind(&ChromotingHost::OnScreenRecorderStopped, this));
527 recorder_ = NULL; 486 recorder_ = NULL;
528 } 487 }
529 488
530 void ChromotingHost::OnScreenRecorderStopped() { 489 void ChromotingHost::OnScreenRecorderStopped() {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
612 571
613 for (std::vector<Task*>::iterator it = shutdown_tasks_.begin(); 572 for (std::vector<Task*>::iterator it = shutdown_tasks_.begin();
614 it != shutdown_tasks_.end(); ++it) { 573 it != shutdown_tasks_.end(); ++it) {
615 (*it)->Run(); 574 (*it)->Run();
616 delete *it; 575 delete *it;
617 } 576 }
618 shutdown_tasks_.clear(); 577 shutdown_tasks_.clear();
619 } 578 }
620 579
621 } // namespace remoting 580 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698