diff options
author | solb@chromium.org <solb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-12 03:10:31 +0000 |
---|---|---|
committer | solb@chromium.org <solb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-12 03:10:31 +0000 |
commit | 00614e8470539b58c7be16edd1456f84a406398d (patch) | |
tree | 690cff5fcf9de9552f63e2cbf2b2114ea81eca7f /remoting | |
parent | c56ab902b31a85347910c5f975508862832a57d5 (diff) | |
download | chromium_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.cc | 210 | ||||
-rw-r--r-- | remoting/client/jni/chromoting_jni_instance.h | 41 | ||||
-rw-r--r-- | remoting/client/jni/jni_interface.cc | 6 |
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" |