15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 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_host.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/location.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/base/constants.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/audio_reader.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/audio_stub.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/auth_util.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/authenticator.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/client_control_dispatcher.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/client_event_dispatcher.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/client_stub.h" 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "remoting/protocol/client_video_dispatcher.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/clipboard_stub.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/errors.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/jingle_session_manager.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/transport.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/video_stub.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace remoting { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace protocol { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28116680a4aac90f2aa7413d9095a592090648e557Ben MurdochConnectionToHost::ConnectionToHost() 29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch : event_callback_(NULL), 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_stub_(NULL), 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clipboard_stub_(NULL), 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_stub_(NULL), 337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) signal_strategy_(NULL), 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_(INITIALIZING), 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_(OK) { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ConnectionToHost::~ConnectionToHost() { 397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) CloseChannels(); 407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (session_.get()) 427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) session_.reset(); 437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (session_manager_.get()) 457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) session_manager_.reset(); 467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (signal_strategy_) 487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) signal_strategy_->RemoveListener(this); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void ConnectionToHost::Connect(SignalStrategy* signal_strategy, 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<TransportFactory> transport_factory, 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Authenticator> authenticator, 54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& host_jid, 55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) HostEventCallback* event_callback) { 56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(client_stub_); 57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(clipboard_stub_); 58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(monitored_video_stub_); 59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Initialize default |candidate_config_| if set_candidate_config() wasn't 615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // called. 625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!candidate_config_) { 635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) candidate_config_ = CandidateSessionConfig::CreateDefault(); 645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!audio_stub_) { 655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) candidate_config_->DisableAudioChannel(); 665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) candidate_config_->EnableVideoCodec(ChannelConfig::CODEC_VP9); 685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) signal_strategy_ = signal_strategy; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_callback_ = event_callback; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) authenticator_ = authenticator.Pass(); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Save jid of the host. The actual connection is created later after 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |signal_strategy_| is connected. 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host_jid_ = host_jid; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signal_strategy_->AddListener(this); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signal_strategy_->Connect(); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session_manager_.reset(new JingleSessionManager(transport_factory.Pass())); 827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) session_manager_->Init(signal_strategy_, this); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetState(CONNECTING, OK); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ConnectionToHost::set_candidate_config( 885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<CandidateSessionConfig> config) { 895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK_EQ(state_, INITIALIZING); 905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) candidate_config_ = config.Pass(); 925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SessionConfig& ConnectionToHost::config() { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return session_->config(); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ClipboardStub* ConnectionToHost::clipboard_forwarder() { 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return &clipboard_forwarder_; 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)HostStub* ConnectionToHost::host_stub() { 104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // TODO(wez): Add a HostFilter class, equivalent to input filter. 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return control_dispatcher_.get(); 106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)InputStub* ConnectionToHost::input_stub() { 109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return &event_forwarder_; 110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ConnectionToHost::set_client_stub(ClientStub* client_stub) { 113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) client_stub_ = client_stub; 114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ConnectionToHost::set_clipboard_stub(ClipboardStub* clipboard_stub) { 117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) clipboard_stub_ = clipboard_stub; 118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ConnectionToHost::set_video_stub(VideoStub* video_stub) { 121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(video_stub); 122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) monitored_video_stub_.reset(new MonitoredVideoStub( 123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) video_stub, 124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::TimeDelta::FromSeconds( 125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MonitoredVideoStub::kConnectivityCheckDelaySeconds), 126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&ConnectionToHost::OnVideoChannelStatus, 127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Unretained(this)))); 128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ConnectionToHost::set_audio_stub(AudioStub* audio_stub) { 131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) audio_stub_ = audio_stub; 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConnectionToHost::OnSignalStrategyStateChange( 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SignalStrategy::State state) { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(event_callback_); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state == SignalStrategy::CONNECTED) { 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "Connected as: " << signal_strategy_->GetLocalJid(); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (state == SignalStrategy::DISCONNECTED) { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "Connection closed."; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseOnError(SIGNALING_ERROR); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ConnectionToHost::OnSignalStrategyIncomingStanza( 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const buzz::XmlElement* stanza) { 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConnectionToHost::OnSessionManagerReady() { 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // After SessionManager is initialized we can try to connect to the host. 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_ = session_manager_->Connect( 1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) host_jid_, authenticator_.Pass(), candidate_config_.Pass()); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_->SetEventHandler(this); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConnectionToHost::OnIncomingSession( 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Session* session, 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionManager::IncomingSessionResponse* response) { 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Client always rejects incoming sessions. 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *response = SessionManager::DECLINE; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConnectionToHost::OnSessionStateChange( 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Session::State state) { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(event_callback_); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (state) { 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case Session::INITIALIZING: 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case Session::CONNECTING: 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case Session::ACCEPTING: 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case Session::CONNECTED: 179c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch case Session::AUTHENTICATING: 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't care about these events. 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case Session::AUTHENTICATED: 184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetState(AUTHENTICATED, OK); 185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) control_dispatcher_.reset(new ClientControlDispatcher()); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) control_dispatcher_->Init( 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_.get(), session_->config().control_config(), 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ConnectionToHost::OnChannelInitialized, 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) control_dispatcher_->set_client_stub(client_stub_); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) control_dispatcher_->set_clipboard_stub(clipboard_stub_); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_dispatcher_.reset(new ClientEventDispatcher()); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_dispatcher_->Init( 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_.get(), session_->config().event_config(), 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ConnectionToHost::OnChannelInitialized, 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci video_dispatcher_.reset( 2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new ClientVideoDispatcher(monitored_video_stub_.get())); 2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci video_dispatcher_->Init(session_.get(), session_->config().video_config(), 2035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Bind(&ConnectionToHost::OnChannelInitialized, 2045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Unretained(this))); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_reader_ = AudioReader::Create(session_->config()); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (audio_reader_.get()) { 2085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu audio_reader_->Init(session_.get(), session_->config().audio_config(), 2095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Bind(&ConnectionToHost::OnChannelInitialized, 2105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Unretained(this))); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_reader_->set_audio_stub(audio_stub_); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case Session::CLOSED: 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseChannels(); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetState(CLOSED, OK); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case Session::FAILED: 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we were connected then treat signaling timeout error as if 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the connection was closed by the peer. 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(sergeyu): This logic belongs to the webapp, but we 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // currently don't expose this error code to the webapp, and it 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // would be hard to add it because client plugin and webapp 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // versions may not be in sync. It should be easy to do after we 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // are finished moving the client plugin to NaCl. 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state_ == CONNECTED && session_->error() == SIGNALING_TIMEOUT) { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseChannels(); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetState(CLOSED, OK); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseOnError(session_->error()); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConnectionToHost::OnSessionRouteChange(const std::string& channel_name, 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const TransportRoute& route) { 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) event_callback_->OnRouteChanged(channel_name, route); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid ConnectionToHost::OnVideoChannelStatus(bool active) { 2455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu event_callback_->OnConnectionReady(active); 2465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ConnectionToHost::State ConnectionToHost::state() const { 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return state_; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConnectionToHost::OnChannelInitialized(bool successful) { 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!successful) { 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Failed to connect video channel"; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseOnError(CHANNEL_CONNECTION_ERROR); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyIfChannelsReady(); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConnectionToHost::NotifyIfChannelsReady() { 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!control_dispatcher_.get() || !control_dispatcher_->is_connected()) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!event_dispatcher_.get() || !event_dispatcher_->is_connected()) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!video_dispatcher_.get() || !video_dispatcher_->is_connected()) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((!audio_reader_.get() || !audio_reader_->is_connected()) && 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_->config().is_audio_enabled()) { 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (state_ != AUTHENTICATED) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start forwarding clipboard and input events. 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clipboard_forwarder_.set_clipboard_stub(control_dispatcher_.get()); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_forwarder_.set_input_stub(event_dispatcher_.get()); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetState(CONNECTED, OK); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConnectionToHost::CloseOnError(ErrorCode error) { 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseChannels(); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetState(FAILED, error); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConnectionToHost::CloseChannels() { 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) control_dispatcher_.reset(); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_dispatcher_.reset(); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clipboard_forwarder_.set_clipboard_stub(NULL); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_forwarder_.set_input_stub(NULL); 2921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci video_dispatcher_.reset(); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_reader_.reset(); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConnectionToHost::SetState(State state, ErrorCode error) { 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |error| should be specified only when |state| is set to FAILED. 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(state == FAILED || error == OK); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state != state_) { 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = state; 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = error; 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_callback_->OnConnectionState(state_, error_); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace protocol 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace remoting 310