OLD | NEW |
---|---|
(Empty) | |
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. | |
4 | |
5 #include "remoting/test/test_chromoting_client.h" | |
6 | |
7 #include <string> | |
8 #include <vector> | |
9 | |
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/authentication_method.h" | |
21 #include "remoting/protocol/chromium_port_allocator.h" | |
22 #include "remoting/protocol/host_stub.h" | |
23 #include "remoting/protocol/libjingle_transport_factory.h" | |
24 #include "remoting/protocol/negotiating_client_authenticator.h" | |
25 #include "remoting/protocol/network_settings.h" | |
26 #include "remoting/protocol/session_config.h" | |
27 #include "remoting/protocol/third_party_client_authenticator.h" | |
28 #include "remoting/signaling/xmpp_signal_strategy.h" | |
29 #include "remoting/test/remote_host_info_fetcher.h" | |
30 #include "remoting/test/test_video_renderer.h" | |
31 | |
32 namespace { | |
33 | |
34 const char kRemotingCapabilities[] = | |
Sergey Ulanov
2015/03/11 00:09:51
suggest renaming this to kLocalCapabilities.
joedow
2015/03/11 19:06:39
Acknowledged.
| |
35 "sendInitialResolution " | |
36 "rateLimitResizeRequests " | |
37 "googleDrive " | |
38 "videoRecorder " | |
39 "casting"; | |
Sergey Ulanov
2015/03/11 00:09:52
Do you really need all of this. I don't think this
joedow
2015/03/11 19:06:39
Done.
| |
40 | |
41 const char kXmppHostName[] = "talk.google.com"; | |
42 const int kXmppPortNumber = 5222; | |
43 | |
44 } // namespace | |
45 | |
46 namespace remoting { | |
47 namespace test { | |
48 | |
49 TestChromotingClient::TestChromotingClient() | |
50 : connection_to_host_state_(protocol::ConnectionToHost::INITIALIZING), | |
51 connection_error_code_(protocol::OK) { | |
52 } | |
53 | |
54 TestChromotingClient::~TestChromotingClient() { | |
55 // Ensure any connections are closed and the members are destroyed in the | |
56 // appropriate order. | |
57 EndConnection(); | |
58 } | |
59 | |
60 void TestChromotingClient::StartConnection( | |
61 const std::string& user_name, | |
62 const std::string& access_token, | |
63 const RemoteHostInfo& remote_host_info) { | |
64 DCHECK(!user_name.empty()); | |
65 DCHECK(!access_token.empty()); | |
66 DCHECK(remote_host_info.IsReadyForConnection()); | |
67 | |
68 // Required to establish a connection to the host. | |
69 jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop(); | |
70 | |
71 scoped_refptr<URLRequestContextGetter> request_context_getter; | |
72 request_context_getter = new URLRequestContextGetter( | |
73 base::ThreadTaskRunnerHandle::Get(), // network_runner | |
74 base::ThreadTaskRunnerHandle::Get()); // file_runner | |
75 | |
76 client_context_.reset(new ClientContext(base::ThreadTaskRunnerHandle::Get())); | |
77 | |
78 video_renderer_.reset(new TestVideoRenderer()); | |
79 | |
80 chromoting_client_.reset(new ChromotingClient(client_context_.get(), | |
81 this, // client_user_interface. | |
82 video_renderer_.get(), | |
83 scoped_ptr<AudioPlayer>())); | |
Sergey Ulanov
2015/03/11 00:09:51
this can be just nullptr.
joedow
2015/03/11 19:06:39
Done.
| |
84 | |
85 if (test_connection_to_host_) { | |
86 chromoting_client_->SetConnectionToHostForTests( | |
87 test_connection_to_host_.Pass()); | |
88 } | |
89 | |
90 XmppSignalStrategy::XmppServerConfig xmpp_server_config; | |
91 xmpp_server_config.host = kXmppHostName; | |
92 xmpp_server_config.port = kXmppPortNumber; | |
93 xmpp_server_config.use_tls = true; | |
94 xmpp_server_config.username = user_name; | |
95 xmpp_server_config.auth_token = access_token; | |
96 | |
97 // Set up the signal strategy. This must outlive the client object. | |
98 signal_strategy_.reset( | |
99 new XmppSignalStrategy(net::ClientSocketFactory::GetDefaultFactory(), | |
100 request_context_getter, xmpp_server_config)); | |
101 | |
102 protocol::NetworkSettings network_settings( | |
103 protocol::NetworkSettings::NAT_TRAVERSAL_FULL); | |
104 | |
105 scoped_ptr<protocol::ChromiumPortAllocator> port_allocator( | |
106 protocol::ChromiumPortAllocator::Create(request_context_getter, | |
107 network_settings)); | |
108 | |
109 scoped_ptr<protocol::TransportFactory> transport_factory( | |
110 new protocol::LibjingleTransportFactory( | |
111 signal_strategy_.get(), port_allocator.Pass(), network_settings)); | |
112 | |
113 scoped_ptr<protocol::ThirdPartyClientAuthenticator::TokenFetcher> | |
114 token_fetcher(new TokenFetcherProxy( | |
115 base::Bind(&TestChromotingClient::FetchThirdPartyToken, | |
116 remote_host_info.authorization_code, | |
117 remote_host_info.shared_secret), | |
118 "FAKE_HOST_PUBLIC_KEY")); | |
119 | |
120 fetch_secret_callback_ = | |
Sergey Ulanov
2015/03/11 00:09:52
I don't think you need this. See my comment below.
joedow
2015/03/11 19:06:39
Done.
| |
121 base::Bind(&TestChromotingClient::FetchSecretFromString, | |
122 remote_host_info.shared_secret); | |
123 | |
124 std::vector<protocol::AuthenticationMethod> auth_methods; | |
125 auth_methods.push_back(protocol::AuthenticationMethod::ThirdParty()); | |
126 | |
127 scoped_ptr<protocol::Authenticator> authenticator( | |
128 new protocol::NegotiatingClientAuthenticator( | |
129 std::string(), // client_pairing_id | |
130 std::string(), // shared_secret | |
131 std::string(), // authentication_tag | |
132 fetch_secret_callback_, token_fetcher.Pass(), auth_methods)); | |
Sergey Ulanov
2015/03/11 00:09:52
If i remember correctly fetch_secret_callback is n
joedow
2015/03/11 19:06:39
Done.
| |
133 | |
134 chromoting_client_->Start(signal_strategy_.get(), authenticator.Pass(), | |
135 transport_factory.Pass(), remote_host_info.host_jid, | |
136 kRemotingCapabilities); | |
137 } | |
138 | |
139 void TestChromotingClient::EndConnection() { | |
140 // Clearing out the client will close the connection. | |
141 chromoting_client_.reset(); | |
142 | |
143 // The signal strategy object must outlive the client so destroy it next. | |
144 signal_strategy_.reset(); | |
145 | |
146 // The connection state should been updated when the chromoting client was | |
147 // destroyed however we will verify and update the connection state if not. | |
Sergey Ulanov
2015/03/11 00:09:52
Maybe better to (D)CHECK here that ChromotingClien
joedow
2015/03/11 19:06:39
Looks like the state that is set depends on whethe
| |
148 if (connection_to_host_state_ != protocol::ConnectionToHost::CLOSED && | |
149 connection_to_host_state_ != protocol::ConnectionToHost::FAILED && | |
150 connection_error_code_ == protocol::OK) { | |
151 OnConnectionState(protocol::ConnectionToHost::CLOSED, protocol::OK); | |
152 } | |
153 } | |
154 | |
155 void TestChromotingClient::AddRemoteConnectionObserver( | |
156 RemoteConnectionObserver* observer) { | |
157 DCHECK(observer); | |
158 | |
159 connection_observers_.AddObserver(observer); | |
160 } | |
161 | |
162 void TestChromotingClient::RemoveRemoteConnectionObserver( | |
163 RemoteConnectionObserver* observer) { | |
164 DCHECK(observer); | |
165 | |
166 connection_observers_.RemoveObserver(observer); | |
167 } | |
168 | |
169 void TestChromotingClient::SetConnectionToHostForTests( | |
170 scoped_ptr<protocol::ConnectionToHost> connection_to_host) { | |
171 test_connection_to_host_ = connection_to_host.Pass(); | |
172 } | |
173 | |
174 void TestChromotingClient::OnConnectionState( | |
175 protocol::ConnectionToHost::State state, | |
176 protocol::ErrorCode error_code) { | |
177 DVLOG(1) << "TestChromotingClient::OnConnectionState() Called"; | |
178 DVLOG(2) << "--State: " << ConnectionStateToFriendlyString(state); | |
Sergey Ulanov
2015/03/11 00:09:51
Please see the second part of this comment: https:
joedow
2015/03/11 19:06:39
Done.
| |
179 DVLOG(2) << "--ErrorCode: " << ProtocolErrorToFriendlyString(error_code); | |
180 | |
181 connection_error_code_ = error_code; | |
182 connection_to_host_state_ = state; | |
183 | |
184 FOR_EACH_OBSERVER(RemoteConnectionObserver, connection_observers_, | |
185 ConnectionStateChanged(state, error_code)); | |
186 } | |
187 | |
188 void TestChromotingClient::OnConnectionReady(bool ready) { | |
189 DVLOG(1) << "TestChromotingClient::OnConnectionReady() Called"; | |
190 DVLOG(2) << "--ready:" << ready; | |
191 | |
192 FOR_EACH_OBSERVER(RemoteConnectionObserver, connection_observers_, | |
193 ConnectionReady(ready)); | |
194 } | |
195 | |
196 void TestChromotingClient::OnRouteChanged( | |
197 const std::string& channel_name, | |
198 const protocol::TransportRoute& route) { | |
199 DVLOG(1) << "TestChromotingClient::OnRouteChanged() Called"; | |
200 DVLOG(2) << "--channel_name:" << channel_name; | |
201 DVLOG(2) << "--route:" << protocol::TransportRoute::GetTypeString(route.type); | |
202 | |
203 FOR_EACH_OBSERVER(RemoteConnectionObserver, connection_observers_, | |
204 RouteChanged(channel_name, route)); | |
205 } | |
206 | |
207 void TestChromotingClient::SetCapabilities(const std::string& capabilities) { | |
208 DVLOG(1) << "TestChromotingClient::SetCapabilities() Called"; | |
209 DVLOG(2) << "--Capabilities: " << capabilities; | |
210 | |
211 FOR_EACH_OBSERVER(RemoteConnectionObserver, connection_observers_, | |
212 CapabilitiesSet(capabilities)); | |
213 } | |
214 | |
215 void TestChromotingClient::SetPairingResponse( | |
216 const protocol::PairingResponse& pairing_response) { | |
217 DVLOG(1) << "TestChromotingClient::SetPairingResponse() Called"; | |
218 DVLOG(2) << "--client_id: " << pairing_response.client_id(); | |
219 DVLOG(2) << "--shared_secret: " << pairing_response.shared_secret(); | |
220 | |
221 FOR_EACH_OBSERVER(RemoteConnectionObserver, connection_observers_, | |
222 PairingResponseSet(pairing_response)); | |
223 } | |
224 | |
225 void TestChromotingClient::DeliverHostMessage( | |
226 const protocol::ExtensionMessage& message) { | |
227 DVLOG(1) << "TestChromotingClient::DeliverHostMessage() called"; | |
228 DVLOG(2) << "--type: " << message.type(); | |
229 DVLOG(2) << "--data: " << message.data(); | |
230 | |
231 FOR_EACH_OBSERVER(RemoteConnectionObserver, connection_observers_, | |
232 HostMessageReceived(message)); | |
233 } | |
234 | |
235 protocol::ClipboardStub* TestChromotingClient::GetClipboardStub() { | |
236 DVLOG(1) << "TestChromotingClient::GetClipboardStub() Called"; | |
237 return this; | |
238 } | |
239 | |
240 protocol::CursorShapeStub* TestChromotingClient::GetCursorShapeStub() { | |
241 DVLOG(1) << "TestChromotingClient::GetCursorShapeStub() Called"; | |
242 return this; | |
243 } | |
244 | |
245 void TestChromotingClient::InjectClipboardEvent( | |
246 const protocol::ClipboardEvent& event) { | |
247 DVLOG(1) << "TestChromotingClient::InjectClipboardEvent() Called"; | |
248 } | |
249 | |
250 void TestChromotingClient::SetCursorShape( | |
251 const protocol::CursorShapeInfo& cursor_shape) { | |
252 DVLOG(1) << "TestChromotingClient::SetCursorShape() Called"; | |
253 } | |
254 | |
255 void TestChromotingClient::FetchSecretFromString( | |
256 const std::string& shared_secret, | |
257 bool pairing_supported, | |
258 const protocol::SecretFetchedCallback& secret_fetched_callback) { | |
259 DVLOG(1) << "TestChromotingClient::FetchSecretFromString Called"; | |
260 secret_fetched_callback.Run(shared_secret); | |
261 } | |
262 | |
263 void TestChromotingClient::FetchThirdPartyToken( | |
264 const std::string& authorization_token, | |
265 const std::string& shared_secret, | |
266 const GURL& token_url, | |
267 const std::string& host_public_key, | |
268 const std::string& scope, | |
269 base::WeakPtr<TokenFetcherProxy> token_fetcher_proxy) { | |
270 DVLOG(1) << "TestChromotingClient::FetchThirdPartyToken Called"; | |
271 DVLOG(2) << "--token_url: " << token_url; | |
272 DVLOG(2) << "--host_public_key: " << host_public_key; | |
273 DVLOG(2) << "--scope: " << scope; | |
274 | |
275 if (token_fetcher_proxy) { | |
276 token_fetcher_proxy->OnTokenFetched(authorization_token, shared_secret); | |
277 token_fetcher_proxy.reset(); | |
278 } else { | |
279 LOG(ERROR) << "Invalid token fetcher proxy passed in"; | |
280 } | |
281 } | |
282 | |
283 const char* TestChromotingClient::ConnectionStateToFriendlyString( | |
Sergey Ulanov
2015/03/11 00:09:51
This doesn't need to be a method. Can be a static
joedow
2015/03/11 19:06:39
Done.
| |
284 protocol::ConnectionToHost::State state) { | |
285 switch (state) { | |
286 case protocol::ConnectionToHost::INITIALIZING: | |
287 return "INITIALIZING"; | |
288 | |
289 case protocol::ConnectionToHost::CONNECTING: | |
290 return "CONNECTING"; | |
291 | |
292 case protocol::ConnectionToHost::AUTHENTICATED: | |
293 return "AUTHENTICATED"; | |
294 | |
295 case protocol::ConnectionToHost::CONNECTED: | |
296 return "CONNECTED"; | |
297 | |
298 case protocol::ConnectionToHost::CLOSED: | |
299 return "CLOSED"; | |
300 | |
301 case protocol::ConnectionToHost::FAILED: | |
302 return "FAILED"; | |
303 | |
304 default: | |
305 LOG(ERROR) << "Unknown connection state: '" << state << "'"; | |
306 return "UNKNOWN"; | |
307 } | |
308 } | |
309 | |
310 const char* TestChromotingClient::ProtocolErrorToFriendlyString( | |
311 protocol::ErrorCode error_code) { | |
312 switch (error_code) { | |
313 case protocol::OK: | |
314 return "NONE"; | |
315 | |
316 case protocol::PEER_IS_OFFLINE: | |
317 return "PEER_IS_OFFLINE"; | |
318 | |
319 case protocol::SESSION_REJECTED: | |
320 return "SESSION_REJECTED"; | |
321 | |
322 case protocol::AUTHENTICATION_FAILED: | |
323 return "AUTHENTICATION_FAILED"; | |
324 | |
325 case protocol::INCOMPATIBLE_PROTOCOL: | |
326 return "INCOMPATIBLE_PROTOCOL"; | |
327 | |
328 case protocol::HOST_OVERLOAD: | |
329 return "HOST_OVERLOAD"; | |
330 | |
331 case protocol::CHANNEL_CONNECTION_ERROR: | |
332 return "CHANNEL_CONNECTION_ERROR"; | |
333 | |
334 case protocol::SIGNALING_ERROR: | |
335 return "SIGNALING_ERROR"; | |
336 | |
337 case protocol::SIGNALING_TIMEOUT: | |
338 return "SIGNALING_TIMEOUT"; | |
339 | |
340 case protocol::UNKNOWN_ERROR: | |
341 return "UNKNOWN_ERROR"; | |
342 | |
343 default: | |
344 LOG(ERROR) << "Unrecognized error code: '" << error_code << "'"; | |
345 return "UNKNOWN_ERROR"; | |
346 } | |
347 } | |
348 | |
349 } // namespace test | |
350 } // namespace remoting | |
OLD | NEW |