summaryrefslogtreecommitdiffstats
path: root/widget/android/jni/Utils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'widget/android/jni/Utils.cpp')
-rw-r--r--widget/android/jni/Utils.cpp291
1 files changed, 0 insertions, 291 deletions
diff --git a/widget/android/jni/Utils.cpp b/widget/android/jni/Utils.cpp
deleted file mode 100644
index 919588851..000000000
--- a/widget/android/jni/Utils.cpp
+++ /dev/null
@@ -1,291 +0,0 @@
-#include "Utils.h"
-#include "Types.h"
-
-#include <android/log.h>
-#include <pthread.h>
-
-#include "mozilla/Assertions.h"
-
-#include "GeneratedJNIWrappers.h"
-#include "nsAppShell.h"
-
-namespace mozilla {
-namespace jni {
-
-namespace detail {
-
-#define DEFINE_PRIMITIVE_TYPE_ADAPTER(NativeType, JNIType, JNIName, ABIName) \
- \
- constexpr JNIType (JNIEnv::*TypeAdapter<NativeType>::Call) \
- (jobject, jmethodID, jvalue*) MOZ_JNICALL_ABI; \
- constexpr JNIType (JNIEnv::*TypeAdapter<NativeType>::StaticCall) \
- (jclass, jmethodID, jvalue*) MOZ_JNICALL_ABI; \
- constexpr JNIType (JNIEnv::*TypeAdapter<NativeType>::Get) \
- (jobject, jfieldID) ABIName; \
- constexpr JNIType (JNIEnv::*TypeAdapter<NativeType>::StaticGet) \
- (jclass, jfieldID) ABIName; \
- constexpr void (JNIEnv::*TypeAdapter<NativeType>::Set) \
- (jobject, jfieldID, JNIType) ABIName; \
- constexpr void (JNIEnv::*TypeAdapter<NativeType>::StaticSet) \
- (jclass, jfieldID, JNIType) ABIName; \
- constexpr void (JNIEnv::*TypeAdapter<NativeType>::GetArray) \
- (JNIType ## Array, jsize, jsize, JNIType*)
-
-DEFINE_PRIMITIVE_TYPE_ADAPTER(bool, jboolean, Boolean, /*nothing*/);
-DEFINE_PRIMITIVE_TYPE_ADAPTER(int8_t, jbyte, Byte, /*nothing*/);
-DEFINE_PRIMITIVE_TYPE_ADAPTER(char16_t, jchar, Char, /*nothing*/);
-DEFINE_PRIMITIVE_TYPE_ADAPTER(int16_t, jshort, Short, /*nothing*/);
-DEFINE_PRIMITIVE_TYPE_ADAPTER(int32_t, jint, Int, /*nothing*/);
-DEFINE_PRIMITIVE_TYPE_ADAPTER(int64_t, jlong, Long, /*nothing*/);
-DEFINE_PRIMITIVE_TYPE_ADAPTER(float, jfloat, Float, MOZ_JNICALL_ABI);
-DEFINE_PRIMITIVE_TYPE_ADAPTER(double, jdouble, Double, MOZ_JNICALL_ABI);
-
-#undef DEFINE_PRIMITIVE_TYPE_ADAPTER
-
-} // namespace detail
-
-template<> const char ObjectBase<Object, jobject>::name[] = "java/lang/Object";
-template<> const char ObjectBase<TypedObject<jstring>, jstring>::name[] = "java/lang/String";
-template<> const char ObjectBase<TypedObject<jclass>, jclass>::name[] = "java/lang/Class";
-template<> const char ObjectBase<TypedObject<jthrowable>, jthrowable>::name[] = "java/lang/Throwable";
-template<> const char ObjectBase<TypedObject<jbooleanArray>, jbooleanArray>::name[] = "[Z";
-template<> const char ObjectBase<TypedObject<jbyteArray>, jbyteArray>::name[] = "[B";
-template<> const char ObjectBase<TypedObject<jcharArray>, jcharArray>::name[] = "[C";
-template<> const char ObjectBase<TypedObject<jshortArray>, jshortArray>::name[] = "[S";
-template<> const char ObjectBase<TypedObject<jintArray>, jintArray>::name[] = "[I";
-template<> const char ObjectBase<TypedObject<jlongArray>, jlongArray>::name[] = "[J";
-template<> const char ObjectBase<TypedObject<jfloatArray>, jfloatArray>::name[] = "[F";
-template<> const char ObjectBase<TypedObject<jdoubleArray>, jdoubleArray>::name[] = "[D";
-template<> const char ObjectBase<TypedObject<jobjectArray>, jobjectArray>::name[] = "[Ljava/lang/Object;";
-template<> const char ObjectBase<ByteBuffer, jobject>::name[] = "java/nio/ByteBuffer";
-
-
-JNIEnv* sGeckoThreadEnv;
-
-namespace {
-
-JavaVM* sJavaVM;
-pthread_key_t sThreadEnvKey;
-jclass sOOMErrorClass;
-jobject sClassLoader;
-jmethodID sClassLoaderLoadClass;
-bool sIsFennec;
-
-void UnregisterThreadEnv(void* env)
-{
- if (!env) {
- // We were never attached.
- return;
- }
- // The thread may have already been detached. In that case, it's still
- // okay to call DetachCurrentThread(); it'll simply return an error.
- // However, we must not access | env | because it may be invalid.
- MOZ_ASSERT(sJavaVM);
- sJavaVM->DetachCurrentThread();
-}
-
-} // namespace
-
-void SetGeckoThreadEnv(JNIEnv* aEnv)
-{
- MOZ_ASSERT(aEnv);
- MOZ_ASSERT(!sGeckoThreadEnv || sGeckoThreadEnv == aEnv);
-
- if (!sGeckoThreadEnv
- && pthread_key_create(&sThreadEnvKey, UnregisterThreadEnv)) {
- MOZ_CRASH("Failed to initialize required TLS");
- }
-
- sGeckoThreadEnv = aEnv;
- MOZ_ALWAYS_TRUE(!pthread_setspecific(sThreadEnvKey, aEnv));
-
- MOZ_ALWAYS_TRUE(!aEnv->GetJavaVM(&sJavaVM));
- MOZ_ASSERT(sJavaVM);
-
- sOOMErrorClass = Class::GlobalRef(Class::LocalRef::Adopt(
- aEnv->FindClass("java/lang/OutOfMemoryError"))).Forget();
- aEnv->ExceptionClear();
-
- sClassLoader = Object::GlobalRef(java::GeckoThread::ClsLoader()).Forget();
- sClassLoaderLoadClass = aEnv->GetMethodID(
- Class::LocalRef::Adopt(aEnv->GetObjectClass(sClassLoader)).Get(),
- "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
- MOZ_ASSERT(sClassLoader && sClassLoaderLoadClass);
-
- auto geckoAppClass = Class::LocalRef::Adopt(
- aEnv->FindClass("org/mozilla/gecko/GeckoApp"));
- aEnv->ExceptionClear();
- sIsFennec = !!geckoAppClass;
-}
-
-JNIEnv* GetEnvForThread()
-{
- MOZ_ASSERT(sGeckoThreadEnv);
-
- JNIEnv* env = static_cast<JNIEnv*>(pthread_getspecific(sThreadEnvKey));
- if (env) {
- return env;
- }
-
- // We don't have a saved JNIEnv, so try to get one.
- // AttachCurrentThread() does the same thing as GetEnv() when a thread is
- // already attached, so we don't have to call GetEnv() at all.
- if (!sJavaVM->AttachCurrentThread(&env, nullptr)) {
- MOZ_ASSERT(env);
- MOZ_ALWAYS_TRUE(!pthread_setspecific(sThreadEnvKey, env));
- return env;
- }
-
- MOZ_CRASH("Failed to get JNIEnv for thread");
- return nullptr; // unreachable
-}
-
-bool ThrowException(JNIEnv *aEnv, const char *aClass,
- const char *aMessage)
-{
- MOZ_ASSERT(aEnv, "Invalid thread JNI env");
-
- Class::LocalRef cls = Class::LocalRef::Adopt(aEnv->FindClass(aClass));
- MOZ_ASSERT(cls, "Cannot find exception class");
-
- return !aEnv->ThrowNew(cls.Get(), aMessage);
-}
-
-bool HandleUncaughtException(JNIEnv* aEnv)
-{
- MOZ_ASSERT(aEnv, "Invalid thread JNI env");
-
- if (!aEnv->ExceptionCheck()) {
- return false;
- }
-
-#ifdef MOZ_CHECK_JNI
- aEnv->ExceptionDescribe();
-#endif
-
- Throwable::LocalRef e =
- Throwable::LocalRef::Adopt(aEnv, aEnv->ExceptionOccurred());
- MOZ_ASSERT(e);
- aEnv->ExceptionClear();
-
- String::LocalRef stack = java::GeckoAppShell::GetExceptionStackTrace(e);
- if (stack && ReportException(aEnv, e.Get(), stack.Get())) {
- return true;
- }
-
- aEnv->ExceptionClear();
- java::GeckoAppShell::HandleUncaughtException(e);
-
- if (NS_WARN_IF(aEnv->ExceptionCheck())) {
- aEnv->ExceptionDescribe();
- aEnv->ExceptionClear();
- }
-
- return true;
-}
-
-bool ReportException(JNIEnv* aEnv, jthrowable aExc, jstring aStack)
-{
- bool result = true;
-
- if (sOOMErrorClass && aEnv->IsInstanceOf(aExc, sOOMErrorClass)) {
- NS_ABORT_OOM(0); // Unknown OOM size
- }
- return result;
-}
-
-namespace {
-
-jclass sJNIObjectClass;
-jfieldID sJNIObjectHandleField;
-
-bool EnsureJNIObject(JNIEnv* env, jobject instance) {
- if (!sJNIObjectClass) {
- sJNIObjectClass = Class::GlobalRef(Class::LocalRef::Adopt(GetClassRef(
- env, "org/mozilla/gecko/mozglue/JNIObject"))).Forget();
-
- sJNIObjectHandleField = env->GetFieldID(
- sJNIObjectClass, "mHandle", "J");
- }
-
- MOZ_ASSERT(env->IsInstanceOf(instance, sJNIObjectClass));
- return true;
-}
-
-} // namespace
-
-uintptr_t GetNativeHandle(JNIEnv* env, jobject instance)
-{
- if (!EnsureJNIObject(env, instance)) {
- return 0;
- }
-
- return static_cast<uintptr_t>(
- env->GetLongField(instance, sJNIObjectHandleField));
-}
-
-void SetNativeHandle(JNIEnv* env, jobject instance, uintptr_t handle)
-{
- if (!EnsureJNIObject(env, instance)) {
- return;
- }
-
- env->SetLongField(instance, sJNIObjectHandleField,
- static_cast<jlong>(handle));
-}
-
-jclass GetClassRef(JNIEnv* aEnv, const char* aClassName)
-{
- // First try the default class loader.
- auto classRef = Class::LocalRef::Adopt(aEnv, aEnv->FindClass(aClassName));
-
- if (!classRef && sClassLoader) {
- // If the default class loader failed but we have an app class loader, try that.
- // Clear the pending exception from failed FindClass call above.
- aEnv->ExceptionClear();
- classRef = Class::LocalRef::Adopt(aEnv, jclass(
- aEnv->CallObjectMethod(sClassLoader, sClassLoaderLoadClass,
- StringParam(aClassName, aEnv).Get())));
- }
-
- if (classRef) {
- return classRef.Forget();
- }
-
- __android_log_print(
- ANDROID_LOG_ERROR, "Gecko",
- ">>> FATAL JNI ERROR! FindClass(className=\"%s\") failed. "
- "Did ProGuard optimize away something it shouldn't have?",
- aClassName);
- aEnv->ExceptionDescribe();
- MOZ_CRASH("Cannot find JNI class");
- return nullptr;
-}
-
-void DispatchToGeckoThread(UniquePtr<AbstractCall>&& aCall)
-{
- class AbstractCallEvent : public nsAppShell::Event
- {
- UniquePtr<AbstractCall> mCall;
-
- public:
- AbstractCallEvent(UniquePtr<AbstractCall>&& aCall)
- : mCall(Move(aCall))
- {}
-
- void Run() override
- {
- (*mCall)();
- }
- };
-
- nsAppShell::PostEvent(MakeUnique<AbstractCallEvent>(Move(aCall)));
-}
-
-bool IsFennec()
-{
- return sIsFennec;
-}
-
-} // jni
-} // mozilla