From 0c251d79739785b79ccd3698757751da48b24510 Mon Sep 17 00:00:00 2001 From: Don Gagne Date: Sun, 18 Oct 2015 09:54:50 -0700 Subject: [PATCH] Fix native function setting --- .../qgchelper/UsbDeviceJNI.java | 1 - libs/qtandroidserialport/src/qserialport.cpp | 6 ++ libs/qtandroidserialport/src/qserialport.h | 2 + .../src/qserialport_android.cpp | 77 +++++++++---------- .../src/qserialport_android_p.h | 3 +- src/main.cc | 19 +++++ 6 files changed, 66 insertions(+), 42 deletions(-) diff --git a/android/src/org/qgroundcontrol/qgchelper/UsbDeviceJNI.java b/android/src/org/qgroundcontrol/qgchelper/UsbDeviceJNI.java index f9bad7086..b317c408c 100644 --- a/android/src/org/qgroundcontrol/qgchelper/UsbDeviceJNI.java +++ b/android/src/org/qgroundcontrol/qgchelper/UsbDeviceJNI.java @@ -79,7 +79,6 @@ public class UsbDeviceJNI extends QtActivity } }; - // NATIVE C++ FUNCTION THAT WILL BE CALLED IF THE DEVICE IS UNPLUGGED private static native void nativeDeviceHasDisconnected(int userDataA); private static native void nativeDeviceException(int userDataA, String messageA); diff --git a/libs/qtandroidserialport/src/qserialport.cpp b/libs/qtandroidserialport/src/qserialport.cpp index 54cbee2e2..c306e7f5d 100644 --- a/libs/qtandroidserialport/src/qserialport.cpp +++ b/libs/qtandroidserialport/src/qserialport.cpp @@ -1370,6 +1370,12 @@ void QSerialPort::setError(QSerialPort::SerialPortError serialPortError, const Q emit error(serialPortError); } +void QSerialPort::setNativeMethods(void) +{ + QSerialPortPrivate::setNativeMethods(); +} + + #include "moc_qserialport.cpp" QT_END_NAMESPACE diff --git a/libs/qtandroidserialport/src/qserialport.h b/libs/qtandroidserialport/src/qserialport.h index e1b6aea92..0fae3545a 100644 --- a/libs/qtandroidserialport/src/qserialport.h +++ b/libs/qtandroidserialport/src/qserialport.h @@ -247,6 +247,8 @@ public: Handle handle() const; + static void setNativeMethods(void); + Q_SIGNALS: void baudRateChanged(qint32 baudRate, QSerialPort::Directions directions); void dataBitsChanged(QSerialPort::DataBits dataBits); diff --git a/libs/qtandroidserialport/src/qserialport_android.cpp b/libs/qtandroidserialport/src/qserialport_android.cpp index 4c15cd2ea..675805a45 100644 --- a/libs/qtandroidserialport/src/qserialport_android.cpp +++ b/libs/qtandroidserialport/src/qserialport_android.cpp @@ -106,7 +106,6 @@ QSerialPortPrivate::QSerialPortPrivate(QSerialPort *q) , isCustomBaudRateSupported(false) , emittedBytesWritten(false) , pendingBytesWritten(0) - , hasRegisteredFunctions(false) , jniDataBits(8) , jniStopBits(1) , jniParity(0) @@ -115,6 +114,43 @@ QSerialPortPrivate::QSerialPortPrivate(QSerialPort *q) { } +void QSerialPortPrivate::setNativeMethods(void) +{ + __android_log_print(ANDROID_LOG_INFO, kJTag, "Registering Native Functions"); + + // REGISTER THE C++ FUNCTION WITH JNI + JNINativeMethod javaMethods[] { + {"nativeDeviceHasDisconnected", "(I)V", reinterpret_cast(jniDeviceHasDisconnected)}, + {"nativeDeviceNewData", "(I[B)V", reinterpret_cast(jniDeviceNewData)}, + {"nativeDeviceException", "(ILjava/lang/String;)V", reinterpret_cast(jniDeviceException)} + }; + + QAndroidJniEnvironment jniEnv; + if (jniEnv->ExceptionCheck()) { + jniEnv->ExceptionDescribe(); + jniEnv->ExceptionClear(); + } + + jclass objectClass = jniEnv->FindClass(kJniClassName); + if(!objectClass) { + __android_log_print(ANDROID_LOG_ERROR, kJTag, "Couldn't find class: %s", kJniClassName); + return; + } + + jint val = jniEnv->RegisterNatives(objectClass, javaMethods, sizeof(javaMethods) / sizeof(javaMethods[0])); + + __android_log_print(ANDROID_LOG_INFO, kJTag, "Native Functions Registered"); + + if (jniEnv->ExceptionCheck()) { + jniEnv->ExceptionDescribe(); + jniEnv->ExceptionClear(); + } + + if (val < 0) { + __android_log_print(ANDROID_LOG_ERROR, kJTag, "Error registering methods"); + } +} + bool QSerialPortPrivate::open(QIODevice::OpenMode mode) { rwMode = mode; @@ -140,45 +176,6 @@ bool QSerialPortPrivate::open(QIODevice::OpenMode mode) return false; } - if (!hasRegisteredFunctions) - { - __android_log_print(ANDROID_LOG_INFO, kJTag, "Registering Native Functions"); - // REGISTER THE C++ FUNCTION WITH JNI - JNINativeMethod javaMethods[] { - {"nativeDeviceHasDisconnected", "(I)V", reinterpret_cast(jniDeviceHasDisconnected)}, - {"nativeDeviceNewData", "(I[B)V", reinterpret_cast(jniDeviceNewData)}, - {"nativeDeviceException", "(ILjava/lang/String;)V", reinterpret_cast(jniDeviceException)} - }; - - QAndroidJniEnvironment jniEnv; - if (jniEnv->ExceptionCheck()) { - jniEnv->ExceptionDescribe(); - jniEnv->ExceptionClear(); - } - - QAndroidJniObject javaClass(kJniClassName); - if(!javaClass.isValid()) { - __android_log_print(ANDROID_LOG_ERROR, kJTag, "Java class %s not valid", kJniClassName); - return false; - } - jclass objectClass = jniEnv->GetObjectClass(javaClass.object()); - jint val = jniEnv->RegisterNatives(objectClass, javaMethods, sizeof(javaMethods) / sizeof(javaMethods[0])); - jniEnv->DeleteLocalRef(objectClass); - hasRegisteredFunctions = true; - __android_log_print(ANDROID_LOG_INFO, kJTag, "Native Functions Registered"); - - if (jniEnv->ExceptionCheck()) { - jniEnv->ExceptionDescribe(); - jniEnv->ExceptionClear(); - } - - if(val < 0) { - __android_log_print(ANDROID_LOG_ERROR, kJTag, "Error registering methods"); - q_ptr->setError(QSerialPort::OpenError); - return false; - } - } - __android_log_print(ANDROID_LOG_INFO, kJTag, "Calling Java getDeviceHandle"); cleanJavaException(); descriptor = QAndroidJniObject::callStaticMethod( diff --git a/libs/qtandroidserialport/src/qserialport_android_p.h b/libs/qtandroidserialport/src/qserialport_android_p.h index f105c1fd7..c10c41cc4 100644 --- a/libs/qtandroidserialport/src/qserialport_android_p.h +++ b/libs/qtandroidserialport/src/qserialport_android_p.h @@ -108,10 +108,11 @@ public: qint64 pendingBytesWritten; + static void setNativeMethods(void); + private: QIODevice::OpenMode rwMode; int deviceId; - bool hasRegisteredFunctions; int jniDataBits; int jniStopBits; int jniParity; diff --git a/src/main.cc b/src/main.cc index 1b48c55ca..3fa649377 100644 --- a/src/main.cc +++ b/src/main.cc @@ -86,6 +86,25 @@ int WindowsCrtReportHook(int reportType, char* message, int* returnValue) #endif +#ifdef __android__ +#include +#include "qserialport.h" + +jint JNI_OnLoad(JavaVM* vm, void* reserved) +{ + Q_UNUSED(reserved); + + JNIEnv* env; + if (vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6) != JNI_OK) { + return -1; + } + + QSerialPort::setNativeMethods(); + + return JNI_VERSION_1_6; +} +#endif + /** * @brief Starts the application * -- 2.22.0