Bug 713803 - Rationalize JNI access accross android widget. r=blassey

This commit is contained in:
Doug Turner 2012-01-28 22:38:02 -08:00
Родитель 3928acc847
Коммит dc1b4c0544
12 изменённых файлов: 726 добавлений и 395 удалений

Просмотреть файл

@ -64,17 +64,20 @@ nsresult
PluginPRLibrary::NP_Initialize(NPNetscapeFuncs* bFuncs, PluginPRLibrary::NP_Initialize(NPNetscapeFuncs* bFuncs,
NPPluginFuncs* pFuncs, NPError* error) NPPluginFuncs* pFuncs, NPError* error)
{ {
JNIEnv* env = GetJNIForThread();
if (!env)
return NS_ERROR_FAILURE;
if (mNP_Initialize) { if (mNP_Initialize) {
*error = mNP_Initialize(bFuncs, pFuncs, GetJNIForThread()); *error = mNP_Initialize(bFuncs, pFuncs, env);
} else { } else {
NP_InitializeFunc pfNP_Initialize = (NP_InitializeFunc) NP_InitializeFunc pfNP_Initialize = (NP_InitializeFunc)
PR_FindFunctionSymbol(mLibrary, "NP_Initialize"); PR_FindFunctionSymbol(mLibrary, "NP_Initialize");
if (!pfNP_Initialize) if (!pfNP_Initialize)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
*error = pfNP_Initialize(bFuncs, pFuncs, GetJNIForThread()); *error = pfNP_Initialize(bFuncs, pFuncs, env);
} }
// Save pointers to functions that get called through PluginLibrary itself. // Save pointers to functions that get called through PluginLibrary itself.
mNPP_New = pFuncs->newp; mNPP_New = pFuncs->newp;
mNPP_GetValue = pFuncs->getvalue; mNPP_GetValue = pFuncs->getvalue;

Просмотреть файл

@ -140,6 +140,8 @@ NS_IMETHODIMP
AudioRunnable::Run() AudioRunnable::Run()
{ {
JNIEnv* jenv = GetJNIForThread(); JNIEnv* jenv = GetJNIForThread();
if (!jenv)
return NS_ERROR_FAILURE;
if (jenv->PushLocalFrame(128)) { if (jenv->PushLocalFrame(128)) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
@ -309,6 +311,9 @@ anp_audio_start(ANPAudioTrack* s)
} }
JNIEnv *jenv = GetJNIForThread(); JNIEnv *jenv = GetJNIForThread();
if (!jenv)
return;
jenv->CallVoidMethod(s->output_unit, at.play); jenv->CallVoidMethod(s->output_unit, at.play);
s->isStopped = false; s->isStopped = false;
@ -329,6 +334,8 @@ anp_audio_pause(ANPAudioTrack* s)
} }
JNIEnv *jenv = GetJNIForThread(); JNIEnv *jenv = GetJNIForThread();
if (!jenv)
return;
jenv->CallVoidMethod(s->output_unit, at.pause); jenv->CallVoidMethod(s->output_unit, at.pause);
} }
@ -341,6 +348,8 @@ anp_audio_stop(ANPAudioTrack* s)
s->isStopped = true; s->isStopped = true;
JNIEnv *jenv = GetJNIForThread(); JNIEnv *jenv = GetJNIForThread();
if (!jenv)
return;
jenv->CallVoidMethod(s->output_unit, at.stop); jenv->CallVoidMethod(s->output_unit, at.stop);
} }

Просмотреть файл

