Bug 932692 - Check for uncaught exceptions after JNI calls followed by JNI calls. r=blassey
authorGian-Carlo Pascutto <gpascutto@mozilla.com>
Fri, 22 Nov 2013 09:54:45 +0100
changeset 157376 fa0d790596e9275fe483afb10a8303e02d98d647
parent 157375 03ece8541cd13bfd705e1a2e1e03ccf9f9b8e5cc
child 157377 b729a21f22c7e04b4bfb3e36fa62d88810d4bd07
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
reviewersblassey
bugs932692
milestone28.0a1
Bug 932692 - Check for uncaught exceptions after JNI calls followed by JNI calls. r=blassey
media/webrtc/trunk/webrtc/modules/video_capture/android/device_info_android.cc
media/webrtc/trunk/webrtc/modules/video_capture/android/video_capture_android.cc
--- a/media/webrtc/trunk/webrtc/modules/video_capture/android/device_info_android.cc
+++ b/media/webrtc/trunk/webrtc/modules/video_capture/android/device_info_android.cc
@@ -100,17 +100,17 @@ int32_t DeviceInfoAndroid::GetDeviceName
   jobject javaCmDevInfoObject = jniFrame.GetCmDevInfoObject();
 
   // get the method ID for the Android Java GetDeviceUniqueName name.
   jmethodID cid = env->GetMethodID(javaCmDevInfoClass, "GetDeviceUniqueName",
                                    "(I)Ljava/lang/String;");
   if (cid != NULL) {
     jobject javaDeviceNameObj = env->CallObjectMethod(javaCmDevInfoObject,
                                                       cid, deviceNumber);
-    if (javaDeviceNameObj == NULL) {
+    if (javaDeviceNameObj == NULL || jniFrame.CheckForException()) {
       WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                    "%s: Failed to get device name for device %d.",
                    __FUNCTION__, (int) deviceNumber);
       result = -1;
     } else {
       jboolean isCopy;
       const char* javaDeviceNameChar = env->GetStringUTFChars(
           (jstring) javaDeviceNameObj
@@ -195,17 +195,17 @@ int32_t DeviceInfoAndroid::CreateCapabil
     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                  "%s: Can't create string for  method GetCapabilityArray.",
                  __FUNCTION__);
     return -1;
   }
   // Call the java class and get an array with capabilities back.
   jobject javaCapabilitiesObj = env->CallObjectMethod(javaCmDevInfoObject,
                                                       cid, capureIdString);
-  if (!javaCapabilitiesObj) {
+  if (!javaCapabilitiesObj || jniFrame.CheckForException()) {
     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                  "%s: Failed to call java GetCapabilityArray.",
                  __FUNCTION__);
     return -1;
   }
 
   jfieldID widthField = env->GetFieldID(javaCapClass, "width", "I");
   jfieldID heigtField = env->GetFieldID(javaCapClass, "height", "I");
--- a/media/webrtc/trunk/webrtc/modules/video_capture/android/video_capture_android.cc
+++ b/media/webrtc/trunk/webrtc/modules/video_capture/android/video_capture_android.cc
@@ -149,17 +149,22 @@ int32_t VideoCaptureAndroid::SetAndroidO
     EARLY_WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, -1,
                  "%s: construct static java device object", __FUNCTION__);
 
     // construct the object by calling the static constructor object
     jobject javaCameraDeviceInfoObjLocal =
         env->CallStaticObjectMethod(g_javaCmDevInfoClass,
                                     cid, (int) -1,
                                     javaContext);
-    if (!javaCameraDeviceInfoObjLocal) {
+    bool exceptionThrown = env->ExceptionCheck();
+    if (!javaCameraDeviceInfoObjLocal || exceptionThrown) {
+      if (exceptionThrown) {
+        env->ExceptionDescribe();
+        env->ExceptionClear();
+      }
       EARLY_WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCapture, -1,
                    "%s: could not create Java Capture Device info object",
                    __FUNCTION__);
       return -1;
     }
     // create a reference to the object (to tell JNI that
     // we are referencing it after this function has returned)
     g_javaCmDevInfoObject = env->NewGlobalRef(javaCameraDeviceInfoObjLocal);
@@ -324,17 +329,17 @@ int32_t VideoCaptureAndroid::Init(const 
   }
 
   jstring capureIdString = env->NewStringUTF((char*) deviceUniqueIdUTF8);
   // construct the object by calling the static constructor object
   jobject javaCameraObjLocal = env->CallObjectMethod(javaCmDevInfoObject,
                                                      cid, (jint) id,
                                                      (jlong) this,
                                                      capureIdString);
-  if (!javaCameraObjLocal) {
+  if (!javaCameraObjLocal || jniFrame.CheckForException()) {
     WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCapture, _id,
                  "%s: could not create Java Capture object", __FUNCTION__);
     return -1;
   }
 
   // create a reference to the object (to tell JNI that we are referencing it
   // after this function has returned)
   _javaCaptureObj = env->NewGlobalRef(javaCameraObjLocal);
@@ -367,16 +372,17 @@ VideoCaptureAndroid::~VideoCaptureAndroi
     jmethodID cid = env->GetStaticMethodID(g_javaCmClass,
                                            "DeleteVideoCaptureAndroid",
                                            "(Lorg/webrtc/videoengine/VideoCaptureAndroid;)V");
     if (cid != NULL) {
       WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, -1,
                    "%s: Call DeleteVideoCaptureAndroid", __FUNCTION__);
       // Close the camera by calling the static destruct function.
       env->CallStaticVoidMethod(g_javaCmClass, cid, _javaCaptureObj);
+      jniFrame.CheckForException();
 
       // Delete global object ref to the camera.
       env->DeleteGlobalRef(_javaCaptureObj);
       _javaCaptureObj = NULL;
     } else {
         WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, -1,
                      "%s: Failed to find DeleteVideoCaptureAndroid id",
                      __FUNCTION__);