зеркало из https://github.com/mozilla/gecko-dev.git
148 строки
3.5 KiB
C++
148 строки
3.5 KiB
C++
#ifndef mozilla_jni_Utils_h__
|
|
#define mozilla_jni_Utils_h__
|
|
|
|
#include <jni.h>
|
|
|
|
#include "mozilla/UniquePtr.h"
|
|
|
|
#if defined(DEBUG) || !defined(RELEASE_OR_BETA)
|
|
#define MOZ_CHECK_JNI
|
|
#endif
|
|
|
|
#ifdef MOZ_CHECK_JNI
|
|
#include <pthread.h>
|
|
#include "mozilla/Assertions.h"
|
|
#include "APKOpen.h"
|
|
#include "MainThreadUtils.h"
|
|
#endif
|
|
|
|
namespace mozilla {
|
|
namespace jni {
|
|
|
|
// How exception during a JNI call should be treated.
|
|
enum class ExceptionMode
|
|
{
|
|
// Abort on unhandled excepion (default).
|
|
ABORT,
|
|
// Ignore the exception and return to caller.
|
|
IGNORE,
|
|
// Catch any exception and return a nsresult.
|
|
NSRESULT,
|
|
};
|
|
|
|
// Thread that a particular JNI call is allowed on.
|
|
enum class CallingThread
|
|
{
|
|
// Can be called from any thread (default).
|
|
ANY,
|
|
// Can be called from the Gecko thread.
|
|
GECKO,
|
|
// Can be called from the Java UI thread.
|
|
UI,
|
|
};
|
|
|
|
// If and where a JNI call will be dispatched.
|
|
enum class DispatchTarget
|
|
{
|
|
// Call happens synchronously on the calling thread (default).
|
|
CURRENT,
|
|
// Call happens synchronously on the calling thread, but the call is
|
|
// wrapped in a function object and is passed thru UsesNativeCallProxy.
|
|
// Method must return void.
|
|
PROXY,
|
|
// Call is dispatched asynchronously on the Gecko thread. Method must
|
|
// return void.
|
|
GECKO,
|
|
};
|
|
|
|
|
|
extern JNIEnv* sGeckoThreadEnv;
|
|
|
|
inline bool IsAvailable()
|
|
{
|
|
return !!sGeckoThreadEnv;
|
|
}
|
|
|
|
inline JNIEnv* GetGeckoThreadEnv()
|
|
{
|
|
#ifdef MOZ_CHECK_JNI
|
|
MOZ_RELEASE_ASSERT(NS_IsMainThread(), "Must be on Gecko thread");
|
|
MOZ_RELEASE_ASSERT(sGeckoThreadEnv, "Must have a JNIEnv");
|
|
#endif
|
|
return sGeckoThreadEnv;
|
|
}
|
|
|
|
void SetGeckoThreadEnv(JNIEnv* aEnv);
|
|
|
|
JNIEnv* GetEnvForThread();
|
|
|
|
#ifdef MOZ_CHECK_JNI
|
|
#define MOZ_ASSERT_JNI_THREAD(thread) \
|
|
do { \
|
|
if ((thread) == mozilla::jni::CallingThread::GECKO) { \
|
|
MOZ_RELEASE_ASSERT(::NS_IsMainThread()); \
|
|
} else if ((thread) == mozilla::jni::CallingThread::UI) { \
|
|
const bool isOnUiThread = ::pthread_equal(::pthread_self(), \
|
|
::getJavaUiThread()); \
|
|
MOZ_RELEASE_ASSERT(isOnUiThread); \
|
|
} \
|
|
} while (0)
|
|
#else
|
|
#define MOZ_ASSERT_JNI_THREAD(thread) do {} while (0)
|
|
#endif
|
|
|
|
bool ThrowException(JNIEnv *aEnv, const char *aClass,
|
|
const char *aMessage);
|
|
|
|
inline bool ThrowException(JNIEnv *aEnv, const char *aMessage)
|
|
{
|
|
return ThrowException(aEnv, "java/lang/Exception", aMessage);
|
|
}
|
|
|
|
inline bool ThrowException(const char *aClass, const char *aMessage)
|
|
{
|
|
return ThrowException(GetEnvForThread(), aClass, aMessage);
|
|
}
|
|
|
|
inline bool ThrowException(const char *aMessage)
|
|
{
|
|
return ThrowException(GetEnvForThread(), aMessage);
|
|
}
|
|
|
|
bool HandleUncaughtException(JNIEnv* aEnv);
|
|
|
|
bool ReportException(JNIEnv* aEnv, jthrowable aExc, jstring aStack);
|
|
|
|
#define MOZ_CATCH_JNI_EXCEPTION(env) \
|
|
do { \
|
|
if (mozilla::jni::HandleUncaughtException((env))) { \
|
|
MOZ_CRASH("JNI exception"); \
|
|
} \
|
|
} while (0)
|
|
|
|
|
|
uintptr_t GetNativeHandle(JNIEnv* env, jobject instance);
|
|
|
|
void SetNativeHandle(JNIEnv* env, jobject instance, uintptr_t handle);
|
|
|
|
jclass GetClassRef(JNIEnv* aEnv, const char* aClassName);
|
|
|
|
struct AbstractCall
|
|
{
|
|
virtual ~AbstractCall() {}
|
|
virtual void operator()() = 0;
|
|
};
|
|
|
|
void DispatchToGeckoThread(UniquePtr<AbstractCall>&& aCall);
|
|
|
|
/**
|
|
* Returns whether Gecko is running in a Fennec environment, as determined by
|
|
* the presence of the GeckoApp class.
|
|
*/
|
|
bool IsFennec();
|
|
|
|
} // jni
|
|
} // mozilla
|
|
|
|
#endif // mozilla_jni_Utils_h__
|