remove globals from DcContext (formerly MrMailbox) to allow multiple instances, add class derived from DcContext

This commit is contained in:
B. Petersen
2018-08-18 23:35:16 +02:00
parent b4bc628f17
commit 59490310fd
6 changed files with 63 additions and 38 deletions
+24 -30
View File
@@ -64,29 +64,6 @@ static jstring jstring_new__(JNIEnv* env, const char* a)
}
/* global stuff */
static JavaVM* s_jvm = NULL;
static jclass s_DcContext_class = NULL;
static jmethodID s_DcCallback_methodID = NULL;
static int s_global_init_done = 0;
static void s_init_globals(JNIEnv *env, jclass DcContext_class)
{
/* make sure, the intialisation is done only once */
if( s_global_init_done ) { return; }
s_global_init_done = 1;
/* prepare calling back a Java function */
(*env)->GetJavaVM(env, &s_jvm); /* JNIEnv cannot be shared between threads, so we share the JavaVM object */
s_DcContext_class = (*env)->NewGlobalRef(env, DcContext_class);
s_DcCallback_methodID = (*env)->GetStaticMethodID(env, DcContext_class, "handleEvent","(IJJ)J" /*signature as "(param)ret" with I=int, J=long*/ );
}
/* tools */
static jintArray dc_array2jintArray_n_unref(JNIEnv *env, dc_array_t* ca)
{
/* takes a C-array of type dc_array_t and converts it it a Java-Array.
@@ -152,6 +129,14 @@ static uint32_t* jintArray2uint32Pointer(JNIEnv* env, jintArray ja, int* ret_icn
******************************************************************************/
typedef struct dc_jnicontext_t {
JavaVM* jvm; // JNIEnv cannot be shared between threads, so we share the JavaVM object
jclass cls;
jobject obj;
jmethodID methodId;
} dc_jnicontext_t;
static dc_context_t* get_dc_context(JNIEnv *env, jobject obj)
{
static jfieldID fid = 0;
@@ -166,23 +151,22 @@ static dc_context_t* get_dc_context(JNIEnv *env, jobject obj)
}
/* DcContext - new/delete */
static uintptr_t s_context_callback_(dc_context_t* context, int event, uintptr_t data1, uintptr_t data2)
{
jlong l;
JNIEnv* env;
dc_jnicontext_t* jnicontext = dc_get_userdata(context);
if( s_jvm==NULL || s_DcContext_class==NULL || s_DcCallback_methodID==NULL ) {
if( jnicontext==NULL || jnicontext->jvm==NULL || jnicontext->cls==NULL || jnicontext->obj==NULL || jnicontext->methodId==NULL ) {
return 0; /* may happen on startup */
}
(*s_jvm)->GetEnv(s_jvm, &env, JNI_VERSION_1_6); /* as this function may be called from _any_ thread, we cannot use a static pointer to JNIEnv */
(*jnicontext->jvm)->GetEnv(jnicontext->jvm, &env, JNI_VERSION_1_6); // as this function may be called from _any_ thread, we cannot use a static pointer to JNIEnv
if( env==NULL ) {
return 0; /* may happen on startup */
}
l = (*env)->CallStaticLongMethod(env, s_DcContext_class, s_DcCallback_methodID, (jint)event, (jlong)data1, (jlong)data2);
l = (*env)->CallLongMethod(env, jnicontext->obj, jnicontext->methodId, (jint)event, (jlong)data1, (jlong)data2);
return (uintptr_t)l;
}
@@ -190,9 +174,19 @@ static uintptr_t s_context_callback_(dc_context_t* context, int event, uintptr_t
JNIEXPORT jlong Java_com_b44t_messenger_DcContext_DcContextNew(JNIEnv *env, jobject obj, jstring osname)
{
jclass cls = (*env)->GetObjectClass(env, obj);
s_init_globals(env, cls);
dc_jnicontext_t* jnicontext = calloc(1, sizeof(dc_jnicontext_t));
if (cls==NULL || jnicontext==NULL) {
return 0;
}
(*env)->GetJavaVM(env, &jnicontext->jvm);
jnicontext->cls = (*env)->NewGlobalRef(env, cls);
jnicontext->obj = (*env)->NewGlobalRef(env, obj);
jnicontext->methodId = (*env)->GetMethodID(env, jnicontext->cls, "handleEvent","(IJJ)J" /*signature as "(param)ret" with I=int, J=long*/ );
CHAR_REF(osname);
jlong hContext = (jlong)dc_context_new(s_context_callback_, NULL, osnamePtr);
jlong hContext = (jlong)dc_context_new(s_context_callback_, jnicontext, osnamePtr);
CHAR_UNREF(osname);
return hContext;
}
+1
View File
@@ -24,6 +24,7 @@ package com.b44t.messenger;
public class DcChatlist {
public DcChatlist(long hChatlist) {
m_hChatlist = hChatlist;
}
+3 -4
View File
@@ -68,7 +68,7 @@ public class DcContext {
public final static int DC_QR_ERROR = 400;
public DcContext(String osName) {
handleEvent(0,0,0);
handleEvent(0,0,0); // call handleEvent() to make sure it is not optimized away and JNI won't find it
m_hContext = DcContextNew(osName);
}
@@ -141,9 +141,8 @@ public class DcContext {
public native String getSecurejoinQr(int chat_id);
public native int joinSecurejoin(String qr);
// event handling
public static long handleEvent(final int event, final long data1, final long data2) // this function is called from within the C-wrapper
{
// event handling - you should @Override this function in derived classes
public long handleEvent(final int event, final long data1, final long data2) {
return 0;
}
+1 -2
View File
@@ -22,9 +22,8 @@
package com.b44t.messenger;
public class DcMsg {
private static final String TAG = "DcMsg";
public class DcMsg {
public final static int DC_MSG_UNDEFINED = 0;
public final static int DC_MSG_TEXT = 10;
@@ -82,7 +82,7 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
private volatile boolean isAppVisible;
public DcContext dcContext;
public ApplicationDcContext dcContext;
public static ApplicationContext getInstance(Context context) {
return (ApplicationContext)context.getApplicationContext();
@@ -93,7 +93,8 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
super.onCreate();
System.loadLibrary("native-utils");
dcContext = new DcContext("Android");
dcContext = new ApplicationDcContext();
dcContext.open("foo");
initializeRandomNumberFix();
initializeLogging();
@@ -0,0 +1,31 @@
/*
* Copyright (C) 2018 Delta Chat contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.thoughtcrime.securesms;
import com.b44t.messenger.DcContext;
public class ApplicationDcContext extends DcContext {
public ApplicationDcContext() {
super("Android");
}
@Override public long handleEvent(final int event, final long data1, final long data2) {
return 0;
}
}