summaryrefslogtreecommitdiff
path: root/widget/android/AndroidJNIWrapper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'widget/android/AndroidJNIWrapper.cpp')
-rw-r--r--widget/android/AndroidJNIWrapper.cpp140
1 files changed, 140 insertions, 0 deletions
diff --git a/widget/android/AndroidJNIWrapper.cpp b/widget/android/AndroidJNIWrapper.cpp
new file mode 100644
index 0000000000..e549c6fc7c
--- /dev/null
+++ b/widget/android/AndroidJNIWrapper.cpp
@@ -0,0 +1,140 @@
+/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include <android/log.h>
+#include <dlfcn.h>
+#include <prthread.h>
+
+#include "mozilla/DebugOnly.h"
+#include "mozilla/Assertions.h"
+#include "mozilla/SyncRunnable.h"
+#include "nsThreadUtils.h"
+#include "AndroidBridge.h"
+
+extern "C" {
+ jclass __jsjni_GetGlobalClassRef(const char *className);
+}
+
+class GetGlobalClassRefRunnable : public mozilla::Runnable {
+ public:
+ GetGlobalClassRefRunnable(const char *className, jclass *foundClass) :
+ mClassName(className), mResult(foundClass) {}
+ NS_IMETHOD Run() override {
+ *mResult = __jsjni_GetGlobalClassRef(mClassName);
+ return NS_OK;
+ }
+ private:
+ const char *mClassName;
+ jclass *mResult;
+};
+
+extern "C" {
+ __attribute__ ((visibility("default")))
+ jclass
+ jsjni_FindClass(const char *className) {
+ // FindClass outside the main thread will run into problems due
+ // to missing the classpath
+ MOZ_ASSERT(NS_IsMainThread());
+ JNIEnv *env = mozilla::jni::GetGeckoThreadEnv();
+ return env->FindClass(className);
+ }
+
+ jclass
+ __jsjni_GetGlobalClassRef(const char *className) {
+ // root class globally
+ JNIEnv *env = mozilla::jni::GetGeckoThreadEnv();
+ jclass globalRef = static_cast<jclass>(env->NewGlobalRef(env->FindClass(className)));
+ if (!globalRef)
+ return nullptr;
+
+ // return the newly create global reference
+ return globalRef;
+ }
+
+ __attribute__ ((visibility("default")))
+ jclass
+ jsjni_GetGlobalClassRef(const char *className) {
+ if (NS_IsMainThread()) {
+ return __jsjni_GetGlobalClassRef(className);
+ }
+
+ nsCOMPtr<nsIThread> mainThread;
+ mozilla::DebugOnly<nsresult> rv = NS_GetMainThread(getter_AddRefs(mainThread));
+ MOZ_ASSERT(NS_SUCCEEDED(rv));
+
+ jclass foundClass;
+ nsCOMPtr<nsIRunnable> runnable_ref(new GetGlobalClassRefRunnable(className,
+ &foundClass));
+ RefPtr<mozilla::SyncRunnable> sr = new mozilla::SyncRunnable(runnable_ref);
+ sr->DispatchToThread(mainThread);
+ if (!foundClass)
+ return nullptr;
+
+ return foundClass;
+ }
+
+ __attribute__ ((visibility("default")))
+ jmethodID
+ jsjni_GetStaticMethodID(jclass methodClass,
+ const char *methodName,
+ const char *signature) {
+ JNIEnv *env = mozilla::jni::GetGeckoThreadEnv();
+ return env->GetStaticMethodID(methodClass, methodName, signature);
+ }
+
+ __attribute__ ((visibility("default")))
+ bool
+ jsjni_ExceptionCheck() {
+ JNIEnv *env = mozilla::jni::GetGeckoThreadEnv();
+ return env->ExceptionCheck();
+ }
+
+ __attribute__ ((visibility("default")))
+ void
+ jsjni_CallStaticVoidMethodA(jclass cls,
+ jmethodID method,
+ jvalue *values) {
+ JNIEnv *env = mozilla::jni::GetGeckoThreadEnv();
+
+ mozilla::AutoLocalJNIFrame jniFrame(env);
+ env->CallStaticVoidMethodA(cls, method, values);
+ }
+
+ __attribute__ ((visibility("default")))
+ int
+ jsjni_CallStaticIntMethodA(jclass cls,
+ jmethodID method,
+ jvalue *values) {
+ JNIEnv *env = mozilla::jni::GetGeckoThreadEnv();
+
+ mozilla::AutoLocalJNIFrame jniFrame(env);
+ return env->CallStaticIntMethodA(cls, method, values);
+ }
+
+ __attribute__ ((visibility("default")))
+ jobject jsjni_GetGlobalContextRef() {
+ return mozilla::AndroidBridge::Bridge()->GetGlobalContextRef();
+ }
+
+ __attribute__ ((visibility("default")))
+ JavaVM* jsjni_GetVM() {
+ JavaVM* jvm;
+ JNIEnv* const env = mozilla::jni::GetGeckoThreadEnv();
+ MOZ_ALWAYS_TRUE(!env->GetJavaVM(&jvm));
+ return jvm;
+ }
+
+ __attribute__ ((visibility("default")))
+ JNIEnv* jsjni_GetJNIForThread() {
+ return mozilla::jni::GetEnvForThread();
+ }
+
+ // For compatibility with JNI.jsm; some addons bundle their own JNI.jsm,
+ // so we cannot just change the function name used in JNI.jsm.
+ __attribute__ ((visibility("default")))
+ JNIEnv* GetJNIForThread() {
+ return mozilla::jni::GetEnvForThread();
+ }
+}