jni.mustache 20.4 KB
Newer Older
Sylvain Berfini's avatar
Sylvain Berfini committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
/*
linphone_jni.cc
Copyright (C) 2017 Belledonne Communications SARL

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
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

#include <jni.h>
#include <cpu-features.h>

23
#include "belle-sip/object.h"
24 25 26 27 28 29
#include "mediastreamer2/mediastream.h"
#include "mediastreamer2/mscommon.h"
#include "mediastreamer2/msmediaplayer.h"
#include "mediastreamer2/msutils.h"
#include "mediastreamer2/devices.h"
#include "mediastreamer2/msjava.h"
30
#include "linphone/core_utils.h"
31 32 33 34 35 36 37 38 39 40
#include "linphone/core.h"
#include "linphone/tunnel.h"
#include "linphone/account_creator.h"
#include "linphone/wrapper_utils.h"
#include "linphone/lpconfig.h"

#ifdef __ANDROID__
#include <android/log.h>
#endif /* __ANDROID__ */

41
static JavaVM *jvm = NULL;
Sylvain Berfini's avatar
Sylvain Berfini committed
42 43 44
static const char* LogDomain = "Linphone";
static jmethodID loghandler_id;
static jobject handler_obj=NULL;
45

Sylvain Berfini's avatar
Sylvain Berfini committed
46 47 48 49
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *ajvm, void *reserved) {
#ifdef __ANDROID__
	ms_set_jvm(ajvm);
#endif /* __ANDROID__ */
50
	jvm = ajvm;
Sylvain Berfini's avatar
Sylvain Berfini committed
51 52 53
	return JNI_VERSION_1_2;
}

54 55
#define belle_sip_java_user_data_key "java_object"

Sylvain Berfini's avatar
Sylvain Berfini committed
56 57 58 59 60 61 62
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);
63 64 65 66 67 68 69 70 71
}

static jlong GetObjectNativePtr(JNIEnv *env, jobject object) {
	jclass objClass = env->GetObjectClass(object);
	jfieldID nativePtrId = env->GetFieldID(objClass, "nativePtr", "J");
	jlong nativePtr = env->GetLongField(object, nativePtrId);
	return nativePtr;
}

72 73 74 75 76 77
static void SetObjectNativePtr(JNIEnv *env, jobject object, jlong ptr) {
	jclass objClass = env->GetObjectClass(object);
	jfieldID nativePtrId = env->GetFieldID(objClass, "nativePtr", "J");
	env->SetLongField(object, nativePtrId, ptr);
}

78 79
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
void linphone_android_log_handler(int prio, char *str) {
	char *current;
	char *next;

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

			*next = '\0';
			if (next != str && next[-1] == '\r')
				next[-1] = '\0';
			__android_log_write(prio, LogDomain, current);
			current = next + 1;
		}
		__android_log_write(prio, LogDomain, current);
	}
}

static void linphone_android_ortp_log_handler(const char *domain, OrtpLogLevel lev, const char *fmt, va_list args) {
	char* str = bctbx_strdup_vprintf(fmt, args);
    const char *levname = "undef";

    if (str == NULL) return;

    int prio;
    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;
    }

    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);
    	if (jdomain) env->DeleteLocalRef(jdomain);
    	if (jlevname) env->DeleteLocalRef(jlevname);
    	if (jstr) env->DeleteLocalRef(jstr);
    } else {
    	linphone_android_log_handler(prio, str);
    }
    bctbx_free(str);
}

131
extern "C" void Java_org_linphone_core_FactoryImpl_setDebugMode(JNIEnv* env, jobject thiz, jboolean isDebug, jstring jdebugTag) {
132 133 134 135 136 137 138 139
	if (isDebug) {
		LogDomain = GetStringUTFChars(env, jdebugTag);
		linphone_core_enable_logs_with_cb(linphone_android_ortp_log_handler);
	} else {
		linphone_core_disable_logs();
	}
}

