diff options
Diffstat (limited to 'widget/android/AndroidJNIWrapper.cpp')
-rw-r--r-- | widget/android/AndroidJNIWrapper.cpp | 140 |
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(); + } +} |