Add exception handling to Android hidapi.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
diff --git a/Xcode-iOS/Demos/Demos.xcodeproj/project.pbxproj b/Xcode-iOS/Demos/Demos.xcodeproj/project.pbxproj
old mode 100644
new mode 100755
diff --git a/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj b/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj
old mode 100644
new mode 100755
diff --git a/Xcode-iOS/Test/TestiPhoneOS.xcodeproj/project.pbxproj b/Xcode-iOS/Test/TestiPhoneOS.xcodeproj/project.pbxproj
old mode 100644
new mode 100755
diff --git a/Xcode/SDL/SDL.xcodeproj/project.pbxproj b/Xcode/SDL/SDL.xcodeproj/project.pbxproj
old mode 100644
new mode 100755
diff --git a/Xcode/SDLTest/SDLTest.xcodeproj/project.pbxproj b/Xcode/SDLTest/SDLTest.xcodeproj/project.pbxproj
old mode 100644
new mode 100755
diff --git a/src/hidapi/android/hid.cpp b/src/hidapi/android/hid.cpp
index 403a77d..7b8d41c 100644
--- a/src/hidapi/android/hid.cpp
+++ b/src/hidapi/android/hid.cpp
@@ -14,6 +14,10 @@
#include <string.h> // For memcpy()
#define TAG "hidapi"
+
+// Have error log always available
+#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
+
#ifdef DEBUG
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, TAG, __VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
@@ -398,6 +402,33 @@ public:
return m_pDevice;
}
+ void ExceptionCheck( JNIEnv *env, const char *pszMethodName )
+ {
+ if ( env->ExceptionCheck() )
+ {
+ // Get our exception
+ jthrowable jExcept = env->ExceptionOccurred();
+
+ // Clear the exception so we can call JNI again
+ env->ExceptionClear();
+
+ // Get our exception message
+ jclass jExceptClass = env->GetObjectClass( jExcept );
+ jmethodID jMessageMethod = env->GetMethodID( jExceptClass, "getMessage", "()Ljava/lang/String;" );
+ jstring jMessage = (jstring)( env->CallObjectMethod( jExcept, jMessageMethod ) );
+ const char *pszMessage = env->GetStringUTFChars( jMessage, NULL );
+
+ // ...and log it.
+ LOGE( "CHIDDevice::%s threw an exception: %s", pszMethodName, pszMessage );
+
+ // Cleanup
+ env->ReleaseStringUTFChars( jMessage, pszMessage );
+ env->DeleteLocalRef( jMessage );
+ env->DeleteLocalRef( jExceptClass );
+ env->DeleteLocalRef( jExcept );
+ }
+ }
+
bool BOpen()
{
// Make sure thread is attached to JVM/env
@@ -407,6 +438,7 @@ public:
m_bIsWaitingForOpen = false;
m_bOpenResult = env->CallBooleanMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerOpen, m_nId );
+ ExceptionCheck( env, "BOpen" );
if ( m_bIsWaitingForOpen )
{
@@ -515,6 +547,8 @@ public:
jbyteArray pBuf = NewByteArray( env, pData, nDataLen );
int nRet = env->CallIntMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerSendOutputReport, m_nId, pBuf );
+ ExceptionCheck( env, "SendOutputReport" );
+
env->DeleteLocalRef( pBuf );
return nRet;
}
@@ -528,6 +562,7 @@ public:
jbyteArray pBuf = NewByteArray( env, pData, nDataLen );
int nRet = env->CallIntMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerSendFeatureReport, m_nId, pBuf );
+ ExceptionCheck( env, "SendFeatureReport" );
env->DeleteLocalRef( pBuf );
return nRet;
}
@@ -564,6 +599,7 @@ public:
jbyteArray pBuf = NewByteArray( env, pData, nDataLen );
int nRet = env->CallBooleanMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerGetFeatureReport, m_nId, pBuf ) ? 0 : -1;
+ ExceptionCheck( env, "GetFeatureReport" );
env->DeleteLocalRef( pBuf );
if ( nRet < 0 )
{
@@ -622,7 +658,8 @@ public:
pthread_setspecific( g_ThreadKey, (void*)env );
env->CallVoidMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerClose, m_nId );
-
+ ExceptionCheck( env, "Close" );
+
hid_mutex_guard dataLock( &m_dataLock );
m_vecData.clear();