Bug 959237 - Define GetVM, GetJNIEnv, and GetJNIForThread as infallible; r=blassey

Currently when either of these methods fail, we log something and rely on the calling code to null check. Since these failures are serious and likely unrecoverable, it's better to define these methods as infallible and just crash if they do fail.
This commit is contained in:
Jim Chen 2014-01-17 23:32:24 -06:00
parent 4f05e792d8
commit 9305d633e9
10 changed files with 27 additions and 149 deletions

View File

@ -38,8 +38,6 @@ PluginPRLibrary::NP_Initialize(NPNetscapeFuncs* bFuncs,
NPPluginFuncs* pFuncs, NPError* error)
{
JNIEnv* env = GetJNIForThread();
if (!env)
return NS_ERROR_FAILURE;
mozilla::AutoLocalJNIFrame jniFrame(env);

View File

@ -125,8 +125,6 @@ AudioRunnable::Run()
PR_SetCurrentThreadName("Android Audio");
JNIEnv* jenv = GetJNIForThread();
if (!jenv)
return NS_ERROR_FAILURE;
mozilla::AutoLocalJNIFrame autoFrame(jenv, 2);
@ -210,8 +208,6 @@ anp_audio_newTrack(uint32_t sampleRate, // sampling rate in Hz
}
JNIEnv *jenv = GetJNIForThread();
if (!jenv)
return nullptr;
s->at_class = init_jni_bindings(jenv);
s->rate = sampleRate;
@ -308,8 +304,6 @@ anp_audio_start(ANPAudioTrack* s)
}
JNIEnv *jenv = GetJNIForThread();
if (!jenv)
return;
mozilla::AutoLocalJNIFrame autoFrame(jenv, 0);
jenv->CallVoidMethod(s->output_unit, at.play);
@ -338,8 +332,6 @@ anp_audio_pause(ANPAudioTrack* s)
}
JNIEnv *jenv = GetJNIForThread();
if (!jenv)
return;
mozilla::AutoLocalJNIFrame autoFrame(jenv, 0);
jenv->CallVoidMethod(s->output_unit, at.pause);
@ -354,8 +346,6 @@ anp_audio_stop(ANPAudioTrack* s)
s->isStopped = true;
JNIEnv *jenv = GetJNIForThread();
if (!jenv)
return;
mozilla::AutoLocalJNIFrame autoFrame(jenv, 0);
jenv->CallVoidMethod(s->output_unit, at.stop);

View File

