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