Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 1 | // 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 Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 13 | // TODO(solb) Move into location shared with client plugin. |
| 14 | const char* const CHAT_SERVER = "talk.google.com"; |
| 15 | const int CHAT_PORT = 5222; |
| 16 | const bool CHAT_USE_TLS = true; |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 17 | |
| 18 | namespace remoting { |
| 19 | |
| 20 | ChromotingJniInstance::ChromotingJniInstance(const char* username, |
Ben Murdoch | 9ab5563 | 2013-07-18 11:57:30 +0100 | [diff] [blame^] | 21 | const char* auth_token, |
| 22 | const char* host_jid, |
| 23 | const char* host_id, |
| 24 | const char* host_pubkey) { |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 25 | 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 | |
| 40 | ChromotingJniInstance::~ChromotingJniInstance() {} |
| 41 | |
| 42 | void ChromotingJniInstance::Cleanup() { |
| 43 | if (!ChromotingJni::GetInstance()-> |
Ben Murdoch | 9ab5563 | 2013-07-18 11:57:30 +0100 | [diff] [blame^] | 44 | display_task_runner()->BelongsToCurrentThread()) { |
| 45 | ChromotingJni::GetInstance()->display_task_runner()->PostTask( |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 46 | FROM_HERE, |
| 47 | base::Bind(&ChromotingJniInstance::Cleanup, this)); |
| 48 | return; |
| 49 | } |
| 50 | |
Ben Murdoch | 9ab5563 | 2013-07-18 11:57:30 +0100 | [diff] [blame^] | 51 | // This must be destroyed on the display thread before the producer is gone. |
| 52 | view_.reset(); |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 53 | |
Ben Murdoch | 9ab5563 | 2013-07-18 11:57:30 +0100 | [diff] [blame^] | 54 | // 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 Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 60 | } |
| 61 | |
| 62 | void 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 Murdoch | 9ab5563 | 2013-07-18 11:57:30 +0100 | [diff] [blame^] | 73 | void 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 Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 86 | void 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 | |
| 104 | void ChromotingJniInstance::OnConnectionReady(bool ready) { |
| 105 | // We ignore this message, since OnConnectionState() tells us the same thing. |
| 106 | } |
| 107 | |
| 108 | void ChromotingJniInstance::SetCapabilities(const std::string& capabilities) {} |
| 109 | |
| 110 | void ChromotingJniInstance::SetPairingResponse( |
| 111 | const protocol::PairingResponse& response) { |
| 112 | NOTIMPLEMENTED(); |
| 113 | } |
| 114 | |
| 115 | protocol::ClipboardStub* ChromotingJniInstance::GetClipboardStub() { |
| 116 | NOTIMPLEMENTED(); |
| 117 | return NULL; |
| 118 | } |
| 119 | |
| 120 | protocol::CursorShapeStub* ChromotingJniInstance::GetCursorShapeStub() { |
| 121 | NOTIMPLEMENTED(); |
| 122 | return NULL; |
| 123 | } |
| 124 | |
| 125 | scoped_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 | |
| 131 | void ChromotingJniInstance::ConnectToHostOnDisplayThread() { |
| 132 | DCHECK(ChromotingJni::GetInstance()-> |
| 133 | display_task_runner()->BelongsToCurrentThread()); |
| 134 | |
Ben Murdoch | 9ab5563 | 2013-07-18 11:57:30 +0100 | [diff] [blame^] | 135 | 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 Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 141 | |
| 142 | ChromotingJni::GetInstance()->network_task_runner()->PostTask( |
| 143 | FROM_HERE, |
| 144 | base::Bind(&ChromotingJniInstance::ConnectToHostOnNetworkThread, |
| 145 | this)); |
| 146 | } |
| 147 | |
| 148 | void 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 Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 161 | 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 Murdoch | 9ab5563 | 2013-07-18 11:57:30 +0100 | [diff] [blame^] | 179 | view_->set_frame_producer(client_->GetFrameProducer()); |
| 180 | |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 181 | 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 Murdoch | 9ab5563 | 2013-07-18 11:57:30 +0100 | [diff] [blame^] | 190 | "oauth2", |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 191 | *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 Murdoch | 9ab5563 | 2013-07-18 11:57:30 +0100 | [diff] [blame^] | 203 | void 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 Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 218 | void 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 |