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(
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) {
37 audio_decode_scheduler_
.reset(new AudioDecodeScheduler(
38 client_context
->main_task_runner(),
39 client_context
->audio_decode_task_runner(),
40 audio_player
.Pass()));
44 ChromotingClient::~ChromotingClient() {}
46 void ChromotingClient::SetProtocolConfigForTests(
47 scoped_ptr
<protocol::CandidateSessionConfig
> config
) {
48 connection_
.set_candidate_config(config
.Pass());
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());
59 local_capabilities_
= capabilities
;
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());
66 connection_
.Connect(signal_strategy
, transport_factory
.Pass(),
67 authenticator
.Pass(), host_jid
, this);
70 void ChromotingClient::SetCapabilities(
71 const protocol::Capabilities
& capabilities
) {
72 DCHECK(task_runner_
->BelongsToCurrentThread());
74 // Only accept the first |protocol::Capabilities| message.
75 if (host_capabilities_received_
) {
76 LOG(WARNING
) << "protocol::Capabilities has been received already.";
80 host_capabilities_received_
= true;
81 if (capabilities
.has_capabilities())
82 host_capabilities_
= capabilities
.capabilities();
84 VLOG(1) << "Host capabilities: " << host_capabilities_
;
86 // Calculate the set of capabilities enabled by both client and host and pass
88 user_interface_
->SetCapabilities(
89 IntersectCapabilities(local_capabilities_
, host_capabilities_
));
92 void ChromotingClient::SetPairingResponse(
93 const protocol::PairingResponse
& pairing_response
) {
94 DCHECK(task_runner_
->BelongsToCurrentThread());
96 user_interface_
->SetPairingResponse(pairing_response
);
99 void ChromotingClient::DeliverHostMessage(
100 const protocol::ExtensionMessage
& message
) {
101 DCHECK(task_runner_
->BelongsToCurrentThread());
103 user_interface_
->DeliverHostMessage(message
);
106 void ChromotingClient::InjectClipboardEvent(
107 const protocol::ClipboardEvent
& event
) {
108 DCHECK(task_runner_
->BelongsToCurrentThread());
110 user_interface_
->GetClipboardStub()->InjectClipboardEvent(event
);
113 void ChromotingClient::SetCursorShape(
114 const protocol::CursorShapeInfo
& cursor_shape
) {
115 DCHECK(task_runner_
->BelongsToCurrentThread());
117 user_interface_
->GetCursorShapeStub()->SetCursorShape(cursor_shape
);
120 void ChromotingClient::OnConnectionState(
121 protocol::ConnectionToHost::State state
,
122 protocol::ErrorCode error
) {
123 DCHECK(task_runner_
->BelongsToCurrentThread());
124 VLOG(1) << "ChromotingClient::OnConnectionState(" << state
<< ")";
126 if (state
== protocol::ConnectionToHost::AUTHENTICATED
) {
128 } else if (state
== protocol::ConnectionToHost::CONNECTED
) {
129 OnChannelsConnected();
131 user_interface_
->OnConnectionState(state
, error
);
134 void ChromotingClient::OnConnectionReady(bool ready
) {
135 VLOG(1) << "ChromotingClient::OnConnectionReady(" << ready
<< ")";
136 user_interface_
->OnConnectionReady(ready
);
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
);
146 void ChromotingClient::OnAuthenticated() {
147 DCHECK(task_runner_
->BelongsToCurrentThread());
149 // Initialize the decoder.
150 video_renderer_
->OnSessionConfig(connection_
.config());
151 if (connection_
.config().is_audio_enabled())
152 audio_decode_scheduler_
->Initialize(connection_
.config());
156 void ChromotingClient::OnChannelsConnected() {
157 DCHECK(task_runner_
->BelongsToCurrentThread());
159 // Negotiate capabilities with the host.
160 VLOG(1) << "Client capabilities: " << local_capabilities_
;
162 protocol::Capabilities capabilities
;
163 capabilities
.set_capabilities(local_capabilities_
);
164 connection_
.host_stub()->SetCapabilities(capabilities
);
167 } // namespace remoting