Home | History | Annotate | Download | only in client
      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
      3 // found in the LICENSE file.
      4 
      5 #include "remoting/client/chromoting_client.h"
      6 
      7 #include "base/bind.h"
      8 #include "remoting/base/capabilities.h"
      9 #include "remoting/client/audio_decode_scheduler.h"
     10 #include "remoting/client/audio_player.h"
     11 #include "remoting/client/client_context.h"
     12 #include "remoting/client/client_user_interface.h"
     13 #include "remoting/client/video_renderer.h"
     14 #include "remoting/proto/audio.pb.h"
     15 #include "remoting/proto/video.pb.h"
     16 #include "remoting/protocol/authentication_method.h"
     17 #include "remoting/protocol/connection_to_host.h"
     18 #include "remoting/protocol/host_stub.h"
     19 #include "remoting/protocol/negotiating_client_authenticator.h"
     20 #include "remoting/protocol/session_config.h"
     21 #include "remoting/protocol/transport.h"
     22 
     23 namespace remoting {
     24 
     25 using protocol::AuthenticationMethod;
     26 
     27 ChromotingClient::ChromotingClient(
     28     ClientContext* client_context,
     29     ClientUserInterface* user_interface,
     30     VideoRenderer* video_renderer,
     31     scoped_ptr<AudioPlayer> audio_player)
     32     : task_runner_(client_context->main_task_runner()),
     33       user_interface_(user_interface),
     34       video_renderer_(video_renderer),
     35       host_capabilities_received_(false) {
     36   if (audio_player) {
     37     audio_decode_scheduler_.reset(new AudioDecodeScheduler(
     38         client_context->main_task_runner(),
     39         client_context->audio_decode_task_runner(),
     40         audio_player.Pass()));
     41   }
     42 }
     43 
     44 ChromotingClient::~ChromotingClient() {}
     45 
     46 void ChromotingClient::SetProtocolConfigForTests(
     47     scoped_ptr<protocol::CandidateSessionConfig> config) {
     48   connection_.set_candidate_config(config.Pass());
     49 }
     50 
     51 void ChromotingClient::Start(
     52     SignalStrategy* signal_strategy,
     53     scoped_ptr<protocol::Authenticator> authenticator,
     54     scoped_ptr<protocol::TransportFactory> transport_factory,
     55     const std::string& host_jid,
     56     const std::string& capabilities) {
     57   DCHECK(task_runner_->BelongsToCurrentThread());
     58 
     59   local_capabilities_ = capabilities;
     60 
     61   connection_.set_client_stub(this);
     62   connection_.set_clipboard_stub(this);
     63   connection_.set_video_stub(video_renderer_);
     64   connection_.set_audio_stub(audio_decode_scheduler_.get());
     65 
     66   connection_.Connect(signal_strategy, transport_factory.Pass(),
     67                        authenticator.Pass(), host_jid, this);
     68 }
     69 
     70 void ChromotingClient::SetCapabilities(
     71     const protocol::Capabilities& capabilities) {
     72   DCHECK(task_runner_->BelongsToCurrentThread());
     73 
     74   // Only accept the first |protocol::Capabilities| message.
     75   if (host_capabilities_received_) {
     76     LOG(WARNING) << "protocol::Capabilities has been received already.";
     77     return;
     78   }
     79 
     80   host_capabilities_received_ = true;
     81   if (capabilities.has_capabilities())
     82     host_capabilities_ = capabilities.capabilities();
     83 
     84   VLOG(1) << "Host capabilities: " << host_capabilities_;
     85 
     86   // Calculate the set of capabilities enabled by both client and host and pass
     87   // it to the webapp.
     88   user_interface_->SetCapabilities(
     89       IntersectCapabilities(local_capabilities_, host_capabilities_));
     90 }
     91 
     92 void ChromotingClient::SetPairingResponse(
     93     const protocol::PairingResponse& pairing_response) {
     94   DCHECK(task_runner_->BelongsToCurrentThread());
     95 
     96   user_interface_->SetPairingResponse(pairing_response);
     97 }
     98 
     99 void ChromotingClient::DeliverHostMessage(
    100     const protocol::ExtensionMessage& message) {
    101   DCHECK(task_runner_->BelongsToCurrentThread());
    102 
    103   user_interface_->DeliverHostMessage(message);
    104 }
    105 
    106 void ChromotingClient::InjectClipboardEvent(
    107     const protocol::ClipboardEvent& event) {
    108   DCHECK(task_runner_->BelongsToCurrentThread());
    109 
    110   user_interface_->GetClipboardStub()->InjectClipboardEvent(event);
    111 }
    112 
    113 void ChromotingClient::SetCursorShape(
    114     const protocol::CursorShapeInfo& cursor_shape) {
    115   DCHECK(task_runner_->BelongsToCurrentThread());
    116 
    117   user_interface_->GetCursorShapeStub()->SetCursorShape(cursor_shape);
    118 }
    119 
    120 void ChromotingClient::OnConnectionState(
    121     protocol::ConnectionToHost::State state,
    122     protocol::ErrorCode error) {
    123   DCHECK(task_runner_->BelongsToCurrentThread());
    124   VLOG(1) << "ChromotingClient::OnConnectionState(" << state << ")";
    125 
    126   if (state == protocol::ConnectionToHost::AUTHENTICATED) {
    127     OnAuthenticated();
    128   } else if (state == protocol::ConnectionToHost::CONNECTED) {
    129     OnChannelsConnected();
    130   }
    131   user_interface_->OnConnectionState(state, error);
    132 }
    133 
    134 void ChromotingClient::OnConnectionReady(bool ready) {
    135   VLOG(1) << "ChromotingClient::OnConnectionReady(" << ready << ")";
    136   user_interface_->OnConnectionReady(ready);
    137 }
    138 
    139 void ChromotingClient::OnRouteChanged(const std::string& channel_name,
    140                                       const protocol::TransportRoute& route) {
    141   VLOG(0) << "Using " << protocol::TransportRoute::GetTypeString(route.type)
    142           << " connection for " << channel_name << " channel";
    143   user_interface_->OnRouteChanged(channel_name, route);
    144 }
    145 
    146 void ChromotingClient::OnAuthenticated() {
    147   DCHECK(task_runner_->BelongsToCurrentThread());
    148 
    149   // Initialize the decoder.
    150   video_renderer_->Initialize(connection_.config());
    151   if (connection_.config().is_audio_enabled())
    152     audio_decode_scheduler_->Initialize(connection_.config());
    153 
    154 }
    155 
    156 void ChromotingClient::OnChannelsConnected() {
    157   DCHECK(task_runner_->BelongsToCurrentThread());
    158 
    159   // Negotiate capabilities with the host.
    160   VLOG(1) << "Client capabilities: " << local_capabilities_;
    161 
    162   protocol::Capabilities capabilities;
    163   capabilities.set_capabilities(local_capabilities_);
    164   connection_.host_stub()->SetCapabilities(capabilities);
    165 }
    166 
    167 }  // namespace remoting
    168