Bug 844289 - Guard against missing Surface.mNativeSurface on Android r=kats
authorJames Willcox <snorp@snorp.net>
Tue, 26 Feb 2013 09:28:57 -0500
changeset 123019 7bdc94c723f30754739a793af634686d4cf1a80e
parent 123018 9cbb040ed6da24a209666df1a96ccb6c1d1a41bf
child 123020 c92816f3028c79db4a16a4b5f7bb7d746080602a
push id24372
push useremorley@mozilla.com
push dateWed, 27 Feb 2013 13:22:59 +0000
treeherdermozilla-central@0a91da5f5eab [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats
bugs844289
milestone22.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 844289 - Guard against missing Surface.mNativeSurface on Android r=kats
widget/android/AndroidBridge.cpp
widget/android/AndroidLayerViewWrapper.cpp
--- a/widget/android/AndroidBridge.cpp
+++ b/widget/android/AndroidBridge.cpp
@@ -184,21 +184,28 @@ AndroidBridge::Init(JNIEnv *jEnv,
 
     jStringClass = (jclass) jEnv->NewGlobalRef(jEnv->FindClass("java/lang/String"));
 
     jSurfaceClass = (jclass) jEnv->NewGlobalRef(jEnv->FindClass("android/view/Surface"));
 
     if (!GetStaticIntField("android/os/Build$VERSION", "SDK_INT", &mAPIVersion, jEnv))
         ALOG_BRIDGE("Failed to find API version");
 
-    if (mAPIVersion <= 8 /* Froyo */)
+    if (mAPIVersion <= 8 /* Froyo */) {
         jSurfacePointerField = jEnv->GetFieldID(jSurfaceClass, "mSurface", "I");
-    else /* not Froyo */
+    } else {
         jSurfacePointerField = jEnv->GetFieldID(jSurfaceClass, "mNativeSurface", "I");
 
+        // Apparently mNativeSurface doesn't exist in Key Lime Pie, so just clear the
+        // exception if we have one and move on.
+        if (jEnv->ExceptionCheck()) {
+            jEnv->ExceptionClear();
+        }
+    }
+
     jNotifyWakeLockChanged = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "notifyWakeLockChanged", "(Ljava/lang/String;Ljava/lang/String;)V");
 
     jGetGfxInfoData = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getGfxInfoData", "()Ljava/lang/String;");
     jGetProxyForURI = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getProxyForURI", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)Ljava/lang/String;");
     jRegisterSurfaceTextureFrameListener = jEnv->GetStaticMethodID(jGeckoAppShellClass, "registerSurfaceTextureFrameListener", "(Ljava/lang/Object;I)V");
     jUnregisterSurfaceTextureFrameListener = jEnv->GetStaticMethodID(jGeckoAppShellClass, "unregisterSurfaceTextureFrameListener", "(Ljava/lang/Object;)V");
 
     jPumpMessageLoop = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "pumpMessageLoop", "()Z");
@@ -1258,17 +1265,17 @@ AndroidBridge::CreateShortcut(const nsAS
     if (!jstrURI || !jstrTitle || !jstrIconData)
         return;
 
     env->CallStaticVoidMethod(mGeckoAppShellClass, jCreateShortcut, jstrTitle, jstrURI, jstrIconData, jstrIntent);
 }
 
 void*
 AndroidBridge::GetNativeSurface(JNIEnv* env, jobject surface) {
-    if (!env || !mHasNativeWindowFallback)
+    if (!env || !mHasNativeWindowFallback || !jSurfacePointerField)
         return nullptr;
 
     return (void*)env->GetIntField(surface, jSurfacePointerField);
 }
 
 void
 AndroidBridge::OpenGraphicsLibraries()
 {
--- a/widget/android/AndroidLayerViewWrapper.cpp
+++ b/widget/android/AndroidLayerViewWrapper.cpp
@@ -10,19 +10,24 @@
 using namespace mozilla;
 
 #define ASSERT_THREAD() \
         NS_ASSERTION(pthread_self() == mThread, "Something is calling AndroidGLController from the wrong thread!")
 
 static jfieldID jEGLSurfacePointerField = 0;
 
 void AndroidEGLObject::Init(JNIEnv* aJEnv) {
+    AutoLocalJNIFrame jniFrame(aJEnv);
+
     jclass jClass;
     jClass = reinterpret_cast<jclass>
         (aJEnv->NewGlobalRef(aJEnv->FindClass("com/google/android/gles_jni/EGLSurfaceImpl")));
+    if (!jClass)
+        return;
+
     jEGLSurfacePointerField = aJEnv->GetFieldID(jClass, "mEGLSurface", "I");
 }
 
 jmethodID AndroidGLController::jWaitForValidSurfaceMethod = 0;
 jmethodID AndroidGLController::jProvideEGLSurfaceMethod = 0;
 jmethodID AndroidGLController::jResumeCompositorIfValidMethod = 0;
 
 void
@@ -53,16 +58,20 @@ AndroidGLController::Reacquire(JNIEnv *a
     AutoLocalJNIFrame jniFrame(aJEnv, 0);
     aJEnv->CallVoidMethod(mJObj, jResumeCompositorIfValidMethod);
 }
 
 EGLSurface
 AndroidGLController::ProvideEGLSurface()
 {
     ASSERT_THREAD();
+
+    if (!jEGLSurfacePointerField)
+        return NULL;
+
     AutoLocalJNIFrame jniFrame(mJEnv);
     jobject jObj = mJEnv->CallObjectMethod(mJObj, jProvideEGLSurfaceMethod);
     if (jniFrame.CheckForException() || !jObj)
         return NULL;
 
     return reinterpret_cast<EGLSurface>(mJEnv->GetIntField(jObj, jEGLSurfacePointerField));
 }