blob: 6c6f075c7f21173b11650f1af05bae6c13b47d76 [file] [log] [blame]
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01001// Copyright 2013 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/jni/chromoting_jni_instance.h"
6
7#include "base/bind.h"
8#include "base/logging.h"
9#include "remoting/client/audio_player.h"
10#include "remoting/client/jni/chromoting_jni.h"
11#include "remoting/protocol/libjingle_transport_factory.h"
12
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010013// TODO(solb) Move into location shared with client plugin.
14const char* const CHAT_SERVER = "talk.google.com";
15const int CHAT_PORT = 5222;
16const bool CHAT_USE_TLS = true;
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010017
18namespace remoting {
19
20ChromotingJniInstance::ChromotingJniInstance(const char* username,
Ben Murdoch9ab55632013-07-18 11:57:30 +010021 const char* auth_token,
22 const char* host_jid,
23 const char* host_id,
24 const char* host_pubkey) {
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010025 DCHECK(ChromotingJni::GetInstance()->
26 ui_task_runner()->BelongsToCurrentThread());
27
28 username_ = username;
29 auth_token_ = auth_token;
30 host_jid_ = host_jid;
31 host_id_ = host_id;
32 host_pubkey_ = host_pubkey;
33
34 ChromotingJni::GetInstance()->display_task_runner()->PostTask(
35 FROM_HERE,
36 base::Bind(&ChromotingJniInstance::ConnectToHostOnDisplayThread,
37 this));
38}
39
40ChromotingJniInstance::~ChromotingJniInstance() {}
41
42void ChromotingJniInstance::Cleanup() {
43 if (!ChromotingJni::GetInstance()->
Ben Murdoch9ab55632013-07-18 11:57:30 +010044 display_task_runner()->BelongsToCurrentThread()) {
45 ChromotingJni::GetInstance()->display_task_runner()->PostTask(
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010046 FROM_HERE,
47 base::Bind(&ChromotingJniInstance::Cleanup, this));
48 return;
49 }
50
Ben Murdoch9ab55632013-07-18 11:57:30 +010051 // This must be destroyed on the display thread before the producer is gone.
52 view_.reset();
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010053
Ben Murdoch9ab55632013-07-18 11:57:30 +010054 // The weak pointers must be invalidated on the same thread they were used.
55 view_weak_factory_->InvalidateWeakPtrs();
56
57 ChromotingJni::GetInstance()->network_task_runner()->PostTask(FROM_HERE,
58 base::Bind(&ChromotingJniInstance::DisconnectFromHostOnNetworkThread,
59 this));
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010060}
61
62void ChromotingJniInstance::ProvideSecret(const char* pin) {
63 DCHECK(ChromotingJni::GetInstance()->
64 ui_task_runner()->BelongsToCurrentThread());
65 DCHECK(!pin_callback_.is_null());
66
67 // We invoke the string constructor to ensure |pin| gets copied *before* the
68 // asynchronous run, since Java might want it back as soon as we return.
69 ChromotingJni::GetInstance()->network_task_runner()->PostTask(FROM_HERE,
70 base::Bind(pin_callback_, pin));
71}
72
Ben Murdoch9ab55632013-07-18 11:57:30 +010073void ChromotingJniInstance::RedrawDesktop() {
74 if (!ChromotingJni::GetInstance()->
75 display_task_runner()->BelongsToCurrentThread()) {
76 ChromotingJni::GetInstance()->display_task_runner()->PostTask(
77 FROM_HERE,
78 base::Bind(&ChromotingJniInstance::RedrawDesktop,
79 this));
80 return;
81 }
82
83 ChromotingJni::GetInstance()->RedrawCanvas();
84}
85
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010086void ChromotingJniInstance::OnConnectionState(
87 protocol::ConnectionToHost::State state,
88 protocol::ErrorCode error) {
89 if (!ChromotingJni::GetInstance()->
90 ui_task_runner()->BelongsToCurrentThread()) {
91 ChromotingJni::GetInstance()->
92 ui_task_runner()->PostTask(
93 FROM_HERE,
94 base::Bind(&ChromotingJniInstance::OnConnectionState,
95 this,
96 state,
97 error));
98 return;
99 }
100
101 ChromotingJni::GetInstance()->ReportConnectionStatus(state, error);
102}
103
104void ChromotingJniInstance::OnConnectionReady(bool ready) {
105 // We ignore this message, since OnConnectionState() tells us the same thing.
106}
107
108void ChromotingJniInstance::SetCapabilities(const std::string& capabilities) {}
109
110void ChromotingJniInstance::SetPairingResponse(
111 const protocol::PairingResponse& response) {
112 NOTIMPLEMENTED();
113}
114
115protocol::ClipboardStub* ChromotingJniInstance::GetClipboardStub() {
116 NOTIMPLEMENTED();
117 return NULL;
118}
119
120protocol::CursorShapeStub* ChromotingJniInstance::GetCursorShapeStub() {
121 NOTIMPLEMENTED();
122 return NULL;
123}
124
125scoped_ptr<protocol::ThirdPartyClientAuthenticator::TokenFetcher>
126 ChromotingJniInstance::GetTokenFetcher(const std::string& host_public_key) {
127 // Return null to indicate that third-party authentication is unsupported.
128 return scoped_ptr<protocol::ThirdPartyClientAuthenticator::TokenFetcher>();
129}
130
131void ChromotingJniInstance::ConnectToHostOnDisplayThread() {
132 DCHECK(ChromotingJni::GetInstance()->
133 display_task_runner()->BelongsToCurrentThread());
134
Ben Murdoch9ab55632013-07-18 11:57:30 +0100135 frame_consumer_ = new FrameConsumerProxy(
136 ChromotingJni::GetInstance()->display_task_runner());
137 view_.reset(new JniFrameConsumer());
138 view_weak_factory_.reset(new base::WeakPtrFactory<JniFrameConsumer>(
139 view_.get()));
140 frame_consumer_->Attach(view_weak_factory_->GetWeakPtr());
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100141
142 ChromotingJni::GetInstance()->network_task_runner()->PostTask(
143 FROM_HERE,
144 base::Bind(&ChromotingJniInstance::ConnectToHostOnNetworkThread,
145 this));
146}
147
148void ChromotingJniInstance::ConnectToHostOnNetworkThread() {
149 DCHECK(ChromotingJni::GetInstance()->
150 network_task_runner()->BelongsToCurrentThread());
151
152 client_config_.reset(new ClientConfig());
153 client_config_->host_jid = host_jid_;
154 client_config_->host_public_key = host_pubkey_;
155
156 client_config_->fetch_secret_callback = base::Bind(
157 &ChromotingJniInstance::FetchSecret,
158 this);
159 client_config_->authentication_tag = host_id_;
160
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100161 client_config_->authentication_methods.push_back(
162 protocol::AuthenticationMethod::FromString("spake2_hmac"));
163 client_config_->authentication_methods.push_back(
164 protocol::AuthenticationMethod::FromString("spake2_plain"));
165
166 client_context_.reset(new ClientContext(
167 ChromotingJni::GetInstance()->network_task_runner().get()));
168 client_context_->Start();
169
170 connection_.reset(new protocol::ConnectionToHost(true));
171
172 client_.reset(new ChromotingClient(*client_config_,
173 client_context_.get(),
174 connection_.get(),
175 this,
176 frame_consumer_,
177 scoped_ptr<AudioPlayer>()));
178
Ben Murdoch9ab55632013-07-18 11:57:30 +0100179 view_->set_frame_producer(client_->GetFrameProducer());
180
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100181 signaling_config_.reset(new XmppSignalStrategy::XmppServerConfig());
182 signaling_config_->host = CHAT_SERVER;
183 signaling_config_->port = CHAT_PORT;
184 signaling_config_->use_tls = CHAT_USE_TLS;
185
186 signaling_.reset(new XmppSignalStrategy(
187 ChromotingJni::GetInstance()->url_requester(),
188 username_,
189 auth_token_,
Ben Murdoch9ab55632013-07-18 11:57:30 +0100190 "oauth2",
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100191 *signaling_config_));
192
193 network_settings_.reset(new NetworkSettings(
194 NetworkSettings::NAT_TRAVERSAL_OUTGOING));
195 scoped_ptr<protocol::TransportFactory> fact(
196 protocol::LibjingleTransportFactory::Create(
197 *network_settings_,
198 ChromotingJni::GetInstance()->url_requester()));
199
200 client_->Start(signaling_.get(), fact.Pass());
201}
202
Ben Murdoch9ab55632013-07-18 11:57:30 +0100203void ChromotingJniInstance::DisconnectFromHostOnNetworkThread() {
204 DCHECK(ChromotingJni::GetInstance()->
205 network_task_runner()->BelongsToCurrentThread());
206
207 username_ = "";
208 auth_token_ = "";
209 host_jid_ = "";
210 host_id_ = "";
211 host_pubkey_ = "";
212
213 // |client_| must be torn down before |signaling_|.
214 connection_.reset();
215 client_.reset();
216}
217
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100218void ChromotingJniInstance::FetchSecret(
219 bool pairable,
220 const protocol::SecretFetchedCallback& callback) {
221 if (!ChromotingJni::GetInstance()->
222 ui_task_runner()->BelongsToCurrentThread()) {
223 ChromotingJni::GetInstance()->ui_task_runner()->PostTask(
224 FROM_HERE,
225 base::Bind(&ChromotingJniInstance::FetchSecret,
226 this,
227 pairable,
228 callback));
229 return;
230 }
231
232 pin_callback_ = callback;
233 ChromotingJni::GetInstance()->DisplayAuthenticationPrompt();
234}
235
236} // namespace remoting