mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1192077 - Move AndroidBridge JNIEnv calls to jni/Utils; r=esawin
Calls like GetJNIForThread should now belong in jni/Utils. Moving the calls also reduce clutter in AndroidBridge.
This commit is contained in:
parent
651217b048
commit
dae9644328
@ -55,10 +55,8 @@ using namespace mozilla::jni;
|
||||
using namespace mozilla::widget;
|
||||
|
||||
AndroidBridge* AndroidBridge::sBridge = nullptr;
|
||||
pthread_t AndroidBridge::sJavaUiThread = -1;
|
||||
static unsigned sJavaEnvThreadIndex = 0;
|
||||
pthread_t AndroidBridge::sJavaUiThread;
|
||||
static jobject sGlobalContext = nullptr;
|
||||
static void JavaThreadDetachFunc(void *arg);
|
||||
|
||||
// This is a dummy class that can be used in the template for android::sp
|
||||
class AndroidRefable {
|
||||
@ -163,8 +161,6 @@ AndroidBridge::ConstructBridge(JNIEnv *jEnv, Object::Param clsLoader, Object::Pa
|
||||
*/
|
||||
putenv("NSS_DISABLE_UNLOAD=1");
|
||||
|
||||
PR_NewThreadPrivateIndex(&sJavaEnvThreadIndex, JavaThreadDetachFunc);
|
||||
|
||||
MOZ_ASSERT(!sBridge);
|
||||
sBridge = new AndroidBridge;
|
||||
sBridge->Init(jEnv, clsLoader); // Success or crash
|
||||
@ -184,10 +180,6 @@ void
|
||||
AndroidBridge::Init(JNIEnv *jEnv, Object::Param clsLoader)
|
||||
{
|
||||
ALOG_BRIDGE("AndroidBridge::Init");
|
||||
jEnv->GetJavaVM(&mJavaVM);
|
||||
if (!mJavaVM) {
|
||||
MOZ_CRASH(); // Nothing we can do here
|
||||
}
|
||||
|
||||
AutoLocalJNIFrame jniFrame(jEnv);
|
||||
|
||||
@ -196,8 +188,6 @@ AndroidBridge::Init(JNIEnv *jEnv, Object::Param clsLoader)
|
||||
jEnv, jEnv->GetObjectClass(clsLoader.Get()),
|
||||
"loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
|
||||
|
||||
mJNIEnv = nullptr;
|
||||
mThread = pthread_t();
|
||||
mGLControllerObj = nullptr;
|
||||
mOpenedGraphicsLibraries = false;
|
||||
mHasNativeBitmapAccess = false;
|
||||
@ -263,14 +253,10 @@ bool
|
||||
AndroidBridge::SetMainThread(pthread_t thr)
|
||||
{
|
||||
ALOG_BRIDGE("AndroidBridge::SetMainThread");
|
||||
if (thr) {
|
||||
mThread = thr;
|
||||
mJavaVM->GetEnv((void**) &mJNIEnv, JNI_VERSION_1_2);
|
||||
return (bool) mJNIEnv;
|
||||
}
|
||||
|
||||
mJNIEnv = nullptr;
|
||||
mThread = pthread_t();
|
||||
if (thr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// SetMainThread(0) is called on Gecko shutdown,
|
||||
// so we should clean up the bridge here.
|
||||
@ -324,29 +310,6 @@ jstring AndroidBridge::NewJavaString(AutoLocalJNIFrame* frame, const nsACString&
|
||||
return NewJavaString(frame, NS_ConvertUTF8toUTF16(string));
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
__attribute__ ((visibility("default")))
|
||||
JNIEnv * GetJNIForThread()
|
||||
{
|
||||
JNIEnv *jEnv = static_cast<JNIEnv*>(PR_GetThreadPrivate(sJavaEnvThreadIndex));
|
||||
if (jEnv) {
|
||||
return jEnv;
|
||||
}
|
||||
JavaVM *jVm = mozilla::AndroidBridge::GetVM();
|
||||
if (!jVm->GetEnv(reinterpret_cast<void**>(&jEnv), JNI_VERSION_1_2)) {
|
||||
MOZ_ASSERT(jEnv);
|
||||
return jEnv;
|
||||
}
|
||||
if (!jVm->AttachCurrentThread(&jEnv, nullptr)) {
|
||||
MOZ_ASSERT(jEnv);
|
||||
PR_SetThreadPrivate(sJavaEnvThreadIndex, jEnv);
|
||||
return jEnv;
|
||||
}
|
||||
MOZ_CRASH();
|
||||
return nullptr; // unreachable
|
||||
}
|
||||
}
|
||||
|
||||
void AutoGlobalWrappedJavaObject::Dispose() {
|
||||
if (isNull()) {
|
||||
return;
|
||||
@ -1636,27 +1599,6 @@ NS_IMETHODIMP nsAndroidBridge::IsContentDocumentDisplayed(bool *aRet)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// DO NOT USE THIS unless you need to access JNI from
|
||||
// non-main threads. This is probably not what you want.
|
||||
// Questions, ask blassey or dougt.
|
||||
|
||||
static void
|
||||
JavaThreadDetachFunc(void *arg)
|
||||
{
|
||||
JNIEnv *env = (JNIEnv*) arg;
|
||||
MOZ_ASSERT(env, "No JNIEnv on Gecko thread");
|
||||
if (!env) {
|
||||
return;
|
||||
}
|
||||
JavaVM *vm = nullptr;
|
||||
env->GetJavaVM(&vm);
|
||||
MOZ_ASSERT(vm, "No JavaVM on Gecko thread");
|
||||
if (!vm) {
|
||||
return;
|
||||
}
|
||||
vm->DetachCurrentThread();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
AndroidBridge::GetScreenOrientation()
|
||||
{
|
||||
|
@ -141,39 +141,6 @@ public:
|
||||
return sBridge;
|
||||
}
|
||||
|
||||
static JavaVM *GetVM() {
|
||||
MOZ_ASSERT(sBridge);
|
||||
return sBridge->mJavaVM;
|
||||
}
|
||||
|
||||
|
||||
static JNIEnv *GetJNIEnv() {
|
||||
MOZ_ASSERT(sBridge);
|
||||
if (MOZ_UNLIKELY(!pthread_equal(pthread_self(), sBridge->mThread))) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
MOZ_ASSERT(sBridge->mJNIEnv);
|
||||
return sBridge->mJNIEnv;
|
||||
}
|
||||
|
||||
static bool HasEnv() {
|
||||
return sBridge && sBridge->mJNIEnv;
|
||||
}
|
||||
|
||||
static bool ThrowException(JNIEnv *aEnv, const char *aClass,
|
||||
const char *aMessage) {
|
||||
|
||||
return jni::ThrowException(aEnv, aClass, aMessage);
|
||||
}
|
||||
|
||||
static bool ThrowException(JNIEnv *aEnv, const char *aMessage) {
|
||||
return jni::ThrowException(aEnv, aMessage);
|
||||
}
|
||||
|
||||
static void HandleUncaughtException(JNIEnv *aEnv) {
|
||||
jni::HandleUncaughtException(aEnv);
|
||||
}
|
||||
|
||||
// The bridge needs to be constructed via ConstructBridge first,
|
||||
// and then once the Gecko main thread is spun up (Gecko side),
|
||||
// SetMainThread should be called which will create the JNIEnv for
|
||||
@ -351,13 +318,6 @@ protected:
|
||||
static AndroidBridge* sBridge;
|
||||
nsTArray<nsCOMPtr<nsIMobileMessageCallback> > mSmsRequests;
|
||||
|
||||
// the global JavaVM
|
||||
JavaVM *mJavaVM;
|
||||
|
||||
// the JNIEnv for the main thread
|
||||
JNIEnv *mJNIEnv;
|
||||
pthread_t mThread;
|
||||
|
||||
widget::GeckoLayerClient::GlobalRef mLayerClient;
|
||||
|
||||
// the android.telephony.SmsMessage class
|
||||
|
@ -127,4 +127,11 @@ extern "C" {
|
||||
JNIEnv* jsjni_GetJNIForThread() {
|
||||
return GetJNIForThread();
|
||||
}
|
||||
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include "Utils.h"
|
||||
#include "Types.h"
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
|
||||
#include "AndroidBridge.h"
|
||||
@ -54,6 +56,67 @@ template<> const char TypedObject<jdoubleArray>::name[] = "[D";
|
||||
template<> const char TypedObject<jobjectArray>::name[] = "[Ljava/lang/Object;";
|
||||
|
||||
|
||||
JNIEnv* sGeckoThreadEnv;
|
||||
|
||||
namespace {
|
||||
|
||||
JavaVM* sJavaVM;
|
||||
pthread_key_t sThreadEnvKey;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -3,14 +3,38 @@
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include "mozilla/Types.h"
|
||||
|
||||
/* See the comment in AndroidBridge about this function before using it */
|
||||
extern "C" MOZ_EXPORT JNIEnv * GetJNIForThread();
|
||||
#if defined(DEBUG) || !defined(RELEASE_BUILD)
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "MainThreadUtils.h"
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace jni {
|
||||
|
||||
extern JNIEnv* sGeckoThreadEnv;
|
||||
|
||||
inline bool IsAvailable()
|
||||
{
|
||||
return !!sGeckoThreadEnv;
|
||||
}
|
||||
|
||||
inline JNIEnv* GetGeckoThreadEnv()
|
||||
{
|
||||
#if defined(DEBUG) || !defined(RELEASE_BUILD)
|
||||
if (!NS_IsMainThread()) {
|
||||
MOZ_CRASH("Not on main thread");
|
||||
}
|
||||
if (!sGeckoThreadEnv) {
|
||||
MOZ_CRASH("Don't have a JNIEnv");
|
||||
}
|
||||
#endif
|
||||
return sGeckoThreadEnv;
|
||||
}
|
||||
|
||||
void SetGeckoThreadEnv(JNIEnv* aEnv);
|
||||
|
||||
JNIEnv* GetEnvForThread();
|
||||
|
||||
bool ThrowException(JNIEnv *aEnv, const char *aClass,
|
||||
const char *aMessage);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user