From 7fb0eefc6951dbfed258640878b8f19426703a87 Mon Sep 17 00:00:00 2001 From: heck Date: Wed, 8 Feb 2023 18:14:36 +0530 Subject: [PATCH] FIX: #33 - BUG: JNI cannot find existing class which leads to hardcrash. Not reproducable on macOS. Globalrefs _seem_ to be thread local on Android, but not on macOS (or different versions or implementations of the JVM) --- ...oundation_pEp_jniadapter_AbstractEngine.cc | 6 ++-- src/cxx/jniutils.cc | 36 +++++++++++++++++++ src/cxx/jniutils.hh | 4 +++ 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/cxx/foundation_pEp_jniadapter_AbstractEngine.cc b/src/cxx/foundation_pEp_jniadapter_AbstractEngine.cc index eb4e9a6..3c86927 100644 --- a/src/cxx/foundation_pEp_jniadapter_AbstractEngine.cc +++ b/src/cxx/foundation_pEp_jniadapter_AbstractEngine.cc @@ -33,6 +33,7 @@ jmethodID passphrase_callback_values = nullptr; jobject objj = nullptr; jclass messageClass = nullptr; +jclass identityClass = nullptr; jclass signalClass = nullptr; jclass abstractEngineClass = nullptr; jclass passphraseTypeClass = nullptr; @@ -68,6 +69,7 @@ void jni_init() { JNIEnv * _env = JNISync::env(); messageClass = static_cast(_env->NewGlobalRef(findClass(_env, "foundation/pEp/jniadapter/Message"))); + identityClass = static_cast(_env->NewGlobalRef(findClass(_env, "foundation/pEp/jniadapter/_Identity"))); signalClass = static_cast(_env->NewGlobalRef(findClass(_env, "foundation/pEp/jniadapter/SyncHandshakeSignal"))); passphraseTypeClass = static_cast(_env->NewGlobalRef(findClass(_env, "foundation/pEp/jniadapter/PassphraseType"))); abstractEngineClass = static_cast(_env->NewGlobalRef(findClass(_env, "foundation/pEp/jniadapter/AbstractEngine"))); @@ -201,8 +203,8 @@ PEP_STATUS notifyHandshake(pEp_identity *me, jobject me_ = nullptr; jobject partner_ = nullptr; - me_ = from_identity(JNISync::env(), me); - partner_ = from_identity(JNISync::env(), partner); + me_ = from_identity(JNISync::env(), me, identityClass); + partner_ = from_identity(JNISync::env(), partner, identityClass); jobject signal_ = nullptr; { diff --git a/src/cxx/jniutils.cc b/src/cxx/jniutils.cc index 7eca08c..9b8c31f 100644 --- a/src/cxx/jniutils.cc +++ b/src/cxx/jniutils.cc @@ -502,6 +502,42 @@ jobject from_identity(JNIEnv *env, return obj; } +// This is being uesd from the callbacks, the env differs. +// Globalrefs _seem_ to be thread local on Android, but not on macOS (or different versions or implementations of the JVM) +jobject from_identity(JNIEnv *env, + pEp_identity *ident, + jclass identityClass) +{ + if (!ident) { + return (jobject) NULL; + } + + static const char *classname = "foundation/pEp/jniadapter/_Identity"; + jmethodID constructor = env->GetMethodID(identityClass, "", "()V"); + assert(constructor); + jobject obj = env->NewObject(identityClass, constructor); + + if (ident) { + _setStringField(env, classname, obj, "address", ident->address, identityClass); + _setStringField(env, classname, obj, "fpr", ident->fpr, identityClass); + _setStringField(env, classname, obj, "user_id", ident->user_id, identityClass); + _setStringField(env, classname, obj, "username", ident->username, identityClass); + + jfieldID comm_type_id = getFieldID(env, classname, "comm_type", "I", identityClass); + env->SetIntField(obj, comm_type_id, static_cast(ident->comm_type)); + + _setStringField(env, classname, obj, "lang", ident->lang, identityClass); + + jfieldID me_id = getFieldID(env, classname, "me", "Z", identityClass); + env->SetBooleanField(obj, me_id, static_cast(ident->me)); + + jfieldID flags_id = getFieldID(env, classname, "flags", "I", identityClass); + env->SetIntField(obj, flags_id, static_cast(ident->flags)); + } + + return obj; +} + char *_getStringField(JNIEnv *env, const char *classname, jobject obj, diff --git a/src/cxx/jniutils.hh b/src/cxx/jniutils.hh index 5f8ea0c..d7a6b25 100644 --- a/src/cxx/jniutils.hh +++ b/src/cxx/jniutils.hh @@ -105,6 +105,10 @@ timestamp *to_timestamp(JNIEnv *env, jobject from_identity(JNIEnv *env, pEp_identity *ident); +jobject from_identity(JNIEnv *env, + pEp_identity *ident, + jclass identityClass); + pEp_identity *to_identity(JNIEnv *env, jobject obj);