summaryrefslogtreecommitdiffstats
path: root/remoting
diff options
context:
space:
mode:
authorsolb@chromium.org <solb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-12 03:10:31 +0000
committersolb@chromium.org <solb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-12 03:10:31 +0000
commit00614e8470539b58c7be16edd1456f84a406398d (patch)
tree690cff5fcf9de9552f63e2cbf2b2114ea81eca7f /remoting
parentc56ab902b31a85347910c5f975508862832a57d5 (diff)
downloadchromium_src-00614e8470539b58c7be16edd1456f84a406398d.zip
chromium_src-00614e8470539b58c7be16edd1456f84a406398d.tar.gz
chromium_src-00614e8470539b58c7be16edd1456f84a406398d.tar.bz2
Construct ChromotingClient instance
And even provide incoming and outgoing JNI calls to handle PIN authentication! Review URL: https://chromiumcodereview.appspot.com/18477010 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@211302 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting')
-rw-r--r--remoting/client/jni/chromoting_jni_instance.cc210
-rw-r--r--remoting/client/jni/chromoting_jni_instance.h41
-rw-r--r--remoting/client/jni/jni_interface.cc6
3 files changed, 220 insertions, 37 deletions
diff --git a/remoting/client/jni/chromoting_jni_instance.cc b/remoting/client/jni/chromoting_jni_instance.cc
index 99743a6..ba68da8 100644
--- a/remoting/client/jni/chromoting_jni_instance.cc
+++ b/remoting/client/jni/chromoting_jni_instance.cc
@@ -12,14 +12,54 @@
#include "base/memory/singleton.h"
#include "net/android/net_jni_registrar.h"
#include "remoting/base/url_request_context.h"
+#include "remoting/client/audio_player.h"
+#include "remoting/protocol/libjingle_transport_factory.h"
namespace remoting {
+// static
ChromotingJNIInstance* ChromotingJNIInstance::GetInstance() {
return Singleton<ChromotingJNIInstance>::get();
}
-// For now, this just gives us access to the strings supplied from Java.
+ChromotingJNIInstance::ChromotingJNIInstance()
+ : username_cstr_(NULL),
+ auth_token_cstr_(NULL),
+ host_jid_cstr_(NULL),
+ host_id_cstr_(NULL),
+ host_pubkey_cstr_(NULL),
+ pin_cstr_(NULL) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+
+ collector_.reset(new base::AtExitManager());
+ base::android::RegisterJni(env);
+ net::android::RegisterJni(env);
+
+ LOG(INFO) << "starting main message loop";
+ ui_loop_.reset(new base::MessageLoopForUI());
+ ui_loop_->Start();
+
+ LOG(INFO) << "spawning additional threads";
+ ui_runner_ = new AutoThreadTaskRunner(ui_loop_->message_loop_proxy(),
+ base::MessageLoop::QuitClosure());
+ net_runner_ = AutoThread::CreateWithType("native_net",
+ ui_runner_,
+ base::MessageLoop::TYPE_IO);
+ disp_runner_ = AutoThread::CreateWithType("native_disp",
+ ui_runner_,
+ base::MessageLoop::TYPE_DEFAULT);
+
+ url_requester_ = new URLRequestContextGetter(ui_runner_, net_runner_);
+
+ class_ = static_cast<jclass>(env->NewGlobalRef(env->FindClass(JAVA_CLASS)));
+}
+
+ChromotingJNIInstance::~ChromotingJNIInstance() {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ env->DeleteGlobalRef(class_);
+ // TODO(solb) detach all threads from JVM
+}
+
void ChromotingJNIInstance::ConnectToHost(jstring username,
jstring auth_token,
jstring host_jid,
@@ -39,10 +79,12 @@ void ChromotingJNIInstance::ConnectToHost(jstring username,
host_id_cstr_ = env->GetStringUTFChars(host_id_jstr_, NULL);
host_pubkey_cstr_ = env->GetStringUTFChars(host_pubkey_jstr_, NULL);
- // TODO(solb) Initiate connection from here.
+ // We're a singleton, so Unretained is safe here.
+ disp_runner_->PostTask(FROM_HERE, base::Bind(
+ &ChromotingJNIInstance::ConnectToHostOnDisplayThread,
+ base::Unretained(this)));
}
-// For the moment, this only releases the Java string references.
void ChromotingJNIInstance::DisconnectFromHost() {
JNIEnv* env = base::android::AttachCurrentThread();
@@ -63,13 +105,74 @@ void ChromotingJNIInstance::DisconnectFromHost() {
env->DeleteGlobalRef(host_jid_jstr_);
env->DeleteGlobalRef(host_id_jstr_);
env->DeleteGlobalRef(host_pubkey_jstr_);
+
+ if (pin_cstr_) {
+ // AuthenticatedWithPin() has been called.
+ env->ReleaseStringUTFChars(pin_jstr_, pin_cstr_);
+ pin_cstr_ = NULL;
+ env->DeleteGlobalRef(pin_jstr_);
+ }
+
+ // We're a singleton, so Unretained is safe here.
+ net_runner_->PostTask(FROM_HERE, base::Bind(
+ &ChromotingJNIInstance::DisconnectFromHostOnNetworkThread,
+ base::Unretained(this)));
+}
+
+void ChromotingJNIInstance::AuthenticateWithPin(jstring pin) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+
+ pin_jstr_ = static_cast<jstring>(env->NewGlobalRef(pin));
+ pin_cstr_ = env->GetStringUTFChars(pin_jstr_, NULL);
+
+ net_runner_->PostTask(FROM_HERE, base::Bind(announce_secret_, pin_cstr_));
+}
+
+void ChromotingJNIInstance::FetchSecret(
+ bool pairable,
+ const protocol::SecretFetchedCallback& callback_encore) {
+ // All our work must be done on the UI thread.
+ if (!ui_runner_->BelongsToCurrentThread()) {
+ // We're a singleton, so Unretained is safe here.
+ ui_runner_->PostTask(FROM_HERE, base::Bind(
+ &ChromotingJNIInstance::FetchSecret,
+ base::Unretained(this),
+ pairable,
+ callback_encore));
+ return;
+ }
+
+ announce_secret_ = callback_encore;
+ JNIEnv* env = base::android::AttachCurrentThread();
+ env->CallStaticVoidMethod(
+ class_,
+ env->GetStaticMethodID(class_, "displayAuthenticationPrompt", "()V"));
}
void ChromotingJNIInstance::OnConnectionState(
protocol::ConnectionToHost::State state,
- protocol::ErrorCode error) {}
+ protocol::ErrorCode error) {
+ // All our work must be done on the UI thread.
+ if (!ui_runner_->BelongsToCurrentThread()) {
+ // We're a singleton, so Unretained is safe here.
+ ui_runner_->PostTask(FROM_HERE, base::Bind(
+ &ChromotingJNIInstance::OnConnectionState,
+ base::Unretained(this),
+ state,
+ error));
+ return;
+ }
+
+ JNIEnv* env = base::android::AttachCurrentThread();
+ env->CallStaticVoidMethod(
+ class_,
+ env->GetStaticMethodID(class_, "reportConnectionStatus", "(II)V"),
+ state,
+ error);
+}
-void ChromotingJNIInstance::OnConnectionReady(bool ready) {}
+void ChromotingJNIInstance::OnConnectionReady(bool ready) {
+}
void ChromotingJNIInstance::SetCapabilities(const std::string& capabilities) {}
@@ -95,43 +198,80 @@ scoped_ptr<protocol::ThirdPartyClientAuthenticator::TokenFetcher>
return scoped_ptr<protocol::ThirdPartyClientAuthenticator::TokenFetcher>();
}
-// This currently only spins up the threads.
-ChromotingJNIInstance::ChromotingJNIInstance()
- : username_cstr_(NULL),
- auth_token_cstr_(NULL),
- host_jid_cstr_(NULL),
- host_id_cstr_(NULL),
- host_pubkey_cstr_(NULL),
- pin_cstr_(NULL) {
- JNIEnv* env = base::android::AttachCurrentThread();
+void ChromotingJNIInstance::ConnectToHostOnDisplayThread() {
+ DCHECK(disp_runner_->BelongsToCurrentThread());
- collector_.reset(new base::AtExitManager());
- base::android::RegisterJni(env);
- net::android::RegisterJni(env);
+ if (!frames_.get()) {
+ frames_ = new FrameConsumerProxy(disp_runner_);
+ // TODO(solb) Instantiate some FrameConsumer implementation and attach it.
+ }
- LOG(INFO) << "starting main message loop";
- ui_loop_.reset(new base::MessageLoopForUI());
- ui_loop_->Start();
+ // We're a singleton, so Unretained is safe here.
+ net_runner_->PostTask(FROM_HERE, base::Bind(
+ &ChromotingJNIInstance::ConnectToHostOnNetworkThread,
+ base::Unretained(this)));
+}
- LOG(INFO) << "spawning additional threads";
- ui_runner_ = new AutoThreadTaskRunner(ui_loop_->message_loop_proxy(),
- base::MessageLoop::QuitClosure());
- net_runner_ = AutoThread::CreateWithType("native_net",
- ui_runner_,
- base::MessageLoop::TYPE_IO);
- disp_runner_ = AutoThread::CreateWithType("native_disp",
- ui_runner_,
- base::MessageLoop::TYPE_DEFAULT);
+void ChromotingJNIInstance::ConnectToHostOnNetworkThread() {
+ DCHECK(net_runner_->BelongsToCurrentThread());
- url_requester_ = new URLRequestContextGetter(ui_runner_, net_runner_);
+ client_config_.reset(new ClientConfig());
+ client_config_->host_jid = host_jid_cstr_;
+ client_config_->host_public_key = host_pubkey_cstr_;
+ // We're a singleton, so Unretained is safe here.
+ client_config_->fetch_secret_callback = base::Bind(
+ &ChromotingJNIInstance::FetchSecret,
+ base::Unretained(this));
+ client_config_->authentication_tag = host_id_cstr_;
- class_ = static_cast<jclass>(env->NewGlobalRef(env->FindClass(JAVA_CLASS)));
+ // TODO(solb) Move these hardcoded values elsewhere:
+ client_config_->authentication_methods.push_back(
+ protocol::AuthenticationMethod::FromString("spake2_pair"));
+ client_config_->authentication_methods.push_back(
+ protocol::AuthenticationMethod::FromString("spake2_hmac"));
+ client_config_->authentication_methods.push_back(
+ protocol::AuthenticationMethod::FromString("spake2_plain"));
+
+ client_context_.reset(new ClientContext(net_runner_.get()));
+ client_context_->Start();
+
+ connection_.reset(new protocol::ConnectionToHost(true));
+
+ client_.reset(new ChromotingClient(*client_config_,
+ client_context_.get(),
+ connection_.get(),
+ this,
+ frames_,
+ scoped_ptr<AudioPlayer>()));
+
+ chat_config_.reset(new XmppSignalStrategy::XmppServerConfig());
+ chat_config_->host = CHAT_SERVER;
+ chat_config_->port = CHAT_PORT;
+ chat_config_->use_tls = CHAT_USE_TLS;
+
+ chat_.reset(new XmppSignalStrategy(url_requester_,
+ username_cstr_,
+ auth_token_cstr_,
+ CHAT_AUTH_METHOD,
+ *chat_config_));
+
+ netset_.reset(new NetworkSettings(NetworkSettings::NAT_TRAVERSAL_OUTGOING));
+ scoped_ptr<protocol::TransportFactory> fact(
+ protocol::LibjingleTransportFactory::Create(*netset_, url_requester_));
+
+ client_->Start(chat_.get(), fact.Pass());
}
-ChromotingJNIInstance::~ChromotingJNIInstance() {
- JNIEnv* env = base::android::AttachCurrentThread();
- env->DeleteGlobalRef(class_);
- // TODO(solb) detach all threads from JVM
+void ChromotingJNIInstance::DisconnectFromHostOnNetworkThread() {
+ DCHECK(net_runner_->BelongsToCurrentThread());
+
+ client_.reset();
+ connection_.reset();
+ client_context_.reset();
+ client_config_.reset();
+ chat_.reset(); // This object must outlive client_.
+ chat_config_.reset(); // TODO(solb) Restructure to reuse between sessions.
+ netset_.reset();
}
} // namespace remoting
diff --git a/remoting/client/jni/chromoting_jni_instance.h b/remoting/client/jni/chromoting_jni_instance.h
index 7326b4f..75ef56b 100644
--- a/remoting/client/jni/chromoting_jni_instance.h
+++ b/remoting/client/jni/chromoting_jni_instance.h
@@ -14,14 +14,27 @@
#include "base/message_loop/message_loop.h"
#include "net/url_request/url_request_context_getter.h"
#include "remoting/base/auto_thread.h"
+#include "remoting/client/chromoting_client.h"
+#include "remoting/client/client_config.h"
+#include "remoting/client/client_context.h"
#include "remoting/client/client_user_interface.h"
+#include "remoting/client/frame_consumer_proxy.h"
+#include "remoting/jingle_glue/network_settings.h"
+#include "remoting/jingle_glue/xmpp_signal_strategy.h"
+#include "remoting/protocol/connection_to_host.h"
template<typename T> struct DefaultSingletonTraits;
+namespace remoting {
+
// Class and package name of the Java class supporting the methods we call.
-const char* const JAVA_CLASS="org/chromium/chromoting/jni/JNIInterface";
+const char* const JAVA_CLASS = "org/chromium/chromoting/jni/JNIInterface";
-namespace remoting {
+// TODO(solb) Move into location shared with client plugin.
+const char* const CHAT_SERVER = "talk.google.com";
+const int CHAT_PORT = 5222;
+const bool CHAT_USE_TLS = true;
+const char* const CHAT_AUTH_METHOD = "oauth2";
// ClientUserInterface that makes and (indirectly) receives JNI calls.
class ChromotingJNIInstance : public ClientUserInterface {
@@ -39,6 +52,14 @@ class ChromotingJNIInstance : public ClientUserInterface {
// Call from UI thread.
void DisconnectFromHost();
+ // Call from UI thread.
+ void AuthenticateWithPin(jstring pin);
+
+ // Called by client authenticator.
+ // Gets notified if the user needs to enter a PIN, and notifies Java in turn.
+ void FetchSecret(bool pairable,
+ const protocol::SecretFetchedCallback& callback_encore);
+
// ClientUserInterface implementation:
virtual void OnConnectionState(
protocol::ConnectionToHost::State state,
@@ -56,6 +77,11 @@ class ChromotingJNIInstance : public ClientUserInterface {
ChromotingJNIInstance();
virtual ~ChromotingJNIInstance();
+ void ConnectToHostOnDisplayThread();
+ void ConnectToHostOnNetworkThread();
+
+ void DisconnectFromHostOnNetworkThread();
+
// Reusable between sessions:
jclass class_; // Reference to the Java class into which we make JNI calls.
scoped_ptr<base::AtExitManager> collector_;
@@ -64,6 +90,17 @@ class ChromotingJNIInstance : public ClientUserInterface {
scoped_refptr<AutoThreadTaskRunner> net_runner_;
scoped_refptr<AutoThreadTaskRunner> disp_runner_;
scoped_refptr<net::URLRequestContextGetter> url_requester_;
+ scoped_refptr<FrameConsumerProxy> frames_;
+
+ // Specific to each session:
+ scoped_ptr<ClientConfig> client_config_;
+ scoped_ptr<ClientContext> client_context_;
+ scoped_ptr<protocol::ConnectionToHost> connection_;
+ scoped_ptr<ChromotingClient> client_;
+ scoped_ptr<XmppSignalStrategy::XmppServerConfig> chat_config_;
+ scoped_ptr<XmppSignalStrategy> chat_; // must outlive client_
+ scoped_ptr<NetworkSettings> netset_;
+ protocol::SecretFetchedCallback announce_secret_;
// Java string handles:
jstring username_jstr_;
diff --git a/remoting/client/jni/jni_interface.cc b/remoting/client/jni/jni_interface.cc
index 22b7f02..205b05b 100644
--- a/remoting/client/jni/jni_interface.cc
+++ b/remoting/client/jni/jni_interface.cc
@@ -79,4 +79,10 @@ JNIEXPORT void JNICALL JNI_IMPLEMENTATION(disconnectNative)(JNIEnv* env,
remoting::ChromotingJNIInstance::GetInstance()->DisconnectFromHost();
}
+JNIEXPORT void JNICALL JNI_IMPLEMENTATION(authenticationResponse)(JNIEnv* env,
+ jobject that,
+ jstring pin) {
+ remoting::ChromotingJNIInstance::GetInstance()->AuthenticateWithPin(pin);
+}
+
} // extern "C"