140 141 142 143 144 145 146 147
static jstring get_jstring_from_char(JNIEnv *env, const char* cString) {
    int len;
    jmethodID constructorString;
    jbyteArray bytesArray = NULL;
    jstring javaString = NULL;
    jclass classString = env->FindClass("java/lang/String");
    if (classString == 0) {
        ms_error("Cannot find java.lang.String class.\n");
148
        goto error;
149 150 151 152 153
    }

    constructorString = env->GetMethodID(classString, "<init>", "([BLjava/lang/String;)V");
    if (constructorString == 0) {
        ms_error("Cannot find String <init> method.\n");
154
        goto error;
155 156 157 158 159 160 161 162 163 164 165 166 167
    }

    len = (int)strlen(cString);
    bytesArray = env->NewByteArray(len);

    if (bytesArray) {
        env->SetByteArrayRegion(bytesArray, 0, len, (jbyte *)cString);
        jstring UTF8 = env->NewStringUTF("UTF8");
        javaString = (jstring)env->NewObject(classString, constructorString, bytesArray, UTF8);
        env->DeleteLocalRef(bytesArray);
        env->DeleteLocalRef(UTF8);
    }

168 169 170
    error:
    if (classString) env->DeleteLocalRef(classString);

171 172 173
    return javaString;
}

174 175
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