@ -66,14 +66,21 @@ void
anp_event_postEvent(NPP inst, const ANPEvent* event) anp_event_postEvent(NPP inst, const ANPEvent* event)
{ {
LOG("%s", __PRETTY_FUNCTION__); LOG("%s", __PRETTY_FUNCTION__);
JNIEnv* env = GetJNIForThread();
if (!env)
return;
if (!mozilla::AndroidBridge::Bridge()) { if (!mozilla::AndroidBridge::Bridge()) {
LOG("no bridge in %s!!!!", __PRETTY_FUNCTION__); LOG("no bridge in %s!!!!", __PRETTY_FUNCTION__);
return; return;
} }
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(inst->ndata); nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(inst->ndata);
NPPluginFuncs* pluginFunctions = pinst->GetPlugin()->PluginFuncs(); NPPluginFuncs* pluginFunctions = pinst->GetPlugin()->PluginFuncs();
mozilla::AndroidBridge::Bridge()->PostToJavaThread( mozilla::AndroidBridge::Bridge()->PostToJavaThread(env,
new PluginEventRunnable(inst, const_cast<ANPEvent*>(event), pluginFunctions), true); new PluginEventRunnable(inst, const_cast<ANPEvent*>(event), pluginFunctions),
true);
LOG("returning from %s", __PRETTY_FUNCTION__); LOG("returning from %s", __PRETTY_FUNCTION__);
} }

Просмотреть файл