@ -1569,10 +1569,10 @@ void nsPluginInstanceOwner::ExitFullScreen() {
void nsPluginInstanceOwner::ExitFullScreen(jobject view) {
JNIEnv* env = AndroidBridge::GetJNIEnv();
if (env && sFullScreenInstance && sFullScreenInstance->mInstance &&
if (sFullScreenInstance && sFullScreenInstance->mInstance &&
env->IsSameObject(view, (jobject)sFullScreenInstance->mInstance->GetJavaSurface())) {
sFullScreenInstance->ExitFullScreen();
}
}
}
#endif

View File

@ -27,15 +27,12 @@ public:
{
}
bool EnsureInitialized()
{
if (mInitialized)
return true;
JNIEnv* env = GetJNIForThread();
if (!env)
return false;
AutoLocalJNIFrame jniFrame(env);
@ -54,8 +51,6 @@ public:
return nullptr;
JNIEnv* env = GetJNIForThread();
if (!env)
return nullptr;
AutoLocalJNIFrame jniFrame(env);
@ -65,8 +60,6 @@ public:
void ReleaseSurfaceTexture(jobject aSurfaceTexture)
{
JNIEnv* env = GetJNIForThread();
if (!env)
return;
env->DeleteGlobalRef(aSurfaceTexture);
}
@ -74,8 +67,6 @@ public:
void UpdateTexImage(jobject aSurfaceTexture)
{
JNIEnv* env = GetJNIForThread();
if (!env)
return;
AutoLocalJNIFrame jniFrame(env);
env->CallObjectMethod(aSurfaceTexture, jSurfaceTexture_updateTexImage);
@ -84,8 +75,6 @@ public:
bool GetTransformMatrix(jobject aSurfaceTexture, gfx3DMatrix& aMatrix)
{
JNIEnv* env = GetJNIForThread();
if (!env)
return false;
AutoLocalJNIFrame jniFrame(env);
@ -172,8 +161,6 @@ nsSurfaceTexture::Init(GLuint aTexture)
return false;
JNIEnv* env = GetJNIForThread();
if (!env)
return false;
mSurfaceTexture = sJNIFunctions.CreateSurfaceTexture(aTexture);
if (!mSurfaceTexture)
@ -204,10 +191,8 @@ nsSurfaceTexture::~nsSurfaceTexture()
}
JNIEnv* env = GetJNIForThread();
if (!env)
return;
if (mSurfaceTexture && env) {
if (mSurfaceTexture) {
GeckoAppShell::UnregisterSurfaceTextureFrameListener(mSurfaceTexture);
env->DeleteGlobalRef(mSurfaceTexture);
@ -259,4 +244,4 @@ nsSurfaceTexture::NotifyFrameAvailable()
}
}
#endif // MOZ_WIDGET_ANDROID
#endif // MOZ_WIDGET_ANDROID

View File

@ -159,6 +159,9 @@ AndroidBridge::Init(JNIEnv *jEnv)
{
ALOG_BRIDGE("AndroidBridge::Init");
jEnv->GetJavaVM(&mJavaVM);
if (!mJavaVM) {
MOZ_CRASH(); // Nothing we can do here
}
AutoLocalJNIFrame jniFrame(jEnv);
@ -269,32 +272,19 @@ extern "C" {
__attribute__ ((visibility("default")))
JNIEnv * GetJNIForThread()
{
JNIEnv *jEnv = nullptr;
JavaVM *jVm = mozilla::AndroidBridge::GetVM();
if (!jVm) {
__android_log_print(ANDROID_LOG_INFO, "GetJNIForThread", "Returned a null VM");
return nullptr;
}
jEnv = static_cast<JNIEnv*>(PR_GetThreadPrivate(sJavaEnvThreadIndex));
if (jEnv)
JNIEnv *jEnv = static_cast<JNIEnv*>(PR_GetThreadPrivate(sJavaEnvThreadIndex));
if (jEnv) {
return jEnv;
int status = jVm->GetEnv((void**) &jEnv, JNI_VERSION_1_2);
if (status) {
status = jVm->AttachCurrentThread(&jEnv, nullptr);
if (status) {
__android_log_print(ANDROID_LOG_INFO, "GetJNIForThread", "Could not attach");
return nullptr;
}
}
JavaVM *jVm = mozilla::AndroidBridge::GetVM();
if (!jVm->GetEnv(reinterpret_cast<void**>(&jEnv), JNI_VERSION_1_2) ||
!jVm->AttachCurrentThread(&jEnv, nullptr)) {
MOZ_ASSERT(jEnv);
PR_SetThreadPrivate(sJavaEnvThreadIndex, jEnv);
return jEnv;
}
if (!jEnv) {
__android_log_print(ANDROID_LOG_INFO, "GetJNIForThread", "returning NULL");
}
return jEnv;
MOZ_CRASH();
return nullptr; // unreachable
}
}
@ -349,8 +339,6 @@ AndroidBridge::GetHandlersForMimeType(const nsAString& aMimeType,
ALOG_BRIDGE("AndroidBridge::GetHandlersForMimeType");
JNIEnv *env = GetJNIEnv();
if (!env)
return false;
AutoLocalJNIFrame jniFrame(env, 1);
jobjectArray arr = GeckoAppShell::GetHandlersForMimeTypeWrapper(aMimeType, aAction);
@ -377,8 +365,6 @@ AndroidBridge::GetHandlersForURL(const nsAString& aURL,
ALOG_BRIDGE("AndroidBridge::GetHandlersForURL");
JNIEnv *env = GetJNIEnv();
if (!env)
return false;
AutoLocalJNIFrame jniFrame(env, 1);
jobjectArray arr = GeckoAppShell::GetHandlersForURLWrapper(aURL, aAction);
@ -401,8 +387,6 @@ AndroidBridge::GetMimeTypeFromExtensions(const nsACString& aFileExt, nsCString&
ALOG_BRIDGE("AndroidBridge::GetMimeTypeFromExtensions");
JNIEnv *env = GetJNIEnv();
if (!env)
return;
AutoLocalJNIFrame jniFrame(env, 1);
jstring jstrType = GeckoAppShell::GetMimeTypeFromExtensionsWrapper(NS_ConvertUTF8toUTF16(aFileExt));
@ -419,8 +403,6 @@ AndroidBridge::GetExtensionFromMimeType(const nsACString& aMimeType, nsACString&
ALOG_BRIDGE("AndroidBridge::GetExtensionFromMimeType");
JNIEnv *env = GetJNIEnv();
if (!env)
return;
AutoLocalJNIFrame jniFrame(env, 1);
jstring jstrExt = GeckoAppShell::GetExtensionFromMimeTypeWrapper(NS_ConvertUTF8toUTF16(aMimeType));
@ -437,8 +419,6 @@ AndroidBridge::GetClipboardText(nsAString& aText)
ALOG_BRIDGE("AndroidBridge::GetClipboardText");
JNIEnv *env = GetJNIEnv();
if (!env)
return false;
AutoLocalJNIFrame jniFrame(env, 1);
jstring result = Clipboard::GetClipboardTextWrapper();
@ -505,8 +485,6 @@ void
AndroidBridge::ShowFilePickerForExtensions(nsAString& aFilePath, const nsAString& aExtensions)
{
JNIEnv *env = GetJNIEnv();
if (!env)
return;
AutoLocalJNIFrame jniFrame(env, 1);
jstring jstr = GeckoAppShell::ShowFilePickerForExtensionsWrapper(aExtensions);
@ -521,8 +499,6 @@ void
AndroidBridge::ShowFilePickerForMimeType(nsAString& aFilePath, const nsAString& aMimeType)
{
JNIEnv *env = GetJNIEnv();
if (!env)
return;
AutoLocalJNIFrame jniFrame(env, 1);
jstring jstr = GeckoAppShell::ShowFilePickerForMimeTypeWrapper(aMimeType);
@ -552,8 +528,6 @@ AndroidBridge::Vibrate(const nsTArray<uint32_t>& aPattern)
}
JNIEnv *env = GetJNIEnv();
if (!env)
return;
AutoLocalJNIFrame jniFrame(env, 1);
@ -603,8 +577,6 @@ AndroidBridge::GetSystemColors(AndroidSystemColors *aColors)
return;
JNIEnv *env = GetJNIEnv();
if (!env)
return;
AutoLocalJNIFrame jniFrame(env, 1);
@ -641,8 +613,6 @@ AndroidBridge::GetIconForExtension(const nsACString& aFileExt, uint32_t aIconSiz
return;
JNIEnv *env = GetJNIEnv();
if (!env)
return;
AutoLocalJNIFrame jniFrame(env, 1);
@ -713,9 +683,6 @@ AndroidBridge::CreateEGLSurfaceForCompositor()
MOZ_ASSERT(mGLControllerObj, "AndroidBridge::CreateEGLSurfaceForCompositor called with a null GL controller ref");
JNIEnv* env = GetJNIForThread(); // called on the compositor thread
if (!env) {
return nullptr;
}
AutoLocalJNIFrame jniFrame(env, 1);
jobject eglSurface = mGLControllerObj->CreateEGLSurfaceForCompositorWrapper();
@ -733,8 +700,6 @@ AndroidBridge::GetStaticIntField(const char *className, const char *fieldName, i
if (!jEnv) {
jEnv = GetJNIEnv();
if (!jEnv)
return false;
}
initInit();
@ -759,8 +724,6 @@ AndroidBridge::GetStaticStringField(const char *className, const char *fieldName
if (!jEnv) {
jEnv = GetJNIEnv();
if (!jEnv)
return false;
}
AutoLocalJNIFrame jniFrame(jEnv, 1);
@ -963,8 +926,6 @@ AndroidBridge::ValidateBitmap(jobject bitmap, int width, int height)
struct BitmapInfo info = { 0, };
JNIEnv *env = GetJNIEnv();
if (!env)
return false;
if ((err = AndroidBitmap_getInfo(env, bitmap, &info)) != 0) {
ALOG_BRIDGE("AndroidBitmap_getInfo failed! (error %d)", err);
@ -981,8 +942,6 @@ bool
AndroidBridge::InitCamera(const nsCString& contentType, uint32_t camera, uint32_t *width, uint32_t *height, uint32_t *fps)
{
JNIEnv *env = GetJNIEnv();
if (!env)
return false;
AutoLocalJNIFrame jniFrame(env, 1);
jintArray arr = GeckoAppShell::InitCameraWrapper(NS_ConvertUTF8toUTF16(contentType), (int32_t) camera, (int32_t) width, (int32_t) height);
@ -1009,8 +968,6 @@ AndroidBridge::GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInf
ALOG_BRIDGE("AndroidBridge::GetCurrentBatteryInformation");
JNIEnv *env = GetJNIEnv();
if (!env)
return;
AutoLocalJNIFrame jniFrame(env, 1);
@ -1036,8 +993,6 @@ AndroidBridge::HandleGeckoMessage(const nsAString &aMessage, nsAString &aRet)
ALOG_BRIDGE("%s", __PRETTY_FUNCTION__);
JNIEnv *env = GetJNIEnv();
if (!env)
return;
AutoLocalJNIFrame jniFrame(env, 1);
jstring returnMessage = GeckoAppShell::HandleGeckoMessageWrapper(aMessage);
@ -1066,8 +1021,6 @@ AndroidBridge::GetSegmentInfoForText(const nsAString& aText,
data.charsAvailableInLastSegment() = 0;
JNIEnv *env = GetJNIEnv();
if (!env)
return NS_ERROR_FAILURE;
AutoLocalJNIFrame jniFrame(env, 2);
jstring jText = NewJavaString(&jniFrame, aText);
@ -1141,8 +1094,6 @@ AndroidBridge::CreateMessageList(const dom::mobilemessage::SmsFilterData& aFilte
ALOG_BRIDGE("AndroidBridge::CreateMessageList");
JNIEnv *env = GetJNIEnv();
if (!env)
return;
uint32_t requestId;
if (!QueueSmsRequest(aRequest, &requestId))
@ -1219,8 +1170,6 @@ AndroidBridge::GetCurrentNetworkInformation(hal::NetworkInformation* aNetworkInf
ALOG_BRIDGE("AndroidBridge::GetCurrentNetworkInformation");
JNIEnv *env = GetJNIEnv();
if (!env)
return;
AutoLocalJNIFrame jniFrame(env, 1);
@ -1246,8 +1195,6 @@ void *
AndroidBridge::LockBitmap(jobject bitmap)
{
JNIEnv *env = GetJNIEnv();
if (!env)
return nullptr;
AutoLocalJNIFrame jniFrame(env, 0);
@ -1266,8 +1213,6 @@ void
AndroidBridge::UnlockBitmap(jobject bitmap)
{
JNIEnv *env = GetJNIEnv();
if (!env)
return;
AutoLocalJNIFrame jniFrame(env, 0);
@ -1415,8 +1360,6 @@ jobject
AndroidBridge::GetGlobalContextRef() {
if (sGlobalContext == nullptr) {
JNIEnv *env = GetJNIForThread();
if (!env)
return 0;
AutoLocalJNIFrame jniFrame(env, 4);
@ -1647,8 +1590,6 @@ AndroidBridge::GetProxyForURI(const nsACString & aSpec,
nsACString & aResult)
{
JNIEnv* env = GetJNIEnv();
if (!env)
return NS_ERROR_FAILURE;
AutoLocalJNIFrame jniFrame(env, 1);
jstring jstrRet = GeckoAppShell::GetProxyForURIWrapper(NS_ConvertUTF8toUTF16(aSpec),
@ -1699,8 +1640,6 @@ bool
AndroidBridge::GetThreadNameJavaProfiling(uint32_t aThreadId, nsCString & aResult)
{
JNIEnv* env = GetJNIForThread();
if (!env)
return false;
AutoLocalJNIFrame jniFrame(env, 1);
@ -1719,8 +1658,6 @@ AndroidBridge::GetFrameNameJavaProfiling(uint32_t aThreadId, uint32_t aSampleId,
uint32_t aFrameId, nsCString & aResult)
{
JNIEnv* env = GetJNIForThread();
if (!env)
return false;
AutoLocalJNIFrame jniFrame(env, 1);
@ -1777,8 +1714,6 @@ nsresult AndroidBridge::CaptureThumbnail(nsIDOMWindow *window, int32_t bufW, int
}
JNIEnv* env = GetJNIEnv();
if (!env)
return NS_ERROR_FAILURE;
AutoLocalJNIFrame jniFrame(env, 0);
@ -1847,7 +1782,7 @@ AndroidBridge::GetDisplayPort(bool aPageSizeUpdate, bool aIsBrowserContentDispla
ALOG_BRIDGE("Enter: %s", __PRETTY_FUNCTION__);
JNIEnv* env = GetJNIEnv();
if (!env || !mLayerClient || mLayerClient->isNull()) {
if (!mLayerClient || mLayerClient->isNull()) {
ALOG_BRIDGE("Exceptional Exit: %s", __PRETTY_FUNCTION__);
return;
@ -1915,8 +1850,7 @@ AndroidBridge::ContentDocumentChanged()
bool
AndroidBridge::IsContentDocumentDisplayed()
{
JNIEnv* env = GetJNIEnv();
if (!env || !mLayerClient)
if (!mLayerClient)
return false;
return mLayerClient->IsContentDocumentDisplayed();

View File

@ -141,24 +141,18 @@ public:
}
static JavaVM *GetVM() {
if (MOZ_LIKELY(sBridge))
return sBridge->mJavaVM;
return nullptr;
MOZ_ASSERT(sBridge);
return sBridge->mJavaVM;
}
static JNIEnv *GetJNIEnv() {
if (MOZ_LIKELY(sBridge)) {
if (!pthread_equal(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);
MOZ_ASSERT(false, "###!!!!!!! Something's grabbing the JNIEnv from the wrong thread!");
return nullptr;
}
return sBridge->mJNIEnv;
static JNIEnv *GetJNIEnv() {
MOZ_ASSERT(sBridge);
if (MOZ_UNLIKELY(!pthread_equal(pthread_self(), sBridge->mThread))) {
MOZ_CRASH();
}
return nullptr;
MOZ_ASSERT(sBridge->mJNIEnv);
return sBridge->mJNIEnv;
}
// The bridge needs to be constructed via ConstructBridge first,

View File

@ -781,11 +781,6 @@ Java_org_mozilla_gecko_GeckoAppShell_onFullScreenPluginHidden(JNIEnv* jenv, jcla
NS_IMETHODIMP Run() {
JNIEnv* env = AndroidBridge::GetJNIEnv();
if (!env) {
NS_WARNING("Failed to acquire JNI env, can't exit plugin fullscreen mode");
return NS_OK;
}
nsPluginInstanceOwner::ExitFullScreen(mView);
env->DeleteGlobalRef(mView);
return NS_OK;

View File

@ -37,7 +37,6 @@ extern "C" {
// to missing the classpath
MOZ_ASSERT(NS_IsMainThread());
JNIEnv *env = mozilla::AndroidBridge::GetJNIEnv();
if (!env) return nullptr;
return env->FindClass(className);
}
@ -76,7 +75,6 @@ extern "C" {
const char *methodName,
const char *signature) {
JNIEnv *env = mozilla::AndroidBridge::GetJNIEnv();
if (!env) return nullptr;
return env->GetStaticMethodID(methodClass, methodName, signature);
}
@ -84,7 +82,6 @@ extern "C" {
bool
jsjni_ExceptionCheck() {
JNIEnv *env = mozilla::AndroidBridge::GetJNIEnv();
if (!env) return nullptr;
return env->ExceptionCheck();
}
@ -94,7 +91,6 @@ extern "C" {
jmethodID method,
jvalue *values) {
JNIEnv *env = mozilla::AndroidBridge::GetJNIEnv();
if (!env) return;
mozilla::AutoLocalJNIFrame jniFrame(env);
env->CallStaticVoidMethodA(cls, method, values);
@ -106,7 +102,6 @@ extern "C" {
jmethodID method,
jvalue *values) {
JNIEnv *env = mozilla::AndroidBridge::GetJNIEnv();
if (!env) return -1;
mozilla::AutoLocalJNIFrame jniFrame(env);
return env->CallStaticIntMethodA(cls, method, values);

View File

@ -968,10 +968,6 @@ nsJNIString::nsJNIString(jstring jstr, JNIEnv *jenv)
JNIEnv *jni = jenv;
if (!jni) {
jni = AndroidBridge::GetJNIEnv();
if (!jni) {
SetIsVoid(true);
return;
}
}
const jchar* jCharPtr = jni->GetStringChars(jstr, nullptr);

View File

@ -1059,9 +1059,6 @@ nsWindow::OnDraw(AndroidGeckoEvent *ae)
nsRefPtr<nsWindow> kungFuDeathGrip(this);
JNIEnv *env = AndroidBridge::GetJNIEnv();
if (!env)
return;
AutoLocalJNIFrame jniFrame;
// We're paused, or we haven't been given a window-size yet, so do nothing
@ -2358,9 +2355,6 @@ void
nsWindow::DrawWindowUnderlay(LayerManagerComposite* aManager, nsIntRect aRect)
{
JNIEnv *env = GetJNIForThread();
NS_ABORT_IF_FALSE(env, "No JNI environment at DrawWindowUnderlay()!");
if (!env)
return;
AutoLocalJNIFrame jniFrame(env);
@ -2397,9 +2391,6 @@ nsWindow::DrawWindowOverlay(LayerManagerComposite* aManager, nsIntRect aRect)
{
PROFILER_LABEL("nsWindow", "DrawWindowOverlay");
JNIEnv *env = GetJNIForThread();
NS_ABORT_IF_FALSE(env, "No JNI environment at DrawWindowOverlay()!");
if (!env)
return;
AutoLocalJNIFrame jniFrame(env);