From f0cd38ef228cf26bfdd0fd8bd037fd74fb1e1c5a Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 8 Apr 2016 14:27:55 +0200 Subject: [PATCH] Improved JNI layer (fixed few leaks) --- coreapi/linphonecore_jni.cc | 54 +++++++++++-------- .../linphone/core/LinphoneChatRoomImpl.java | 19 +++---- 2 files changed, 38 insertions(+), 35 deletions(-) diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index db1f72246..84ccf5342 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -452,7 +452,7 @@ jobject getProxy(JNIEnv *env, LinphoneProxyConfig *proxy, jobject core){ linphone_proxy_config_set_user_data(proxy,(void*)env->NewWeakGlobalRef(jobj)); linphone_proxy_config_ref(proxy); }else{ - //promote the weak ref to local ref + //promote the weak ref to local ref jobj=env->NewLocalRef((jobject)up); if (jobj == NULL){ //the weak ref was dead @@ -496,11 +496,17 @@ jobject getChatMessage(JNIEnv *env, LinphoneChatMessage *msg){ void *up = linphone_chat_message_get_user_data(msg); if (up == NULL) { - jobj = env->NewObject(ljb->chatMessageClass, ljb->chatMessageCtrId, (jlong)linphone_chat_message_ref(msg)); - jobj = env->NewGlobalRef(jobj); - linphone_chat_message_set_user_data(msg,(void*)jobj); + 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); } else { - jobj = (jobject)up; + 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)); + } } } return jobj; @@ -523,7 +529,7 @@ jobject getChatRoom(JNIEnv *env, LinphoneChatRoom *room) { jobj = env->NewLocalRef((jobject)up); if (jobj == NULL) { // takes implicit local ref - jobj=env->NewObject(ljb->chatRoomClass, ljb->chatRoomCtrId, (jlong)room); + jobj = env->NewObject(ljb->chatRoomClass, ljb->chatRoomCtrId, (jlong)room); linphone_chat_room_set_user_data(room, (void*)env->NewWeakGlobalRef(jobj)); } } @@ -3460,6 +3466,7 @@ extern "C" jlongArray Java_org_linphone_core_LinphoneFriendImpl_getAddresses(JNI ,jobject thiz ,jlong ptr) { MSList *addresses = linphone_friend_get_addresses((LinphoneFriend*)ptr); + MSList *list = addresses; int size = ms_list_size(addresses); jlongArray jaddresses = env->NewLongArray(size); jlong *jInternalArray = env->GetLongArrayElements(jaddresses, NULL); @@ -3467,7 +3474,7 @@ extern "C" jlongArray Java_org_linphone_core_LinphoneFriendImpl_getAddresses(JNI jInternalArray[i] = (unsigned long) (addresses->data); addresses = ms_list_next(addresses); } - ms_list_free(addresses); + ms_list_free(list); env->ReleaseLongArrayElements(jaddresses, jInternalArray, 0); return jaddresses; } @@ -3490,6 +3497,7 @@ extern "C" jobjectArray Java_org_linphone_core_LinphoneFriendImpl_getPhoneNumber ,jobject thiz ,jlong ptr) { MSList *phone_numbers = linphone_friend_get_phone_numbers((LinphoneFriend*)ptr); + MSList *list = phone_numbers; int size = ms_list_size(phone_numbers); jobjectArray jphonenumbers = env->NewObjectArray(size, env->FindClass("java/lang/String"), env->NewStringUTF("")); for (int i = 0; i < size; i++) { @@ -3497,7 +3505,7 @@ extern "C" jobjectArray Java_org_linphone_core_LinphoneFriendImpl_getPhoneNumber env->SetObjectArrayElement(jphonenumbers, i, env->NewStringUTF(phone)); phone_numbers = ms_list_next(phone_numbers); } - ms_list_free(phone_numbers); + ms_list_free(list); return jphonenumbers; } @@ -3686,26 +3694,28 @@ extern "C" jobject Java_org_linphone_core_LinphoneCoreImpl_getFriendByAddress(JN } } -extern "C" jlongArray _LinphoneChatRoomImpl_getHistory(JNIEnv* env - ,jobject thiz - ,jlong ptr - ,MSList* history) { +extern "C" jobjectArray _LinphoneChatRoomImpl_getHistory(JNIEnv* env, jobject thiz, jlong ptr, MSList* history) { + LinphoneChatRoom *room = (LinphoneChatRoom *)ptr; + LinphoneCore *lc = linphone_chat_room_get_core(room); + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); + MSList *list = history; int historySize = ms_list_size(history); - jlongArray jHistory = env->NewLongArray(historySize); - jlong *jInternalArray = env->GetLongArrayElements(jHistory, NULL); - + jobjectArray jHistory = env->NewObjectArray(historySize, ljb->chatMessageClass, NULL); + for (int i = 0; i < historySize; i++) { - jInternalArray[i] = (unsigned long) (history->data); + LinphoneChatMessage *msg = (LinphoneChatMessage *)history->data; + jobject jmsg = getChatMessage(env, msg); + if (jmsg != NULL) { + env->SetObjectArrayElement(jHistory, i, jmsg); + env->DeleteLocalRef(jmsg); + } history = history->next; } - ms_list_free(history); - - env->ReleaseLongArrayElements(jHistory, jInternalArray, 0); - + ms_list_free(list); return jHistory; } -extern "C" jlongArray Java_org_linphone_core_LinphoneChatRoomImpl_getHistoryRange(JNIEnv* env +extern "C" jobjectArray Java_org_linphone_core_LinphoneChatRoomImpl_getHistoryRange(JNIEnv* env ,jobject thiz ,jlong ptr ,jint start @@ -3713,7 +3723,7 @@ extern "C" jlongArray Java_org_linphone_core_LinphoneChatRoomImpl_getHistoryRang MSList* history = linphone_chat_room_get_history_range((LinphoneChatRoom*)ptr, start, end); return _LinphoneChatRoomImpl_getHistory(env, thiz, ptr, history); } -extern "C" jlongArray Java_org_linphone_core_LinphoneChatRoomImpl_getHistory(JNIEnv* env +extern "C" jobjectArray Java_org_linphone_core_LinphoneChatRoomImpl_getHistory(JNIEnv* env ,jobject thiz ,jlong ptr ,jint limit) { diff --git a/java/impl/org/linphone/core/LinphoneChatRoomImpl.java b/java/impl/org/linphone/core/LinphoneChatRoomImpl.java index ffb0b521a..d3d5ef967 100644 --- a/java/impl/org/linphone/core/LinphoneChatRoomImpl.java +++ b/java/impl/org/linphone/core/LinphoneChatRoomImpl.java @@ -29,8 +29,8 @@ class LinphoneChatRoomImpl implements LinphoneChatRoom { private native long getPeerAddress(long ptr); private native void sendMessage(long ptr, String message); private native void sendMessage2(long ptr, Object msg, long messagePtr, StateListener listener); - private native long[] getHistoryRange(long ptr, int begin, int end); - private native long[] getHistory(long ptr, int limit); + private native Object[] getHistoryRange(long ptr, int begin, int end); + private native Object[] getHistory(long ptr, int limit); private native void destroy(long ptr); private native int getUnreadMessagesCount(long ptr); private native int getHistorySize(long ptr); @@ -88,14 +88,14 @@ class LinphoneChatRoomImpl implements LinphoneChatRoom { public LinphoneChatMessage[] getHistoryRange(int begin, int end) { synchronized(getCore()){ - long[] typesPtr = getHistoryRange(nativePtr, begin, end); + Object[] typesPtr = getHistoryRange(nativePtr, begin, end); return getHistoryPrivate(typesPtr); } } public LinphoneChatMessage[] getHistory(int limit) { synchronized(getCore()){ - long[] typesPtr = getHistory(nativePtr, limit); + Object[] typesPtr = getHistory(nativePtr, limit); return getHistoryPrivate(typesPtr); } } @@ -157,15 +157,8 @@ class LinphoneChatRoomImpl implements LinphoneChatRoom { public synchronized LinphoneCore getCore() { return (LinphoneCore)getCore(nativePtr); } - private LinphoneChatMessage[] getHistoryPrivate(long[] typesPtr) { - if (typesPtr == null) return null; - - LinphoneChatMessage[] messages = new LinphoneChatMessage[typesPtr.length]; - for (int i=0; i < messages.length; i++) { - messages[i] = new LinphoneChatMessageImpl(typesPtr[i]); - } - - return messages; + private LinphoneChatMessage[] getHistoryPrivate(Object[] typesPtr) { + return (LinphoneChatMessage[]) typesPtr; } private native long createFileTransferMessage(long ptr, String name, String type, String subtype, int size);