176 177 178
class LinphoneJavaBindings {
public:
	LinphoneJavaBindings(JNIEnv *env) {
179 180 181
		ms_factory_class = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/mediastream/Factory"));
		ms_factory_class_constructor = env->GetMethodID(ms_factory_class, "<init>", "(J)V");

182 183 184 185
		{{#objects}}
		{{cPrefix}}_class = (jclass)env->NewGlobalRef(env->FindClass("{{jniPath}}{{classImplName}}"));
		{{cPrefix}}_class_constructor = env->GetMethodID({{cPrefix}}_class, "<init>", "(J)V");
		{{/objects}}
186 187 188 189 190

		{{#enums}}
		{{cPrefix}}_class = (jclass)env->NewGlobalRef(env->FindClass("{{jniPath}}{{jniName}}"));
		{{cPrefix}}_class_constructor_from_int = env->GetStaticMethodID({{cPrefix}}_class, "fromInt", "(I)L{{jniPath}}{{jniName}};");
		{{/enums}}
191 192 193 194 195
	}

	~LinphoneJavaBindings() {
		JNIEnv *env = 0;
		jvm->AttachCurrentThread(&env,NULL);
196 197 198

		env->DeleteGlobalRef(ms_factory_class);

199 200 201
		{{#objects}}
		env->DeleteGlobalRef({{cPrefix}}_class);
		{{/objects}}
202

203 204 205
		{{#enums}}
		env->DeleteGlobalRef({{cPrefix}}_class);
		{{/enums}}
206 207
	}

208 209 210
	jclass ms_factory_class;
	jmethodID ms_factory_class_constructor;

211 212 213 214
	{{#objects}}
	jclass {{cPrefix}}_class;
	jmethodID {{cPrefix}}_class_constructor;
	{{/objects}}
215 216 217 218 219

	{{#enums}}
	jclass {{cPrefix}}_class;
	jmethodID {{cPrefix}}_class_constructor_from_int;
	{{/enums}}
220 221
};

222
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
223

224 225 226
#ifdef __cplusplus
extern "C" {
#endif
227

228
{{#objects}}
229
jobject get{{className}}(JNIEnv *env, {{classCName}} *cptr) {
230 231
	jobject jobj = 0;

232 233
	if (cptr != NULL) {
		void *up = belle_sip_object_data_get((belle_sip_object_t *)cptr, belle_sip_java_user_data_key);
234
		LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_factory_get_user_data(linphone_factory_get());
235 236 237 238 239
		if (!ljb) {
			ljb = new LinphoneJavaBindings(env);
			linphone_factory_set_user_data(linphone_factory_get(), ljb);
		}

240 241
		jclass {{cPrefix}}_class = ljb->{{cPrefix}}_class;
		jmethodID {{cPrefix}}_constructor = ljb->{{cPrefix}}_class_constructor;
242 243

		if (up == NULL) {
244 245
			jobj = env->NewObject({{cPrefix}}_class, {{cPrefix}}_constructor, (jlong)cptr);
			belle_sip_object_data_set((belle_sip_object_t *)cptr, belle_sip_java_user_data_key, (void*)env->NewWeakGlobalRef(jobj), NULL);
246
			{{#refCountable}}{{cPrefix}}_ref(cptr);{{/refCountable}}
247 248 249 250 251 252
		} else {
			jobj = env->NewLocalRef((jobject)up);
			if (jobj == NULL) {
				// Delete weak ref ?
				env->DeleteWeakGlobalRef((jobject)up);
				// takes implicit local ref
253 254
				jobj = env->NewObject({{cPrefix}}_class, {{cPrefix}}_constructor, (jlong)cptr);
				belle_sip_object_data_set((belle_sip_object_t *)cptr, belle_sip_java_user_data_key, (void*)env->NewWeakGlobalRef(jobj), NULL);
255
				{{#refCountable}}{{cPrefix}}_ref(cptr);{{/refCountable}}
256 257 258 259 260 261 262 263
			}
		}
	}
	return jobj;
}

void Java_{{jniPrefix}}{{classImplName}}_unref(JNIEnv* env, jobject thiz, jlong ptr) {
	{{classCName}} *cptr = ({{classCName}}*)ptr;
264 265
	jobject wref = (jobject)belle_sip_object_data_get((belle_sip_object_t *)cptr, belle_sip_java_user_data_key);
	belle_sip_object_data_set((belle_sip_object_t *)cptr, belle_sip_java_user_data_key, NULL, NULL);
266 267 268
	if (wref) {
		env->DeleteWeakGlobalRef(wref);
	}
269
	{{#refCountable}}{{cPrefix}}_unref(cptr);{{/refCountable}}
270 271 272
}

{{/objects}}
273 274 275 276 277 278 279 280 281 282 283
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

static inline void handle_possible_java_exception(JNIEnv *env, jobject listener)
{
	if (env->ExceptionCheck()) {
		env->ExceptionDescribe();
		env->ExceptionClear();
		ms_error("Listener %p raised an exception",listener);
	}
}

284
{{#callbacks}}
285 286
static {{return}} {{callbackName}}({{params}}) {
	JNIEnv *env = 0;
287 288
	jint jvmResult = jvm->AttachCurrentThread(&env,NULL);
	if (jvmResult != 0) {
289
		ms_error("cannot attach VM");
290
		return{{returnIfFail}};
291 292
	}

293
	{{#isSingleListener}}
294
	{{classCName}}Cbs *cbs = {{cPrefix}}_get_callbacks({{firstParam}});
295 296
	{{/isSingleListener}}
	{{#isMultiListener}}
297
	{{classCName}}Cbs *cbs = {{cPrefix}}_get_current_callbacks({{firstParam}});
298
	{{/isMultiListener}}
299 300 301
	jobject jlistener = (jobject) {{cPrefix}}_cbs_get_user_data(cbs);

	if (jlistener == NULL) {
302
		ms_warning("{{callbackName}}() notification without listener");
303
		return{{returnIfFail}};
304 305 306 307 308 309 310
	}

	jclass jlistenerClass = (jclass) env->GetObjectClass(jlistener);
	jmethodID jcallback = env->GetMethodID(jlistenerClass, "{{jname}}", "{{jparams}}");
	env->DeleteLocalRef(jlistenerClass);

	{{#jobjects}}
311
	jobject j_{{objectName}} = get{{className}}(env, (Linphone{{className}} *){{objectName}});
312 313
	{{/jobjects}}
	{{#jenums}}
314
	LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_factory_get_user_data(linphone_factory_get());
315 316 317
	jobject j_{{enumName}} = env->CallStaticObjectMethod(ljb->{{cEnumPrefix}}_class, ljb->{{cEnumPrefix}}_class_constructor_from_int, (jint){{enumName}});
	{{/jenums}}
	{{#jstrings}}
318
	jstring j_{{stringName}} = {{stringName}} ? get_jstring_from_char(env, {{stringName}}) : NULL;
319
	{{/jstrings}}
320

321 322 323 324 325 326 327 328 329 330
	{{#hasReturn}}{{jniUpcallType}} jni_upcall_result = {{/hasReturn}}env->{{jniUpcallMethod}}(jlistener, jcallback, {{params_impl}});
	{{#hasReturn}}
	{{#isJniUpcallObject}}
	{{return}} c_upcall_result = NULL;
	if (jni_upcall_result) c_upcall_result = ({{return}})GetObjectNativePtr(env, jni_upcall_result);
	{{/isJniUpcallObject}}
	{{#isJniUpcallBasicType}}
	{{return}} c_upcall_result = ({{return}}) jni_upcall_result;
	{{/isJniUpcallBasicType}}
	{{/hasReturn}}
331 332 333 334 335 336

	{{#jobjects}}
	if (j_{{objectName}}) {
		env->DeleteLocalRef(j_{{objectName}});
	}
	{{/jobjects}}
337 338 339 340 341
	{{#jenums}}
	if (j_{{enumName}}) {
		env->DeleteLocalRef(j_{{enumName}});
	}
	{{/jenums}}
342 343 344 345 346 347 348
	{{#jstrings}}
	if (j_{{stringName}}) {
		env->DeleteLocalRef(j_{{stringName}});
	}
	{{/jstrings}}

	handle_possible_java_exception(env, jlistener);
349
	{{#hasReturn}}
350
	return c_upcall_result;
351
	{{/hasReturn}}
352 353
}

354 355 356 357 358
{{/callbacks}}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

{{#interfaces}}
{{#isSingleListener}}
359
void Java_{{jniPackage}}{{className}}Impl_setListener(JNIEnv* env, jobject thiz, jlong ptr, jobject jlistener) {
360 361
{{/isSingleListener}}
{{#isMultiListener}}
362
void Java_{{jniPackage}}{{className}}Impl_addListener(JNIEnv* env, jobject thiz, jlong ptr, jobject jlistener) {
363 364 365 366
{{/isMultiListener}}
	{{classCName}} *cptr = ({{classCName}}*)ptr;
	jobject listener = env->NewGlobalRef(jlistener);
	{{#isSingleListener}}
367
	{{classCName}}Cbs *cbs = {{cPrefix}}_get_callbacks(cptr);
368 369 370 371 372 373 374 375
	{{/isSingleListener}}
	{{#isMultiListener}}
	{{classCName}}Cbs *cbs = linphone_factory_create_{{factoryName}}_cbs(NULL);
	{{/isMultiListener}}
	{{cPrefix}}_cbs_set_user_data(cbs, listener);
	{{#callbacksList}}
	{{cPrefix}}_cbs_set_{{callback}}(cbs, {{callbackName}});
	{{/callbacksList}}
376 377 378
	{{#isMultiListener}}
	{{cPrefix}}_add_callbacks(cptr, cbs);
	{{/isMultiListener}}
379 380 381
}
{{#isMultiListener}}

382
void Java_{{jniPackage}}{{className}}Impl_removeListener(JNIEnv* env, jobject thiz, jlong ptr, jobject jlistener) {
383
	{{classCName}} *cptr = ({{classCName}}*)ptr;
Sylvain Berfini's avatar
Sylvain Berfini committed
384
	const bctbx_list_t *cbs_list = {{cPrefix}}_get_callbacks_list(cptr);
385
	bctbx_list_t *it;
386
	for (it = (bctbx_list_t *)cbs_list; it != NULL; it = it->next) {
387 388 389 390 391
		{{classCName}}Cbs *cbs = ({{classCName}}Cbs *)it->data;
		if ({{cPrefix}}_cbs_get_user_data(cbs) == jlistener) {
			{{cPrefix}}_remove_callbacks(cptr, cbs);
			break;
		}
392
	}
393 394 395
}
{{/isMultiListener}}

396 397
{{/interfaces}}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
398

399
jobject Java_{{jni_package}}CoreImpl_getMediastreamerFactory(JNIEnv *env, jobject thiz, jlong ptr) {
400 401 402 403 404 405
	LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_factory_get_user_data(linphone_factory_get());
	MSFactory *factory = linphone_core_get_ms_factory((LinphoneCore*)ptr);
	return env->NewObject(ljb->ms_factory_class, ljb->ms_factory_class_constructor, (jlong)factory);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
406 407

{{#methods}}
408
{{#notEmpty}}
409
{{return}} {{name}}({{params}}) {
410 411
	{{#notStatic}}{{classCName}} *cptr = ({{classCName}}*)ptr;
	{{#isLinphoneFactory}}cptr = linphone_factory_get();{{/isLinphoneFactory}}
412 413 414
	if (cptr == 0) {
		return {{#hasReturn}}0{{/hasReturn}}{{#hasStringReturn}}0{{/hasStringReturn}}{{#hasListReturn}}0{{/hasListReturn}}{{#hasByteArrayReturn}}0{{/hasByteArrayReturn}};
	}
415
	{{/notStatic}}{{#strings}}
416
	const char* c_{{string}} = GetStringUTFChars(env, {{string}});
417 418 419
	{{/strings}}{{#bytes}}
	{{bytesargtype}} c_{{bytesargname}} = ({{bytesargtype}})env->GetByteArrayElements({{bytesargname}}, NULL);
	{{/bytes}}{{#objects}}
420 421
	{{objectClassCName}}* c_{{object}} = NULL;
	if ({{object}}) c_{{object}} = ({{objectClassCName}}*)GetObjectNativePtr(env, {{object}});
422 423
	{{/objects}}{{#lists}}
	bctbx_list_t *bctbx_list_{{list}} = NULL;
424 425
	int {{list}}_count = env->GetArrayLength({{list}});
	for (int i=0; i < {{list}}_count; i++) {
426 427 428 429 430 431 432 433 434 435
		{{#isStringList}}
		jstring obj = (jstring) env->GetObjectArrayElement({{list}}, i);
		const char *str = GetStringUTFChars(env, obj);
		if (str) {
			bctbx_list_{{list}} = bctbx_list_append(bctbx_list_{{list}}, ms_strdup(str));
			ReleaseStringUTFChars(env, obj, str);
		}
		{{/isStringList}}
		{{#isObjList}}
		jobject obj = env->GetObjectArrayElement({{list}}, i);
436
		bctbx_list_{{list}} = bctbx_list_append(bctbx_list_{{list}}, ({{objectClassCName}} *)GetObjectNativePtr(env, obj));
437 438 439
		{{/isObjList}}
	}
	{{/lists}}{{#hasListReturn}}
440
	const bctbx_list_t *list = {{c_name}}({{#notStatic}}cptr{{/notStatic}}{{params_impl}});
441
	size_t count = bctbx_list_size(list);
442
	{{#isRealObjectArray}}
443
	LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_factory_get_user_data(linphone_factory_get());
444 445
	jobjectArray jni_list_result = env->NewObjectArray((int)count, ljb->{{objectCPrefix}}_class, NULL);{{/isRealObjectArray}}
	{{#isStringObjectArray}}jobjectArray jni_list_result = env->NewObjectArray((int)count, env->FindClass("java/lang/String"), env->NewStringUTF(""));{{/isStringObjectArray}}
446 447 448
	for (size_t i = 0; i < count; i++) {
		{{#isRealObjectArray}}
		{{objectClassCName}}* c_object = ({{objectClassCName}}*)list->data;
449
		jobject object = get{{objectClassName}}(env, c_object);
450
		{{/isRealObjectArray}}
451
		{{#isStringObjectArray}}const char *cstring = (const char *)list->data;
452
		jstring object = cstring ? get_jstring_from_char(env, cstring) : 0;{{/isStringObjectArray}}
453
		if (object != 0) {
454
			env->SetObjectArrayElement(jni_list_result, (int)i, object);
455 456 457 458
			{{#isRealObjectArray}}env->DeleteLocalRef(object);{{/isRealObjectArray}}
		}
		list = bctbx_list_next(list);
	}
459 460 461 462 463 464 465 466
	{{/hasListReturn}}{{#hasByteArrayReturn}}
	{{c_type_return}} jni_result = {{c_name}}({{#notStatic}}cptr{{/notStatic}}{{params_impl}});
	if (!jni_result) return NULL;
	size_t jni_result_length = strlen((const char *)jni_result);
	jbyteArray array = env->NewByteArray((int)jni_result_length);
	env->SetByteArrayRegion(array, 0, (int)jni_result_length, (const jbyte*)jni_result);
	return array;
	{{/hasByteArrayReturn}}{{#hasStringReturn}}
467
	const char *c_string = {{c_name}}({{#notStatic}}cptr{{/notStatic}}{{params_impl}}){{#returnObject}}){{/returnObject}};
468
	jstring jni_result = (c_string != NULL) ? get_jstring_from_char(env, c_string) : NULL;
469 470
	{{/hasStringReturn}}{{#hasNormalReturn}}
	{{#hasReturn}}{{return}} jni_result = ({{return}}){{#returnObject}}get{{returnClassName}}(env, (Linphone{{returnClassName}} *){{/returnObject}}{{/hasReturn}}{{c_name}}({{#notStatic}}cptr{{/notStatic}}{{params_impl}}){{#returnObject}}){{/returnObject}};
471
	{{/hasNormalReturn}}{{#strings}}
472
	ReleaseStringUTFChars(env, {{string}}, c_{{string}});
473 474 475
	{{/strings}}{{#bytes}}
	env->ReleaseByteArrayElements({{bytesargname}}, (jbyte*)c_{{bytesargname}}, JNI_ABORT);
	{{/bytes}}{{#hasReturn}}return jni_result;{{/hasReturn}}{{#hasListReturn}}return jni_list_result;{{/hasListReturn}}
476
}
477
{{/notEmpty}}
478 479
{{/methods}}

480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Manually wrapped
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void Java_org_linphone_core_CallImpl_setNativeVideoWindowId(JNIEnv *env, jobject thiz, jlong ptr, jobject id) {
	LinphoneCall *cptr = (LinphoneCall*)ptr;
	jobject oldWindow = (jobject) linphone_call_get_native_video_window_id(cptr);
	if (oldWindow == id) {
		ms_warning("Java_org_linphone_core_CallImpl_setNativeVideoWindowId(): new id (%p) is the same as the current one, skipping...", id);
		return;
	}
	if (id != NULL) {
		id = env->NewGlobalRef(id);
		ms_message("Java_org_linphone_core_CallImpl_setNativeVideoWindowId(): NewGlobalRef(%p)", id);
	} else ms_message("Java_org_linphone_core_CallImpl_setNativeVideoWindowId(): setting to NULL");
	linphone_call_set_native_video_window_id(cptr, (void *)id);
	if (oldWindow != NULL) {
		ms_message("Java_org_linphone_core_CallImpl_setNativeVideoWindowId(): DeleteGlobalRef(%p)", oldWindow);
		env->DeleteGlobalRef(oldWindow);
	}
}

void Java_org_linphone_core_CoreImpl_setNativePreviewWindowId(JNIEnv *env, jobject thiz, jlong ptr, jobject id) {
	LinphoneCore *cptr = (LinphoneCore*)ptr;
504
	jobject oldWindow = (jobject) linphone_core_get_native_preview_window_id(cptr);
505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521
	if (oldWindow == id) {
		ms_warning("Java_org_linphone_core_CoreImpl_setNativePreviewWindowId(): new id (%p) is the same as the current one, skipping...", id);
		return;
	}
	if (id != NULL) {
		id = env->NewGlobalRef(id);
		ms_message("Java_org_linphone_core_CoreImpl_setNativePreviewWindowId(): NewGlobalRef(%p)", id);
	} else ms_message("Java_org_linphone_core_CoreImpl_setNativePreviewWindowId(): setting to NULL");
	linphone_core_set_native_preview_window_id(cptr, (void *)id);
	if (oldWindow != NULL) {
		ms_message("Java_org_linphone_core_CoreImpl_setNativePreviewWindowId(): DeleteGlobalRef(%p)", oldWindow);
		env->DeleteGlobalRef(oldWindow);
	}
}

void Java_org_linphone_core_CoreImpl_setNativeVideoWindowId(JNIEnv *env, jobject thiz, jlong ptr, jobject id) {
	LinphoneCore *cptr = (LinphoneCore*)ptr;
522
	jobject oldWindow = (jobject) linphone_core_get_native_video_window_id(cptr);
523 524 525 526 527 528 529 530 531 532 533 534 535 536 537
	if (oldWindow == id) {
		ms_warning("Java_org_linphone_core_CoreImpl_setNativeVideoWindowId(): new id (%p) is the same as the current one, skipping...", id);
		return;
	}
	if (id != NULL) {
		id = env->NewGlobalRef(id);
		ms_message("Java_org_linphone_core_CoreImpl_setNativeVideoWindowId(): NewGlobalRef(%p)", id);
	} else ms_message("Java_org_linphone_core_CoreImpl_setNativeVideoWindowId(): setting to NULL");
	linphone_core_set_native_video_window_id(cptr, (void *)id);
	if (oldWindow != NULL) {
		ms_message("Java_org_linphone_core_CoreImpl_setNativeVideoWindowId(): DeleteGlobalRef(%p)", oldWindow);
		env->DeleteGlobalRef(oldWindow);
	}
}

538 539 540 541
jobject Java_org_linphone_core_FactoryImpl_getCore(JNIEnv *env, jobject thiz, jlong ptr, jlong lcPtr) {
	return getCore(env, (LinphoneCore*)lcPtr);
}

542 543
#ifdef __cplusplus
}
544
#endif