linphonecore_jni.cc 347 KB
Newer Older
jehan's avatar
jehan committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/*
linphonecore_jni.cc
Copyright (C) 2010  Belledonne Communications, Grenoble, France

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 2
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, write to the Free Software
17
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
jehan's avatar
jehan committed
18 19
 */
#include <jni.h>
20
#ifdef USE_JAVAH
21
#include "linphonecore_jni.h"
22
#endif
23
#include "linphone/core_utils.h"
24
#include <mediastreamer2/zrtp.h>
jehan's avatar
jehan committed
25

Guillaume Beraudo's avatar
Guillaume Beraudo committed
26

27 28
extern "C" {
#include "mediastreamer2/mediastream.h"
29
#include "mediastreamer2/mscommon.h"
François Grisez's avatar
François Grisez committed
30
#include "mediastreamer2/msmediaplayer.h"
Gautier Pelloux-Prayer's avatar
Gautier Pelloux-Prayer committed
31
#include "mediastreamer2/msutils.h"
32
#include "mediastreamer2/devices.h"
33
}
Simon Morlat's avatar
Simon Morlat committed
34
#include "mediastreamer2/msjava.h"
35 36
#include "linphone/core.h"
#include "linphone/tunnel.h"
37
#include "linphone/account_creator.h"
38 39

#include "private.h" /*Included for multicast and wifi lock management by linphonecore. Very ugly.*/
40 41
#include <cpu-features.h>

42
#include "linphone/lpconfig.h"
43

44
#ifdef __ANDROID__
jehan's avatar
jehan committed
45
#include <android/log.h>
46
#include <belle-sip/wakelock.h>
47
#endif /* __ANDROID__ */
jehan's avatar
jehan committed
48