@ -67,6 +67,9 @@ jclass anp_system_loadJavaClass(NPP instance, const char* className)
LOG("%s", __PRETTY_FUNCTION__); LOG("%s", __PRETTY_FUNCTION__);
JNIEnv* env = GetJNIForThread(); JNIEnv* env = GetJNIForThread();
if (!env)
return nsnull;
jclass cls = env->FindClass("org/mozilla/gecko/GeckoAppShell"); jclass cls = env->FindClass("org/mozilla/gecko/GeckoAppShell");
jmethodID method = env->GetStaticMethodID(cls, jmethodID method = env->GetStaticMethodID(cls,
"loadPluginClass", "loadPluginClass",

Просмотреть файл

@ -2383,7 +2383,10 @@ _getvalue(NPP npp, NPNVariable variable, void *result)
case kJavaContext_ANPGetValue: { case kJavaContext_ANPGetValue: {
LOG("get context"); LOG("get context");
JNIEnv* env = GetJNIForThread(); JNIEnv* env = GetJNIForThread();
if (!env)
return NPERR_GENERIC_ERROR;
jclass cls = env->FindClass("org/mozilla/gecko/GeckoApp"); jclass cls = env->FindClass("org/mozilla/gecko/GeckoApp");
jfieldID field = env->GetStaticFieldID(cls, "mAppContext", jfieldID field = env->GetStaticFieldID(cls, "mAppContext",
"Lorg/mozilla/gecko/GeckoApp;"); "Lorg/mozilla/gecko/GeckoApp;");

Просмотреть файл

@ -750,7 +750,15 @@ public:
return NS_OK; return NS_OK;
} }
void RequestSurface() { void RequestSurface() {
mozilla::AndroidBridge::Bridge()->PostToJavaThread(this); JNIEnv* env = GetJNIForThread();
if (!env)
return;
if (!mozilla::AndroidBridge::Bridge()) {
PLUGIN_LOG(PLUGIN_LOG_BASIC, ("nsNPAPIPluginInstance null AndroidBridge"));
return;
}
mozilla::AndroidBridge::Bridge()->PostToJavaThread(env, this);
} }
private: private:
nsNPAPIPluginInstance* mInstance; nsNPAPIPluginInstance* mInstance;

Просмотреть файл

@ -1736,33 +1736,32 @@ bool nsPluginInstanceOwner::AddPluginView(const gfxRect& aRect)
void nsPluginInstanceOwner::RemovePluginView() void nsPluginInstanceOwner::RemovePluginView()
{ {
if (mInstance && mObjectFrame && mPluginViewAdded) { if (!mInstance || !mObjectFrame | !mPluginViewAdded)
mPluginViewAdded = false; return;
void* surface = mInstance->GetJavaSurface(); mPluginViewAdded = false;
if (!surface)
return;
JNIEnv* env = GetJNIForThread(); void* surface = mInstance->GetJavaSurface();
if (!env) if (!surface)
return; return;
AndroidBridge::AutoLocalJNIFrame frame(env, 1); JNIEnv* env = GetJNIForThread();
if (!env)
return;
jclass cls = env->FindClass("org/mozilla/gecko/GeckoAppShell"); AndroidBridge::AutoLocalJNIFrame frame(env, 1);
jmethodID method = env->GetStaticMethodID(cls,
"removePluginView",
"(Landroid/view/View;)V");
env->CallStaticVoidMethod(cls, method, surface);
{ jclass cls = env->FindClass("org/mozilla/gecko/GeckoAppShell");
ANPEvent event; jmethodID method = env->GetStaticMethodID(cls,
event.inSize = sizeof(ANPEvent); "removePluginView",
event.eventType = kLifecycle_ANPEventType; "(Landroid/view/View;)V");
event.data.lifecycle.action = kOffScreen_ANPLifecycleAction; env->CallStaticVoidMethod(cls, method, surface);
mInstance->HandleEvent(&event, nsnull);
} ANPEvent event;
} event.inSize = sizeof(ANPEvent);
event.eventType = kLifecycle_ANPEventType;
event.data.lifecycle.action = kOffScreen_ANPLifecycleAction;
mInstance->HandleEvent(&event, nsnull);
} }
#endif #endif

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -41,11 +41,13 @@
#include <jni.h> #include <jni.h>
#include <android/log.h> #include <android/log.h>
#include <cstdlib> #include <cstdlib>
#include <pthread.h>
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsCOMArray.h" #include "nsCOMArray.h"
#include "nsIRunnable.h" #include "nsIRunnable.h"
#include "nsIObserver.h" #include "nsIObserver.h"
#include "nsThreadUtils.h"
#include "AndroidJavaWrappers.h" #include "AndroidJavaWrappers.h"
@ -62,6 +64,12 @@
class nsWindow; class nsWindow;
class nsIDOMMozSmsMessage; class nsIDOMMozSmsMessage;
/* See the comment in AndroidBridge about this function before using it */
extern "C" JNIEnv * GetJNIForThread();
extern bool mozilla_AndroidBridge_SetMainThread(void *);
extern jclass GetGeckoAppShellClass();
namespace mozilla { namespace mozilla {
namespace hal { namespace hal {
@ -108,18 +116,23 @@ public:
return sBridge; return sBridge;
} }
static JavaVM *VM() { static JavaVM *GetVM() {
return sBridge->mJavaVM;
}
static JNIEnv *JNI() {
sBridge->EnsureJNIThread();
return sBridge->mJNIEnv;
}
static JNIEnv *JNIForThread() {
if (NS_LIKELY(sBridge)) if (NS_LIKELY(sBridge))
return sBridge->AttachThread(); return sBridge->mJavaVM;
return nsnull;
}
static JNIEnv *GetJNIEnv() {
if (NS_LIKELY(sBridge)) {
if ((void*)pthread_self() != sBridge->mThread) {
__android_log_print(ANDROID_LOG_INFO, "AndroidBridge",
"###!!!!!!! Something's grabbing the JNIEnv from the wrong thread! (thr %p should be %p)",
(void*)pthread_self(), (void*)sBridge->mThread);
return nsnull;
}
return sBridge->mJNIEnv;
}
return nsnull; return nsnull;
} }
@ -134,8 +147,6 @@ public:
// SetMainThread. // SetMainThread.
bool SetMainThread(void *thr); bool SetMainThread(void *thr);
JNIEnv* AttachThread(bool asDaemon = true);
/* These are all implemented in Java */ /* These are all implemented in Java */
static void NotifyIME(int aType, int aState); static void NotifyIME(int aType, int aState);
@ -242,15 +253,16 @@ public:
public: public:
AutoLocalJNIFrame(int nEntries = 128) AutoLocalJNIFrame(int nEntries = 128)
: mEntries(nEntries) : mEntries(nEntries)
, mJNIEnv(JNI())
{ {
mJNIEnv = AndroidBridge::GetJNIEnv();
Push(); Push();
} }
AutoLocalJNIFrame(JNIEnv* aJNIEnv, int nEntries = 128) AutoLocalJNIFrame(JNIEnv* aJNIEnv, int nEntries = 128)
: mEntries(nEntries) : mEntries(nEntries)
, mJNIEnv(aJNIEnv ? aJNIEnv : JNI())
{ {
mJNIEnv = aJNIEnv ? aJNIEnv : AndroidBridge::GetJNIEnv();
Push(); Push();
} }
@ -258,11 +270,16 @@ public:
// the AutoLocalJNIFrame's scope INVALID; be sure that you locked down // the AutoLocalJNIFrame's scope INVALID; be sure that you locked down
// any local refs that you need to keep around in global refs! // any local refs that you need to keep around in global refs!
void Purge() { void Purge() {
mJNIEnv->PopLocalFrame(NULL); if (mJNIEnv) {
Push(); mJNIEnv->PopLocalFrame(NULL);
Push();
}
} }
~AutoLocalJNIFrame() { ~AutoLocalJNIFrame() {
if (!mJNIEnv)
return;
jthrowable exception = mJNIEnv->ExceptionOccurred(); jthrowable exception = mJNIEnv->ExceptionOccurred();
if (exception) { if (exception) {
mJNIEnv->ExceptionDescribe(); mJNIEnv->ExceptionDescribe();
@ -274,6 +291,9 @@ public:
private: private:
void Push() { void Push() {
if (!mJNIEnv)
return;
// Make sure there is enough space to store a local ref to the // Make sure there is enough space to store a local ref to the
// exception. I am not completely sure this is needed, but does // exception. I am not completely sure this is needed, but does
// not hurt. // not hurt.
@ -306,9 +326,9 @@ public:
void UnlockBitmap(jobject bitmap); void UnlockBitmap(jobject bitmap);
void PostToJavaThread(nsIRunnable* aRunnable, bool aMainThread = false); void PostToJavaThread(JNIEnv *aEnv, nsIRunnable* aRunnable, bool aMainThread = false);
void ExecuteNextRunnable(); void ExecuteNextRunnable(JNIEnv *aEnv);
/* Copied from Android's native_window.h in newer (platform 9) NDK */ /* Copied from Android's native_window.h in newer (platform 9) NDK */
enum { enum {
@ -378,8 +398,6 @@ protected:
AndroidBridge() { } AndroidBridge() { }
bool Init(JNIEnv *jEnv, jclass jGeckoApp); bool Init(JNIEnv *jEnv, jclass jGeckoApp);
void EnsureJNIThread();
bool mOpenedGraphicsLibraries; bool mOpenedGraphicsLibraries;
void OpenGraphicsLibraries(); void OpenGraphicsLibraries();
@ -498,8 +516,5 @@ private:
protected: protected:
}; };
extern "C" JNIEnv * GetJNIForThread();
extern bool mozilla_AndroidBridge_SetMainThread(void *);
extern jclass GetGeckoAppShellClass();
#endif /* AndroidBridge_h__ */ #endif /* AndroidBridge_h__ */

Просмотреть файл

@ -218,14 +218,14 @@ Java_org_mozilla_gecko_GeckoAppShell_reportJavaCrash(JNIEnv *jenv, jclass, jstri
} }
NS_EXPORT void JNICALL NS_EXPORT void JNICALL
Java_org_mozilla_gecko_GeckoAppShell_executeNextRunnable(JNIEnv *, jclass) Java_org_mozilla_gecko_GeckoAppShell_executeNextRunnable(JNIEnv *jenv, jclass)
{ {
__android_log_print(ANDROID_LOG_INFO, "GeckoJNI", "%s", __PRETTY_FUNCTION__); __android_log_print(ANDROID_LOG_INFO, "GeckoJNI", "%s", __PRETTY_FUNCTION__);
if (!AndroidBridge::Bridge()) { if (!AndroidBridge::Bridge()) {
__android_log_print(ANDROID_LOG_INFO, "GeckoJNI", "no bridge in %s!!!!", __PRETTY_FUNCTION__); __android_log_print(ANDROID_LOG_INFO, "GeckoJNI", "no bridge in %s!!!!", __PRETTY_FUNCTION__);
return; return;
} }
AndroidBridge::Bridge()->ExecuteNextRunnable(); AndroidBridge::Bridge()->ExecuteNextRunnable(jenv);
__android_log_print(ANDROID_LOG_INFO, "GeckoJNI", "leaving %s", __PRETTY_FUNCTION__); __android_log_print(ANDROID_LOG_INFO, "GeckoJNI", "leaving %s", __PRETTY_FUNCTION__);
} }

Просмотреть файл

@ -124,8 +124,6 @@ jmethodID AndroidGeckoSurfaceView::jGetSoftwareDrawBufferMethod = 0;
jmethodID AndroidGeckoSurfaceView::jGetSurfaceMethod = 0; jmethodID AndroidGeckoSurfaceView::jGetSurfaceMethod = 0;
jmethodID AndroidGeckoSurfaceView::jGetHolderMethod = 0; jmethodID AndroidGeckoSurfaceView::jGetHolderMethod = 0;
#define JNI() (AndroidBridge::JNI())
#define initInit() jclass jClass #define initInit() jclass jClass
// note that this also sets jClass // note that this also sets jClass
@ -608,43 +606,68 @@ AndroidGeckoSurfaceView::BeginDrawing()
{ {
NS_ASSERTION(!isNull(), "BeginDrawing called on null surfaceview!"); NS_ASSERTION(!isNull(), "BeginDrawing called on null surfaceview!");
return JNI()->CallIntMethod(wrapped_obj, jBeginDrawingMethod); JNIEnv *env = AndroidBridge::GetJNIEnv();
if (!env)
return 0;
return env->CallIntMethod(wrapped_obj, jBeginDrawingMethod);
} }
void void
AndroidGeckoSurfaceView::EndDrawing() AndroidGeckoSurfaceView::EndDrawing()
{ {
JNI()->CallVoidMethod(wrapped_obj, jEndDrawingMethod); JNIEnv *env = AndroidBridge::GetJNIEnv();
if (!env)
return;
env->CallVoidMethod(wrapped_obj, jEndDrawingMethod);
} }
void void
AndroidGeckoSurfaceView::Draw2D(jobject bitmap, int width, int height) AndroidGeckoSurfaceView::Draw2D(jobject bitmap, int width, int height)
{ {
JNI()->CallVoidMethod(wrapped_obj, jDraw2DBitmapMethod, bitmap, width, height); JNIEnv *env = AndroidBridge::GetJNIEnv();
if (!env)
return;
env->CallVoidMethod(wrapped_obj, jDraw2DBitmapMethod, bitmap, width, height);
} }
void void
AndroidGeckoSurfaceView::Draw2D(jobject buffer, int stride) AndroidGeckoSurfaceView::Draw2D(jobject buffer, int stride)
{ {
JNI()->CallVoidMethod(wrapped_obj, jDraw2DBufferMethod, buffer, stride); JNIEnv *env = AndroidBridge::GetJNIEnv();
if (!env)
return;
env->CallVoidMethod(wrapped_obj, jDraw2DBufferMethod, buffer, stride);
} }
jobject jobject
AndroidGeckoSoftwareLayerClient::LockBuffer() AndroidGeckoSoftwareLayerClient::LockBuffer()
{ {
NS_ASSERTION(!isNull(), "LockBuffer() called on null software layer client!"); NS_ASSERTION(!isNull(), "LockBuffer() called on null software layer client!");
AndroidBridge::AutoLocalJNIFrame(1);
return JNI()->CallObjectMethod(wrapped_obj, jLockBufferMethod); JNIEnv *env = AndroidBridge::GetJNIEnv();
if (!env)
return nsnull;
AndroidBridge::AutoLocalJNIFrame(env, 1);
return env->CallObjectMethod(wrapped_obj, jLockBufferMethod);
} }
unsigned char * unsigned char *
AndroidGeckoSoftwareLayerClient::LockBufferBits() AndroidGeckoSoftwareLayerClient::LockBufferBits()
{ {
AndroidBridge::AutoLocalJNIFrame(1); JNIEnv *env = AndroidBridge::GetJNIEnv();
if (!env)
return nsnull;
AndroidBridge::AutoLocalJNIFrame(env, 1);
jobject bufferObject = LockBuffer(); jobject bufferObject = LockBuffer();
if (bufferObject != nsnull) if (bufferObject != nsnull)
return reinterpret_cast<unsigned char *>(JNI()->GetDirectBufferAddress(bufferObject)); return reinterpret_cast<unsigned char *>(env->GetDirectBufferAddress(bufferObject));
return nsnull; return nsnull;
} }
@ -653,14 +676,22 @@ void
AndroidGeckoSoftwareLayerClient::UnlockBuffer() AndroidGeckoSoftwareLayerClient::UnlockBuffer()
{ {
NS_ASSERTION(!isNull(), "UnlockBuffer() called on null software layer client!"); NS_ASSERTION(!isNull(), "UnlockBuffer() called on null software layer client!");
AndroidBridge::AutoLocalJNIFrame(1); JNIEnv *env = AndroidBridge::GetJNIEnv();
JNI()->CallVoidMethod(wrapped_obj, jUnlockBufferMethod); if (!env)
return;
AndroidBridge::AutoLocalJNIFrame(env, 1);
env->CallVoidMethod(wrapped_obj, jUnlockBufferMethod);
} }
void void
AndroidGeckoSoftwareLayerClient::GetRenderOffset(nsIntPoint &aOffset) AndroidGeckoSoftwareLayerClient::GetRenderOffset(nsIntPoint &aOffset)
{ {
AndroidPoint offset(JNI(), JNI()->CallObjectMethod(wrapped_obj, jGetRenderOffsetMethod)); JNIEnv *env = AndroidBridge::GetJNIEnv();
if (!env)
return;
AndroidPoint offset(env, env->CallObjectMethod(wrapped_obj, jGetRenderOffsetMethod));
aOffset.x = offset.X(); aOffset.x = offset.X();
aOffset.y = offset.Y(); aOffset.y = offset.Y();
} }
@ -669,41 +700,65 @@ bool
AndroidGeckoSoftwareLayerClient::BeginDrawing(int aWidth, int aHeight, int aTileWidth, int aTileHeight, const nsAString &aMetadata, bool aHasDirectTexture) AndroidGeckoSoftwareLayerClient::BeginDrawing(int aWidth, int aHeight, int aTileWidth, int aTileHeight, const nsAString &aMetadata, bool aHasDirectTexture)
{ {
NS_ASSERTION(!isNull(), "BeginDrawing() called on null software layer client!"); NS_ASSERTION(!isNull(), "BeginDrawing() called on null software layer client!");
AndroidBridge::AutoLocalJNIFrame(1); JNIEnv *env = AndroidBridge::GetJNIEnv();
jstring jMetadata = JNI()->NewString(nsPromiseFlatString(aMetadata).get(), aMetadata.Length()); if (!env)
return JNI()->CallBooleanMethod(wrapped_obj, jBeginDrawingMethod, aWidth, aHeight, aTileWidth, aTileHeight, jMetadata, aHasDirectTexture); return false;
AndroidBridge::AutoLocalJNIFrame(env, 1);
jstring jMetadata = env->NewString(nsPromiseFlatString(aMetadata).get(), aMetadata.Length());
return env->CallBooleanMethod(wrapped_obj, jBeginDrawingMethod, aWidth, aHeight, aTileWidth, aTileHeight, jMetadata, aHasDirectTexture);
} }
void void
AndroidGeckoSoftwareLayerClient::EndDrawing(const nsIntRect &aRect) AndroidGeckoSoftwareLayerClient::EndDrawing(const nsIntRect &aRect)
{ {
NS_ASSERTION(!isNull(), "EndDrawing() called on null software layer client!"); NS_ASSERTION(!isNull(), "EndDrawing() called on null software layer client!");
AndroidBridge::AutoLocalJNIFrame(1); JNIEnv *env = AndroidBridge::GetJNIEnv();
return JNI()->CallVoidMethod(wrapped_obj, jEndDrawingMethod, aRect.x, aRect.y, aRect.width, aRect.height); if (!env)
return;
AndroidBridge::AutoLocalJNIFrame(env, 1);
return env->CallVoidMethod(wrapped_obj, jEndDrawingMethod, aRect.x, aRect.y, aRect.width, aRect.height);
} }
jobject jobject
AndroidGeckoSurfaceView::GetSoftwareDrawBitmap() AndroidGeckoSurfaceView::GetSoftwareDrawBitmap()
{ {
return JNI()->CallObjectMethod(wrapped_obj, jGetSoftwareDrawBitmapMethod); JNIEnv *env = AndroidBridge::GetJNIEnv();
if (!env)
return nsnull;
return env->CallObjectMethod(wrapped_obj, jGetSoftwareDrawBitmapMethod);
} }
jobject jobject
AndroidGeckoSurfaceView::GetSoftwareDrawBuffer() AndroidGeckoSurfaceView::GetSoftwareDrawBuffer()
{ {
return JNI()->CallObjectMethod(wrapped_obj, jGetSoftwareDrawBufferMethod); JNIEnv *env = AndroidBridge::GetJNIEnv();
if (!env)
return nsnull;
return env->CallObjectMethod(wrapped_obj, jGetSoftwareDrawBufferMethod);
} }
jobject jobject
AndroidGeckoSurfaceView::GetSurface() AndroidGeckoSurfaceView::GetSurface()
{ {
return JNI()->CallObjectMethod(wrapped_obj, jGetSurfaceMethod); JNIEnv *env = AndroidBridge::GetJNIEnv();
if (!env)
return nsnull;
return env->CallObjectMethod(wrapped_obj, jGetSurfaceMethod);
} }
jobject jobject
AndroidGeckoSurfaceView::GetSurfaceHolder() AndroidGeckoSurfaceView::GetSurfaceHolder()
{ {
return JNI()->CallObjectMethod(wrapped_obj, jGetHolderMethod); JNIEnv *env = AndroidBridge::GetJNIEnv();
if (!env)
return nsnull;
return env->CallObjectMethod(wrapped_obj, jGetHolderMethod);
} }
void void
@ -734,7 +789,7 @@ nsJNIString::nsJNIString(jstring jstr, JNIEnv *jenv)
} }
JNIEnv *jni = jenv; JNIEnv *jni = jenv;
if (!jni) if (!jni)
jni = JNI(); jni = AndroidBridge::GetJNIEnv();
const jchar* jCharPtr = jni->GetStringChars(jstr, NULL); const jchar* jCharPtr = jni->GetStringChars(jstr, NULL);
if (!jCharPtr) { if (!jCharPtr) {

Просмотреть файл

@ -1352,8 +1352,12 @@ nsWindow::OnDraw(AndroidGeckoEvent *ae)
return; return;
} }
void *buf = AndroidBridge::JNI()->GetDirectBufferAddress(bytebuf); JNIEnv *env = AndroidBridge::GetJNIEnv();
int cap = AndroidBridge::JNI()->GetDirectBufferCapacity(bytebuf); if (!env)
return;
void *buf = env->GetDirectBufferAddress(bytebuf);
int cap = env->GetDirectBufferCapacity(bytebuf);
if (!buf || cap != (mBounds.width * mBounds.height * 2)) { if (!buf || cap != (mBounds.width * mBounds.height * 2)) {
ALOG("### Software drawing, but unexpected buffer size %d expected %d (or no buffer %p)!", cap, mBounds.width * mBounds.height * 2, buf); ALOG("### Software drawing, but unexpected buffer size %d expected %d (or no buffer %p)!", cap, mBounds.width * mBounds.height * 2, buf);
return; return;