Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / remoting / test / test_chromoting_client.cc
blobd838ba3a7986d363609e23777dedede28d182e5f
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"
7 #include <string>
8 #include <vector>
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"
31 namespace {
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();
51 } else {
52 LOG(ERROR) << "Invalid token fetcher proxy passed in";
56 void FetchSecret(
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);
63 const char* ConnectionStateToFriendlyString(
64 remoting::protocol::ConnectionToHost::State state) {
65 switch (state) {
66 case remoting::protocol::ConnectionToHost::INITIALIZING:
67 return "INITIALIZING";
69 case remoting::protocol::ConnectionToHost::CONNECTING:
70 return "CONNECTING";
72 case remoting::protocol::ConnectionToHost::AUTHENTICATED:
73 return "AUTHENTICATED";
75 case remoting::protocol::ConnectionToHost::CONNECTED:
76 return "CONNECTED";
78 case remoting::protocol::ConnectionToHost::CLOSED:
79 return "CLOSED";
81 case remoting::protocol::ConnectionToHost::FAILED:
82 return "FAILED";
84 default:
85 LOG(ERROR) << "Unknown connection state: '" << state << "'";
86 return "UNKNOWN";
90 const char* ProtocolErrorToFriendlyString(
91 remoting::protocol::ErrorCode error_code) {
92 switch (error_code) {
93 case remoting::protocol::OK:
94 return "NONE";
96 case remoting::protocol::PEER_IS_OFFLINE:
97 return "PEER_IS_OFFLINE";
99 case remoting::protocol::SESSION_REJECTED:
100 return "SESSION_REJECTED";
102 case remoting::protocol::AUTHENTICATION_FAILED:
103 return "AUTHENTICATION_FAILED";
105 case remoting::protocol::INCOMPATIBLE_PROTOCOL:
106 return "INCOMPATIBLE_PROTOCOL";
108 case remoting::protocol::HOST_OVERLOAD:
109 return "HOST_OVERLOAD";
111 case remoting::protocol::CHANNEL_CONNECTION_ERROR:
112 return "CHANNEL_CONNECTION_ERROR";
114 case remoting::protocol::SIGNALING_ERROR:
115 return "SIGNALING_ERROR";
117 case remoting::protocol::SIGNALING_TIMEOUT:
118 return "SIGNALING_TIMEOUT";
120 case remoting::protocol::UNKNOWN_ERROR:
121 return "UNKNOWN_ERROR";
123 default:
124 LOG(ERROR) << "Unrecognized error code: '" << error_code << "'";
125 return "UNKNOWN_ERROR";
129 } // namespace
131 namespace remoting {
132 namespace test {
134 TestChromotingClient::TestChromotingClient()
135 : connection_to_host_state_(protocol::ConnectionToHost::INITIALIZING),
136 connection_error_code_(protocol::OK) {
139 TestChromotingClient::TestChromotingClient(
140 scoped_ptr<VideoRenderer> video_renderer)
141 : video_renderer_(video_renderer.Pass()) {
142 TestChromotingClient();
145 TestChromotingClient::~TestChromotingClient() {
146 // Ensure any connections are closed and the members are destroyed in the
147 // appropriate order.
148 EndConnection();
151 void TestChromotingClient::StartConnection(
152 const ConnectionSetupInfo& connection_setup_info) {
153 // Required to establish a connection to the host.
154 jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop();
156 scoped_refptr<URLRequestContextGetter> request_context_getter;
157 request_context_getter = new URLRequestContextGetter(
158 base::ThreadTaskRunnerHandle::Get(), // network_runner
159 base::ThreadTaskRunnerHandle::Get()); // file_runner
161 client_context_.reset(new ClientContext(base::ThreadTaskRunnerHandle::Get()));
163 // Check to see if the user passed in a customized video renderer.
164 if (!video_renderer_) {
165 video_renderer_.reset(new TestVideoRenderer());
168 chromoting_client_.reset(new ChromotingClient(client_context_.get(),
169 this, // client_user_interface.
170 video_renderer_.get(),
171 nullptr)); // audio_player
173 if (test_connection_to_host_) {
174 chromoting_client_->SetConnectionToHostForTests(
175 test_connection_to_host_.Pass());
178 XmppSignalStrategy::XmppServerConfig xmpp_server_config;
179 xmpp_server_config.host = kXmppHostName;
180 xmpp_server_config.port = kXmppPortNumber;
181 xmpp_server_config.use_tls = true;
182 xmpp_server_config.username = connection_setup_info.user_name;
183 xmpp_server_config.auth_token = connection_setup_info.access_token;
185 // Set up the signal strategy. This must outlive the client object.
186 signal_strategy_.reset(
187 new XmppSignalStrategy(net::ClientSocketFactory::GetDefaultFactory(),
188 request_context_getter, xmpp_server_config));
190 protocol::NetworkSettings network_settings(
191 protocol::NetworkSettings::NAT_TRAVERSAL_FULL);
193 scoped_ptr<protocol::ChromiumPortAllocator> port_allocator(
194 protocol::ChromiumPortAllocator::Create(request_context_getter,
195 network_settings));
197 scoped_ptr<protocol::TransportFactory> transport_factory(
198 new protocol::LibjingleTransportFactory(
199 signal_strategy_.get(), port_allocator.Pass(), network_settings,
200 protocol::TransportRole::CLIENT));
202 scoped_ptr<protocol::ThirdPartyClientAuthenticator::TokenFetcher>
203 token_fetcher(new TokenFetcherProxy(
204 base::Bind(&FetchThirdPartyToken,
205 connection_setup_info.authorization_code,
206 connection_setup_info.shared_secret),
207 connection_setup_info.public_key));
209 protocol::FetchSecretCallback fetch_secret_callback;
210 if (!connection_setup_info.pin.empty()) {
211 fetch_secret_callback = base::Bind(&FetchSecret, connection_setup_info.pin);
214 scoped_ptr<protocol::Authenticator> authenticator(
215 new protocol::NegotiatingClientAuthenticator(
216 connection_setup_info.pairing_id,
217 connection_setup_info.shared_secret,
218 connection_setup_info.host_id,
219 fetch_secret_callback,
220 token_fetcher.Pass(),
221 connection_setup_info.auth_methods));
223 chromoting_client_->Start(
224 signal_strategy_.get(), authenticator.Pass(), transport_factory.Pass(),
225 connection_setup_info.host_jid, connection_setup_info.capabilities);
228 void TestChromotingClient::EndConnection() {
229 // Clearing out the client will close the connection.
230 chromoting_client_.reset();
232 // The signal strategy object must outlive the client so destroy it next.
233 signal_strategy_.reset();
235 // The connection state will be updated when the chromoting client was
236 // destroyed if an active connection was established, but not in other cases.
237 // We should be consistent in either case so we will set the state if needed.
238 if (connection_to_host_state_ != protocol::ConnectionToHost::CLOSED &&
239 connection_to_host_state_ != protocol::ConnectionToHost::FAILED &&
240 connection_error_code_ == protocol::OK) {
241 OnConnectionState(protocol::ConnectionToHost::CLOSED, protocol::OK);
245 void TestChromotingClient::AddRemoteConnectionObserver(
246 RemoteConnectionObserver* observer) {
247 DCHECK(observer);
249 connection_observers_.AddObserver(observer);
252 void TestChromotingClient::RemoveRemoteConnectionObserver(
253 RemoteConnectionObserver* observer) {
254 DCHECK(observer);
256 connection_observers_.RemoveObserver(observer);
259 void TestChromotingClient::SetConnectionToHostForTests(
260 scoped_ptr<protocol::ConnectionToHost> connection_to_host) {
261 test_connection_to_host_ = connection_to_host.Pass();
264 void TestChromotingClient::OnConnectionState(
265 protocol::ConnectionToHost::State state,
266 protocol::ErrorCode error_code) {
267 VLOG(1) << "TestChromotingClient::OnConnectionState("
268 << "state: " << ConnectionStateToFriendlyString(state) << ", "
269 << "error_code: " << ProtocolErrorToFriendlyString(error_code)
270 << ") Called";
272 connection_error_code_ = error_code;
273 connection_to_host_state_ = state;
275 FOR_EACH_OBSERVER(RemoteConnectionObserver, connection_observers_,
276 ConnectionStateChanged(state, error_code));
279 void TestChromotingClient::OnConnectionReady(bool ready) {
280 VLOG(1) << "TestChromotingClient::OnConnectionReady("
281 << "ready:" << ready << ") Called";
283 FOR_EACH_OBSERVER(RemoteConnectionObserver, connection_observers_,
284 ConnectionReady(ready));
287 void TestChromotingClient::OnRouteChanged(
288 const std::string& channel_name,
289 const protocol::TransportRoute& route) {
290 VLOG(1) << "TestChromotingClient::OnRouteChanged("
291 << "channel_name:" << channel_name << ", "
292 << "route:" << protocol::TransportRoute::GetTypeString(route.type)
293 << ") Called";
295 FOR_EACH_OBSERVER(RemoteConnectionObserver, connection_observers_,
296 RouteChanged(channel_name, route));
299 void TestChromotingClient::SetCapabilities(const std::string& capabilities) {
300 VLOG(1) << "TestChromotingClient::SetCapabilities("
301 << "capabilities: " << capabilities << ") Called";
303 FOR_EACH_OBSERVER(RemoteConnectionObserver, connection_observers_,
304 CapabilitiesSet(capabilities));
307 void TestChromotingClient::SetPairingResponse(
308 const protocol::PairingResponse& pairing_response) {
309 VLOG(1) << "TestChromotingClient::SetPairingResponse("
310 << "client_id: " << pairing_response.client_id() << ", "
311 << "shared_secret: " << pairing_response.shared_secret()
312 << ") Called";
314 FOR_EACH_OBSERVER(RemoteConnectionObserver, connection_observers_,
315 PairingResponseSet(pairing_response));
318 void TestChromotingClient::DeliverHostMessage(
319 const protocol::ExtensionMessage& message) {
320 VLOG(1) << "TestChromotingClient::DeliverHostMessage("
321 << "type: " << message.type() << ", "
322 << "data: " << message.data() << ") Called";
324 FOR_EACH_OBSERVER(RemoteConnectionObserver, connection_observers_,
325 HostMessageReceived(message));
328 protocol::ClipboardStub* TestChromotingClient::GetClipboardStub() {
329 VLOG(1) << "TestChromotingClient::GetClipboardStub() Called";
330 return this;
333 protocol::CursorShapeStub* TestChromotingClient::GetCursorShapeStub() {
334 VLOG(1) << "TestChromotingClient::GetCursorShapeStub() Called";
335 return this;
338 void TestChromotingClient::InjectClipboardEvent(
339 const protocol::ClipboardEvent& event) {
340 VLOG(1) << "TestChromotingClient::InjectClipboardEvent() Called";
343 void TestChromotingClient::SetCursorShape(
344 const protocol::CursorShapeInfo& cursor_shape) {
345 VLOG(1) << "TestChromotingClient::SetCursorShape() Called";
348 } // namespace test
349 } // namespace remoting