diff options
author | Christian Strømme <christian.stromme@digia.com> | 2014-04-23 15:14:13 +0200 |
---|---|---|
committer | Christian Stromme <christian.stromme@digia.com> | 2014-07-14 02:24:36 +0200 |
commit | c4b1fffb22e8b20ffe51c5367cdf49eaeada9546 (patch) | |
tree | 930e9e732d6feaaf508078dc7465a795b97a6765 /src | |
parent | d88e4edcd548e5bb024e75016c5a3449d103bd8d (diff) |
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 <eskil.abrahamsen-blomfeldt@digia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/network/ssl/qsslsocket_openssl_android.cpp | 126 |
1 files changed, 16 insertions, 110 deletions
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 <jni.h> -#include <android/log.h> - -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<jclass>(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 <QtCore/private/qjni_p.h> QT_BEGIN_NAMESPACE QList<QByteArray> QSslSocketPrivate::fetchSslCertificateData() { QList<QByteArray> certificateData; - AttachedJNIEnv env; - if (env.jniEnv) { - jobjectArray jcertificates = - static_cast<jobjectArray>(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<jbyteArray>(env.jniEnv->GetObjectArrayElement(jcertificates, i)); + QJNIEnvironmentPrivate env; + jobjectArray jcertificates = static_cast<jobjectArray>(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<char*>(buffer), sz)); + for (int i = 0; i < nCertificates; ++i) { + jbyteArray jCert = static_cast<jbyteArray>(env->GetObjectArrayElement(jcertificates, i)); + const uint sz = env->GetArrayLength(jCert); + jbyte *buffer = env->GetByteArrayElements(jCert, 0); + certificateData.append(QByteArray(reinterpret_cast<char*>(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; |