1 // Copyright 2015 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/test/test_chromoting_client.h"
10 #include "base/logging.h"
11 #include "base/thread_task_runner_handle.h"
12 #include "jingle/glue/thread_wrapper.h"
13 #include "net/base/request_priority.h"
14 #include "net/socket/client_socket_factory.h"
15 #include "remoting/base/url_request_context_getter.h"
16 #include "remoting/client/audio_player.h"
17 #include "remoting/client/chromoting_client.h"
18 #include "remoting/client/client_context.h"
19 #include "remoting/client/token_fetcher_proxy.h"
20 #include "remoting/protocol/chromium_port_allocator.h"
21 #include "remoting/protocol/host_stub.h"
22 #include "remoting/protocol/libjingle_transport_factory.h"
23 #include "remoting/protocol/negotiating_client_authenticator.h"
24 #include "remoting/protocol/network_settings.h"
25 #include "remoting/protocol/session_config.h"
26 #include "remoting/protocol/third_party_client_authenticator.h"
27 #include "remoting/signaling/xmpp_signal_strategy.h"
28 #include "remoting/test/connection_setup_info.h"
29 #include "remoting/test/test_video_renderer.h"
32 const char kXmppHostName
[] = "talk.google.com";
33 const int kXmppPortNumber
= 5222;
35 // Used as the TokenFetcherCallback for App Remoting sessions.
36 void FetchThirdPartyToken(
37 const std::string
& authorization_token
,
38 const std::string
& shared_secret
,
39 const GURL
& token_url
,
40 const std::string
& host_public_key
,
41 const std::string
& scope
,
42 base::WeakPtr
<remoting::TokenFetcherProxy
> token_fetcher_proxy
) {
43 VLOG(2) << "FetchThirdPartyToken("
44 << "token_url: " << token_url
<< ", "
45 << "host_public_key: " << host_public_key
<< ", "
46 << "scope: " << scope
<< ") Called";
48 if (token_fetcher_proxy
) {
49 token_fetcher_proxy
->OnTokenFetched(authorization_token
, shared_secret
);
50 token_fetcher_proxy
.reset();
52 LOG(ERROR
) << "Invalid token fetcher proxy passed in";
57 const std::string
& client_secret
,
58 bool pairing_expected
,
59 const remoting::protocol::SecretFetchedCallback
& secret_fetched_callback
) {
60 secret_fetched_callback
.Run(client_secret
);
68 TestChromotingClient::TestChromotingClient()
69 : connection_to_host_state_(protocol::ConnectionToHost::INITIALIZING
),
70 connection_error_code_(protocol::OK
) {}
72 TestChromotingClient::TestChromotingClient(
73 scoped_ptr
<VideoRenderer
> video_renderer
)
74 : video_renderer_(video_renderer
.Pass()) {
75 TestChromotingClient();
78 TestChromotingClient::~TestChromotingClient() {
79 // Ensure any connections are closed and the members are destroyed in the
84 void TestChromotingClient::StartConnection(
85 const ConnectionSetupInfo
& connection_setup_info
) {
86 // Required to establish a connection to the host.
87 jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop();
89 scoped_refptr
<URLRequestContextGetter
> request_context_getter
;
90 request_context_getter
= new URLRequestContextGetter(
91 base::ThreadTaskRunnerHandle::Get(), // network_runner
92 base::ThreadTaskRunnerHandle::Get()); // file_runner
94 client_context_
.reset(new ClientContext(base::ThreadTaskRunnerHandle::Get()));
96 // Check to see if the user passed in a customized video renderer.
97 if (!video_renderer_
) {
98 video_renderer_
.reset(new TestVideoRenderer());
101 chromoting_client_
.reset(new ChromotingClient(client_context_
.get(),
102 this, // client_user_interface.
103 video_renderer_
.get(),
104 nullptr)); // audio_player
106 if (test_connection_to_host_
) {
107 chromoting_client_
->SetConnectionToHostForTests(
108 test_connection_to_host_
.Pass());
111 XmppSignalStrategy::XmppServerConfig xmpp_server_config
;
112 xmpp_server_config
.host
= kXmppHostName
;
113 xmpp_server_config
.port
= kXmppPortNumber
;
114 xmpp_server_config
.use_tls
= true;
115 xmpp_server_config
.username
= connection_setup_info
.user_name
;
116 xmpp_server_config
.auth_token
= connection_setup_info
.access_token
;
118 // Set up the signal strategy. This must outlive the client object.
119 signal_strategy_
.reset(
120 new XmppSignalStrategy(net::ClientSocketFactory::GetDefaultFactory(),
121 request_context_getter
, xmpp_server_config
));
123 protocol::NetworkSettings
network_settings(
124 protocol::NetworkSettings::NAT_TRAVERSAL_FULL
);
126 scoped_ptr
<protocol::ChromiumPortAllocator
> port_allocator(
127 protocol::ChromiumPortAllocator::Create(request_context_getter
,
130 scoped_ptr
<protocol::TransportFactory
> transport_factory(
131 new protocol::LibjingleTransportFactory(
132 signal_strategy_
.get(), port_allocator
.Pass(), network_settings
,
133 protocol::TransportRole::CLIENT
));
135 scoped_ptr
<protocol::ThirdPartyClientAuthenticator::TokenFetcher
>
136 token_fetcher(new TokenFetcherProxy(
137 base::Bind(&FetchThirdPartyToken
,
138 connection_setup_info
.authorization_code
,
139 connection_setup_info
.shared_secret
),
140 connection_setup_info
.public_key
));
142 protocol::FetchSecretCallback fetch_secret_callback
;
143 if (!connection_setup_info
.pin
.empty()) {
144 fetch_secret_callback
= base::Bind(&FetchSecret
, connection_setup_info
.pin
);
147 scoped_ptr
<protocol::Authenticator
> authenticator(
148 new protocol::NegotiatingClientAuthenticator(
149 connection_setup_info
.pairing_id
,
150 connection_setup_info
.shared_secret
,
151 connection_setup_info
.host_id
,
152 fetch_secret_callback
,
153 token_fetcher
.Pass(),
154 connection_setup_info
.auth_methods
));
156 chromoting_client_
->Start(
157 signal_strategy_
.get(), authenticator
.Pass(), transport_factory
.Pass(),
158 connection_setup_info
.host_jid
, connection_setup_info
.capabilities
);
161 void TestChromotingClient::EndConnection() {
162 // Clearing out the client will close the connection.
163 chromoting_client_
.reset();
165 // The signal strategy object must outlive the client so destroy it next.
166 signal_strategy_
.reset();
168 // The connection state will be updated when the chromoting client was
169 // destroyed if an active connection was established, but not in other cases.
170 // We should be consistent in either case so we will set the state if needed.
171 if (connection_to_host_state_
!= protocol::ConnectionToHost::CLOSED
&&
172 connection_to_host_state_
!= protocol::ConnectionToHost::FAILED
&&
173 connection_error_code_
== protocol::OK
) {
174 OnConnectionState(protocol::ConnectionToHost::CLOSED
, protocol::OK
);
178 void TestChromotingClient::AddRemoteConnectionObserver(
179 RemoteConnectionObserver
* observer
) {
182 connection_observers_
.AddObserver(observer
);
185 void TestChromotingClient::RemoveRemoteConnectionObserver(
186 RemoteConnectionObserver
* observer
) {
189 connection_observers_
.RemoveObserver(observer
);
192 void TestChromotingClient::SetConnectionToHostForTests(
193 scoped_ptr
<protocol::ConnectionToHost
> connection_to_host
) {
194 test_connection_to_host_
= connection_to_host
.Pass();
197 void TestChromotingClient::OnConnectionState(
198 protocol::ConnectionToHost::State state
,
199 protocol::ErrorCode error_code
) {
200 VLOG(1) << "TestChromotingClient::OnConnectionState("
201 << "state: " << protocol::ConnectionToHost::StateToString(state
)
202 << ", error_code: " << protocol::ErrorCodeToString(error_code
)
205 connection_error_code_
= error_code
;
206 connection_to_host_state_
= state
;
208 FOR_EACH_OBSERVER(RemoteConnectionObserver
, connection_observers_
,
209 ConnectionStateChanged(state
, error_code
));
212 void TestChromotingClient::OnConnectionReady(bool ready
) {
213 VLOG(1) << "TestChromotingClient::OnConnectionReady("
214 << "ready:" << ready
<< ") Called";
216 FOR_EACH_OBSERVER(RemoteConnectionObserver
, connection_observers_
,
217 ConnectionReady(ready
));
220 void TestChromotingClient::OnRouteChanged(
221 const std::string
& channel_name
,
222 const protocol::TransportRoute
& route
) {
223 VLOG(1) << "TestChromotingClient::OnRouteChanged("
224 << "channel_name:" << channel_name
<< ", "
225 << "route:" << protocol::TransportRoute::GetTypeString(route
.type
)
228 FOR_EACH_OBSERVER(RemoteConnectionObserver
, connection_observers_
,
229 RouteChanged(channel_name
, route
));
232 void TestChromotingClient::SetCapabilities(const std::string
& capabilities
) {
233 VLOG(1) << "TestChromotingClient::SetCapabilities("
234 << "capabilities: " << capabilities
<< ") Called";
236 FOR_EACH_OBSERVER(RemoteConnectionObserver
, connection_observers_
,
237 CapabilitiesSet(capabilities
));
240 void TestChromotingClient::SetPairingResponse(
241 const protocol::PairingResponse
& pairing_response
) {
242 VLOG(1) << "TestChromotingClient::SetPairingResponse("
243 << "client_id: " << pairing_response
.client_id() << ", "
244 << "shared_secret: " << pairing_response
.shared_secret()
247 FOR_EACH_OBSERVER(RemoteConnectionObserver
, connection_observers_
,
248 PairingResponseSet(pairing_response
));
251 void TestChromotingClient::DeliverHostMessage(
252 const protocol::ExtensionMessage
& message
) {
253 VLOG(1) << "TestChromotingClient::DeliverHostMessage("
254 << "type: " << message
.type() << ", "
255 << "data: " << message
.data() << ") Called";
257 FOR_EACH_OBSERVER(RemoteConnectionObserver
, connection_observers_
,
258 HostMessageReceived(message
));
261 protocol::ClipboardStub
* TestChromotingClient::GetClipboardStub() {
262 VLOG(1) << "TestChromotingClient::GetClipboardStub() Called";
266 protocol::CursorShapeStub
* TestChromotingClient::GetCursorShapeStub() {
267 VLOG(1) << "TestChromotingClient::GetCursorShapeStub() Called";
271 void TestChromotingClient::InjectClipboardEvent(
272 const protocol::ClipboardEvent
& event
) {
273 VLOG(1) << "TestChromotingClient::InjectClipboardEvent() Called";
276 void TestChromotingClient::SetCursorShape(
277 const protocol::CursorShapeInfo
& cursor_shape
) {
278 VLOG(1) << "TestChromotingClient::SetCursorShape() Called";
282 } // namespace remoting