From c4918db58094ec85f672bf2c22358b846598bcb7 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 22 Oct 2018 14:55:42 -0700 Subject: [PATCH] Add exception handling to Android hidapi. --- .../Demos/Demos.xcodeproj/project.pbxproj | 0 Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj | 0 .../TestiPhoneOS.xcodeproj/project.pbxproj | 0 Xcode/SDL/SDL.xcodeproj/project.pbxproj | 0 .../SDLTest/SDLTest.xcodeproj/project.pbxproj | 0 src/hidapi/android/hid.cpp | 39 ++++++++++++++++++- 6 files changed, 38 insertions(+), 1 deletion(-) mode change 100644 => 100755 Xcode-iOS/Demos/Demos.xcodeproj/project.pbxproj mode change 100644 => 100755 Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj mode change 100644 => 100755 Xcode-iOS/Test/TestiPhoneOS.xcodeproj/project.pbxproj mode change 100644 => 100755 Xcode/SDL/SDL.xcodeproj/project.pbxproj mode change 100644 => 100755 Xcode/SDLTest/SDLTest.xcodeproj/project.pbxproj 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 403a77d72..7b8d41c71 100644 --- a/src/hidapi/android/hid.cpp +++ b/src/hidapi/android/hid.cpp @@ -14,6 +14,10 @@ #include // 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();