| OLD | NEW | 
|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/client/chromoting_client.h" | 5 #include "remoting/client/chromoting_client.h" | 
| 6 | 6 | 
| 7 #include "base/bind.h" |  | 
| 8 #include "remoting/base/capabilities.h" | 7 #include "remoting/base/capabilities.h" | 
| 9 #include "remoting/client/audio_decode_scheduler.h" | 8 #include "remoting/client/audio_decode_scheduler.h" | 
| 10 #include "remoting/client/audio_player.h" | 9 #include "remoting/client/audio_player.h" | 
| 11 #include "remoting/client/client_context.h" | 10 #include "remoting/client/client_context.h" | 
| 12 #include "remoting/client/client_user_interface.h" | 11 #include "remoting/client/client_user_interface.h" | 
| 13 #include "remoting/client/video_renderer.h" | 12 #include "remoting/client/video_renderer.h" | 
| 14 #include "remoting/proto/audio.pb.h" | 13 #include "remoting/protocol/authenticator.h" | 
| 15 #include "remoting/proto/video.pb.h" |  | 
| 16 #include "remoting/protocol/authentication_method.h" |  | 
| 17 #include "remoting/protocol/connection_to_host.h" | 14 #include "remoting/protocol/connection_to_host.h" | 
| 18 #include "remoting/protocol/host_stub.h" | 15 #include "remoting/protocol/host_stub.h" | 
| 19 #include "remoting/protocol/negotiating_client_authenticator.h" | 16 #include "remoting/protocol/ice_transport.h" | 
|  | 17 #include "remoting/protocol/jingle_session_manager.h" | 
| 20 #include "remoting/protocol/session_config.h" | 18 #include "remoting/protocol/session_config.h" | 
| 21 #include "remoting/protocol/transport_context.h" | 19 #include "remoting/protocol/transport_context.h" | 
| 22 | 20 | 
| 23 namespace remoting { | 21 namespace remoting { | 
| 24 | 22 | 
| 25 using protocol::AuthenticationMethod; |  | 
| 26 |  | 
| 27 ChromotingClient::ChromotingClient(ClientContext* client_context, | 23 ChromotingClient::ChromotingClient(ClientContext* client_context, | 
| 28                                    ClientUserInterface* user_interface, | 24                                    ClientUserInterface* user_interface, | 
| 29                                    VideoRenderer* video_renderer, | 25                                    VideoRenderer* video_renderer, | 
| 30                                    scoped_ptr<AudioPlayer> audio_player) | 26                                    scoped_ptr<AudioPlayer> audio_player) | 
| 31     : task_runner_(client_context->main_task_runner()), | 27     : user_interface_(user_interface), | 
| 32       user_interface_(user_interface), |  | 
| 33       video_renderer_(video_renderer), | 28       video_renderer_(video_renderer), | 
| 34       connection_(new protocol::ConnectionToHostImpl()), | 29       connection_(new protocol::ConnectionToHostImpl()) { | 
| 35       host_capabilities_received_(false) { | 30   DCHECK(client_context->main_task_runner()->BelongsToCurrentThread()); | 
| 36   if (audio_player) { | 31   if (audio_player) { | 
| 37     audio_decode_scheduler_.reset(new AudioDecodeScheduler( | 32     audio_decode_scheduler_.reset(new AudioDecodeScheduler( | 
| 38         client_context->main_task_runner(), | 33         client_context->main_task_runner(), | 
| 39         client_context->audio_decode_task_runner(), audio_player.Pass())); | 34         client_context->audio_decode_task_runner(), audio_player.Pass())); | 
| 40   } | 35   } | 
| 41 } | 36 } | 
| 42 | 37 | 
| 43 ChromotingClient::~ChromotingClient() { | 38 ChromotingClient::~ChromotingClient() { | 
| 44 } | 39   if (signal_strategy_) | 
| 45 | 40       signal_strategy_->RemoveListener(this); | 
| 46 void ChromotingClient::set_protocol_config( |  | 
| 47     scoped_ptr<protocol::CandidateSessionConfig> config) { |  | 
| 48   connection_->set_candidate_config(config.Pass()); |  | 
| 49 } | 41 } | 
| 50 | 42 | 
| 51 void ChromotingClient::SetConnectionToHostForTests( | 43 void ChromotingClient::SetConnectionToHostForTests( | 
| 52     scoped_ptr<protocol::ConnectionToHost> connection_to_host) { | 44     scoped_ptr<protocol::ConnectionToHost> connection_to_host) { | 
| 53   connection_ = connection_to_host.Pass(); | 45   connection_ = connection_to_host.Pass(); | 
| 54 } | 46 } | 
| 55 | 47 | 
| 56 void ChromotingClient::Start( | 48 void ChromotingClient::Start( | 
| 57     SignalStrategy* signal_strategy, | 49     SignalStrategy* signal_strategy, | 
| 58     scoped_ptr<protocol::Authenticator> authenticator, | 50     scoped_ptr<protocol::Authenticator> authenticator, | 
| 59     scoped_refptr<protocol::TransportContext> transport_context, | 51     scoped_refptr<protocol::TransportContext> transport_context, | 
| 60     const std::string& host_jid, | 52     const std::string& host_jid, | 
| 61     const std::string& capabilities) { | 53     const std::string& capabilities) { | 
| 62   DCHECK(task_runner_->BelongsToCurrentThread()); | 54   DCHECK(thread_checker_.CalledOnValidThread()); | 
|  | 55   DCHECK(!session_manager_);  // Start must be called more than once. | 
| 63 | 56 | 
|  | 57   host_jid_ = host_jid; | 
| 64   local_capabilities_ = capabilities; | 58   local_capabilities_ = capabilities; | 
| 65 | 59 | 
| 66   connection_->set_client_stub(this); | 60   connection_->set_client_stub(this); | 
| 67   connection_->set_clipboard_stub(this); | 61   connection_->set_clipboard_stub(this); | 
| 68   connection_->set_video_stub(video_renderer_->GetVideoStub()); | 62   connection_->set_video_stub(video_renderer_->GetVideoStub()); | 
| 69   connection_->set_audio_stub(audio_decode_scheduler_.get()); | 63   connection_->set_audio_stub(audio_decode_scheduler_.get()); | 
| 70 | 64 | 
| 71   connection_->Connect(signal_strategy, transport_context, authenticator.Pass(), | 65   session_manager_.reset(new protocol::JingleSessionManager( | 
| 72                        host_jid, this); | 66       make_scoped_ptr(new protocol::IceTransportFactory(transport_context)), | 
|  | 67       signal_strategy)); | 
|  | 68 | 
|  | 69   if (!protocol_config_) | 
|  | 70     protocol_config_ = protocol::CandidateSessionConfig::CreateDefault(); | 
|  | 71   if (!audio_decode_scheduler_) | 
|  | 72     protocol_config_->DisableAudioChannel(); | 
|  | 73   session_manager_->set_protocol_config(protocol_config_.Pass()); | 
|  | 74 | 
|  | 75   authenticator_ = authenticator.Pass(); | 
|  | 76 | 
|  | 77   signal_strategy_ = signal_strategy; | 
|  | 78   signal_strategy_->AddListener(this); | 
|  | 79 | 
|  | 80   switch (signal_strategy_->GetState()) { | 
|  | 81     case SignalStrategy::CONNECTING: | 
|  | 82       // Nothing to do here. Just need to wait until |signal_strategy_| becomes | 
|  | 83       // connected. | 
|  | 84       break; | 
|  | 85     case SignalStrategy::CONNECTED: | 
|  | 86       StartConnection(); | 
|  | 87       break; | 
|  | 88     case SignalStrategy::DISCONNECTED: | 
|  | 89       signal_strategy_->Connect(); | 
|  | 90       break; | 
|  | 91   } | 
| 73 } | 92 } | 
| 74 | 93 | 
| 75 void ChromotingClient::SetCapabilities( | 94 void ChromotingClient::SetCapabilities( | 
| 76     const protocol::Capabilities& capabilities) { | 95     const protocol::Capabilities& capabilities) { | 
| 77   DCHECK(task_runner_->BelongsToCurrentThread()); | 96   DCHECK(thread_checker_.CalledOnValidThread()); | 
| 78 | 97 | 
| 79   // Only accept the first |protocol::Capabilities| message. | 98   // Only accept the first |protocol::Capabilities| message. | 
| 80   if (host_capabilities_received_) { | 99   if (host_capabilities_received_) { | 
| 81     LOG(WARNING) << "protocol::Capabilities has been received already."; | 100     LOG(WARNING) << "protocol::Capabilities has been received already."; | 
| 82     return; | 101     return; | 
| 83   } | 102   } | 
| 84 | 103 | 
| 85   host_capabilities_received_ = true; | 104   host_capabilities_received_ = true; | 
| 86   if (capabilities.has_capabilities()) | 105   if (capabilities.has_capabilities()) | 
| 87     host_capabilities_ = capabilities.capabilities(); | 106     host_capabilities_ = capabilities.capabilities(); | 
| 88 | 107 | 
| 89   VLOG(1) << "Host capabilities: " << host_capabilities_; | 108   VLOG(1) << "Host capabilities: " << host_capabilities_; | 
| 90 | 109 | 
| 91   // Calculate the set of capabilities enabled by both client and host and pass | 110   // Calculate the set of capabilities enabled by both client and host and pass | 
| 92   // it to the webapp. | 111   // it to the webapp. | 
| 93   user_interface_->SetCapabilities( | 112   user_interface_->SetCapabilities( | 
| 94       IntersectCapabilities(local_capabilities_, host_capabilities_)); | 113       IntersectCapabilities(local_capabilities_, host_capabilities_)); | 
| 95 } | 114 } | 
| 96 | 115 | 
| 97 void ChromotingClient::SetPairingResponse( | 116 void ChromotingClient::SetPairingResponse( | 
| 98     const protocol::PairingResponse& pairing_response) { | 117     const protocol::PairingResponse& pairing_response) { | 
| 99   DCHECK(task_runner_->BelongsToCurrentThread()); | 118   DCHECK(thread_checker_.CalledOnValidThread()); | 
| 100 | 119 | 
| 101   user_interface_->SetPairingResponse(pairing_response); | 120   user_interface_->SetPairingResponse(pairing_response); | 
| 102 } | 121 } | 
| 103 | 122 | 
| 104 void ChromotingClient::DeliverHostMessage( | 123 void ChromotingClient::DeliverHostMessage( | 
| 105     const protocol::ExtensionMessage& message) { | 124     const protocol::ExtensionMessage& message) { | 
| 106   DCHECK(task_runner_->BelongsToCurrentThread()); | 125   DCHECK(thread_checker_.CalledOnValidThread()); | 
| 107 | 126 | 
| 108   user_interface_->DeliverHostMessage(message); | 127   user_interface_->DeliverHostMessage(message); | 
| 109 } | 128 } | 
| 110 | 129 | 
| 111 void ChromotingClient::InjectClipboardEvent( | 130 void ChromotingClient::InjectClipboardEvent( | 
| 112     const protocol::ClipboardEvent& event) { | 131     const protocol::ClipboardEvent& event) { | 
| 113   DCHECK(task_runner_->BelongsToCurrentThread()); | 132   DCHECK(thread_checker_.CalledOnValidThread()); | 
| 114 | 133 | 
| 115   user_interface_->GetClipboardStub()->InjectClipboardEvent(event); | 134   user_interface_->GetClipboardStub()->InjectClipboardEvent(event); | 
| 116 } | 135 } | 
| 117 | 136 | 
| 118 void ChromotingClient::SetCursorShape( | 137 void ChromotingClient::SetCursorShape( | 
| 119     const protocol::CursorShapeInfo& cursor_shape) { | 138     const protocol::CursorShapeInfo& cursor_shape) { | 
| 120   DCHECK(task_runner_->BelongsToCurrentThread()); | 139   DCHECK(thread_checker_.CalledOnValidThread()); | 
| 121 | 140 | 
| 122   user_interface_->GetCursorShapeStub()->SetCursorShape(cursor_shape); | 141   user_interface_->GetCursorShapeStub()->SetCursorShape(cursor_shape); | 
| 123 } | 142 } | 
| 124 | 143 | 
| 125 void ChromotingClient::OnConnectionState( | 144 void ChromotingClient::OnConnectionState( | 
| 126     protocol::ConnectionToHost::State state, | 145     protocol::ConnectionToHost::State state, | 
| 127     protocol::ErrorCode error) { | 146     protocol::ErrorCode error) { | 
| 128   DCHECK(task_runner_->BelongsToCurrentThread()); | 147   DCHECK(thread_checker_.CalledOnValidThread()); | 
| 129   VLOG(1) << "ChromotingClient::OnConnectionState(" << state << ")"; | 148   VLOG(1) << "ChromotingClient::OnConnectionState(" << state << ")"; | 
| 130 | 149 | 
| 131   if (state == protocol::ConnectionToHost::AUTHENTICATED) { | 150   if (state == protocol::ConnectionToHost::AUTHENTICATED) { | 
| 132     OnAuthenticated(); | 151     OnAuthenticated(); | 
| 133   } else if (state == protocol::ConnectionToHost::CONNECTED) { | 152   } else if (state == protocol::ConnectionToHost::CONNECTED) { | 
| 134     OnChannelsConnected(); | 153     OnChannelsConnected(); | 
| 135   } | 154   } | 
| 136   user_interface_->OnConnectionState(state, error); | 155   user_interface_->OnConnectionState(state, error); | 
| 137 } | 156 } | 
| 138 | 157 | 
| 139 void ChromotingClient::OnConnectionReady(bool ready) { | 158 void ChromotingClient::OnConnectionReady(bool ready) { | 
| 140   VLOG(1) << "ChromotingClient::OnConnectionReady(" << ready << ")"; | 159   VLOG(1) << "ChromotingClient::OnConnectionReady(" << ready << ")"; | 
| 141   user_interface_->OnConnectionReady(ready); | 160   user_interface_->OnConnectionReady(ready); | 
| 142 } | 161 } | 
| 143 | 162 | 
| 144 void ChromotingClient::OnRouteChanged(const std::string& channel_name, | 163 void ChromotingClient::OnRouteChanged(const std::string& channel_name, | 
| 145                                       const protocol::TransportRoute& route) { | 164                                       const protocol::TransportRoute& route) { | 
| 146   VLOG(0) << "Using " << protocol::TransportRoute::GetTypeString(route.type) | 165   VLOG(0) << "Using " << protocol::TransportRoute::GetTypeString(route.type) | 
| 147           << " connection for " << channel_name << " channel"; | 166           << " connection for " << channel_name << " channel"; | 
| 148   user_interface_->OnRouteChanged(channel_name, route); | 167   user_interface_->OnRouteChanged(channel_name, route); | 
| 149 } | 168 } | 
| 150 | 169 | 
|  | 170 void ChromotingClient::OnSignalStrategyStateChange( | 
|  | 171     SignalStrategy::State state) { | 
|  | 172   DCHECK(thread_checker_.CalledOnValidThread()); | 
|  | 173 | 
|  | 174   if (state == SignalStrategy::CONNECTED) { | 
|  | 175     VLOG(1) << "Connected as: " << signal_strategy_->GetLocalJid(); | 
|  | 176     // After signaling has been connected we can try connecting to the host. | 
|  | 177     if (connection_ && | 
|  | 178         connection_->state() == protocol::ConnectionToHost::INITIALIZING) { | 
|  | 179       StartConnection(); | 
|  | 180     } | 
|  | 181   } else if (state == SignalStrategy::DISCONNECTED) { | 
|  | 182     VLOG(1) << "Signaling connection closed."; | 
|  | 183     connection_.reset(); | 
|  | 184     user_interface_->OnConnectionState(protocol::ConnectionToHost::CLOSED, | 
|  | 185                                        protocol::SIGNALING_ERROR); | 
|  | 186   } | 
|  | 187 } | 
|  | 188 | 
|  | 189 bool ChromotingClient::OnSignalStrategyIncomingStanza( | 
|  | 190     const buzz::XmlElement* stanza) { | 
|  | 191   return false; | 
|  | 192 } | 
|  | 193 | 
|  | 194 void ChromotingClient::StartConnection() { | 
|  | 195   DCHECK(thread_checker_.CalledOnValidThread()); | 
|  | 196   connection_->Connect( | 
|  | 197       session_manager_->Connect(host_jid_, authenticator_.Pass()), this); | 
|  | 198 } | 
|  | 199 | 
| 151 void ChromotingClient::OnAuthenticated() { | 200 void ChromotingClient::OnAuthenticated() { | 
| 152   DCHECK(task_runner_->BelongsToCurrentThread()); | 201   DCHECK(thread_checker_.CalledOnValidThread()); | 
| 153 | 202 | 
| 154   // Initialize the decoder. | 203   // Initialize the decoder. | 
| 155   video_renderer_->OnSessionConfig(connection_->config()); | 204   video_renderer_->OnSessionConfig(connection_->config()); | 
| 156   if (connection_->config().is_audio_enabled()) | 205   if (connection_->config().is_audio_enabled()) | 
| 157     audio_decode_scheduler_->Initialize(connection_->config()); | 206     audio_decode_scheduler_->Initialize(connection_->config()); | 
| 158 } | 207 } | 
| 159 | 208 | 
| 160 void ChromotingClient::OnChannelsConnected() { | 209 void ChromotingClient::OnChannelsConnected() { | 
| 161   DCHECK(task_runner_->BelongsToCurrentThread()); | 210   DCHECK(thread_checker_.CalledOnValidThread()); | 
| 162 | 211 | 
| 163   // Negotiate capabilities with the host. | 212   // Negotiate capabilities with the host. | 
| 164   VLOG(1) << "Client capabilities: " << local_capabilities_; | 213   VLOG(1) << "Client capabilities: " << local_capabilities_; | 
| 165 | 214 | 
| 166   protocol::Capabilities capabilities; | 215   protocol::Capabilities capabilities; | 
| 167   capabilities.set_capabilities(local_capabilities_); | 216   capabilities.set_capabilities(local_capabilities_); | 
| 168   connection_->host_stub()->SetCapabilities(capabilities); | 217   connection_->host_stub()->SetCapabilities(capabilities); | 
| 169 } | 218 } | 
| 170 | 219 | 
| 171 }  // namespace remoting | 220 }  // namespace remoting | 
| OLD | NEW | 
|---|