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.
5 #include "remoting/client/chromoting_client.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"
25 using protocol::AuthenticationMethod
;
27 ChromotingClient::ChromotingClient(ClientContext
* client_context
,
28 ClientUserInterface
* user_interface
,
29 VideoRenderer
* video_renderer
,
30 scoped_ptr
<AudioPlayer
> audio_player
)
31 : task_runner_(client_context
->main_task_runner()),
32 user_interface_(user_interface
),
33 video_renderer_(video_renderer
),
34 connection_(new protocol::ConnectionToHostImpl()),
35 host_capabilities_received_(false) {
37 audio_decode_scheduler_
.reset(new AudioDecodeScheduler(
38 client_context
->main_task_runner(),
39 client_context
->audio_decode_task_runner(), audio_player
.Pass()));
43 ChromotingClient::~ChromotingClient() {
46 void ChromotingClient::SetProtocolConfigForTests(
47 scoped_ptr
<protocol::CandidateSessionConfig
> config
) {
48 connection_
->set_candidate_config(config
.Pass());
51 void ChromotingClient::SetConnectionToHostForTests(
52 scoped_ptr
<protocol::ConnectionToHost
> connection_to_host
) {
53 connection_
= connection_to_host
.Pass();
56 void ChromotingClient::Start(
57 SignalStrategy
* signal_strategy
,
58 scoped_ptr
<protocol::Authenticator
> authenticator
,
59 scoped_ptr
<protocol::TransportFactory
> transport_factory
,
60 const std::string
& host_jid
,
61 const std::string
& capabilities
) {
62 DCHECK(task_runner_
->BelongsToCurrentThread());
64 local_capabilities_
= capabilities
;
66 connection_
->set_client_stub(this);
67 connection_
->set_clipboard_stub(this);
68 connection_
->set_video_stub(video_renderer_
->GetVideoStub());
69 connection_
->set_audio_stub(audio_decode_scheduler_
.get());
71 connection_
->Connect(signal_strategy
, transport_factory
.Pass(),
72 authenticator
.Pass(), host_jid
, this);
75 void ChromotingClient::SetCapabilities(
76 const protocol::Capabilities
& capabilities
) {
77 DCHECK(task_runner_
->BelongsToCurrentThread());
79 // Only accept the first |protocol::Capabilities| message.
80 if (host_capabilities_received_
) {
81 LOG(WARNING
) << "protocol::Capabilities has been received already.";
85 host_capabilities_received_
= true;
86 if (capabilities
.has_capabilities())
87 host_capabilities_
= capabilities
.capabilities();
89 VLOG(1) << "Host capabilities: " << host_capabilities_
;
91 // Calculate the set of capabilities enabled by both client and host and pass
93 user_interface_
->SetCapabilities(
94 IntersectCapabilities(local_capabilities_
, host_capabilities_
));
97 void ChromotingClient::SetPairingResponse(
98 const protocol::PairingResponse
& pairing_response
) {
99 DCHECK(task_runner_
->BelongsToCurrentThread());
101 user_interface_
->SetPairingResponse(pairing_response
);
104 void ChromotingClient::DeliverHostMessage(
105 const protocol::ExtensionMessage
& message
) {
106 DCHECK(task_runner_
->BelongsToCurrentThread());
108 user_interface_
->DeliverHostMessage(message
);
111 void ChromotingClient::InjectClipboardEvent(
112 const protocol::ClipboardEvent
& event
) {
113 DCHECK(task_runner_
->BelongsToCurrentThread());
115 user_interface_
->GetClipboardStub()->InjectClipboardEvent(event
);
118 void ChromotingClient::SetCursorShape(
119 const protocol::CursorShapeInfo
& cursor_shape
) {
120 DCHECK(task_runner_
->BelongsToCurrentThread());
122 user_interface_
->GetCursorShapeStub()->SetCursorShape(cursor_shape
);
125 void ChromotingClient::OnConnectionState(
126 protocol::ConnectionToHost::State state
,
127 protocol::ErrorCode error
) {
128 DCHECK(task_runner_
->BelongsToCurrentThread());
129 VLOG(1) << "ChromotingClient::OnConnectionState(" << state
<< ")";
131 if (state
== protocol::ConnectionToHost::AUTHENTICATED
) {
133 } else if (state
== protocol::ConnectionToHost::CONNECTED
) {
134 OnChannelsConnected();
136 user_interface_
->OnConnectionState(state
, error
);
139 void ChromotingClient::OnConnectionReady(bool ready
) {
140 VLOG(1) << "ChromotingClient::OnConnectionReady(" << ready
<< ")";
141 user_interface_
->OnConnectionReady(ready
);
144 void ChromotingClient::OnRouteChanged(const std::string
& channel_name
,
145 const protocol::TransportRoute
& route
) {
146 VLOG(0) << "Using " << protocol::TransportRoute::GetTypeString(route
.type
)
147 << " connection for " << channel_name
<< " channel";
148 user_interface_
->OnRouteChanged(channel_name
, route
);
151 void ChromotingClient::OnAuthenticated() {
152 DCHECK(task_runner_
->BelongsToCurrentThread());
154 // Initialize the decoder.
155 video_renderer_
->OnSessionConfig(connection_
->config());
156 if (connection_
->config().is_audio_enabled())
157 audio_decode_scheduler_
->Initialize(connection_
->config());
160 void ChromotingClient::OnChannelsConnected() {
161 DCHECK(task_runner_
->BelongsToCurrentThread());
163 // Negotiate capabilities with the host.
164 VLOG(1) << "Client capabilities: " << local_capabilities_
;
166 protocol::Capabilities capabilities
;
167 capabilities
.set_capabilities(local_capabilities_
);
168 connection_
->host_stub()->SetCapabilities(capabilities
);
171 } // namespace remoting