From c4b1fffb22e8b20ffe51c5367cdf49eaeada9546 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Wed, 23 Apr 2014 15:14:13 +0200 Subject: Android: Update QSslSocketPrivate::fetchSslCertificateData() Replaces the raw jni calls with our own jni wrappers. This allows us to make use of the centralized cache, avoid global data storage and use a more optimized way to attach to the jni environment. This change also removes the JNI_OnLoad() function since it's not used. If we need to add a JNI_OnLoad() function later, we should find a more suited place for it. Change-Id: Id84ead10c27d03d19c160304b1f9853b381a103c Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/network/ssl/qsslsocket_openssl_android.cpp | 126 ++++--------------------- 1 file changed, 16 insertions(+), 110 deletions(-) (limited to 'src/network') diff --git a/src/network/ssl/qsslsocket_openssl_android.cpp b/src/network/ssl/qsslsocket_openssl_android.cpp index c7cf03d86d..8cff542e47 100644 --- a/src/network/ssl/qsslsocket_openssl_android.cpp +++ b/src/network/ssl/qsslsocket_openssl_android.cpp @@ -55,126 +55,32 @@ ****************************************************************************/ #include "qsslsocket_openssl_p.h" - - - -#include -#include - -static JavaVM *javaVM = 0; -static jclass appClass; - -static jmethodID getSslCertificatesMethodID; - -struct AttachedJNIEnv -{ - AttachedJNIEnv() - { - attached = false; - if (javaVM->GetEnv((void**)&jniEnv, JNI_VERSION_1_6) < 0) { - if (javaVM->AttachCurrentThread(&jniEnv, NULL) < 0) { - __android_log_print(ANDROID_LOG_ERROR, "Qt", "AttachCurrentThread failed"); - jniEnv = 0; - return; - } - attached = true; - } - } - - ~AttachedJNIEnv() - { - if (attached) - javaVM->DetachCurrentThread(); - } - bool attached; - JNIEnv *jniEnv; -}; - -static const char logTag[] = "Qt"; -static const char classErrorMsg[] = "Can't find class \"%s\""; -static const char methodErrorMsg[] = "Can't find method \"%s%s\""; - - -#define FIND_AND_CHECK_CLASS(CLASS_NAME) \ -clazz = env->FindClass(CLASS_NAME); \ -if (!clazz) { \ - __android_log_print(ANDROID_LOG_FATAL, logTag, classErrorMsg, CLASS_NAME); \ - return JNI_FALSE; \ -} - -#define GET_AND_CHECK_STATIC_METHOD(VAR, CLASS, METHOD_NAME, METHOD_SIGNATURE) \ -VAR = env->GetStaticMethodID(CLASS, METHOD_NAME, METHOD_SIGNATURE); \ -if (!VAR) { \ - __android_log_print(ANDROID_LOG_FATAL, logTag, methodErrorMsg, METHOD_NAME, METHOD_SIGNATURE); \ - return JNI_FALSE; \ -} - -static bool registerNatives(JNIEnv *env) -{ - jclass clazz; - FIND_AND_CHECK_CLASS("org/qtproject/qt5/android/QtNative"); - appClass = static_cast(env->NewGlobalRef(clazz)); - -#if 0 //we don't call C++ functions from Java at this time - if (env->RegisterNatives(appClass, methods, sizeof(methods) / sizeof(methods[0])) < 0) { - __android_log_print(ANDROID_LOG_FATAL, logTag, "RegisterNatives failed"); - return JNI_FALSE; - } -#endif - - GET_AND_CHECK_STATIC_METHOD(getSslCertificatesMethodID, appClass, "getSSLCertificates", "()[[B"); - - return true; -} - -Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void * /*reserved*/) -{ - typedef union { - JNIEnv *nativeEnvironment; - void *venv; - } UnionJNIEnvToVoid; - - __android_log_print(ANDROID_LOG_INFO, logTag, "Network start"); - UnionJNIEnvToVoid uenv; - uenv.venv = NULL; - javaVM = 0; - - if (vm->GetEnv(&uenv.venv, JNI_VERSION_1_4) != JNI_OK) { - __android_log_print(ANDROID_LOG_FATAL, logTag, "GetEnv failed"); - return -1; - } - JNIEnv *env = uenv.nativeEnvironment; - if (!registerNatives(env)) { - __android_log_print(ANDROID_LOG_FATAL, logTag, "registerNatives failed"); - return -1; - } - - javaVM = vm; - return JNI_VERSION_1_4; -} +#include QT_BEGIN_NAMESPACE QList QSslSocketPrivate::fetchSslCertificateData() { QList certificateData; - AttachedJNIEnv env; - if (env.jniEnv) { - jobjectArray jcertificates = - static_cast(env.jniEnv->CallStaticObjectMethod(appClass, getSslCertificatesMethodID)); - jint nCertificates = env.jniEnv->GetArrayLength(jcertificates); + QJNIObjectPrivate certificates = QJNIObjectPrivate::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", + "getSSLCertificates", + "()[[B"); + if (!certificates.isValid()) + return certificateData; - for (int i = 0; i < nCertificates; ++i) { - jbyteArray jCert = static_cast(env.jniEnv->GetObjectArrayElement(jcertificates, i)); + QJNIEnvironmentPrivate env; + jobjectArray jcertificates = static_cast(certificates.object()); + const jint nCertificates = env->GetArrayLength(jcertificates); - const uint sz = env.jniEnv->GetArrayLength(jCert); - jbyte *buffer = env.jniEnv->GetByteArrayElements(jCert, 0); - certificateData.append(QByteArray(reinterpret_cast(buffer), sz)); + for (int i = 0; i < nCertificates; ++i) { + jbyteArray jCert = static_cast(env->GetObjectArrayElement(jcertificates, i)); + const uint sz = env->GetArrayLength(jCert); + jbyte *buffer = env->GetByteArrayElements(jCert, 0); + certificateData.append(QByteArray(reinterpret_cast(buffer), sz)); - env.jniEnv->ReleaseByteArrayElements(jCert, buffer, JNI_ABORT); // don't copy back the elements - env.jniEnv->DeleteLocalRef(jCert); - } + env->ReleaseByteArrayElements(jCert, buffer, JNI_ABORT); // don't copy back the elements + env->DeleteLocalRef(jCert); } return certificateData; -- cgit v1.2.3