/* 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 #ifdef USE_JAVAH #include "linphonecore_jni.h" #endif #include "linphone/core_utils.h" #include #include "mediastreamer2/mediastream.h" #include "mediastreamer2/mscommon.h" #include "mediastreamer2/msmediaplayer.h" #include "mediastreamer2/msutils.h" #include "mediastreamer2/devices.h" #include "mediastreamer2/msjava.h" #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 #include #endif /* __ANDROID__ */ static JavaVM *jvm=0; JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *ajvm, void *reserved) { #ifdef __ANDROID__ ms_set_jvm(ajvm); #endif /* __ANDROID__ */ jvm=ajvm; return JNI_VERSION_1_2; } 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); } 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; } {{#objects}} jobject get{{className}}(JNIEnv *env, {{classCName}} *ptr) { jobject jobj = 0; if (ptr != NULL) { void *up = {{cPrefix}}_get_user_data(ptr); jclass {{cPrefix}}_class = env->FindClass("{{jniPath}}{{classImplName}}"); jmethodID {{cPrefix}}_constructor = env->GetMethodID({{cPrefix}}_class, "", "(J)V"); if (up == NULL) { jobj = env->NewObject({{cPrefix}}_class, {{cPrefix}}_constructor, (jlong)ptr); {{cPrefix}}_set_user_data(ptr, (void*)env->NewWeakGlobalRef(jobj)); {{cPrefix}}_ref(ptr); } else { jobj = env->NewLocalRef((jobject)up); if (jobj == NULL) { // Delete weak ref ? env->DeleteWeakGlobalRef((jobject)up); // takes implicit local ref jobj = env->NewObject({{cPrefix}}_class, {{cPrefix}}_constructor, (jlong)ptr); {{cPrefix}}_set_user_data(ptr, (void*)env->NewWeakGlobalRef(jobj)); {{cPrefix}}_ref(ptr); } } } return jobj; } void Java_{{jniPrefix}}{{classImplName}}_unref(JNIEnv* env, jobject thiz, jlong ptr) { {{classCName}} *cptr = ({{classCName}}*)ptr; jobject wref = (jobject){{cPrefix}}_get_user_data(cptr); {{cPrefix}}_set_user_data(cptr, NULL); if (wref) { env->DeleteWeakGlobalRef(wref); } {{cPrefix}}_unref(cptr); } {{/objects}} {{#methods}} {{return}} {{name}}({{params}}) { {{#notStatic}}{{classCName}} *cptr = ({{classCName}}*)ptr;{{/notStatic}} {{#strings}} const char* c_{{string}} = GetStringUTFChars(env, {{string}}); {{/strings}}{{#objects}} {{objectClassCName}}* c_{{object}} = NULL; if ({{object}}) c_{{object}} = ({{objectClassCName}}*)GetObjectNativePtr(env, {{object}}); {{/objects}}{{#lists}} bctbx_list_t *bctbx_list_{{list}} = NULL; int count = env->GetArrayLength({{list}}); for (int i=0; i < count; i++) { {{#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); bctbx_list_{{list}} = bctbx_list_append(bctbx_list_{{list}}, GetObjectNativePtr(env, obj)); {{/isObjList}} } {{/lists}}{{#hasListReturn}} bctbx_list_t *list = {{c_name}}({{#notStatic}}cptr{{/notStatic}}{{params_impl}}); size_t count = bctbx_list_size(list); {{#isRealObjectArray}}jobjectArray jni_list_result = env->NewObjectArray(count, env->FindClass("{{jniPath}}{{objectClassImplName}}"), NULL);{{/isRealObjectArray}} {{#isStringObjectArray}}jobjectArray jni_list_result = env->NewObjectArray(count, env->FindClass("java/lang/String"), env->NewStringUTF(""));{{/isStringObjectArray}} for (size_t i = 0; i < count; i++) { {{#isRealObjectArray}} {{objectClassCName}}* c_object = ({{objectClassCName}}*)list->data; jobject object = get{{objectClassName}}(c_object); {{/isRealObjectArray}} {{#isStringObjectArray}}jstring object = list->data ? env->NewStringUTF(list->data) : 0;{{/isStringObjectArray}} if (object != 0) { env->SetObjectArrayElement(jni_list_result, i, object); {{#isRealObjectArray}}env->DeleteLocalRef(object);{{/isRealObjectArray}} } list = bctbx_list_next(list); } {{/hasListReturn}}{{#hasNormalReturn}} {{#hasReturn}}{{return}} jni_result = {{#returnObject}}get{{returnClassName}}({{/returnObject}}{{/hasReturn}}{{c_name}}({{#notStatic}}cptr{{/notStatic}}{{params_impl}}){{#returnObject}}){{/returnObject}}; {{/hasNormalReturn}}{{#strings}} ReleaseStringUTFChars(env, {{string}}, c_{{string}}); {{/strings}}{{#hasReturn}}return jni_result;{{/hasReturn}}{{#hasListReturn}}return jni_list_result;{{/hasListReturn}} } {{/methods}}