12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/connection_to_client.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/location.h"
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/io_buffer.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/clipboard_stub.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/host_control_dispatcher.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/host_event_dispatcher.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/host_stub.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/input_stub.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace remoting {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace protocol {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ConnectionToClient::ConnectionToClient(protocol::Session* session)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : handler_(NULL),
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      clipboard_stub_(NULL),
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      host_stub_(NULL),
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      input_stub_(NULL),
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session_(session) {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  session_->SetEventHandler(this);
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ConnectionToClient::~ConnectionToClient() {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConnectionToClient::SetEventHandler(EventHandler* event_handler) {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  handler_ = event_handler;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)protocol::Session* ConnectionToClient::session() {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return session_.get();
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConnectionToClient::Disconnect() {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CloseChannels();
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This should trigger OnConnectionClosed() event and this object
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // may be destroyed as the result.
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  session_->Close();
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConnectionToClient::UpdateSequenceNumber(int64 sequence_number) {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  handler_->OnSequenceNumberUpdated(this, sequence_number);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)VideoStub* ConnectionToClient::video_stub() {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return video_writer_.get();
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AudioStub* ConnectionToClient::audio_stub() {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return audio_writer_.get();
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Return pointer to ClientStub.
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ClientStub* ConnectionToClient::client_stub() {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return control_dispatcher_.get();
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConnectionToClient::set_clipboard_stub(
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    protocol::ClipboardStub* clipboard_stub) {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  clipboard_stub_ = clipboard_stub;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ClipboardStub* ConnectionToClient::clipboard_stub() {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return clipboard_stub_;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConnectionToClient::set_host_stub(protocol::HostStub* host_stub) {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_stub_ = host_stub;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HostStub* ConnectionToClient::host_stub() {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return host_stub_;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConnectionToClient::set_input_stub(protocol::InputStub* input_stub) {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  input_stub_ = input_stub;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InputStub* ConnectionToClient::input_stub() {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return input_stub_;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConnectionToClient::OnSessionStateChange(Session::State state) {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(handler_);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch(state) {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case Session::INITIALIZING:
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case Session::CONNECTING:
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case Session::ACCEPTING:
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case Session::CONNECTED:
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Don't care about these events.
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case Session::AUTHENTICATED:
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Initialize channels.
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      control_dispatcher_.reset(new HostControlDispatcher());
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      control_dispatcher_->Init(
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          session_.get(), session_->config().control_config(),
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Bind(&ConnectionToClient::OnChannelInitialized,
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     base::Unretained(this)));
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      control_dispatcher_->set_clipboard_stub(clipboard_stub_);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      control_dispatcher_->set_host_stub(host_stub_);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      event_dispatcher_.reset(new HostEventDispatcher());
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      event_dispatcher_->Init(
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          session_.get(), session_->config().event_config(),
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Bind(&ConnectionToClient::OnChannelInitialized,
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     base::Unretained(this)));
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      event_dispatcher_->set_input_stub(input_stub_);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      event_dispatcher_->set_sequence_number_callback(base::Bind(
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &ConnectionToClient::UpdateSequenceNumber, base::Unretained(this)));
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      video_writer_ = VideoWriter::Create(session_->config());
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      video_writer_->Init(session_.get(), base::Bind(
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &ConnectionToClient::OnChannelInitialized, base::Unretained(this)));
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      audio_writer_ = AudioWriter::Create(session_->config());
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (audio_writer_.get()) {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        audio_writer_->Init(
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            session_.get(), session_->config().audio_config(),
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            base::Bind(&ConnectionToClient::OnChannelInitialized,
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       base::Unretained(this)));
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Notify the handler after initializing the channels, so that
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // ClientSession can get a client clipboard stub.
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      handler_->OnConnectionAuthenticated(this);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case Session::CLOSED:
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Close(OK);
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case Session::FAILED:
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Close(session_->error());
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConnectionToClient::OnSessionRouteChange(
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& channel_name,
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const TransportRoute& route) {
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  handler_->OnRouteChange(this, channel_name, route);
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConnectionToClient::OnChannelInitialized(bool successful) {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!successful) {
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Failed to connect a channel";
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Close(CHANNEL_CONNECTION_ERROR);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NotifyIfChannelsReady();
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConnectionToClient::NotifyIfChannelsReady() {
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(CalledOnValidThread());
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!control_dispatcher_.get() || !control_dispatcher_->is_connected())
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!event_dispatcher_.get() || !event_dispatcher_->is_connected())
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!video_writer_.get() || !video_writer_->is_connected())
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if ((!audio_writer_.get() || !audio_writer_->is_connected()) &&
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session_->config().is_audio_enabled()) {
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  handler_->OnConnectionChannelsConnected(this);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConnectionToClient::Close(ErrorCode error) {
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CloseChannels();
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  handler_->OnConnectionClosed(this, error);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConnectionToClient::CloseChannels() {
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  control_dispatcher_.reset();
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event_dispatcher_.reset();
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  video_writer_.reset();
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  audio_writer_.reset();
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace protocol
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace remoting
210