Ghislain MARY's avatar
Ghislain MARY committed
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
#define RETURN_USER_DATA_OBJECT(javaclass, funcprefix, cobj) \
	{ \
		jclass jUserDataObjectClass; \
		jmethodID jUserDataObjectCtor; \
		jobject jUserDataObj; \
		jUserDataObj = (jobject)funcprefix ## _get_user_data(cobj); \
		if (jUserDataObj == NULL) { \
			jUserDataObjectClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/" javaclass)); \
			jUserDataObjectCtor = env->GetMethodID(jUserDataObjectClass,"<init>", "(J)V"); \
			jUserDataObj = env->NewObject(jUserDataObjectClass, jUserDataObjectCtor, (jlong)funcprefix ## _ref(cobj)); \
			jUserDataObj = env->NewGlobalRef(jUserDataObj); \
			funcprefix ## _set_user_data(cobj, jUserDataObj); \
			env->DeleteGlobalRef(jUserDataObjectClass); \
		} \
		return jUserDataObj; \
	}

jehan's avatar
jehan committed
66
static JavaVM *jvm=0;
67
static const char* LogDomain = "Linphone";
68 69 70
static jclass handler_class;
static jmethodID loghandler_id;
static jobject handler_obj=NULL;
jehan's avatar
jehan committed
71

72
static jobject create_java_linphone_content(JNIEnv *env, const LinphoneContent *content);
73
static jobject create_java_linphone_buffer(JNIEnv *env, const LinphoneBuffer *buffer);
74
static LinphoneBuffer* create_c_linphone_buffer_from_java_linphone_buffer(JNIEnv *env, jobject jbuffer);
75
static jobject getTunnelConfig(JNIEnv *env, LinphoneTunnelConfig *cfg);
76

77
#ifdef __ANDROID__
78
void linphone_android_log_handler(int prio, char *str) {
79 80
	char *current;
	char *next;
81 82

	if (strlen(str) < 512) {
83
		__android_log_write(prio, LogDomain, str);
84 85 86
	} else {
		current = str;
		while ((next = strchr(current, '\n')) != NULL) {
87

88
			*next = '\0';
89 90
			if (next != str && next[-1] == '\r')
				next[-1] = '\0';
91
			__android_log_write(prio, LogDomain, current);
92 93
			current = next + 1;
		}
94
		__android_log_write(prio, LogDomain, current);
95
	}
jehan's avatar
jehan committed
96
}
97

Sylvain Berfini's avatar
Sylvain Berfini committed
98 99 100 101 102 103
JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneCoreFactoryImpl__1setLogHandler(JNIEnv *env, jobject jfactory, jobject jhandler) {
	if (handler_obj) {
		env->DeleteGlobalRef(handler_obj);
		handler_obj = NULL;
	}
	if (jhandler) {
104 105
		handler_class = (jclass) env->GetObjectClass(jhandler);
		loghandler_id = env->GetMethodID(handler_class, "log", "(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)V");
106

107 108 109
		if (loghandler_id == NULL) {
			ms_fatal("log method not found");
		}
Sylvain Berfini's avatar
Sylvain Berfini committed
110 111 112 113
		handler_obj = env->NewGlobalRef(jhandler);
	}
}

Simon Morlat's avatar
Simon Morlat committed
114
static void linphone_android_ortp_log_handler(const char *domain, OrtpLogLevel lev, const char *fmt, va_list args) {
115
	char str[4096];
Sylvain Berfini's avatar
Sylvain Berfini committed
116
	const char *levname = "undef";
117 118
	vsnprintf(str, sizeof(str) - 1, fmt, args);
	str[sizeof(str) - 1] = '\0';
Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
119

120
	int prio;
Sylvain Berfini's avatar
Sylvain Berfini committed
121 122 123 124 125 126 127 128
	switch(lev) {
		case ORTP_DEBUG:	prio = ANDROID_LOG_DEBUG;	levname="debug"; break;
		case ORTP_MESSAGE:	prio = ANDROID_LOG_INFO;	levname="message"; break;
		case ORTP_WARNING:	prio = ANDROID_LOG_WARN;	levname="warning"; break;
		case ORTP_ERROR:	prio = ANDROID_LOG_ERROR;	levname="error"; break;
		case ORTP_FATAL:	prio = ANDROID_LOG_FATAL;	levname="fatal"; break;
		default:			prio = ANDROID_LOG_DEFAULT;	break;
	}
129

Sylvain Berfini's avatar
Sylvain Berfini committed
130 131 132 133 134 135
	if (handler_obj) {
		JNIEnv *env = ms_get_jni_env();
		jstring jdomain = env->NewStringUTF(LogDomain);
		jstring jlevname = env->NewStringUTF(levname);
		jstring jstr = env->NewStringUTF(str);
		env->CallVoidMethod(handler_obj, loghandler_id, jdomain, (jint)lev, jlevname, jstr, NULL);
136 137 138
		if (jdomain) env->DeleteLocalRef(jdomain);
		if (jlevname) env->DeleteLocalRef(jlevname);
		if (jstr) env->DeleteLocalRef(jstr);
Sylvain Berfini's avatar
Sylvain Berfini committed
139
	} else {
140
		linphone_android_log_handler(prio, str);
Sylvain Berfini's avatar
Sylvain Berfini committed
141
	}
142 143
}

144 145 146
int dumbMethodForAllowingUsageOfCpuFeaturesFromStaticLibMediastream() {
	return (android_getCpuFamily() == ANDROID_CPU_FAMILY_ARM && (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0);
}
147 148 149 150

int dumbMethodForAllowingUsageOfMsAudioDiffFromStaticLibMediastream() {
	return ms_audio_diff(NULL, NULL, NULL, 0, NULL, NULL);
}
151 152 153 154

extern "C" void setAndroidLogHandler() {
	linphone_core_enable_logs_with_cb(linphone_android_ortp_log_handler);
}
155 156 157 158 159 160

extern "C" void setMediastreamerAndroidContext(JNIEnv *env, void *context) {
	jclass ms_class = env->FindClass("org/linphone/mediastream/MediastreamerAndroidContext");
	jmethodID set_context = env->GetStaticMethodID(ms_class, "setContext", "(Ljava/lang/Object;)V");
	env->CallStaticVoidMethod(ms_class, set_context, (jobject)context);
}
161
#endif /* __ANDROID__ */
jehan's avatar
jehan committed
162

163

jehan's avatar
jehan committed
164 165
JNIEXPORT jint JNICALL  JNI_OnLoad(JavaVM *ajvm, void *reserved)
{
166
#ifdef __ANDROID__
Simon Morlat's avatar
Simon Morlat committed
167
	ms_set_jvm(ajvm);
168
#endif /* __ANDROID__ */
jehan's avatar
jehan committed
169 170 171 172
	jvm=ajvm;
	return JNI_VERSION_1_2;
}

173 174 175 176 177 178 179 180
static const char* GetStringUTFChars(JNIEnv* env, jstring string) {
	const char *cstring = string ? env->GetStringUTFChars(string, NULL) : NULL;
	return cstring;
}

static void ReleaseStringUTFChars(JNIEnv* env, jstring string, const char *cstring) {
	if (string) env->ReleaseStringUTFChars(string, cstring);
}
jehan's avatar
jehan committed
181

jehan's avatar
jehan committed
182
//LinphoneFactory
jehan's avatar
jehan committed
183
extern "C" void Java_org_linphone_core_LinphoneCoreFactoryImpl_setDebugMode(JNIEnv*  env
jehan's avatar
jehan committed
184
		,jobject  thiz
185 186
		,jboolean isDebug
		,jstring  jdebugTag) {
jehan's avatar
jehan committed
187
	if (isDebug) {
188
		LogDomain = GetStringUTFChars(env, jdebugTag);
189
		linphone_core_enable_logs_with_cb(linphone_android_ortp_log_handler);
jehan's avatar
jehan committed
190 191 192 193
	} else {
		linphone_core_disable_logs();
	}
}
194

195 196 197 198 199 200 201 202
extern "C" jobject Java_org_linphone_core_LinphoneCoreFactoryImpl__1createTunnelConfig(JNIEnv*  env, jobject  thiz){
	jobject jobj;
	LinphoneTunnelConfig *cfg =  linphone_tunnel_config_new();
	jobj = getTunnelConfig(env, cfg); //this will take a ref.
	linphone_tunnel_config_unref(cfg);
	return jobj;
}

203 204 205 206 207 208 209 210 211 212
extern "C" void Java_org_linphone_core_LinphoneCoreFactoryImpl_enableLogCollection(JNIEnv* env
		,jobject  thiz
		,jboolean enable) {
	linphone_core_enable_log_collection(enable ? LinphoneLogCollectionEnabledWithoutPreviousLogHandler : LinphoneLogCollectionDisabled);
}

extern "C" void Java_org_linphone_core_LinphoneCoreFactoryImpl_setLogCollectionPath(JNIEnv* env
		,jobject  thiz
		,jstring jpath) {

213
	const char* path = GetStringUTFChars(env, jpath);
214
	linphone_core_set_log_collection_path(path);
215
	ReleaseStringUTFChars(env, jpath, path);
216
}
Erwan Croze's avatar
Erwan Croze committed
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248

extern "C" jobjectArray Java_org_linphone_core_LinphoneCoreFactoryImpl_getAllDialPlanNative(JNIEnv *env, jobject thiz) {
	LinphoneDialPlan *countries;
	jclass addr_class = env->FindClass("org/linphone/core/DialPlanImpl");
	jmethodID addr_constructor = env->GetMethodID(addr_class, "<init>", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;)V");
	jobjectArray jaddr_array;
	int i, size = 0;
	countries = (LinphoneDialPlan *)linphone_dial_plan_get_all();

	while (countries[size].country != NULL) size++;

	jaddr_array = env->NewObjectArray(size, addr_class, NULL);

	for (i=0; i < size ; i++) {
		jstring jcountry = env->NewStringUTF(countries[i].country);
		jstring jiso = env->NewStringUTF(countries[i].iso_country_code);
		jstring jccc = env->NewStringUTF(countries[i].ccc);
		jint jnnl = (jint)countries[i].nnl;
		jstring jicp = env->NewStringUTF(countries[i].icp);

		jobject jaddr = env->NewObject(addr_class, addr_constructor, jcountry, jiso, jccc, jnnl, jicp);

		env->SetObjectArrayElement(jaddr_array, i, jaddr);

		env->DeleteLocalRef(jcountry);
		env->DeleteLocalRef(jiso);
		env->DeleteLocalRef(jccc);
		env->DeleteLocalRef(jicp);
	}
	return jaddr_array;
}

jehan's avatar
jehan committed
249 250
// LinphoneCore

Sylvain Berfini's avatar
Sylvain Berfini committed
251
class LinphoneJavaBindings {
jehan's avatar
jehan committed
252
public:
Sylvain Berfini's avatar
Sylvain Berfini committed
253 254
	LinphoneJavaBindings(JNIEnv *env) {
		listenerClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCoreListener"));
255

256 257
		authMethodClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCore$AuthMethod"));
		authMethodFromIntId = env->GetStaticMethodID(authMethodClass,"fromInt","(I)Lorg/linphone/core/LinphoneCore$AuthMethod;");
258

jehan's avatar
jehan committed
259
		/*displayStatus(LinphoneCore lc,String message);*/
260
		displayStatusId = env->GetMethodID(listenerClass,"displayStatus","(Lorg/linphone/core/LinphoneCore;Ljava/lang/String;)V");
261

jehan's avatar
jehan committed
262
		/*void generalState(LinphoneCore lc,int state); */
263 264
		globalStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCore$GlobalState"));
		globalStateFromIntId = env->GetStaticMethodID(globalStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneCore$GlobalState;");
265
		globalStateId = env->GetMethodID(listenerClass,"globalState","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCore$GlobalState;Ljava/lang/String;)V");
266

267 268 269
		/*registrationState(LinphoneCore lc, LinphoneProxyConfig cfg, LinphoneCore.RegistrationState cstate, String smessage);*/
		registrationStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCore$RegistrationState"));
		registrationStateFromIntId = env->GetStaticMethodID(registrationStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneCore$RegistrationState;");
270
		registrationStateId = env->GetMethodID(listenerClass,"registrationState","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneProxyConfig;Lorg/linphone/core/LinphoneCore$RegistrationState;Ljava/lang/String;)V");
271

272 273 274
		/*callState(LinphoneCore lc, LinphoneCall call, LinphoneCall.State cstate,String message);*/
		callStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCall$State"));
		callStateFromIntId = env->GetStaticMethodID(callStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneCall$State;");
275
		callStateId = env->GetMethodID(listenerClass,"callState","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;Lorg/linphone/core/LinphoneCall$State;Ljava/lang/String;)V");
276

277
		transferStateId = env->GetMethodID(listenerClass,"transferState","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;Lorg/linphone/core/LinphoneCall$State;)V");
Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
278

279 280 281
		/*callStatsUpdated(LinphoneCore lc, LinphoneCall call, LinphoneCallStats stats);*/
		callStatsUpdatedId = env->GetMethodID(listenerClass, "callStatsUpdated", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;Lorg/linphone/core/LinphoneCallStats;)V");

282
		/*callEncryption(LinphoneCore lc, LinphoneCall call, boolean encrypted,String auth_token);*/
283
		callEncryptionChangedId = env->GetMethodID(listenerClass,"callEncryptionChanged","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;ZLjava/lang/String;)V");
284

jehan's avatar
jehan committed
285 286 287
		/*void ecCalibrationStatus(LinphoneCore.EcCalibratorStatus status, int delay_ms, Object data);*/
		ecCalibratorStatusClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCore$EcCalibratorStatus"));
		ecCalibratorStatusFromIntId = env->GetStaticMethodID(ecCalibratorStatusClass,"fromInt","(I)Lorg/linphone/core/LinphoneCore$EcCalibratorStatus;");
288
		ecCalibrationStatusId = env->GetMethodID(listenerClass,"ecCalibrationStatus","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCore$EcCalibratorStatus;ILjava/lang/Object;)V");
289

290
		/*void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf, String url)*/
291
		newSubscriptionRequestId = env->GetMethodID(listenerClass,"newSubscriptionRequest","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneFriend;Ljava/lang/String;)V");
Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
292

293 294
		authInfoRequestedId = env->GetMethodID(listenerClass,"authInfoRequested","(Lorg/linphone/core/LinphoneCore;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
		authenticationRequestedId = env->GetMethodID(listenerClass,"authenticationRequested","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneAuthInfo;Lorg/linphone/core/LinphoneCore$AuthMethod;)V");
295 296

		/*void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf);*/
297
		notifyPresenceReceivedId = env->GetMethodID(listenerClass,"notifyPresenceReceived","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneFriend;)V");
298

Simon Morlat's avatar
Simon Morlat committed
299
		messageReceivedId = env->GetMethodID(listenerClass,"messageReceived","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatRoom;Lorg/linphone/core/LinphoneChatMessage;)V");
300

301 302
		messageReceivedUnableToDecryptedId = env->GetMethodID(listenerClass,"messageReceivedUnableToDecrypted","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatRoom;Lorg/linphone/core/LinphoneChatMessage;)V");

303
		isComposingReceivedId = env->GetMethodID(listenerClass,"isComposingReceived","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatRoom;)V");
304

Sylvain Berfini's avatar
Sylvain Berfini committed
305
		dtmfReceivedId = env->GetMethodID(listenerClass,"dtmfReceived","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;I)V");
306

307
		infoReceivedId = env->GetMethodID(listenerClass,"infoReceived", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;Lorg/linphone/core/LinphoneInfoMessage;)V");
308

309 310
		subscriptionStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/SubscriptionState"));
		subscriptionStateFromIntId = env->GetStaticMethodID(subscriptionStateClass,"fromInt","(I)Lorg/linphone/core/SubscriptionState;");
311
		subscriptionStateId = env->GetMethodID(listenerClass,"subscriptionStateChanged", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneEvent;Lorg/linphone/core/SubscriptionState;)V");
312

313 314
		publishStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/PublishState"));
		publishStateFromIntId = env->GetStaticMethodID(publishStateClass,"fromInt","(I)Lorg/linphone/core/PublishState;");
315
		publishStateId = env->GetMethodID(listenerClass,"publishStateChanged", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneEvent;Lorg/linphone/core/PublishState;)V");
316

317
		notifyRecvId = env->GetMethodID(listenerClass,"notifyReceived", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneEvent;Ljava/lang/String;Lorg/linphone/core/LinphoneContent;)V");
Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
318

319 320
		networkReachableId = env->GetMethodID(listenerClass,"networkReachableChanged", "(Lorg/linphone/core/LinphoneCore;Z)V");

321 322
		configuringStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCore$RemoteProvisioningState"));
		configuringStateFromIntId = env->GetStaticMethodID(configuringStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneCore$RemoteProvisioningState;");
323
		configuringStateId = env->GetMethodID(listenerClass,"configuringStatus","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCore$RemoteProvisioningState;Ljava/lang/String;)V");
Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
324

325
		fileTransferProgressIndicationId = env->GetMethodID(listenerClass, "fileTransferProgressIndication", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneContent;I)V");
326

327 328 329
		fileTransferSendId = env->GetMethodID(listenerClass, "fileTransferSend", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneContent;Ljava/nio/ByteBuffer;I)I");

		fileTransferRecvId = env->GetMethodID(listenerClass, "fileTransferRecv", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneContent;[BI)V");
Gautier Pelloux-Prayer's avatar
Gautier Pelloux-Prayer committed
330

331 332
		logCollectionUploadStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCore$LogCollectionUploadState"));
		logCollectionUploadStateFromIntId = env->GetStaticMethodID(logCollectionUploadStateClass, "fromInt", "(I)Lorg/linphone/core/LinphoneCore$LogCollectionUploadState;");
Sylvain Berfini's avatar
Sylvain Berfini committed
333
		logCollectionUploadProgressId = env->GetMethodID(listenerClass, "uploadProgressIndication", "(Lorg/linphone/core/LinphoneCore;II)V");
334
		logCollectionUploadStateId = env->GetMethodID(listenerClass, "uploadStateChanged", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCore$LogCollectionUploadState;Ljava/lang/String;)V");
335 336 337

		chatMessageStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneChatMessage$State"));
		chatMessageStateFromIntId = env->GetStaticMethodID(chatMessageStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneChatMessage$State;");
338

339 340
		authInfoClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneAuthInfoImpl"));
		authInfoCtrId = env->GetMethodID(authInfoClass,"<init>", "(J)V");
341

342
		proxyClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneProxyConfigImpl"));
343
		proxyCtrId = env->GetMethodID(proxyClass,"<init>", "(Lorg/linphone/core/LinphoneCoreImpl;J)V");
344 345 346

		callClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCallImpl"));
		callCtrId = env->GetMethodID(callClass,"<init>", "(J)V");
jehan's avatar
jehan committed
347

348
		chatMessageClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneChatMessageImpl"));
349 350 351
		if (chatMessageClass) {
			chatMessageCtrId = env->GetMethodID(chatMessageClass,"<init>", "(J)V");
		}
352

353 354 355
		chatRoomClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneChatRoomImpl"));
		chatRoomCtrId = env->GetMethodID(chatRoomClass,"<init>", "(J)V");

Ghislain MARY's avatar
Ghislain MARY committed
356
		friendClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneFriendImpl"));
357
		friendCtrId = env->GetMethodID(friendClass,"<init>", "(J)V");
358

Ghislain MARY's avatar
Ghislain MARY committed
359
		friendListClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneFriendListImpl"));
360 361 362
		friendListCtrId = env->GetMethodID(friendListClass,"<init>", "(J)V");
		friendListCreatedId = env->GetMethodID(listenerClass, "friendListCreated", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneFriendList;)V");
		friendListRemovedId = env->GetMethodID(listenerClass, "friendListRemoved", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneFriendList;)V");
363 364
		friendListSyncStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneFriendList$State"));
		friendListSyncStateFromIntId = env->GetStaticMethodID(friendListSyncStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneFriendList$State;");
365

Ghislain MARY's avatar
Ghislain MARY committed
366 367 368
		natPolicyClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneNatPolicyImpl"));
		natPolicyCtrId = env->GetMethodID(natPolicyClass, "<init>", "(J)V");

jehan's avatar
jehan committed
369
		addressClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneAddressImpl"));
370
		addressCtrId = env->GetMethodID(addressClass,"<init>", "(J)V");
jehan's avatar
jehan committed
371

372
		callStatsClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCallStatsImpl"));
373
		callStatsId = env->GetMethodID(callStatsClass, "<init>", "(J)V");
Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
374

375 376
		infoMessageClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneInfoMessageImpl"));
		infoMessageCtor = env->GetMethodID(infoMessageClass,"<init>", "(J)V");
Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
377

378 379
		linphoneEventClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneEventImpl"));
		linphoneEventCtrId = env->GetMethodID(linphoneEventClass,"<init>", "(J)V");
Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
380

381 382
		subscriptionDirClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/SubscriptionDir"));
		subscriptionDirFromIntId = env->GetStaticMethodID(subscriptionDirClass,"fromInt","(I)Lorg/linphone/core/SubscriptionDir;");
383

384 385
		msFactoryClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/mediastream/Factory"));
		msFactoryCtrId = env->GetMethodID(msFactoryClass,"<init>", "(J)V");
386

387 388 389 390
		accountCreatorClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneAccountCreatorImpl"));
		accountCreatorCtrId = env->GetMethodID(accountCreatorClass, "<init>", "(J)V");
		accountCreatorStatusClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneAccountCreator$Status"));
		accountCreatorStatusFromIntId = env->GetStaticMethodID(accountCreatorStatusClass,"fromInt","(I)Lorg/linphone/core/LinphoneAccountCreator$Status;");
jehan's avatar
jehan committed
391
	}
392

Sylvain Berfini's avatar
Sylvain Berfini committed
393 394 395
	void setCore(jobject c) {
		core = c;
	}
396

Sylvain Berfini's avatar
Sylvain Berfini committed
397 398 399
	jobject getCore() {
		return core;
	}
jehan's avatar
jehan committed
400

Sylvain Berfini's avatar
Sylvain Berfini committed
401
	~LinphoneJavaBindings() {
jehan's avatar
jehan committed
402 403
		JNIEnv *env = 0;
		jvm->AttachCurrentThread(&env,NULL);
404
		env->DeleteGlobalRef(listenerClass);
405
		env->DeleteGlobalRef(authMethodClass);
jehan's avatar
jehan committed
406
		env->DeleteGlobalRef(globalStateClass);
407
		env->DeleteGlobalRef(configuringStateClass);
jehan's avatar
jehan committed
408 409
		env->DeleteGlobalRef(registrationStateClass);
		env->DeleteGlobalRef(callStateClass);
410
		env->DeleteGlobalRef(chatMessageStateClass);
411
		env->DeleteGlobalRef(authInfoClass);
jehan's avatar
jehan committed
412 413
		env->DeleteGlobalRef(proxyClass);
		env->DeleteGlobalRef(callClass);
414
		env->DeleteGlobalRef(chatMessageClass);
415 416
		env->DeleteGlobalRef(chatRoomClass);
		env->DeleteGlobalRef(friendClass);
417
		env->DeleteGlobalRef(friendListClass);
418
		env->DeleteGlobalRef(friendListSyncStateClass);
419
		env->DeleteGlobalRef(natPolicyClass);
420
		env->DeleteGlobalRef(infoMessageClass);
421 422 423
		env->DeleteGlobalRef(linphoneEventClass);
		env->DeleteGlobalRef(subscriptionStateClass);
		env->DeleteGlobalRef(subscriptionDirClass);
424
		env->DeleteGlobalRef(logCollectionUploadStateClass);
425
		env->DeleteGlobalRef(msFactoryClass);
426 427
		env->DeleteGlobalRef(accountCreatorClass);
		env->DeleteGlobalRef(accountCreatorStatusClass);
jehan's avatar
jehan committed
428
	}
429

jehan's avatar
jehan committed
430 431
	jobject core;

432
	jclass listenerClass;
jehan's avatar
jehan committed
433
	jmethodID displayStatusId;
434 435
	jmethodID newSubscriptionRequestId;
	jmethodID notifyPresenceReceivedId;
436
	jmethodID messageReceivedId;
437
	jmethodID messageReceivedUnableToDecryptedId;
438
	jmethodID isComposingReceivedId;
Sylvain Berfini's avatar
Sylvain Berfini committed
439
	jmethodID dtmfReceivedId;
440
	jmethodID callStatsUpdatedId;
441
	jmethodID transferStateId;
442
	jmethodID infoReceivedId;
443
	jmethodID subscriptionStateId;
444
	jmethodID authInfoRequestedId;
445
	jmethodID authenticationRequestedId;
446
	jmethodID publishStateId;
447
	jmethodID notifyRecvId;
448
	jmethodID networkReachableId;
449

450 451
	jclass authMethodClass;
	jmethodID authMethodFromIntId;
Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
452

453 454 455
	jclass configuringStateClass;
	jmethodID configuringStateId;
	jmethodID configuringStateFromIntId;
456 457 458 459 460 461 462 463 464 465 466 467 468

	jclass globalStateClass;
	jmethodID globalStateId;
	jmethodID globalStateFromIntId;

	jclass registrationStateClass;
	jmethodID registrationStateId;
	jmethodID registrationStateFromIntId;

	jclass callStateClass;
	jmethodID callStateId;
	jmethodID callStateFromIntId;

469 470 471
	jclass callStatsClass;
	jmethodID callStatsId;

472 473 474
	jclass chatMessageStateClass;
	jmethodID chatMessageStateFromIntId;

475 476
	jmethodID callEncryptionChangedId;

jehan's avatar
jehan committed
477 478 479
	jclass ecCalibratorStatusClass;
	jmethodID ecCalibrationStatusId;
	jmethodID ecCalibratorStatusFromIntId;
480

481 482
	jclass authInfoClass;
	jmethodID authInfoCtrId;
jehan's avatar
jehan committed
483

484 485 486 487 488 489
	jclass proxyClass;
	jmethodID proxyCtrId;

	jclass callClass;
	jmethodID callCtrId;

490 491 492
	jclass chatMessageClass;
	jmethodID chatMessageCtrId;

493 494 495 496 497 498
	jclass chatRoomClass;
	jmethodID chatRoomCtrId;

	jclass friendClass;
	jmethodID friendCtrId;

499 500 501 502
	jclass friendListClass;
	jmethodID friendListCtrId;
	jmethodID friendListCreatedId;
	jmethodID friendListRemovedId;
503 504
	jclass friendListSyncStateClass;
	jmethodID friendListSyncStateFromIntId;
505

Ghislain MARY's avatar
Ghislain MARY committed
506 507 508
	jclass natPolicyClass;
	jmethodID natPolicyCtrId;

jehan's avatar
jehan committed
509 510
	jclass addressClass;
	jmethodID addressCtrId;
Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
511

512 513
	jclass infoMessageClass;
	jmethodID infoMessageCtor;
Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
514

515 516
	jclass linphoneEventClass;
	jmethodID linphoneEventCtrId;
Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
517

518 519
	jclass subscriptionStateClass;
	jmethodID subscriptionStateFromIntId;
Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
520

521 522
	jclass publishStateClass;
	jmethodID publishStateFromIntId;
Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
523

524 525
	jclass subscriptionDirClass;
	jmethodID subscriptionDirFromIntId;
jehan's avatar
jehan committed
526

527
	jmethodID fileTransferProgressIndicationId;
528 529
	jmethodID fileTransferSendId;
	jmethodID fileTransferRecvId;
530

531 532 533 534
	jclass logCollectionUploadStateClass;
	jmethodID logCollectionUploadStateId;
	jmethodID logCollectionUploadStateFromIntId;
	jmethodID logCollectionUploadProgressId;
535

536 537
	jclass msFactoryClass;
	jmethodID msFactoryCtrId;
538

539 540 541 542
	jclass accountCreatorClass;
	jmethodID accountCreatorCtrId;
	jclass accountCreatorStatusClass;
	jmethodID accountCreatorStatusFromIntId;
Sylvain Berfini's avatar
Sylvain Berfini committed
543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561
};

/*
 * returns the java LinphoneProxyConfig associated with a C LinphoneProxyConfig.
**/
jobject getProxy(JNIEnv *env, LinphoneProxyConfig *proxy, jobject core){
	jobject jobj=0;

	if (proxy!=NULL){
		LinphoneCore *lc = linphone_proxy_config_get_core(proxy);
		LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc);

		void *up=linphone_proxy_config_get_user_data(proxy);

		if (up==NULL){
			jobj=env->NewObject(ljb->proxyClass, ljb->proxyCtrId, core, (jlong)proxy);
			linphone_proxy_config_set_user_data(proxy,(void*)env->NewWeakGlobalRef(jobj));
			linphone_proxy_config_ref(proxy);
		}else{
562
 			//promote the weak ref to local ref
Sylvain Berfini's avatar
Sylvain Berfini committed
563 564 565 566 567 568 569 570 571 572 573
			jobj=env->NewLocalRef((jobject)up);
			if (jobj == NULL){
				//the weak ref was dead
				jobj=env->NewObject(ljb->proxyClass, ljb->proxyCtrId, core, (jlong)proxy);
				linphone_proxy_config_set_user_data(proxy,(void*)env->NewWeakGlobalRef(jobj));
			}
		}
	}
	return jobj;
}

574 575 576 577 578 579 580 581 582 583
jobject getAuthInfo(JNIEnv *env, LinphoneCore *lc, LinphoneAuthInfo *authInfo, jobject core){
	jobject jobj = 0;

	if (authInfo && lc) {
		LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc);
		jobj = env->NewObject(ljb->authInfoClass, ljb->authInfoCtrId, core, (jlong)authInfo);
	}
	return jobj;
}

Sylvain Berfini's avatar
Sylvain Berfini committed
584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615
jobject getCall(JNIEnv *env, LinphoneCall *call){
	jobject jobj=0;

	if (call!=NULL){
		LinphoneCore *lc = linphone_call_get_core(call);
		LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc);

		void *up=linphone_call_get_user_pointer(call);

		if (up==NULL){
			jobj=env->NewObject(ljb->callClass, ljb->callCtrId, (jlong)call);
			jobj=env->NewGlobalRef(jobj);
			linphone_call_set_user_pointer(call,(void*)jobj);
			linphone_call_ref(call);
		}else{
			jobj=(jobject)up;
		}
	}
	return jobj;
}

jobject getChatMessage(JNIEnv *env, LinphoneChatMessage *msg){
	jobject jobj = 0;

	if (msg != NULL){
		LinphoneChatRoom *room = linphone_chat_message_get_chat_room(msg);
		LinphoneCore *lc = linphone_chat_room_get_core(room);
		LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc);

		void *up = linphone_chat_message_get_user_data(msg);

		if (up == NULL) {
616 617 618 619
			jobj = env->NewObject(ljb->chatMessageClass, ljb->chatMessageCtrId, (jlong)msg);
			void *userdata = (void*)env->NewWeakGlobalRef(jobj);
			linphone_chat_message_set_user_data(msg, userdata);
			linphone_chat_message_ref(msg);
Sylvain Berfini's avatar
Sylvain Berfini committed
620
		} else {
621 622 623 624 625 626
			jobj = env->NewLocalRef((jobject)up);
			if (jobj == NULL) {
				// takes implicit local ref
				jobj = env->NewObject(ljb->chatMessageClass, ljb->chatMessageCtrId, (jlong)msg);
				linphone_chat_message_set_user_data(msg, (void*)env->NewWeakGlobalRef(jobj));
			}
Sylvain Berfini's avatar
Sylvain Berfini committed
627 628 629 630 631
		}
	}
	return jobj;
}

632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648
jobject getChatRoom(JNIEnv *env, LinphoneChatRoom *room) {
	jobject jobj = 0;

	if (room != NULL){
		LinphoneCore *lc = linphone_chat_room_get_core(room);
		LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc);

		void *up = linphone_chat_room_get_user_data(room);
		if (up == NULL) {
			// take implicit local ref
			jobj = env->NewObject(ljb->chatRoomClass, ljb->chatRoomCtrId, (jlong)room);
			linphone_chat_room_set_user_data(room, (void*)env->NewWeakGlobalRef(jobj));
			linphone_chat_room_ref(room);
		} else {
			jobj = env->NewLocalRef((jobject)up);
			if (jobj == NULL) {
				// takes implicit local ref
649
				jobj = env->NewObject(ljb->chatRoomClass, ljb->chatRoomCtrId, (jlong)room);
650 651 652 653 654 655 656
				linphone_chat_room_set_user_data(room, (void*)env->NewWeakGlobalRef(jobj));
			}
		}
	}
	return jobj;
}

657
jobject getFriend(JNIEnv *env, LinphoneFriend *lfriend){
Sylvain Berfini's avatar
Sylvain Berfini committed
658 659
	jobject jobj=0;

660

Sylvain Berfini's avatar
Sylvain Berfini committed
661 662 663 664 665 666 667
	if (lfriend != NULL){
		LinphoneCore *lc = linphone_friend_get_core(lfriend);
		LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc);

		void *up=linphone_friend_get_user_data(lfriend);

		if (up == NULL){
668 669

			// take implicit local ref
Sylvain Berfini's avatar
Sylvain Berfini committed
670 671 672 673 674 675 676
			jobj=env->NewObject(ljb->friendClass, ljb->friendCtrId, (jlong)lfriend);
			linphone_friend_set_user_data(lfriend,(void*)env->NewWeakGlobalRef(jobj));
			linphone_friend_ref(lfriend);
		}else{

			jobj=env->NewLocalRef((jobject)up);
			if (jobj == NULL){
677
				// takes implicit local ref
Sylvain Berfini's avatar
Sylvain Berfini committed
678 679 680 681 682 683 684 685
				jobj=env->NewObject(ljb->friendClass, ljb->friendCtrId, (jlong)lfriend);
				linphone_friend_set_user_data(lfriend,(void*)env->NewWeakGlobalRef(jobj));
			}
		}
	}
	return jobj;
}

686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710
jobject getFriendList(JNIEnv *env, LinphoneFriendList *lfriendList){
	jobject jobj=0;

	if (lfriendList != NULL){
		LinphoneCore *lc = linphone_friend_list_get_core(lfriendList);
		LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc);

		void *up=linphone_friend_list_get_user_data(lfriendList);

		if (up == NULL){
			jobj=env->NewObject(ljb->friendListClass, ljb->friendListCtrId, (jlong)lfriendList);
			linphone_friend_list_set_user_data(lfriendList,(void*)env->NewWeakGlobalRef(jobj));
			linphone_friend_list_ref(lfriendList);
		}else{

			jobj=env->NewLocalRef((jobject)up);
			if (jobj == NULL){
				jobj=env->NewObject(ljb->friendListClass, ljb->friendListCtrId, (jlong)lfriendList);
				linphone_friend_list_set_user_data(lfriendList,(void*)env->NewWeakGlobalRef(jobj));
			}
		}
	}
	return jobj;
}

Ghislain MARY's avatar
Ghislain MARY committed
711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733
jobject getNatPolicy(JNIEnv *env, LinphoneNatPolicy *lNatPolicy) {
	jobject jobj = 0;

	if (lNatPolicy != NULL) {
		LinphoneCore *lc = lNatPolicy->lc;
		LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc);

		void *up = linphone_nat_policy_get_user_data(lNatPolicy);
		if (up == NULL) {
			jobj = env->NewObject(ljb->natPolicyClass, ljb->natPolicyCtrId, (jlong)lNatPolicy);
			linphone_nat_policy_set_user_data(lNatPolicy, (void *)env->NewWeakGlobalRef(jobj));
			linphone_nat_policy_ref(lNatPolicy);
		} else {
			jobj = env->NewLocalRef((jobject)up);
			if (jobj == NULL) {
				jobj = env->NewObject(ljb->natPolicyClass, ljb->natPolicyCtrId, (jlong)lNatPolicy);
				linphone_nat_policy_set_user_data(lNatPolicy, (void *)env->NewWeakGlobalRef(jobj));
			}
		}
	}
	return jobj;
}

Sylvain Berfini's avatar
Sylvain Berfini committed
734 735 736 737 738 739 740 741 742 743 744 745 746 747
jobject getEvent(JNIEnv *env, LinphoneEvent *lev){
	if (lev==NULL) return NULL;
	jobject jev=(jobject)linphone_event_get_user_data(lev);
	if (jev==NULL){
		LinphoneCore *lc = linphone_event_get_core(lev);
		LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc);

		jev=env->NewObject(ljb->linphoneEventClass, ljb->linphoneEventCtrId, (jlong)linphone_event_ref(lev));
		jev=env->NewGlobalRef(jev);
		linphone_event_set_user_data(lev,jev);
	}
	return jev;
}

748 749 750 751 752 753
jobject getXmlRpcRequest(JNIEnv *env, LinphoneXmlRpcRequest *lrequest) {
	jobject jobj = 0;

	if (lrequest != NULL) {
		jclass xmlRpcSessionClass = (jclass)env->FindClass("org/linphone/core/LinphoneXmlRpcRequestImpl");
		jmethodID xmlRpcSessionCtrId = env->GetMethodID(xmlRpcSessionClass, "<init>", "(J)V");
754

755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770
		void *up = linphone_xml_rpc_request_get_user_data(lrequest);
		if (up == NULL) {
			jobj = env->NewObject(xmlRpcSessionClass, xmlRpcSessionCtrId, (jlong)lrequest);
			linphone_xml_rpc_request_set_user_data(lrequest, (void *)env->NewWeakGlobalRef(jobj));
			linphone_xml_rpc_request_ref(lrequest);
		} else {
			jobj = env->NewLocalRef((jobject)up);
			if (jobj == NULL) {
				jobj = env->NewObject(xmlRpcSessionClass, xmlRpcSessionCtrId, (jlong)lrequest);
				linphone_xml_rpc_request_set_user_data(lrequest, (void *)env->NewWeakGlobalRef(jobj));
			}
		}
	}
	return jobj;
}

771 772 773 774 775 776 777 778 779
jobject getAccountCreator(JNIEnv *env, LinphoneAccountCreator *account_creator) {
	jobject jobj = 0;

	if (account_creator != NULL) {
		LinphoneCore *lc = account_creator->core;
		LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc);

		void *up = linphone_account_creator_get_user_data(account_creator);
		if (up == NULL) {
780
			jobj = env->NewObject(ljb->accountCreatorClass, ljb->accountCreatorCtrId, (jlong)account_creator);
781 782 783 784 785
			linphone_account_creator_set_user_data(account_creator, (void *)env->NewWeakGlobalRef(jobj));
			linphone_account_creator_ref(account_creator);
		} else {
			jobj = env->NewLocalRef((jobject)up);
			if (jobj == NULL) {
786
				jobj = env->NewObject(ljb->accountCreatorClass, ljb->accountCreatorCtrId, (jlong)account_creator);
787 788 789 790 791 792 793
				linphone_account_creator_set_user_data(account_creator, (void *)env->NewWeakGlobalRef(jobj));
			}
		}
	}
	return jobj;
}

Sylvain Berfini's avatar
Sylvain Berfini committed
794 795 796 797 798
class LinphoneCoreData {
public:
	LinphoneCoreData(JNIEnv *env, jobject lc, LinphoneCoreVTable *vTable, jobject alistener, LinphoneJavaBindings *ljb) {
		core = env->NewGlobalRef(lc);
		listener = env->NewGlobalRef(alistener);
799

Sylvain Berfini's avatar
Sylvain Berfini committed
800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836
		memset(vTable, 0, sizeof(LinphoneCoreVTable));

		if (ljb->displayStatusId) {
			vTable->display_status = displayStatusCb;
		}

		if (ljb->globalStateId) {
			vTable->global_state_changed = globalStateChange;
		}

		if (ljb->registrationStateId) {
			vTable->registration_state_changed = registrationStateChange;
		}

		if (ljb->callStateId) {
			vTable->call_state_changed = callStateChange;
		}

		if (ljb->transferStateId) {
			vTable->transfer_state_changed = transferStateChanged;
		}

		if (ljb->callStatsUpdatedId) {
			vTable->call_stats_updated = callStatsUpdated;
		}

		if (ljb->callEncryptionChangedId) {
			vTable->call_encryption_changed = callEncryptionChange;
		}

		if (ljb->newSubscriptionRequestId) {
			vTable->new_subscription_requested = new_subscription_requested;
		}

		if (ljb->authInfoRequestedId) {
			vTable->auth_info_requested = authInfoRequested;
		}
837

838 839 840
		if (ljb->authenticationRequestedId) {
			vTable->authentication_requested = authenticationRequested;
		}
Sylvain Berfini's avatar
Sylvain Berfini committed
841 842 843 844 845 846 847 848 849

		if (ljb->notifyPresenceReceivedId) {
			vTable->notify_presence_received = notify_presence_received;
		}

		if (ljb->messageReceivedId) {
			vTable->message_received = message_received;
		}

850 851 852 853
		if (ljb->messageReceivedUnableToDecryptedId) {
		    vTable->message_received_unable_decrypt = message_received_unable_decrypt;
		}

Sylvain Berfini's avatar
Sylvain Berfini committed
854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877
		if (ljb->isComposingReceivedId) {
			vTable->is_composing_received = is_composing_received;
		}

		if (ljb->dtmfReceivedId) {
			vTable->dtmf_received = dtmf_received;
		}

		if (ljb->infoReceivedId) {
			vTable->info_received = infoReceived;
		}

		if (ljb->subscriptionStateId) {
			vTable->subscription_state_changed = subscriptionStateChanged;
		}

		if (ljb->publishStateId) {
			vTable->publish_state_changed = publishStateChanged;
		}

		if (ljb->notifyRecvId) {
			vTable->notify_received = notifyReceived;
		}

878 879 880 881
		if (ljb->networkReachableId) {
			vTable->network_reachable = networkReachableCb;
		}

Sylvain Berfini's avatar
Sylvain Berfini committed
882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903
		if (ljb->configuringStateId) {
			vTable->configuring_status = configuringStatus;
		}

		if (ljb->fileTransferProgressIndicationId) {
			vTable->file_transfer_progress_indication = fileTransferProgressIndication;
		}

		if (ljb->fileTransferSendId) {
			vTable->file_transfer_send = fileTransferSend;
		}

		if (ljb->fileTransferRecvId) {
			vTable->file_transfer_recv = fileTransferRecv;
		}

		if (ljb->logCollectionUploadProgressId) {
			vTable->log_collection_upload_progress_indication = logCollectionUploadProgressIndication;
		}
		if (ljb->logCollectionUploadStateId) {
			vTable->log_collection_upload_state_changed = logCollectionUploadStateChange;
		}
904

905 906 907 908 909 910
		if (ljb->friendListCreatedId) {
			vTable->friend_list_created = friendListCreated;
		}
		if (ljb->friendListRemovedId) {
			vTable->friend_list_removed = friendListRemoved;
		}
Sylvain Berfini's avatar
Sylvain Berfini committed
911
	}
912

Sylvain Berfini's avatar
Sylvain Berfini committed
913 914 915 916 917 918
	~LinphoneCoreData() {
		JNIEnv *env = 0;
		jvm->AttachCurrentThread(&env,NULL);
		env->DeleteGlobalRef(core);
		env->DeleteGlobalRef(listener);
	}
919

Sylvain Berfini's avatar
Sylvain Berfini committed
920 921
	jobject core;
	jobject listener;
922

jehan's avatar
jehan committed
923
	LinphoneCoreVTable vTable;
924

jehan's avatar
jehan committed
925 926 927 928
	static void displayStatusCb(LinphoneCore *lc, const char *message) {
		JNIEnv *env = 0;
		jint result = jvm->AttachCurrentThread(&env,NULL);
		if (result != 0) {
929
			ms_error("cannot attach VM");
jehan's avatar
jehan committed
930 931
			return;
		}
932

Sylvain Berfini's avatar
Sylvain Berfini committed
933
		LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc);
934 935
		LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc);
		LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table);
936
		jstring msg = message ? env->NewStringUTF(message) : NULL;
Sylvain Berfini's avatar
Sylvain Berfini committed
937
		env->CallVoidMethod(lcData->listener,ljb->