Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(554)

Side by Side Diff: remoting/client/ios/bridge/client_instance.cc

Issue 2829853003: Remove crufty bridge code from old CRD iOS app. (Closed)
Patch Set: Fix remoting/display proto import issue. Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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/client/ios/bridge/client_instance.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/logging.h"
10 #include "base/memory/ptr_util.h"
11 #include "base/synchronization/waitable_event.h"
12 #include "jingle/glue/thread_wrapper.h"
13 #include "net/socket/client_socket_factory.h"
14 #include "remoting/base/chromium_url_request.h"
15 #include "remoting/base/url_request_context_getter.h"
16 #include "remoting/client/audio_player.h"
17 //#include "remoting/client/client_status_logger.h"
18 #include "remoting/client/ios/bridge/client_proxy.h"
19 #include "remoting/proto/event.pb.h"
20 #include "remoting/protocol/chromium_port_allocator_factory.h"
21 #include "remoting/protocol/client_authentication_config.h"
22 #include "remoting/protocol/host_stub.h"
23 #include "remoting/protocol/negotiating_client_authenticator.h"
24 #include "remoting/protocol/transport_context.h"
25 #include "remoting/signaling/delegating_signal_strategy.h"
26
27
28 //#include "remoting/client/ios/audio_player_buffer.h" // TODO(nicholss): need
29 // to also pull in the player and attach to buffer.
30
31 // TODO(nicholss): There is another client instance used by android. Need to
32 // merge the two.
33
34 namespace {
35 const char* const kXmppServer = "talk.google.com";
36 // const char kDirectoryBotJid[] = "remoting@bot.talk.google.com";
37 } // namespace
38
39 namespace remoting {
40
41 ClientInstance::ClientInstance(const base::WeakPtr<ClientProxy>& proxy,
42 const std::string& username,
43 const std::string& auth_token,
44 const std::string& host_jid,
45 const std::string& host_id,
46 const std::string& host_pubkey)
47 : proxyToClient_(proxy), host_jid_(host_jid), device_id_() {
48 if (!base::MessageLoop::current()) {
49 ui_loop_ = new base::MessageLoop(base::MessageLoop::TYPE_UI);
50 base::MessageLoopForUI::current()->Attach();
51 } else {
52 ui_loop_ = base::MessageLoopForUI::current();
53 }
54
55 // |ui_loop_| runs on the main thread, so |ui_task_runner_| will run on the
56 // main thread. We can not kill the main thread when the message loop becomes
57 // idle so the callback function does nothing (as opposed to the typical
58 // base::MessageLoop::QuitClosure())
59 ui_task_runner_ = new AutoThreadTaskRunner(ui_loop_->task_runner(),
60 base::Bind(&base::DoNothing));
61
62 network_task_runner_ = AutoThread::CreateWithType(
63 "native_net", ui_task_runner_, base::MessageLoop::TYPE_IO);
64 file_task_runner_ = AutoThread::CreateWithType("native_file", ui_task_runner_,
65 base::MessageLoop::TYPE_IO);
66 audio_task_runner_ = AutoThread::CreateWithType(
67 "native_audio", ui_task_runner_, base::MessageLoop::TYPE_IO);
68
69 url_requester_ =
70 new URLRequestContextGetter(network_task_runner_, file_task_runner_);
71
72 DCHECK(ui_task_runner_->BelongsToCurrentThread());
73
74 // Initialize XMPP config.
75 xmpp_config_.host = kXmppServer;
76 xmpp_config_.username = username;
77 xmpp_config_.auth_token = auth_token;
78
79 client_auth_config_.host_id = host_id;
80 client_auth_config_.fetch_secret_callback =
81 base::Bind(&ClientInstance::FetchSecret, this);
82 // client_auth_config_.fetch_third_party_token_callback =
83 // std::unique_ptr<protocol::ThirdPartyClientAuthenticator::TokenFetcher>();
84 }
85
86 ClientInstance::~ClientInstance() {}
87
88 void ClientInstance::Start(const std::string& pairing_id,
89 const std::string& pairing_secret) {
90 DCHECK(ui_task_runner_->BelongsToCurrentThread());
91
92 client_auth_config_.pairing_client_id = pairing_id;
93 client_auth_config_.pairing_secret = pairing_secret;
94
95 view_.reset(new FrameConsumerBridge(
96 this, base::Bind(&ClientProxy::RedrawCanvas, proxyToClient_)));
97
98 network_task_runner_->PostTask(
99 FROM_HERE,
100 base::Bind(&ClientInstance::ConnectToHostOnNetworkThread, this));
101 }
102
103 void ClientInstance::Cleanup() {
104 DCHECK(ui_task_runner_->BelongsToCurrentThread());
105
106 // |view_| must be destroyed on the UI thread before the producer is gone.
107 view_.reset();
108
109 network_task_runner_->PostTask(
110 FROM_HERE,
111 base::Bind(&ClientInstance::DisconnectFromHostOnNetworkThread, this));
112 }
113
114 // HOST attempts to continue automatically with previously supplied credentials,
115 // if it can't it requests the user's PIN.
116 void ClientInstance::FetchSecret(
117 bool pairable,
118 const protocol::SecretFetchedCallback& callback) {
119 if (!ui_task_runner_->BelongsToCurrentThread()) {
120 ui_task_runner_->PostTask(
121 FROM_HERE,
122 base::Bind(&ClientInstance::FetchSecret, this, pairable, callback));
123 return;
124 }
125
126 pin_callback_ = callback;
127
128 if (proxyToClient_) {
129 // We attempted to connect using an existing pairing that was rejected.
130 // Unless we forget about the stale credentials, we'll continue trying
131 // them.
132 proxyToClient_->CommitPairingCredentials(client_auth_config_.host_id, "",
133 "");
134
135 proxyToClient_->DisplayAuthenticationPrompt(pairable);
136 }
137 }
138
139 void ClientInstance::ProvideSecret(const std::string& pin,
140 bool create_pairing,
141 const std::string& device_id) {
142 DCHECK(ui_task_runner_->BelongsToCurrentThread());
143 create_pairing_ = create_pairing;
144 device_id_ = device_id;
145
146 // Before this function can be called, FetchSecret must have been called,
147 // which creates |pin_callback_|
148 DCHECK(!pin_callback_.is_null());
149 network_task_runner_->PostTask(FROM_HERE, base::Bind(pin_callback_, pin));
150 }
151
152 void ClientInstance::PerformMouseAction(
153 const webrtc::DesktopVector& position,
154 const webrtc::DesktopVector& wheel_delta,
155 protocol::MouseEvent_MouseButton button,
156 bool button_down) {
157 if (!network_task_runner_->BelongsToCurrentThread()) {
158 network_task_runner_->PostTask(
159 FROM_HERE, base::Bind(&ClientInstance::PerformMouseAction, this,
160 position, wheel_delta, button, button_down));
161 return;
162 }
163
164 protocol::MouseEvent action;
165 action.set_x(position.x());
166 action.set_y(position.y());
167 action.set_wheel_delta_x(wheel_delta.x());
168 action.set_wheel_delta_y(wheel_delta.y());
169 action.set_button(button);
170
171 // TODO(nicholss) this throws a npe when there is a delay on connecting to a
172 // host + touch.
173 client_->input_stub()->InjectMouseEvent(action);
174 }
175
176 void ClientInstance::PerformKeyboardAction(int key_code, bool key_down) {
177 if (!network_task_runner_->BelongsToCurrentThread()) {
178 network_task_runner_->PostTask(
179 FROM_HERE, base::Bind(&ClientInstance::PerformKeyboardAction, this,
180 key_code, key_down));
181 return;
182 }
183
184 protocol::KeyEvent action;
185 action.set_usb_keycode(key_code);
186 action.set_pressed(key_down);
187 client_->input_stub()->InjectKeyEvent(action);
188 }
189
190 void ClientInstance::OnConnectionState(protocol::ConnectionToHost::State state,
191 protocol::ErrorCode error) {
192 DCHECK(network_task_runner_->BelongsToCurrentThread());
193
194 // client_status_logger_->LogSessionStateChange(state, error);
195
196 ui_task_runner_->PostTask(
197 FROM_HERE, base::Bind(&ClientInstance::HandleConnectionStateOnUIThread,
198 this, state, error));
199 }
200
201 void ClientInstance::OnConnectionReady(bool ready) {
202 // We ignore this message, since OnConnectionState tells us the same thing.
203 }
204
205 void ClientInstance::OnRouteChanged(const std::string& channel_name,
206 const protocol::TransportRoute& route) {
207 VLOG(1) << "Using " << protocol::TransportRoute::GetTypeString(route.type)
208 << " connection for " << channel_name << " channel";
209 }
210
211 void ClientInstance::SetCapabilities(const std::string& capabilities) {}
212
213 void ClientInstance::SetPairingResponse(
214 const protocol::PairingResponse& response) {
215 if (!ui_task_runner_->BelongsToCurrentThread()) {
216 ui_task_runner_->PostTask(
217 FROM_HERE,
218 base::Bind(&ClientInstance::SetPairingResponse, this, response));
219 return;
220 }
221
222 VLOG(1) << "Successfully established pairing with host";
223
224 if (proxyToClient_)
225 proxyToClient_->CommitPairingCredentials(client_auth_config_.host_id,
226 response.client_id(),
227 response.shared_secret());
228 }
229
230 void ClientInstance::DeliverHostMessage(
231 const protocol::ExtensionMessage& message) {
232 NOTIMPLEMENTED();
233 }
234
235 void ClientInstance::SetDesktopSize(const webrtc::DesktopSize& size,
236 const webrtc::DesktopVector& dpi) {
237 // ClientInstance get size from the frames and it doesn't use DPI, so this
238 // call can be ignored.
239 }
240
241 // Returning interface of protocol::ClipboardStub.
242 protocol::ClipboardStub* ClientInstance::GetClipboardStub() {
243 return this;
244 }
245
246 // Returning interface of protocol::CursorShapeStub.
247 protocol::CursorShapeStub* ClientInstance::GetCursorShapeStub() {
248 return this;
249 }
250
251 void ClientInstance::InjectClipboardEvent(
252 const protocol::ClipboardEvent& event) {
253 NOTIMPLEMENTED();
254 }
255
256 void ClientInstance::SetCursorShape(const protocol::CursorShapeInfo& shape) {
257 if (!ui_task_runner_->BelongsToCurrentThread()) {
258 ui_task_runner_->PostTask(
259 FROM_HERE, base::Bind(&ClientInstance::SetCursorShape, this, shape));
260 return;
261 }
262 if (proxyToClient_)
263 proxyToClient_->UpdateCursorShape(shape);
264 }
265
266 void ClientInstance::ConnectToHostOnNetworkThread() {
267 DCHECK(network_task_runner_->BelongsToCurrentThread());
268
269 jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop();
270
271 client_context_.reset(new ClientContext(network_task_runner_));
272 client_context_->Start();
273
274 perf_tracker_.reset(new protocol::PerformanceTracker());
275
276 video_renderer_.reset(new SoftwareVideoRenderer(view_.get()));
277 // TODO(nicholss): SoftwareVideoRenderer was changed to now have Initialize,
278 // but it is unclear how to integrate into existing code.
279 // video_renderer_->Initialize(client_context_, perf_tracker_.get()));
280
281 client_.reset(new ChromotingClient(
282 client_context_.get(), this, video_renderer_.get(),
283 nullptr // TODO(nicholss): GetAudioConsumer().get()
284 ));
285
286 signaling_.reset(
287 new XmppSignalStrategy(net::ClientSocketFactory::GetDefaultFactory(),
288 url_requester_, xmpp_config_));
289
290 // client_status_logger_.reset(new ClientStatusLogger(
291 // ServerLogEntry::ME2ME, signaling_.get(), kDirectoryBotJid));
292
293 protocol::NetworkSettings network_settings(
294 protocol::NetworkSettings::NAT_TRAVERSAL_FULL);
295
296 // Use Chrome's network stack to allocate ports for peer-to-peer channels.
297
298 scoped_refptr<protocol::TransportContext> transport_context =
299 new protocol::TransportContext(
300 signaling_.get(),
301 base::WrapUnique(new protocol::ChromiumPortAllocatorFactory()),
302 base::WrapUnique(new ChromiumUrlRequestFactory(url_requester_)),
303 protocol::NetworkSettings(
304 protocol::NetworkSettings::NAT_TRAVERSAL_FULL),
305 protocol::TransportRole::CLIENT);
306
307 client_->Start(signaling_.get(), client_auth_config_, transport_context,
308 host_jid_, std::string());
309 }
310
311 // TODO(nicholss): Port audio impl for iOS.
312 // base::WeakPtr<protocol::AudioStub> ClientInstance::GetAudioConsumer() {
313 // if (!audio_player_) {
314 // audio_player_ = AudioPlayerIos::CreateAudioPlayer(
315 // network_task_runner_,
316 // audio_task_runner_);
317 // }
318 //
319 // return audio_player_->GetAudioConsumer();
320 // }
321
322 void ClientInstance::DisconnectFromHostOnNetworkThread() {
323 DCHECK(network_task_runner_->BelongsToCurrentThread());
324
325 // |client_| must be torn down before |signaling_|.
326 client_.reset();
327 // client_status_logger_.reset();
328 signaling_.reset();
329 perf_tracker_.reset();
330 // audio_consumer_->reset(); // TODO(nicholss): Or should this be a call to
331 // Stop?
332 // audio_player_->reset(); // TODO(nicholss): Or should this be a call to
333 // Stop?
334 video_renderer_.reset();
335 client_context_->Stop();
336 }
337
338 void ClientInstance::HandleConnectionStateOnUIThread(
339 protocol::ConnectionToHost::State state,
340 protocol::ErrorCode error) {
341 if (create_pairing_ && device_id_.length() > 0 &&
342 state == protocol::ConnectionToHost::CONNECTED) {
343 DoPairing();
344 }
345
346 if (proxyToClient_)
347 proxyToClient_->ReportConnectionStatus(state, error);
348 }
349
350 void ClientInstance::DoPairing() {
351 if (!network_task_runner_->BelongsToCurrentThread()) {
352 network_task_runner_->PostTask(
353 FROM_HERE, base::Bind(&ClientInstance::DoPairing, this));
354 return;
355 }
356
357 VLOG(1) << "Attempting to pair with host";
358 protocol::PairingRequest request;
359 request.set_client_name(device_id_);
360 client_->host_stub()->RequestPairing(request);
361 }
362
363 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/client/ios/bridge/client_instance.h ('k') | remoting/client/ios/bridge/client_instance_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698