summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--build/all_android.gyp1
-rw-r--r--remoting/client/jni/OWNERS3
-rw-r--r--remoting/client/jni/chromoting_jni_instance.cc137
-rw-r--r--remoting/client/jni/chromoting_jni_instance.h91
-rw-r--r--remoting/client/jni/jni_interface.cc57
-rw-r--r--remoting/remoting.gyp20
6 files changed, 309 insertions, 0 deletions
diff --git a/build/all_android.gyp b/build/all_android.gyp
index 79bbcdd..eaac50c8 100644
--- a/build/all_android.gyp
+++ b/build/all_android.gyp
@@ -22,6 +22,7 @@
'android_builder_tests',
'../android_webview/android_webview.gyp:android_webview_apk',
'../chrome/chrome.gyp:chromium_testshell',
+ '../remoting/remoting.gyp:remoting_client_jni',
# TODO(nyquist) This should instead by a target for sync when all of
# the sync-related code for Android has been upstreamed.
# See http://crbug.com/159203
diff --git a/remoting/client/jni/OWNERS b/remoting/client/jni/OWNERS
new file mode 100644
index 0000000..f94f63b
--- /dev/null
+++ b/remoting/client/jni/OWNERS
@@ -0,0 +1,3 @@
+garykac@chromium.org
+solb@chromium.org
+wez@chromium.org
diff --git a/remoting/client/jni/chromoting_jni_instance.cc b/remoting/client/jni/chromoting_jni_instance.cc
new file mode 100644
index 0000000..99743a6
--- /dev/null
+++ b/remoting/client/jni/chromoting_jni_instance.cc
@@ -0,0 +1,137 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "remoting/client/jni/chromoting_jni_instance.h"
+
+#include "base/android/base_jni_registrar.h"
+#include "base/android/jni_android.h"
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/logging.h"
+#include "base/memory/singleton.h"
+#include "net/android/net_jni_registrar.h"
+#include "remoting/base/url_request_context.h"
+
+namespace remoting {
+
+ChromotingJNIInstance* ChromotingJNIInstance::GetInstance() {
+ return Singleton<ChromotingJNIInstance>::get();
+}
+
+// For now, this just gives us access to the strings supplied from Java.
+void ChromotingJNIInstance::ConnectToHost(jstring username,
+ jstring auth_token,
+ jstring host_jid,
+ jstring host_id,
+ jstring host_pubkey) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+
+ username_jstr_ = static_cast<jstring>(env->NewGlobalRef(username));
+ auth_token_jstr_ = static_cast<jstring>(env->NewGlobalRef(auth_token));
+ host_jid_jstr_ = static_cast<jstring>(env->NewGlobalRef(host_jid));
+ host_id_jstr_ = static_cast<jstring>(env->NewGlobalRef(host_id));
+ host_pubkey_jstr_ = static_cast<jstring>(env->NewGlobalRef(host_pubkey));
+
+ username_cstr_ = env->GetStringUTFChars(username_jstr_, NULL);
+ auth_token_cstr_ = env->GetStringUTFChars(auth_token_jstr_, NULL);
+ host_jid_cstr_ = env->GetStringUTFChars(host_jid_jstr_, NULL);
+ host_id_cstr_ = env->GetStringUTFChars(host_id_jstr_, NULL);
+ host_pubkey_cstr_ = env->GetStringUTFChars(host_pubkey_jstr_, NULL);
+
+ // TODO(solb) Initiate connection from here.
+}
+
+// For the moment, this only releases the Java string references.
+void ChromotingJNIInstance::DisconnectFromHost() {
+ JNIEnv* env = base::android::AttachCurrentThread();
+
+ env->ReleaseStringUTFChars(username_jstr_, username_cstr_);
+ env->ReleaseStringUTFChars(auth_token_jstr_, auth_token_cstr_);
+ env->ReleaseStringUTFChars(host_jid_jstr_, host_jid_cstr_);
+ env->ReleaseStringUTFChars(host_id_jstr_, host_id_cstr_);
+ env->ReleaseStringUTFChars(host_pubkey_jstr_, host_pubkey_cstr_);
+
+ username_cstr_ = NULL;
+ auth_token_cstr_ = NULL;
+ host_jid_cstr_ = NULL;
+ host_id_cstr_ = NULL;
+ host_pubkey_cstr_ = NULL;
+
+ env->DeleteGlobalRef(username_jstr_);
+ env->DeleteGlobalRef(auth_token_jstr_);
+ env->DeleteGlobalRef(host_jid_jstr_);
+ env->DeleteGlobalRef(host_id_jstr_);
+ env->DeleteGlobalRef(host_pubkey_jstr_);
+}
+
+void ChromotingJNIInstance::OnConnectionState(
+ protocol::ConnectionToHost::State state,
+ protocol::ErrorCode error) {}
+
+void ChromotingJNIInstance::OnConnectionReady(bool ready) {}
+
+void ChromotingJNIInstance::SetCapabilities(const std::string& capabilities) {}
+
+void ChromotingJNIInstance::SetPairingResponse(
+ const protocol::PairingResponse& response) {}
+
+protocol::ClipboardStub* ChromotingJNIInstance::GetClipboardStub() {
+ NOTIMPLEMENTED();
+ return NULL;
+}
+
+protocol::CursorShapeStub* ChromotingJNIInstance::GetCursorShapeStub() {
+ NOTIMPLEMENTED();
+ return NULL;
+}
+
+// We don't use NOTIMPLEMENTED() here because NegotiatingClientAuthenticator
+// calls this even if it doesn't use the configuration method, and we don't
+// want to print an error on every run.
+scoped_ptr<protocol::ThirdPartyClientAuthenticator::TokenFetcher>
+ ChromotingJNIInstance::GetTokenFetcher(const std::string& host_public_key) {
+ LOG(INFO) << "ChromotingJNIInstance::GetTokenFetcher(...) [unimplemented]";
+ 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();
+
+ 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
+}
+
+} // namespace remoting
diff --git a/remoting/client/jni/chromoting_jni_instance.h b/remoting/client/jni/chromoting_jni_instance.h
new file mode 100644
index 0000000..7326b4f
--- /dev/null
+++ b/remoting/client/jni/chromoting_jni_instance.h
@@ -0,0 +1,91 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef REMOTING_CLIENT_CHROMOTING_JNI_INSTANCE_H_
+#define REMOTING_CLIENT_CHROMOTING_JNI_INSTANCE_H_
+
+#include <jni.h>
+#include <string>
+
+#include "base/at_exit.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#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/client_user_interface.h"
+
+template<typename T> struct DefaultSingletonTraits;
+
+// Class and package name of the Java class supporting the methods we call.
+const char* const JAVA_CLASS="org/chromium/chromoting/jni/JNIInterface";
+
+namespace remoting {
+
+// ClientUserInterface that makes and (indirectly) receives JNI calls.
+class ChromotingJNIInstance : public ClientUserInterface {
+ public:
+ static ChromotingJNIInstance* GetInstance();
+
+ // Call from UI thread.
+ void ConnectToHost(
+ jstring username,
+ jstring auth_token,
+ jstring host_jid,
+ jstring host_id,
+ jstring host_pubkey);
+
+ // Call from UI thread.
+ void DisconnectFromHost();
+
+ // ClientUserInterface implementation:
+ virtual void OnConnectionState(
+ protocol::ConnectionToHost::State state,
+ protocol::ErrorCode error) OVERRIDE;
+ virtual void OnConnectionReady(bool ready) OVERRIDE;
+ virtual void SetCapabilities(const std::string& capabilities) OVERRIDE;
+ virtual void SetPairingResponse(
+ const protocol::PairingResponse& response) OVERRIDE;
+ virtual protocol::ClipboardStub* GetClipboardStub() OVERRIDE;
+ virtual protocol::CursorShapeStub* GetCursorShapeStub() OVERRIDE;
+ virtual scoped_ptr<protocol::ThirdPartyClientAuthenticator::TokenFetcher>
+ GetTokenFetcher(const std::string& host_public_key) OVERRIDE;
+
+ private:
+ ChromotingJNIInstance();
+ virtual ~ChromotingJNIInstance();
+
+ // Reusable between sessions:
+ jclass class_; // Reference to the Java class into which we make JNI calls.
+ scoped_ptr<base::AtExitManager> collector_;
+ scoped_ptr<base::MessageLoopForUI> ui_loop_;
+ scoped_refptr<AutoThreadTaskRunner> ui_runner_;
+ scoped_refptr<AutoThreadTaskRunner> net_runner_;
+ scoped_refptr<AutoThreadTaskRunner> disp_runner_;
+ scoped_refptr<net::URLRequestContextGetter> url_requester_;
+
+ // Java string handles:
+ jstring username_jstr_;
+ jstring auth_token_jstr_;
+ jstring host_jid_jstr_;
+ jstring host_id_jstr_;
+ jstring host_pubkey_jstr_;
+ jstring pin_jstr_;
+
+ // C string pointers:
+ const char* username_cstr_;
+ const char* auth_token_cstr_;
+ const char* host_jid_cstr_;
+ const char* host_id_cstr_;
+ const char* host_pubkey_cstr_;
+ const char* pin_cstr_;
+
+ friend struct DefaultSingletonTraits<ChromotingJNIInstance>;
+
+ DISALLOW_COPY_AND_ASSIGN(ChromotingJNIInstance);
+};
+
+} // namespace remoting
+
+#endif
diff --git a/remoting/client/jni/jni_interface.cc b/remoting/client/jni/jni_interface.cc
new file mode 100644
index 0000000..cb7f6c2
--- /dev/null
+++ b/remoting/client/jni/jni_interface.cc
@@ -0,0 +1,57 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file defines functions that implement the static methods declared in a
+// closely-related Java class in the platform-specific user interface
+// implementation. In effect, it is the entry point for all JNI calls *into*
+// the C++ codebase from Java. The separate ChromotingJNIInstance class serves
+// as the corresponding exit point, and is responsible for making all JNI calls
+// *out of* the C++ codebase into Java.
+
+#include <jni.h>
+
+#include "base/android/jni_android.h"
+#include "base/memory/ref_counted.h"
+#include "remoting/client/jni/chromoting_jni_instance.h"
+
+// Class and package name of the Java class that declares this file's functions.
+#define JNI_IMPLEMENTATION(method) \
+ Java_org_chromium_chromoting_jni_JNIInterface_##method
+
+extern "C" {
+
+JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
+ base::android::InitVM(vm);
+ return JNI_VERSION_1_2;
+}
+
+JNIEXPORT void JNICALL JNI_IMPLEMENTATION(loadNative)(JNIEnv* env,
+ jobject that,
+ jobject context) {
+ base::android::ScopedJavaLocalRef<jobject> context_activity(env, context);
+ base::android::InitApplicationContext(context_activity);
+
+ remoting::ChromotingJNIInstance::GetInstance(); // Initialize threads now.
+}
+
+JNIEXPORT void JNICALL JNI_IMPLEMENTATION(connectNative)(JNIEnv* env,
+ jobject that,
+ jstring username,
+ jstring auth_token,
+ jstring host_jid,
+ jstring host_id,
+ jstring host_pubkey) {
+ remoting::ChromotingJNIInstance::GetInstance()->ConnectToHost(username,
+ auth_token,
+ host_jid,
+ host_id,
+ host_pubkey);
+}
+
+JNIEXPORT void JNICALL JNI_IMPLEMENTATION(disconnectNative)(JNIEnv* env,
+ jobject that) {
+ remoting::ChromotingJNIInstance::GetInstance()->DisconnectFromHost();
+}
+
+} // extern "C"
diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp
index 9885a4b..375f562 100644
--- a/remoting/remoting.gyp
+++ b/remoting/remoting.gyp
@@ -1880,6 +1880,26 @@
], # end of 'targets'
}], # 'OS=="win"'
+ ['OS=="android"', {
+ 'targets': [
+ {
+ 'target_name': 'remoting_client_jni',
+ 'type': 'shared_library',
+ 'dependencies': [
+ 'remoting_base',
+ 'remoting_client',
+ 'remoting_jingle_glue',
+ 'remoting_protocol',
+ ],
+ 'sources': [
+ 'client/jni/chromoting_jni_instance.cc',
+ 'client/jni/chromoting_jni_instance.h',
+ 'client/jni/jni_interface.cc',
+ ],
+ }, # end of target 'remoting_client_jni'
+ ], # end of 'targets'
+ }], # 'OS=="android"'
+
# The host installation is generated only if WiX is available. If
# component build is used the produced installation will not work due to
# missing DLLs. We build it anyway to make sure the GYP scripts are executed