From cfa911e27f62b456139509c5cac1541f895bf690 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 4 Dec 2015 16:13:55 +0100 Subject: [PATCH 1/9] Fix crash in JNI getChatMessage method because it was called from wrong thread --- coreapi/linphonecall.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 76621ab7c..269b71095 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -3317,7 +3317,7 @@ static void linphone_call_start_text_stream(LinphoneCall *call) { if (is_multicast) rtp_session_set_multicast_ttl(call->textstream->ms.sessions.rtp_session,tstream->ttl); text_stream_start(call->textstream, call->text_profile, rtp_addr, tstream->rtp_port, rtcp_addr, (linphone_core_rtcp_enabled(lc) && !is_multicast) ? (tstream->rtcp_port ? tstream->rtcp_port : tstream->rtp_port + 1) : 0, used_pt); - ms_filter_add_notify_callback(call->textstream->rttsink, real_time_text_character_received, call, TRUE); + ms_filter_add_notify_callback(call->textstream->rttsink, real_time_text_character_received, call, FALSE); ms_media_stream_sessions_set_encryption_mandatory(&call->textstream->ms.sessions,linphone_core_is_media_encryption_mandatory(call->core)); } else ms_warning("No text stream accepted."); From 7b04214dae674443ddf8d4c3a9791d538a3e4cc7 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 4 Dec 2015 16:28:17 +0100 Subject: [PATCH 2/9] Prevent useless FindClass calls in linphonecore_jni.cc callbacks --- coreapi/linphonecore_jni.cc | 224 +++++++++++++++++++----------------- 1 file changed, 117 insertions(+), 107 deletions(-) diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 9638fe9de..a48c07ce3 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -199,117 +199,15 @@ extern "C" void Java_org_linphone_core_LinphoneCoreFactoryImpl_setLogCollectionP /* * returns the java LinphoneProxyConfig associated with a C LinphoneProxyConfig. **/ -jobject getProxy(JNIEnv *env, LinphoneProxyConfig *proxy, jobject core){ - jobject jobj=0; +jobject getProxy(JNIEnv *env, LinphoneProxyConfig *proxy, jobject core); - if (proxy!=NULL){ - jclass proxyClass = (jclass)env->FindClass("org/linphone/core/LinphoneProxyConfigImpl"); - jmethodID proxyCtrId = env->GetMethodID(proxyClass,"", "(Lorg/linphone/core/LinphoneCoreImpl;J)V"); +jobject getCall(JNIEnv *env, LinphoneCall *call); - void *up=linphone_proxy_config_get_user_data(proxy); +jobject getChatMessage(JNIEnv *env, LinphoneChatMessage *msg); - if (up==NULL){ - jobj=env->NewObject(proxyClass,proxyCtrId,core,(jlong)proxy); - linphone_proxy_config_set_user_data(proxy,(void*)env->NewWeakGlobalRef(jobj)); - linphone_proxy_config_ref(proxy); - }else{ - //promote the weak ref to local ref - jobj=env->NewLocalRef((jobject)up); - if (jobj == NULL){ - //the weak ref was dead - jobj=env->NewObject(proxyClass,proxyCtrId,core,(jlong)proxy); - linphone_proxy_config_set_user_data(proxy,(void*)env->NewWeakGlobalRef(jobj)); - } - } - env->DeleteLocalRef(proxyClass); - } - return jobj; -} +jobject getFriend(JNIEnv *env, LinphoneFriend *lfriend); -jobject getCall(JNIEnv *env, LinphoneCall *call){ - jobject jobj=0; - - if (call!=NULL){ - jclass callClass = (jclass)env->FindClass("org/linphone/core/LinphoneCallImpl"); - jmethodID callCtrId = env->GetMethodID(callClass,"", "(J)V"); - - void *up=linphone_call_get_user_pointer(call); - - if (up==NULL){ - jobj=env->NewObject(callClass,callCtrId,(jlong)call); - jobj=env->NewGlobalRef(jobj); - linphone_call_set_user_pointer(call,(void*)jobj); - linphone_call_ref(call); - }else{ - jobj=(jobject)up; - } - env->DeleteLocalRef(callClass); - } - return jobj; -} - -jobject getChatMessage(JNIEnv *env, LinphoneChatMessage *msg){ - jobject jobj = 0; - - if (msg != NULL){ - jclass chatMessageClass = (jclass)env->FindClass("org/linphone/core/LinphoneChatMessageImpl"); - jmethodID chatMessageCtrId = env->GetMethodID(chatMessageClass,"", "(J)V"); - - void *up = linphone_chat_message_get_user_data(msg); - - if (up == NULL) { - jobj = env->NewObject(chatMessageClass,chatMessageCtrId,(jlong)linphone_chat_message_ref(msg)); - jobj = env->NewGlobalRef(jobj); - linphone_chat_message_set_user_data(msg,(void*)jobj); - } else { - jobj = (jobject)up; - } - env->DeleteLocalRef(chatMessageClass); - } - return jobj; -} - -jobject getFriend(JNIEnv *env, LinphoneFriend *lfriend){ - jobject jobj=0; - - if (lfriend != NULL){ - jclass friendClass = (jclass)env->FindClass("org/linphone/core/LinphoneFriendImpl"); - jmethodID friendCtrId = env->GetMethodID(friendClass,"", "(J)V"); - - void *up=linphone_friend_get_user_data(lfriend); - - if (up == NULL){ - jobj=env->NewObject(friendClass,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){ - jobj=env->NewObject(friendClass,friendCtrId,(jlong)lfriend); - linphone_friend_set_user_data(lfriend,(void*)env->NewWeakGlobalRef(jobj)); - } - } - env->DeleteLocalRef(friendClass); - } - return jobj; -} - -jobject getEvent(JNIEnv *env, LinphoneEvent *lev){ - if (lev==NULL) return NULL; - jobject jev=(jobject)linphone_event_get_user_data(lev); - if (jev==NULL){ - jclass linphoneEventClass = (jclass)env->FindClass("org/linphone/core/LinphoneEventImpl"); - jmethodID linphoneEventCtrId = env->GetMethodID(linphoneEventClass,"", "(J)V"); - - jev=env->NewObject(linphoneEventClass,linphoneEventCtrId,(jlong)linphone_event_ref(lev)); - jev=env->NewGlobalRef(jev); - linphone_event_set_user_data(lev,jev); - - env->DeleteLocalRef(linphoneEventClass); - } - return jev; -} +jobject getEvent(JNIEnv *env, LinphoneEvent *lev); class LinphoneCoreData { public: @@ -1132,6 +1030,118 @@ private: } }; +jobject getProxy(JNIEnv *env, LinphoneProxyConfig *proxy, jobject core){ + jobject jobj=0; + + if (proxy!=NULL){ + LinphoneCore *lc = linphone_proxy_config_get_core(proxy); + LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); + LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); + + void *up=linphone_proxy_config_get_user_data(proxy); + + if (up==NULL){ + jobj=env->NewObject(lcData->proxyClass, lcData->proxyCtrId, core, (jlong)proxy); + linphone_proxy_config_set_user_data(proxy,(void*)env->NewWeakGlobalRef(jobj)); + linphone_proxy_config_ref(proxy); + }else{ + //promote the weak ref to local ref + jobj=env->NewLocalRef((jobject)up); + if (jobj == NULL){ + //the weak ref was dead + jobj=env->NewObject(lcData->proxyClass, lcData->proxyCtrId, core, (jlong)proxy); + linphone_proxy_config_set_user_data(proxy,(void*)env->NewWeakGlobalRef(jobj)); + } + } + } + return jobj; +} + +jobject getCall(JNIEnv *env, LinphoneCall *call){ + jobject jobj=0; + + if (call!=NULL){ + LinphoneCore *lc = linphone_call_get_core(call); + LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); + LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); + + void *up=linphone_call_get_user_pointer(call); + + if (up==NULL){ + jobj=env->NewObject(lcData->callClass, lcData->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); + LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); + LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); + + void *up = linphone_chat_message_get_user_data(msg); + + if (up == NULL) { + jobj = env->NewObject(lcData->chatMessageClass, lcData->chatMessageCtrId, (jlong)linphone_chat_message_ref(msg)); + jobj = env->NewGlobalRef(jobj); + linphone_chat_message_set_user_data(msg,(void*)jobj); + } else { + jobj = (jobject)up; + } + } + return jobj; +} + +jobject getFriend(JNIEnv *env, LinphoneFriend *lfriend){ + jobject jobj=0; + + if (lfriend != NULL){ + LinphoneCore *lc = linphone_friend_get_core(lfriend); + LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); + LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); + + void *up=linphone_friend_get_user_data(lfriend); + + if (up == NULL){ + jobj=env->NewObject(lcData->friendClass, lcData->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){ + jobj=env->NewObject(lcData->friendClass, lcData->friendCtrId, lcData->(jlong)lfriend); + linphone_friend_set_user_data(lfriend,(void*)env->NewWeakGlobalRef(jobj)); + } + } + } + return jobj; +} + +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); + LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); + LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); + + jev=env->NewObject(lcData->linphoneEventClass, lcData->linphoneEventCtrId, (jlong)linphone_event_ref(lev)); + jev=env->NewGlobalRef(jev); + linphone_event_set_user_data(lev,jev); + } + return jev; +} + extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_newLinphoneCore(JNIEnv* env ,jobject thiz ,jobject jlistener From 48510f3000961867d8de79899f0a5732f3fc0259 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 4 Dec 2015 16:43:36 +0100 Subject: [PATCH 3/9] Fixed copy/paste mistake --- coreapi/linphonecore_jni.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index a48c07ce3..95081ab6f 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -1119,7 +1119,7 @@ jobject getFriend(JNIEnv *env, LinphoneFriend *lfriend){ jobj=env->NewLocalRef((jobject)up); if (jobj == NULL){ - jobj=env->NewObject(lcData->friendClass, lcData->friendCtrId, lcData->(jlong)lfriend); + jobj=env->NewObject(lcData->friendClass, lcData->friendCtrId, (jlong)lfriend); linphone_friend_set_user_data(lfriend,(void*)env->NewWeakGlobalRef(jobj)); } } From 9d71678c2863f723d4c2010ce292c41e09f42f3b Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 4 Dec 2015 17:02:29 +0100 Subject: [PATCH 4/9] If there is no current vtable, return the first one if exists --- coreapi/vtables.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/coreapi/vtables.c b/coreapi/vtables.c index b01a91f08..3611d290a 100644 --- a/coreapi/vtables.c +++ b/coreapi/vtables.c @@ -38,6 +38,9 @@ void linphone_core_v_table_destroy(LinphoneCoreVTable* table) { } LinphoneCoreVTable *linphone_core_get_current_vtable(LinphoneCore *lc) { + if (lc->current_vtable == NULL && ms_list_size(lc->vtable_refs) > 0) { + return (LinphoneCoreVTable *)ms_list_nth_data(lc->vtable_refs, 0); + } return lc->current_vtable; } From 6325178af5611159322125d763a07144d8ba2085 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 4 Dec 2015 22:25:22 +0100 Subject: [PATCH 5/9] Update ms2 and rely on the new specific codec offer answer logic declaration. --- coreapi/linphonecore.c | 1 + coreapi/offeranswer.c | 170 ++++++++++++++++++++--------------------- coreapi/private.h | 1 + mediastreamer2 | 2 +- 4 files changed, 87 insertions(+), 87 deletions(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 7eb42fb17..c6bebdb9f 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1684,6 +1684,7 @@ static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtab ms_init(); linphone_core_register_default_codecs(lc); + linphone_core_register_offer_answer_providers(lc); /* Get the mediastreamer2 event queue */ /* This allows to run event's callback in linphone_core_iterate() */ lc->msevq=ms_factory_create_event_queue(ms_factory_get_fallback()); diff --git a/coreapi/offeranswer.c b/coreapi/offeranswer.c index 15abe2ca6..b16e6899d 100644 --- a/coreapi/offeranswer.c +++ b/coreapi/offeranswer.c @@ -31,12 +31,8 @@ static bool_t only_telephone_event(const MSList *l){ return TRUE; } -typedef struct _PayloadTypeMatcher{ - const char *mime_type; - PayloadType *(*match_func)(const MSList *local_payloads, const PayloadType *refpt, const MSList *remote_payloads); -}PayloadTypeMatcher; -static PayloadType * opus_match(const MSList *local_payloads, const PayloadType *refpt, const MSList *remote_payloads){ +static PayloadType * opus_match(MSOfferAnswerContext *ctx, const MSList *local_payloads, const PayloadType *refpt, const MSList *remote_payloads, bool_t reading_response){ PayloadType *pt; const MSList *elem; PayloadType *candidate=NULL; @@ -54,11 +50,21 @@ static PayloadType * opus_match(const MSList *local_payloads, const PayloadType } } } - return candidate; + return candidate ? payload_type_clone(candidate) : NULL; } +static MSOfferAnswerContext *opus_offer_answer_create_context(void){ + static MSOfferAnswerContext opus_oa = {opus_match, NULL}; + return &opus_oa; +} + +MSOfferAnswerProvider opus_offer_answer_provider={ + "opus", + opus_offer_answer_create_context +}; + /* the reason for this matcher is for some stupid uncompliant phone that offer G729a mime type !*/ -static PayloadType * g729A_match(const MSList *local_payloads, const PayloadType *refpt, const MSList *remote_payloads){ +static PayloadType * g729A_match(MSOfferAnswerContext *ctx, const MSList *local_payloads, const PayloadType *refpt, const MSList *remote_payloads, bool_t reading_response){ PayloadType *pt; const MSList *elem; PayloadType *candidate=NULL; @@ -70,38 +76,56 @@ static PayloadType * g729A_match(const MSList *local_payloads, const PayloadType candidate=pt; } } - return candidate; + return candidate ? payload_type_clone(candidate) : NULL; } -static PayloadType * amr_match(const MSList *local_payloads, const PayloadType *refpt, const MSList *remote_payloads){ - PayloadType *pt; - char value[10]; - const MSList *elem; - PayloadType *candidate=NULL; +static MSOfferAnswerContext *g729a_offer_answer_create_context(void){ + static MSOfferAnswerContext g729_oa = {g729A_match, NULL}; + return &g729_oa; +} - for (elem=local_payloads;elem!=NULL;elem=elem->next){ - pt=(PayloadType*)elem->data; +MSOfferAnswerProvider g729a_offer_answer_provider={ + "G729A", + g729a_offer_answer_create_context +}; + +static PayloadType * red_match(MSOfferAnswerContext *ctx, const MSList *local_payloads, const PayloadType *refpt, const MSList *remote_payloads, bool_t reading_response) { + const MSList *elem_local, *elem_remote; + PayloadType *red = NULL; + + for (elem_local = local_payloads; elem_local != NULL; elem_local = elem_local->next) { + PayloadType *pt = (PayloadType*)elem_local->data; - if ( pt->mime_type && refpt->mime_type - && strcasecmp(pt->mime_type, refpt->mime_type)==0 - && pt->clock_rate==refpt->clock_rate - && pt->channels==refpt->channels) { - int octedalign1=0,octedalign2=0; - if (pt->recv_fmtp!=NULL && fmtp_get_value(pt->recv_fmtp,"octet-align",value,sizeof(value))){ - octedalign1=atoi(value); - } - if (refpt->send_fmtp!=NULL && fmtp_get_value(refpt->send_fmtp,"octet-align",value,sizeof(value))){ - octedalign2=atoi(value); - } - if (octedalign1==octedalign2) { - candidate=pt; - break; /*exact match */ + if (strcasecmp(pt->mime_type, payload_type_t140_red.mime_type) == 0) { + red = payload_type_clone(pt); + + for (elem_remote = remote_payloads; elem_remote != NULL; elem_remote = elem_remote->next) { + PayloadType *pt2 = (PayloadType*)elem_remote->data; + if (strcasecmp(pt2->mime_type, payload_type_t140.mime_type) == 0) { + int t140_payload_number = payload_type_get_number(pt2); + const char *red_fmtp = ms_strdup_printf("%i/%i/%i", t140_payload_number, t140_payload_number, t140_payload_number); + /*modify the local payload and the return value*/ + payload_type_set_recv_fmtp(pt, red_fmtp); + payload_type_set_recv_fmtp(red, red_fmtp); + break; + } } + break; } } - return candidate; + return red; } +static MSOfferAnswerContext *red_offer_answer_create_context(void){ + static MSOfferAnswerContext red_oa = {red_match, NULL}; + return &red_oa; +} + +MSOfferAnswerProvider red_offer_answer_provider={ + "red", + red_offer_answer_create_context +}; + static PayloadType * generic_match(const MSList *local_payloads, const PayloadType *refpt, const MSList *remote_payloads){ PayloadType *pt; const MSList *elem; @@ -113,55 +137,31 @@ static PayloadType * generic_match(const MSList *local_payloads, const PayloadTy && strcasecmp(pt->mime_type, refpt->mime_type)==0 && pt->clock_rate==refpt->clock_rate && pt->channels==refpt->channels) - return pt; + return payload_type_clone(pt); } return NULL; } -static PayloadType * red_match(const MSList *local_payloads, const PayloadType *refpt, const MSList *remote_payloads) { - const MSList *elem_local, *elem_remote; - PayloadType *red = NULL; - for (elem_local = local_payloads; elem_local != NULL; elem_local = elem_local->next) { - PayloadType *pt = (PayloadType*)elem_local->data; - - if (strcasecmp(pt->mime_type, payload_type_t140_red.mime_type) == 0) { - red = pt; - - for (elem_remote = remote_payloads; elem_remote != NULL; elem_remote = elem_remote->next) { - PayloadType *pt2 = (PayloadType*)elem_remote->data; - if (strcasecmp(pt2->mime_type, payload_type_t140.mime_type) == 0) { - int t140_payload_number = payload_type_get_number(pt2); - const char *red_fmtp = ms_strdup_printf("%i/%i/%i", t140_payload_number, t140_payload_number, t140_payload_number); - payload_type_set_recv_fmtp(red, red_fmtp); - break; - } - } - break; - } - } - return red; +void linphone_core_register_offer_answer_providers(LinphoneCore *lc){ + MSFactory *factory = ms_factory_get_fallback(); + ms_factory_register_offer_answer_provider(factory, &red_offer_answer_provider); + ms_factory_register_offer_answer_provider(factory, &g729a_offer_answer_provider); + ms_factory_register_offer_answer_provider(factory, &opus_offer_answer_provider); } -static PayloadTypeMatcher matchers[]={ - {"opus", opus_match}, - {"G729A", g729A_match}, - {"AMR", amr_match}, - {"AMR-WB", amr_match}, - {"red", red_match}, - {NULL, NULL} -}; - - /* * Returns a PayloadType from the local list that matches a PayloadType offered or answered in the remote list */ -static PayloadType * find_payload_type_best_match(const MSList *local_payloads, const PayloadType *refpt, const MSList *remote_payloads){ - PayloadTypeMatcher *m; - for(m=matchers;m->mime_type!=NULL;++m){ - if (refpt->mime_type && strcasecmp(m->mime_type,refpt->mime_type)==0){ - return m->match_func(local_payloads, refpt, remote_payloads); - } +static PayloadType * find_payload_type_best_match(const MSList *local_payloads, const PayloadType *refpt, + const MSList *remote_payloads, bool_t reading_response){ + PayloadType *ret = NULL; + MSOfferAnswerContext *ctx = ms_factory_create_offer_answer_context(ms_factory_get_fallback(), refpt->mime_type); + if (ctx){ + ms_message("Doing offer/answer processing with specific provider for codec [%s]", refpt->mime_type); + ret = ms_offer_answer_context_match_payload(ctx, local_payloads, refpt, remote_payloads, reading_response); + ms_offer_answer_context_destroy(ctx); + return ret; } return generic_match(local_payloads, refpt, remote_payloads); } @@ -175,9 +175,8 @@ static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t for(e2=remote;e2!=NULL;e2=e2->next){ PayloadType *p2=(PayloadType*)e2->data; - matched=find_payload_type_best_match(local,p2,remote); + matched=find_payload_type_best_match(local, p2, remote, reading_response); if (matched){ - PayloadType *newp; int local_number=payload_type_get_number(matched); int remote_number=payload_type_get_number(p2); @@ -189,37 +188,36 @@ static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t } } - newp=payload_type_clone(matched); if (p2->send_fmtp){ - payload_type_append_send_fmtp(newp,p2->send_fmtp); + payload_type_append_send_fmtp(matched,p2->send_fmtp); } - newp->flags|=PAYLOAD_TYPE_FLAG_CAN_RECV|PAYLOAD_TYPE_FLAG_CAN_SEND; + matched->flags|=PAYLOAD_TYPE_FLAG_CAN_RECV|PAYLOAD_TYPE_FLAG_CAN_SEND; if (p2->flags & PAYLOAD_TYPE_RTCP_FEEDBACK_ENABLED) { - newp->flags |= PAYLOAD_TYPE_RTCP_FEEDBACK_ENABLED; + matched->flags |= PAYLOAD_TYPE_RTCP_FEEDBACK_ENABLED; /* Negotiation of AVPF features (keep common features) */ - newp->avpf.features &= p2->avpf.features; - newp->avpf.rpsi_compatibility = p2->avpf.rpsi_compatibility; + matched->avpf.features &= p2->avpf.features; + matched->avpf.rpsi_compatibility = p2->avpf.rpsi_compatibility; /* Take bigger AVPF trr interval */ if (p2->avpf.trr_interval < matched->avpf.trr_interval) { - newp->avpf.trr_interval = matched->avpf.trr_interval; + matched->avpf.trr_interval = matched->avpf.trr_interval; } } - res=ms_list_append(res,newp); + res=ms_list_append(res,matched); /* we should use the remote numbering even when parsing a response */ - payload_type_set_number(newp,remote_number); - payload_type_set_flag(newp, PAYLOAD_TYPE_FROZEN_NUMBER); + payload_type_set_number(matched,remote_number); + payload_type_set_flag(matched, PAYLOAD_TYPE_FROZEN_NUMBER); if (reading_response && remote_number!=local_number){ ms_warning("For payload type %s, proposed number was %i but the remote phone answered %i", - newp->mime_type, local_number, remote_number); + matched->mime_type, local_number, remote_number); /* We must add this payload type with our local numbering in order to be able to receive it. Indeed despite we must sent with the remote numbering, we must be able to receive with our local one. */ - newp=payload_type_clone(newp); - payload_type_set_number(newp,local_number); - payload_type_set_flag(newp, PAYLOAD_TYPE_FROZEN_NUMBER); - res=ms_list_append(res,newp); + matched=payload_type_clone(matched); + payload_type_set_number(matched,local_number); + payload_type_set_flag(matched, PAYLOAD_TYPE_FROZEN_NUMBER); + res=ms_list_append(res,matched); } }else{ if (p2->channels>0) diff --git a/coreapi/private.h b/coreapi/private.h index 1a10bed92..27420aabb 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -1082,6 +1082,7 @@ void linphone_event_set_publish_state(LinphoneEvent *lev, LinphonePublishState s LinphoneSubscriptionState linphone_subscription_state_from_sal(SalSubscribeStatus ss); LinphoneContent *linphone_content_from_sal_body(const SalBody *ref); void linphone_core_invalidate_friend_subscriptions(LinphoneCore *lc); +void linphone_core_register_offer_answer_providers(LinphoneCore *lc); struct _LinphoneContent { diff --git a/mediastreamer2 b/mediastreamer2 index 3caf56649..ca35de0fb 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 3caf56649034b6f5ec633372ae0c24416b9013a5 +Subproject commit ca35de0fbd6b7e1a93f0f2bd1ea9983074e6c6f7 From e6977c69158d46b16190a50f48d47f126c9001d6 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Sat, 5 Dec 2015 18:05:09 +0100 Subject: [PATCH 6/9] fix crash due to payload type being freed twice, and fix a small memory leak --- coreapi/offeranswer.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/coreapi/offeranswer.c b/coreapi/offeranswer.c index b16e6899d..0fc099460 100644 --- a/coreapi/offeranswer.c +++ b/coreapi/offeranswer.c @@ -46,7 +46,7 @@ static PayloadType * opus_match(MSOfferAnswerContext *ctx, const MSList *local_p pt->channels=1; /*so that we respond with same number of channels */ candidate=pt; }else if (refpt->channels==2){ - return pt; + return payload_type_clone(pt); } } } @@ -103,10 +103,11 @@ static PayloadType * red_match(MSOfferAnswerContext *ctx, const MSList *local_pa PayloadType *pt2 = (PayloadType*)elem_remote->data; if (strcasecmp(pt2->mime_type, payload_type_t140.mime_type) == 0) { int t140_payload_number = payload_type_get_number(pt2); - const char *red_fmtp = ms_strdup_printf("%i/%i/%i", t140_payload_number, t140_payload_number, t140_payload_number); + char *red_fmtp = ms_strdup_printf("%i/%i/%i", t140_payload_number, t140_payload_number, t140_payload_number); /*modify the local payload and the return value*/ payload_type_set_recv_fmtp(pt, red_fmtp); payload_type_set_recv_fmtp(red, red_fmtp); + ms_free(red_fmtp); break; } } From 44dbe602ebfd9a5eeb95bb6f146780f08b8c62f8 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 4 Dec 2015 17:14:40 +0100 Subject: [PATCH 7/9] Revert "If there is no current vtable, return the first one if exists" This reverts commit 9d71678c2863f723d4c2010ce292c41e09f42f3b. --- coreapi/vtables.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/coreapi/vtables.c b/coreapi/vtables.c index 3611d290a..b01a91f08 100644 --- a/coreapi/vtables.c +++ b/coreapi/vtables.c @@ -38,9 +38,6 @@ void linphone_core_v_table_destroy(LinphoneCoreVTable* table) { } LinphoneCoreVTable *linphone_core_get_current_vtable(LinphoneCore *lc) { - if (lc->current_vtable == NULL && ms_list_size(lc->vtable_refs) > 0) { - return (LinphoneCoreVTable *)ms_list_nth_data(lc->vtable_refs, 0); - } return lc->current_vtable; } From f95eb81ec1a1e00ef0daaaa89466de02c96ce773 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 7 Dec 2015 09:40:37 +0100 Subject: [PATCH 8/9] Improved JNI layer --- coreapi/linphonecore_jni.cc | 602 +++++++++++++++++++++--------------- 1 file changed, 345 insertions(+), 257 deletions(-) diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 95081ab6f..57ed5f7b2 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -196,75 +196,36 @@ extern "C" void Java_org_linphone_core_LinphoneCoreFactoryImpl_setLogCollectionP } // LinphoneCore -/* - * returns the java LinphoneProxyConfig associated with a C LinphoneProxyConfig. -**/ -jobject getProxy(JNIEnv *env, LinphoneProxyConfig *proxy, jobject core); - -jobject getCall(JNIEnv *env, LinphoneCall *call); - -jobject getChatMessage(JNIEnv *env, LinphoneChatMessage *msg); - -jobject getFriend(JNIEnv *env, LinphoneFriend *lfriend); - -jobject getEvent(JNIEnv *env, LinphoneEvent *lev); - -class LinphoneCoreData { +class LinphoneJavaBindings { public: - LinphoneCoreData(JNIEnv *env, jobject lc, LinphoneCoreVTable *vTable, jobject alistener) { - core = env->NewGlobalRef(lc); - listener = env->NewGlobalRef(alistener); - - memset(vTable, 0, sizeof(LinphoneCoreVTable)); - - listenerClass = (jclass)env->NewGlobalRef(env->GetObjectClass(alistener)); - + LinphoneJavaBindings(JNIEnv *env) { + listenerClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCoreListener")); + /*displayStatus(LinphoneCore lc,String message);*/ displayStatusId = env->GetMethodID(listenerClass,"displayStatus","(Lorg/linphone/core/LinphoneCore;Ljava/lang/String;)V"); - if (displayStatusId) { - vTable->display_status = displayStatusCb; - } /*void generalState(LinphoneCore lc,int state); */ globalStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCore$GlobalState")); globalStateFromIntId = env->GetStaticMethodID(globalStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneCore$GlobalState;"); globalStateId = env->GetMethodID(listenerClass,"globalState","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCore$GlobalState;Ljava/lang/String;)V"); - if (globalStateId) { - vTable->global_state_changed = globalStateChange; - } /*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;"); registrationStateId = env->GetMethodID(listenerClass,"registrationState","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneProxyConfig;Lorg/linphone/core/LinphoneCore$RegistrationState;Ljava/lang/String;)V"); - if (registrationStateId) { - vTable->registration_state_changed = registrationStateChange; - } /*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;"); callStateId = env->GetMethodID(listenerClass,"callState","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;Lorg/linphone/core/LinphoneCall$State;Ljava/lang/String;)V"); - if (callStateId) { - vTable->call_state_changed = callStateChange; - } transferStateId = env->GetMethodID(listenerClass,"transferState","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;Lorg/linphone/core/LinphoneCall$State;)V"); - if (transferStateId) { - vTable->transfer_state_changed = transferStateChanged; - } /*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"); - if (callStatsUpdatedId) { - vTable->call_stats_updated = callStatsUpdated; - } /*callEncryption(LinphoneCore lc, LinphoneCall call, boolean encrypted,String auth_token);*/ callEncryptionChangedId = env->GetMethodID(listenerClass,"callEncryptionChanged","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;ZLjava/lang/String;)V"); - if (callEncryptionChangedId) { - vTable->call_encryption_changed = callEncryptionChange; - } /*void ecCalibrationStatus(LinphoneCore.EcCalibratorStatus status, int delay_ms, Object data);*/ ecCalibratorStatusClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCore$EcCalibratorStatus")); @@ -273,92 +234,44 @@ public: /*void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf, String url)*/ newSubscriptionRequestId = env->GetMethodID(listenerClass,"newSubscriptionRequest","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneFriend;Ljava/lang/String;)V"); - if (newSubscriptionRequestId) { - vTable->new_subscription_requested = new_subscription_requested; - } authInfoRequestedId = env->GetMethodID(listenerClass,"authInfoRequested","(Lorg/linphone/core/LinphoneCore;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"); - if (authInfoRequestedId) { - vTable->auth_info_requested = authInfoRequested; - } /*void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf);*/ notifyPresenceReceivedId = env->GetMethodID(listenerClass,"notifyPresenceReceived","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneFriend;)V"); - if (notifyPresenceReceivedId) { - vTable->notify_presence_received = notify_presence_received; - } messageReceivedId = env->GetMethodID(listenerClass,"messageReceived","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatRoom;Lorg/linphone/core/LinphoneChatMessage;)V"); - if (messageReceivedId) { - vTable->message_received = message_received; - } isComposingReceivedId = env->GetMethodID(listenerClass,"isComposingReceived","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatRoom;)V"); - if (isComposingReceivedId) { - vTable->is_composing_received = is_composing_received; - } dtmfReceivedId = env->GetMethodID(listenerClass,"dtmfReceived","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;I)V"); - if (dtmfReceivedId) { - vTable->dtmf_received = dtmf_received; - } infoReceivedId = env->GetMethodID(listenerClass,"infoReceived", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;Lorg/linphone/core/LinphoneInfoMessage;)V"); - if (infoReceivedId) { - vTable->info_received = infoReceived; - } subscriptionStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/SubscriptionState")); subscriptionStateFromIntId = env->GetStaticMethodID(subscriptionStateClass,"fromInt","(I)Lorg/linphone/core/SubscriptionState;"); subscriptionStateId = env->GetMethodID(listenerClass,"subscriptionStateChanged", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneEvent;Lorg/linphone/core/SubscriptionState;)V"); - if (subscriptionStateId) { - vTable->subscription_state_changed = subscriptionStateChanged; - } publishStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/PublishState")); publishStateFromIntId = env->GetStaticMethodID(publishStateClass,"fromInt","(I)Lorg/linphone/core/PublishState;"); publishStateId = env->GetMethodID(listenerClass,"publishStateChanged", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneEvent;Lorg/linphone/core/PublishState;)V"); - if (publishStateId) { - vTable->publish_state_changed = publishStateChanged; - } notifyRecvId = env->GetMethodID(listenerClass,"notifyReceived", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneEvent;Ljava/lang/String;Lorg/linphone/core/LinphoneContent;)V"); - if (notifyRecvId) { - vTable->notify_received = notifyReceived; - } configuringStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCore$RemoteProvisioningState")); configuringStateFromIntId = env->GetStaticMethodID(configuringStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneCore$RemoteProvisioningState;"); configuringStateId = env->GetMethodID(listenerClass,"configuringStatus","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCore$RemoteProvisioningState;Ljava/lang/String;)V"); - if (configuringStateId) { - vTable->configuring_status = configuringStatus; - } fileTransferProgressIndicationId = env->GetMethodID(listenerClass, "fileTransferProgressIndication", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneContent;I)V"); - if (fileTransferProgressIndicationId) { - vTable->file_transfer_progress_indication = fileTransferProgressIndication; - } fileTransferSendId = env->GetMethodID(listenerClass, "fileTransferSend", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneContent;Ljava/nio/ByteBuffer;I)I"); - if (fileTransferSendId) { - vTable->file_transfer_send = fileTransferSend; - } fileTransferRecvId = env->GetMethodID(listenerClass, "fileTransferRecv", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneContent;[BI)V"); - if (fileTransferRecvId) { - vTable->file_transfer_recv = fileTransferRecv; - } logCollectionUploadStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCore$LogCollectionUploadState")); logCollectionUploadStateFromIntId = env->GetStaticMethodID(logCollectionUploadStateClass, "fromInt", "(I)Lorg/linphone/core/LinphoneCore$LogCollectionUploadState;"); logCollectionUploadProgressId = env->GetMethodID(listenerClass, "uploadProgressIndication", "(Lorg/linphone/core/LinphoneCore;II)V"); - if (logCollectionUploadProgressId) { - vTable->log_collection_upload_progress_indication = logCollectionUploadProgressIndication; - } logCollectionUploadStateId = env->GetMethodID(listenerClass, "uploadStateChanged", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCore$LogCollectionUploadState;Ljava/lang/String;)V"); - if (logCollectionUploadStateId) { - vTable->log_collection_upload_state_changed = logCollectionUploadStateChange; - } chatMessageStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneChatMessage$State")); chatMessageStateFromIntId = env->GetStaticMethodID(chatMessageStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneChatMessage$State;"); @@ -397,12 +310,18 @@ public: subscriptionDirClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/SubscriptionDir")); subscriptionDirFromIntId = env->GetStaticMethodID(subscriptionDirClass,"fromInt","(I)Lorg/linphone/core/SubscriptionDir;"); } + + void setCore(jobject c) { + core = c; + } + + jobject getCore() { + return core; + } - ~LinphoneCoreData() { + ~LinphoneJavaBindings() { JNIEnv *env = 0; jvm->AttachCurrentThread(&env,NULL); - env->DeleteGlobalRef(core); - env->DeleteGlobalRef(listener); env->DeleteGlobalRef(listenerClass); env->DeleteGlobalRef(globalStateClass); env->DeleteGlobalRef(configuringStateClass); @@ -420,8 +339,8 @@ public: env->DeleteGlobalRef(subscriptionDirClass); env->DeleteGlobalRef(logCollectionUploadStateClass); } + jobject core; - jobject listener; jclass listenerClass; jmethodID displayStatusId; @@ -509,6 +428,227 @@ public: jmethodID logCollectionUploadStateId; jmethodID logCollectionUploadStateFromIntId; jmethodID logCollectionUploadProgressId; +}; + +/* + * 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{ + //promote the weak ref to local ref + 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; +} + +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) { + 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); + } else { + jobj = (jobject)up; + } + } + return jobj; +} + +jobject getFriend(JNIEnv *env, LinphoneFriend *lfriend){ + jobject jobj=0; + + 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){ + 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){ + jobj=env->NewObject(ljb->friendClass, ljb->friendCtrId, (jlong)lfriend); + linphone_friend_set_user_data(lfriend,(void*)env->NewWeakGlobalRef(jobj)); + } + } + } + return jobj; +} + +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; +} + +class LinphoneCoreData { +public: + LinphoneCoreData(JNIEnv *env, jobject lc, LinphoneCoreVTable *vTable, jobject alistener, LinphoneJavaBindings *ljb) { + core = env->NewGlobalRef(lc); + listener = env->NewGlobalRef(alistener); + + 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; + } + + if (ljb->notifyPresenceReceivedId) { + vTable->notify_presence_received = notify_presence_received; + } + + if (ljb->messageReceivedId) { + vTable->message_received = message_received; + } + + 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; + } + + 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; + } + } + + ~LinphoneCoreData() { + JNIEnv *env = 0; + jvm->AttachCurrentThread(&env,NULL); + env->DeleteGlobalRef(core); + env->DeleteGlobalRef(listener); + } + + jobject core; + jobject listener; LinphoneCoreVTable vTable; @@ -519,10 +659,12 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); jstring msg = message ? env->NewStringUTF(message) : NULL; - env->CallVoidMethod(lcData->listener,lcData->displayStatusId,lcData->core,msg); + env->CallVoidMethod(lcData->listener,ljb->displayStatusId,lcData->core,msg); handle_possible_java_exception(env, lcData->listener); if (msg) { env->DeleteLocalRef(msg); @@ -535,13 +677,15 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); jstring r = realm ? env->NewStringUTF(realm) : NULL; jstring u = username ? env->NewStringUTF(username) : NULL; jstring d = domain ? env->NewStringUTF(domain) : NULL; env->CallVoidMethod(lcData->listener, - lcData->authInfoRequestedId, + ljb->authInfoRequestedId, lcData->core, r, u, @@ -573,6 +717,8 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); @@ -582,9 +728,9 @@ public: jstring msg = message ? env->NewStringUTF(message) : NULL; env->CallVoidMethod(lcData->listener - ,lcData->globalStateId + ,ljb->globalStateId ,lcData->core - ,env->CallStaticObjectMethod(lcData->globalStateClass,lcData->globalStateFromIntId,(jint)gstate), + ,env->CallStaticObjectMethod(ljb->globalStateClass,ljb->globalStateFromIntId,(jint)gstate), msg); handle_possible_java_exception(env, lcData->listener); if (msg) { @@ -599,14 +745,16 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); jstring msg = message ? env->NewStringUTF(message) : NULL; env->CallVoidMethod(lcData->listener - ,lcData->registrationStateId + ,ljb->registrationStateId ,lcData->core ,(jproxy=getProxy(env,proxy,lcData->core)) - ,env->CallStaticObjectMethod(lcData->registrationStateClass,lcData->registrationStateFromIntId,(jint)state), + ,env->CallStaticObjectMethod(ljb->registrationStateClass,ljb->registrationStateFromIntId,(jint)state), msg); handle_possible_java_exception(env, lcData->listener); if (msg) { @@ -622,14 +770,16 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); jstring msg = message ? env->NewStringUTF(message) : NULL; env->CallVoidMethod(lcData->listener - ,lcData->callStateId + ,ljb->callStateId ,lcData->core ,(jcall=getCall(env,call)) - ,env->CallStaticObjectMethod(lcData->callStateClass,lcData->callStateFromIntId,(jint)state), + ,env->CallStaticObjectMethod(ljb->callStateClass,ljb->callStateFromIntId,(jint)state), msg); handle_possible_java_exception(env, lcData->listener); if (state==LinphoneCallReleased) { @@ -647,10 +797,12 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); env->CallVoidMethod(lcData->listener - ,lcData->callEncryptionChangedId + ,ljb->callEncryptionChangedId ,lcData->core ,getCall(env,call) ,encrypted @@ -664,10 +816,12 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); env->CallVoidMethod(lcData->listener - ,lcData->notifyPresenceReceivedId + ,ljb->notifyPresenceReceivedId ,lcData->core ,getFriend(env,my_friend)); handle_possible_java_exception(env, lcData->listener); @@ -679,10 +833,12 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); env->CallVoidMethod(lcData->listener - ,lcData->newSubscriptionRequestId + ,ljb->newSubscriptionRequestId ,lcData->core ,getFriend(env,my_friend) ,url ? env->NewStringUTF(url) : NULL); @@ -695,10 +851,12 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); env->CallVoidMethod(lcData->listener - ,lcData->dtmfReceivedId + ,ljb->dtmfReceivedId ,lcData->core ,getCall(env,call) ,dtmf); @@ -712,13 +870,15 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); /*note: we call linphone_chat_message_ref() because the application does not acquire the object when invoked from a callback*/ env->CallVoidMethod(lcData->listener - ,lcData->messageReceivedId + ,ljb->messageReceivedId ,lcData->core - ,env->NewObject(lcData->chatRoomClass,lcData->chatRoomCtrId,(jlong)room) + ,env->NewObject(ljb->chatRoomClass,ljb->chatRoomCtrId,(jlong)room) ,(jmsg = getChatMessage(env, msg))); handle_possible_java_exception(env, lcData->listener); } @@ -729,12 +889,14 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); env->CallVoidMethod(lcData->listener - ,lcData->isComposingReceivedId + ,ljb->isComposingReceivedId ,lcData->core - ,env->NewObject(lcData->chatRoomClass,lcData->chatRoomCtrId,(jlong)room)); + ,env->NewObject(ljb->chatRoomClass,ljb->chatRoomCtrId,(jlong)room)); handle_possible_java_exception(env, lcData->listener); } static void ecCalibrationStatus(LinphoneCore *lc, LinphoneEcCalibratorStatus status, int delay_ms, void *data) { @@ -745,13 +907,14 @@ public: return; } + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = (LinphoneCoreVTable*) data; - if (table) { + if (table && ljb) { LinphoneCoreData* lcData = (LinphoneCoreData*) linphone_core_v_table_get_user_data(table); - if (lcData->ecCalibrationStatusId) { - jobject state = env->CallStaticObjectMethod(lcData->ecCalibratorStatusClass, lcData->ecCalibratorStatusFromIntId, (jint)status); + if (ljb->ecCalibrationStatusId) { + jobject state = env->CallStaticObjectMethod(ljb->ecCalibratorStatusClass, ljb->ecCalibratorStatusFromIntId, (jint)status); env->CallVoidMethod(lcData->listener - ,lcData->ecCalibrationStatusId + ,ljb->ecCalibrationStatusId ,lcData->core ,state ,delay_ms @@ -773,15 +936,17 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); - statsobj = env->NewObject(lcData->callStatsClass, lcData->callStatsId, (jlong)call, (jlong)stats); + statsobj = env->NewObject(ljb->callStatsClass, ljb->callStatsId, (jlong)call, (jlong)stats); callobj = getCall(env, call); if (stats->type == LINPHONE_CALL_STATS_AUDIO) - env->CallVoidMethod(callobj, lcData->callSetAudioStatsId, statsobj); + env->CallVoidMethod(callobj, ljb->callSetAudioStatsId, statsobj); else - env->CallVoidMethod(callobj, lcData->callSetVideoStatsId, statsobj); - env->CallVoidMethod(lcData->listener, lcData->callStatsUpdatedId, lcData->core, callobj, statsobj); + env->CallVoidMethod(callobj, ljb->callSetVideoStatsId, statsobj); + env->CallVoidMethod(lcData->listener, ljb->callStatsUpdatedId, lcData->core, callobj, statsobj); handle_possible_java_exception(env, lcData->listener); if (statsobj) env->DeleteLocalRef(statsobj); } @@ -793,13 +958,15 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); env->CallVoidMethod(lcData->listener - ,lcData->transferStateId + ,ljb->transferStateId ,lcData->core ,(jcall=getCall(env,call)) - ,env->CallStaticObjectMethod(lcData->callStateClass,lcData->callStateFromIntId,(jint)remote_call_state) + ,env->CallStaticObjectMethod(ljb->callStateClass,ljb->callStateFromIntId,(jint)remote_call_state) ); handle_possible_java_exception(env, lcData->listener); } @@ -810,14 +977,16 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneInfoMessage *copy_info=linphone_info_message_copy(info); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); env->CallVoidMethod(lcData->listener - ,lcData->infoReceivedId + ,ljb->infoReceivedId ,lcData->core ,getCall(env,call) - ,env->NewObject(lcData->infoMessageClass,lcData->infoMessageCtor,(jlong)copy_info) + ,env->NewObject(ljb->infoMessageClass,ljb->infoMessageCtor,(jlong)copy_info) ); handle_possible_java_exception(env, lcData->listener); } @@ -830,12 +999,14 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); jevent=getEvent(env,ev); - jstate=env->CallStaticObjectMethod(lcData->subscriptionStateClass,lcData->subscriptionStateFromIntId,(jint)state); + jstate=env->CallStaticObjectMethod(ljb->subscriptionStateClass,ljb->subscriptionStateFromIntId,(jint)state); env->CallVoidMethod(lcData->listener - ,lcData->subscriptionStateId + ,ljb->subscriptionStateId ,lcData->core ,jevent ,jstate @@ -856,12 +1027,14 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); jevent=getEvent(env,ev); - jstate=env->CallStaticObjectMethod(lcData->publishStateClass,lcData->publishStateFromIntId,(jint)state); + jstate=env->CallStaticObjectMethod(ljb->publishStateClass,ljb->publishStateFromIntId,(jint)state); env->CallVoidMethod(lcData->listener - ,lcData->publishStateId + ,ljb->publishStateId ,lcData->core ,jevent ,jstate @@ -876,11 +1049,13 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); jevent=getEvent(env,ev); env->CallVoidMethod(lcData->listener - ,lcData->notifyRecvId + ,ljb->notifyRecvId ,lcData->core ,jevent ,env->NewStringUTF(evname) @@ -896,9 +1071,11 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); - env->CallVoidMethod(lcData->listener, lcData->configuringStateId, lcData->core, env->CallStaticObjectMethod(lcData->configuringStateClass,lcData->configuringStateFromIntId,(jint)status), message ? env->NewStringUTF(message) : NULL); + env->CallVoidMethod(lcData->listener, ljb->configuringStateId, lcData->core, env->CallStaticObjectMethod(ljb->configuringStateClass,ljb->configuringStateFromIntId,(jint)status), message ? env->NewStringUTF(message) : NULL); handle_possible_java_exception(env, lcData->listener); } @@ -911,11 +1088,13 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); jobject jcontent = content ? create_java_linphone_content(env, content) : NULL; env->CallVoidMethod(lcData->listener, - lcData->fileTransferProgressIndicationId, + ljb->fileTransferProgressIndicationId, lcData->core, (jmsg = getChatMessage(env, message)), jcontent, @@ -935,12 +1114,14 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); jobject jcontent = content ? create_java_linphone_content(env, content) : NULL; jobject jbuffer = buff ? env->NewDirectByteBuffer(buff, asking) : NULL; *size = env->CallIntMethod(lcData->listener, - lcData->fileTransferSendId, + ljb->fileTransferSendId, lcData->core, (jmsg = getChatMessage(env, message)), jcontent, @@ -963,6 +1144,8 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); @@ -971,7 +1154,7 @@ public: jobject jcontent = content ? create_java_linphone_content(env, content) : NULL; env->CallVoidMethod(lcData->listener, - lcData->fileTransferRecvId, + ljb->fileTransferRecvId, lcData->core, (jmsg = getChatMessage(env, message)), jcontent, @@ -989,10 +1172,12 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); env->CallVoidMethod(lcData->listener - ,lcData->logCollectionUploadProgressId + ,ljb->logCollectionUploadProgressId ,lcData->core ,(jlong)offset ,(jlong)total); @@ -1005,13 +1190,15 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); jstring msg = info ? env->NewStringUTF(info) : NULL; env->CallVoidMethod(lcData->listener - ,lcData->logCollectionUploadStateId + ,ljb->logCollectionUploadStateId ,lcData->core - ,env->CallStaticObjectMethod(lcData->logCollectionUploadStateClass,lcData->logCollectionUploadStateFromIntId,(jint)state), + ,env->CallStaticObjectMethod(ljb->logCollectionUploadStateClass,ljb->logCollectionUploadStateFromIntId,(jint)state), msg); handle_possible_java_exception(env, lcData->listener); if (msg) { @@ -1030,118 +1217,6 @@ private: } }; -jobject getProxy(JNIEnv *env, LinphoneProxyConfig *proxy, jobject core){ - jobject jobj=0; - - if (proxy!=NULL){ - LinphoneCore *lc = linphone_proxy_config_get_core(proxy); - LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); - LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); - - void *up=linphone_proxy_config_get_user_data(proxy); - - if (up==NULL){ - jobj=env->NewObject(lcData->proxyClass, lcData->proxyCtrId, core, (jlong)proxy); - linphone_proxy_config_set_user_data(proxy,(void*)env->NewWeakGlobalRef(jobj)); - linphone_proxy_config_ref(proxy); - }else{ - //promote the weak ref to local ref - jobj=env->NewLocalRef((jobject)up); - if (jobj == NULL){ - //the weak ref was dead - jobj=env->NewObject(lcData->proxyClass, lcData->proxyCtrId, core, (jlong)proxy); - linphone_proxy_config_set_user_data(proxy,(void*)env->NewWeakGlobalRef(jobj)); - } - } - } - return jobj; -} - -jobject getCall(JNIEnv *env, LinphoneCall *call){ - jobject jobj=0; - - if (call!=NULL){ - LinphoneCore *lc = linphone_call_get_core(call); - LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); - LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); - - void *up=linphone_call_get_user_pointer(call); - - if (up==NULL){ - jobj=env->NewObject(lcData->callClass, lcData->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); - LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); - LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); - - void *up = linphone_chat_message_get_user_data(msg); - - if (up == NULL) { - jobj = env->NewObject(lcData->chatMessageClass, lcData->chatMessageCtrId, (jlong)linphone_chat_message_ref(msg)); - jobj = env->NewGlobalRef(jobj); - linphone_chat_message_set_user_data(msg,(void*)jobj); - } else { - jobj = (jobject)up; - } - } - return jobj; -} - -jobject getFriend(JNIEnv *env, LinphoneFriend *lfriend){ - jobject jobj=0; - - if (lfriend != NULL){ - LinphoneCore *lc = linphone_friend_get_core(lfriend); - LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); - LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); - - void *up=linphone_friend_get_user_data(lfriend); - - if (up == NULL){ - jobj=env->NewObject(lcData->friendClass, lcData->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){ - jobj=env->NewObject(lcData->friendClass, lcData->friendCtrId, (jlong)lfriend); - linphone_friend_set_user_data(lfriend,(void*)env->NewWeakGlobalRef(jobj)); - } - } - } - return jobj; -} - -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); - LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); - LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); - - jev=env->NewObject(lcData->linphoneEventClass, lcData->linphoneEventCtrId, (jlong)linphone_event_ref(lev)); - jev=env->NewGlobalRef(jev); - linphone_event_set_user_data(lev,jev); - } - return jev; -} - extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_newLinphoneCore(JNIEnv* env ,jobject thiz ,jobject jlistener @@ -1152,8 +1227,10 @@ extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_newLinphoneCore(JNIEnv* const char* userConfig = juserConfig?env->GetStringUTFChars(juserConfig, NULL):NULL; const char* factoryConfig = jfactoryConfig?env->GetStringUTFChars(jfactoryConfig, NULL):NULL; + LinphoneJavaBindings *ljb = new LinphoneJavaBindings(env); + LinphoneCoreVTable *vTable = linphone_core_v_table_new(); - LinphoneCoreData* ldata = new LinphoneCoreData(env, thiz, vTable, jlistener); + LinphoneCoreData* ldata = new LinphoneCoreData(env, thiz, vTable, jlistener, ljb); linphone_core_v_table_set_user_data(vTable, ldata); ms_init(); // Initialize mediastreamer2 before loading the plugins @@ -1184,7 +1261,9 @@ extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_newLinphoneCore(JNIEnv* #endif jobject core = env->NewGlobalRef(thiz); - jlong nativePtr = (jlong)linphone_core_new(vTable, userConfig, factoryConfig, core); + ljb->setCore(core); + LinphoneCore *lc = linphone_core_new(vTable, userConfig, factoryConfig, ljb); + jlong nativePtr = (jlong)lc; if (userConfig) env->ReleaseStringUTFChars(juserConfig, userConfig); if (factoryConfig) env->ReleaseStringUTFChars(jfactoryConfig, factoryConfig); @@ -1192,7 +1271,7 @@ extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_newLinphoneCore(JNIEnv* } extern "C" void Java_org_linphone_core_LinphoneCoreImpl_delete(JNIEnv* env, jobject thiz, jlong native_ptr) { LinphoneCore *lc=(LinphoneCore*)native_ptr; - jobject core = (jobject)linphone_core_get_user_data(lc); + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); jobject multicast_lock = lc->multicast_lock; jobject multicast_lock_class = lc->multicast_lock_class; @@ -1207,14 +1286,19 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_delete(JNIEnv* env, jobj if (multicast_lock) env->DeleteGlobalRef(multicast_lock); if (multicast_lock_class) env->DeleteGlobalRef(multicast_lock_class); - if (core) { - env->DeleteGlobalRef(core); + if (ljb) { + jobject core = ljb->getCore(); + if (core) { + env->DeleteGlobalRef(core); + } + delete ljb; } } extern "C" void Java_org_linphone_core_LinphoneCoreImpl_addListener(JNIEnv* env, jobject thiz, jlong lc, jobject jlistener) { + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *) linphone_core_get_user_data((LinphoneCore *)lc); LinphoneCoreVTable *vTable = linphone_core_v_table_new(); - LinphoneCoreData* ldata = new LinphoneCoreData(env, thiz, vTable, jlistener); + LinphoneCoreData* ldata = new LinphoneCoreData(env, thiz, vTable, jlistener, ljb); linphone_core_v_table_set_user_data(vTable, ldata); linphone_core_add_listener((LinphoneCore*)lc, vTable); } @@ -2049,8 +2133,9 @@ extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_startEchoCalibration(JNI ,jobject thiz ,jlong lc ,jobject data) { + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *) linphone_core_get_user_data((LinphoneCore *)lc); LinphoneCoreVTable *vTable = linphone_core_v_table_new(); - LinphoneCoreData* ldata = new LinphoneCoreData(env, thiz, vTable, data); + LinphoneCoreData* ldata = new LinphoneCoreData(env, thiz, vTable, data, ljb); linphone_core_v_table_set_user_data(vTable, ldata); return (jint)linphone_core_start_echo_calibration((LinphoneCore*)lc, ldata->ecCalibrationStatus, NULL, NULL, vTable); @@ -3013,7 +3098,8 @@ extern "C" jobject Java_org_linphone_core_LinphoneFriendImpl_getCore(JNIEnv* en ,jlong ptr) { LinphoneCore *lc=linphone_friend_get_core((LinphoneFriend*)ptr); if (lc!=NULL){ - jobject core = (jobject)linphone_core_get_user_data(lc); + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); + jobject core = ljb->getCore(); return core; } return NULL; @@ -3551,7 +3637,8 @@ extern "C" jobject Java_org_linphone_core_LinphoneChatRoomImpl_getCore(JNIEnv* ,jobject thiz ,jlong chatroom_ptr){ LinphoneCore *lc=linphone_chat_room_get_core((LinphoneChatRoom*)chatroom_ptr); - jobject core = (jobject)linphone_core_get_user_data(lc); + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); + jobject core = ljb->getCore(); return core; } @@ -4944,7 +5031,8 @@ JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneCoreFactoryImpl__1setLogHa JNIEXPORT jobject JNICALL Java_org_linphone_core_LinphoneEventImpl_getCore(JNIEnv *env, jobject jobj, jlong evptr){ LinphoneCore *lc=linphone_event_get_core((LinphoneEvent*)evptr); - jobject core = (jobject)linphone_core_get_user_data(lc); + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); + jobject core = ljb->getCore(); return core; } From 917da92fbf5f1c56cbe3cc13dc7106f3bead2a40 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 7 Dec 2015 10:35:37 +0100 Subject: [PATCH 9/9] More findClass removed in JNI layer --- coreapi/linphonecore_jni.cc | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 57ed5f7b2..92a648b60 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -1434,8 +1434,8 @@ extern "C" jobject Java_org_linphone_core_LinphoneCoreImpl_getDefaultProxyConfig extern "C" jobjectArray Java_org_linphone_core_LinphoneCoreImpl_getProxyConfigList(JNIEnv* env, jobject thiz, jlong lc) { const MSList* proxies = linphone_core_get_proxy_config_list((LinphoneCore*)lc); int proxyCount = ms_list_size(proxies); - jclass cls = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneProxyConfigImpl")); - jobjectArray jProxies = env->NewObjectArray(proxyCount,cls,NULL); + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data((LinphoneCore *)lc); + jobjectArray jProxies = env->NewObjectArray(proxyCount,ljb->proxyClass,NULL); for (int i = 0; i < proxyCount; i++ ) { LinphoneProxyConfig* proxy = (LinphoneProxyConfig*)proxies->data; @@ -1445,7 +1445,7 @@ extern "C" jobjectArray Java_org_linphone_core_LinphoneCoreImpl_getProxyConfigLi } proxies = proxies->next; } - env->DeleteGlobalRef(cls); + return jProxies; } @@ -1944,8 +1944,8 @@ extern "C" jobjectArray Java_org_linphone_core_LinphoneCoreImpl_getFriendList(JN ,jlong lc) { const MSList* friends = linphone_core_get_friend_list((LinphoneCore*)lc); int friendsSize = ms_list_size(friends); - jclass cls = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneFriendImpl")); - jobjectArray jFriends = env->NewObjectArray(friendsSize,cls,NULL); + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data((LinphoneCore *)lc); + jobjectArray jFriends = env->NewObjectArray(friendsSize,ljb->friendClass,NULL); for (int i = 0; i < friendsSize; i++) { LinphoneFriend* lfriend = (LinphoneFriend*)friends->data; @@ -1955,8 +1955,7 @@ extern "C" jobjectArray Java_org_linphone_core_LinphoneCoreImpl_getFriendList(JN } friends = friends->next; } - - env->DeleteGlobalRef(cls); + return jFriends; } extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setPresenceInfo(JNIEnv* env @@ -3475,15 +3474,15 @@ static void message_state_changed(LinphoneChatMessage* msg, LinphoneChatMessageS jobject jmessage = getChatMessage(env, msg); env->DeleteLocalRef(clazz); - jclass chatMessageStateClass = (jclass)env->FindClass("org/linphone/core/LinphoneChatMessage$State"); - jmethodID chatMessageStateFromIntId = env->GetStaticMethodID(chatMessageStateClass, "fromInt","(I)Lorg/linphone/core/LinphoneChatMessage$State;"); - env->CallVoidMethod(listener, method, jmessage, env->CallStaticObjectMethod(chatMessageStateClass, chatMessageStateFromIntId, (jint)state)); + 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); + env->CallVoidMethod(listener, method, jmessage, env->CallStaticObjectMethod(ljb->chatMessageStateClass, ljb->chatMessageStateFromIntId, (jint)state)); if (state == LinphoneChatMessageStateDelivered || state == LinphoneChatMessageStateNotDelivered) { env->DeleteGlobalRef(listener); msg->message_state_changed_user_data = NULL; } - env->DeleteLocalRef(chatMessageStateClass); } static void file_transfer_progress_indication(LinphoneChatMessage *msg, const LinphoneContent* content, size_t offset, size_t total) { @@ -3617,18 +3616,18 @@ static void chat_room_impl_callback(LinphoneChatMessage* msg, LinphoneChatMessag jmethodID method = env->GetMethodID(clazz, "onLinphoneChatMessageStateChanged","(Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneChatMessage$State;)V"); jobject jmessage=(jobject)linphone_chat_message_get_user_data(msg); - jclass chatMessageStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneChatMessage$State")); - jmethodID chatMessageStateFromIntId = env->GetStaticMethodID(chatMessageStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneChatMessage$State;"); + 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); env->CallVoidMethod( listener, method, jmessage, - env->CallStaticObjectMethod(chatMessageStateClass,chatMessageStateFromIntId,(jint)state)); + env->CallStaticObjectMethod(ljb->chatMessageStateClass,ljb->chatMessageStateFromIntId,(jint)state)); if (state == LinphoneChatMessageStateDelivered || state == LinphoneChatMessageStateNotDelivered) { env->DeleteGlobalRef(listener); env->DeleteGlobalRef(jmessage); - env->DeleteGlobalRef(chatMessageStateClass); linphone_chat_message_set_user_data(msg,NULL); } } @@ -4433,6 +4432,7 @@ extern "C" jobjectArray Java_org_linphone_core_LinphoneCoreImpl_tunnelGetServers const MSList *servers = linphone_tunnel_get_servers(tunnel); const MSList *it; int i; + tunnelConfigArray = env->NewObjectArray(ms_list_size(servers), tunnelConfigClass, NULL); for(it = servers, i=0; it != NULL; it = it->next, i++) { LinphoneTunnelConfig *conf = (LinphoneTunnelConfig *)it->data;