From 06cac462a7e414f00334a660cddff2140ec36ccf Mon Sep 17 00:00:00 2001 From: Margaux Clerc Date: Thu, 28 Aug 2014 16:05:56 +0200 Subject: [PATCH] Use ref/unref function in JNI for proxy config --- .../core/tutorials/TutorialBuddyStatus.java | 2 +- .../core/tutorials/TutorialRegistration.java | 2 +- coreapi/linphonecore_jni.cc | 86 ++++++++++++------- .../org/linphone/core/LinphoneCore.java | 1 + .../linphone/core/LinphoneCoreFactory.java | 2 - .../core/LinphoneCoreFactoryImpl.java | 6 -- .../org/linphone/core/LinphoneCoreImpl.java | 29 +++---- .../core/LinphoneProxyConfigImpl.java | 36 ++++---- 8 files changed, 89 insertions(+), 75 deletions(-) diff --git a/coreapi/help/java/org/linphone/core/tutorials/TutorialBuddyStatus.java b/coreapi/help/java/org/linphone/core/tutorials/TutorialBuddyStatus.java index 6424442e7..03942d559 100644 --- a/coreapi/help/java/org/linphone/core/tutorials/TutorialBuddyStatus.java +++ b/coreapi/help/java/org/linphone/core/tutorials/TutorialBuddyStatus.java @@ -165,7 +165,7 @@ public class TutorialBuddyStatus implements LinphoneCoreListener { } // create proxy config - LinphoneProxyConfig proxyCfg = lcFactory.createProxyConfig(mySipAddress, domain, null, true); + LinphoneProxyConfig proxyCfg = lc.createProxyConfig(mySipAddress, domain, null, true); proxyCfg.enablePublish(true); lc.addProxyConfig(proxyCfg); // add it to linphone lc.setDefaultProxyConfig(proxyCfg); diff --git a/coreapi/help/java/org/linphone/core/tutorials/TutorialRegistration.java b/coreapi/help/java/org/linphone/core/tutorials/TutorialRegistration.java index 91a778feb..616914c54 100644 --- a/coreapi/help/java/org/linphone/core/tutorials/TutorialRegistration.java +++ b/coreapi/help/java/org/linphone/core/tutorials/TutorialRegistration.java @@ -136,7 +136,7 @@ public class TutorialRegistration implements LinphoneCoreListener { } // create proxy config - LinphoneProxyConfig proxyCfg = lcFactory.createProxyConfig(sipAddress, domain, null, true); + LinphoneProxyConfig proxyCfg = lc.createProxyConfig(sipAddress, domain, null, true); proxyCfg.setExpires(2000); lc.addProxyConfig(proxyCfg); // add it to linphone lc.setDefaultProxyConfig(proxyCfg); diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 30ab20685..fb244a201 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -77,8 +77,7 @@ extern "C" void libmswebrtc_init(); return jUserDataObj; \ } - -#define RETURN_PROXY_CONFIG_USER_DATA_OBJECT(javaclass, funcprefix, cobj) \ +#define RETURN_PROXY_CONFIG_USER_DATA_OBJECT(javaclass, funcprefix, cobj, lc) \ { \ jclass jUserDataObjectClass; \ jmethodID jUserDataObjectCtor; \ @@ -86,16 +85,16 @@ extern "C" void libmswebrtc_init(); jUserDataObj = (jobject)funcprefix ## _get_user_data(cobj); \ if (jUserDataObj == NULL) { \ jUserDataObjectClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/" javaclass)); \ - jUserDataObjectCtor = env->GetMethodID(jUserDataObjectClass,"", "(J)V"); \ - jUserDataObj = env->NewObject(jUserDataObjectClass, jUserDataObjectCtor,(jlong) cobj); \ - jUserDataObj = env->NewGlobalRef(jUserDataObj); \ + jUserDataObjectCtor = env->GetMethodID(jUserDataObjectClass,"", "(Lorg/linphone/core/LinphoneCoreImpl;J)V"); \ + jUserDataObj = env->NewObject(jUserDataObjectClass, jUserDataObjectCtor,lc, (jlong) cobj); \ + jUserDataObj = env->NewWeakGlobalRef(jUserDataObj); \ funcprefix ## _set_user_data(cobj, jUserDataObj); \ + funcprefix ## _ref(cobj); \ env->DeleteGlobalRef(jUserDataObjectClass); \ } \ return jUserDataObj; \ } - static JavaVM *jvm=0; static const char* LogDomain = "Linphone"; static jclass handler_class; @@ -468,9 +467,30 @@ public: ,env->CallStaticObjectMethod(lcData->globalStateClass,lcData->globalStateFromIntId,(jint)gstate), message ? env->NewStringUTF(message) : NULL); } + jobject getProxy(JNIEnv *env , LinphoneProxyConfig *proxy, jobject core){ + jobject jobj=0; + + if (proxy!=NULL){ + void *up=linphone_proxy_config_get_user_data(proxy); + + 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{ + jobj=env->NewLocalRef((jobject)up); + if (jobj == NULL){ + jobj=env->NewObject(proxyClass,proxyCtrId,core,(jlong)proxy); + linphone_proxy_config_set_user_data(proxy,(void*)env->NewWeakGlobalRef(jobj)); + } + } + } + return jobj; + } static void registrationStateChange(LinphoneCore *lc, LinphoneProxyConfig* proxy,LinphoneRegistrationState state,const char* message) { JNIEnv *env = 0; jint result = jvm->AttachCurrentThread(&env,NULL); + jobject jproxy; if (result != 0) { ms_error("cannot attach VM"); return; @@ -479,7 +499,7 @@ public: env->CallVoidMethod(lcData->listener ,lcData->registrationStateId ,lcData->core - ,env->NewObject(lcData->proxyClass,lcData->proxyCtrId,lcData->core,(jlong)proxy) + ,(jproxy=lcData->getProxy(env,proxy,lcData->core)) ,env->CallStaticObjectMethod(lcData->registrationStateClass,lcData->registrationStateFromIntId,(jint)state), message ? env->NewStringUTF(message) : NULL); } @@ -895,35 +915,42 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setDefaultProxyConfig( J ,jlong pc) { linphone_core_set_default_proxy((LinphoneCore*)lc,(LinphoneProxyConfig*)pc); } -extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_getDefaultProxyConfig( JNIEnv* env + +static jobject getOrCreateProxy(JNIEnv* env,LinphoneProxyConfig* proxy,jobject lc){ + RETURN_PROXY_CONFIG_USER_DATA_OBJECT("LinphoneProxyConfigImpl", linphone_proxy_config, proxy, lc); +} + +extern "C" jobject Java_org_linphone_core_LinphoneCoreImpl_getDefaultProxyConfig( JNIEnv* env ,jobject thiz ,jlong lc) { LinphoneProxyConfig *config=0; + LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_get_user_data((LinphoneCore*)lc); linphone_core_get_default_proxy((LinphoneCore*)lc,&config); - return (jlong)config; -} - -static jobject getOrCreateProxy(JNIEnv* env,LinphoneProxyConfig* proxy){ - RETURN_PROXY_CONFIG_USER_DATA_OBJECT("LinphoneProxyConfigImpl", linphone_proxy_config, proxy); + if(config != 0) { + jobject jproxy = getOrCreateProxy(env,config,lcData->core); + return jproxy; + } else { + return NULL; + } } 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 = env->FindClass("org/linphone/core/LinphoneProxyConfigImpl"); + jclass cls = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneProxyConfigImpl")); jobjectArray jProxies = env->NewObjectArray(proxyCount,cls,NULL); + LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_get_user_data((LinphoneCore*)lc); for (int i = 0; i < proxyCount; i++ ) { LinphoneProxyConfig* proxy = (LinphoneProxyConfig*)proxies->data; - jobject jproxy = getOrCreateProxy(env,proxy); + jobject jproxy = getOrCreateProxy(env,proxy,lcData->core); if(jproxy != NULL){ env->SetObjectArrayElement(jProxies, i, jproxy); - } else { - return NULL; } proxies = proxies->next; } + env->DeleteGlobalRef(cls); return jProxies; } @@ -933,9 +960,7 @@ extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_addProxyConfig( JNIEnv* ,jlong lc ,jlong pc) { LinphoneProxyConfig* proxy = (LinphoneProxyConfig*)pc; - linphone_proxy_config_set_user_data(proxy, env->NewGlobalRef(jproxyCfg)); - - return (jint)linphone_core_add_proxy_config((LinphoneCore*)lc,(LinphoneProxyConfig*)pc); + return (jint)linphone_core_add_proxy_config((LinphoneCore*)lc,proxy); } extern "C" void Java_org_linphone_core_LinphoneCoreImpl_removeProxyConfig(JNIEnv* env, jobject thiz, jlong lc, jlong proxy) { @@ -1547,11 +1572,6 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setMediaEncryptionMandat linphone_core_set_media_encryption_mandatory((LinphoneCore*)lc, yesno); } -extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_createProxyConfig(JNIEnv* env, jobject thiz, jlong lc) { - LinphoneProxyConfig* proxy = linphone_core_create_proxy_config((LinphoneCore *)lc); - return (jlong) proxy; -} - /* * Class: org_linphone_core_LinphoneCoreImpl * Method: disableChat @@ -1582,14 +1602,20 @@ extern "C" JNIEXPORT jboolean JNICALL Java_org_linphone_core_LinphoneCoreImpl_ch //ProxyConfig -extern "C" jlong Java_org_linphone_core_LinphoneProxyConfigImpl_newLinphoneProxyConfig(JNIEnv* env,jobject thiz) { - LinphoneProxyConfig* proxy = linphone_proxy_config_new(); - return (jlong) proxy; +extern "C" jlong Java_org_linphone_core_LinphoneProxyConfigImpl_createProxyConfig(JNIEnv* env, jobject thiz, jlong lc) { + LinphoneProxyConfig* proxy = linphone_core_create_proxy_config((LinphoneCore *)lc); + linphone_proxy_config_set_user_data(proxy,env->NewWeakGlobalRef(thiz)); + return (jlong) proxy; } -extern "C" void Java_org_linphone_core_LinphoneProxyConfigImpl_delete(JNIEnv* env,jobject thiz,jlong ptr) { - linphone_proxy_config_destroy((LinphoneProxyConfig*)ptr); +extern "C" void Java_org_linphone_core_LinphoneProxyConfigImpl_finalize(JNIEnv* env + ,jobject thiz + ,jlong ptr) { + LinphoneProxyConfig *proxy=(LinphoneProxyConfig*)ptr; + linphone_proxy_config_set_user_data(proxy,NULL); + linphone_proxy_config_unref(proxy); } + extern "C" void Java_org_linphone_core_LinphoneProxyConfigImpl_setIdentity(JNIEnv* env,jobject thiz,jlong proxyCfg,jstring jidentity) { const char* identity = env->GetStringUTFChars(jidentity, NULL); linphone_proxy_config_set_identity((LinphoneProxyConfig*)proxyCfg,identity); diff --git a/java/common/org/linphone/core/LinphoneCore.java b/java/common/org/linphone/core/LinphoneCore.java index 54f923dd6..4a903e187 100644 --- a/java/common/org/linphone/core/LinphoneCore.java +++ b/java/common/org/linphone/core/LinphoneCore.java @@ -1558,6 +1558,7 @@ public interface LinphoneCore { * @return a default proxy config */ public LinphoneProxyConfig createProxyConfig(); + public LinphoneProxyConfig createProxyConfig(String identity,String proxy,String route, boolean enableRegister) throws LinphoneCoreException; /** * Assign an audio file to played locally upon call failure, for a given reason. diff --git a/java/common/org/linphone/core/LinphoneCoreFactory.java b/java/common/org/linphone/core/LinphoneCoreFactory.java index 5838594dc..a21b52539 100644 --- a/java/common/org/linphone/core/LinphoneCoreFactory.java +++ b/java/common/org/linphone/core/LinphoneCoreFactory.java @@ -104,8 +104,6 @@ abstract public class LinphoneCoreFactory { abstract public LinphoneAddress createLinphoneAddress(String address) throws LinphoneCoreException; abstract public LpConfig createLpConfig(String file); - abstract public LinphoneProxyConfig createProxyConfig(String identity, String proxy,String route,boolean enableRegister) throws LinphoneCoreException; - /** * Enable verbose traces * @param enable diff --git a/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java b/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java index 85bff8ffa..f0d3ae064 100644 --- a/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java +++ b/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java @@ -108,12 +108,6 @@ public class LinphoneCoreFactoryImpl extends LinphoneCoreFactory { } } - @Override - public LinphoneProxyConfig createProxyConfig(String identity, String proxy, - String route, boolean enableRegister) throws LinphoneCoreException { - return new LinphoneProxyConfigImpl(identity,proxy,route,enableRegister); - } - @Override public native void setDebugMode(boolean enable, String tag); diff --git a/java/impl/org/linphone/core/LinphoneCoreImpl.java b/java/impl/org/linphone/core/LinphoneCoreImpl.java index 2e3d64efa..b1a7c7bd9 100644 --- a/java/impl/org/linphone/core/LinphoneCoreImpl.java +++ b/java/impl/org/linphone/core/LinphoneCoreImpl.java @@ -34,13 +34,13 @@ import android.media.AudioManager; class LinphoneCoreImpl implements LinphoneCore { private final LinphoneCoreListener mListener; //to make sure to keep a reference on this object - private long nativePtr = 0; + protected long nativePtr = 0; private Context mContext = null; private AudioManager mAudioManager = null; private boolean mSpeakerEnabled = false; private native long newLinphoneCore(LinphoneCoreListener listener,String userConfig,String factoryConfig,Object userdata); private native void iterate(long nativePtr); - private native long getDefaultProxyConfig(long nativePtr); + private native LinphoneProxyConfig getDefaultProxyConfig(long nativePtr); private native void setDefaultProxyConfig(long nativePtr,long proxyCfgNativePtr); private native int addProxyConfig(LinphoneProxyConfig jprtoxyCfg,long nativePtr,long proxyCfgNativePtr); @@ -148,7 +148,6 @@ class LinphoneCoreImpl implements LinphoneCore { private native void setChatDatabasePath(long nativePtr, String path); private native long[] getChatRooms(long nativePtr); private native int migrateToMultiTransport(long nativePtr); - private native long createProxyConfig(long nativePtr); private native void setCallErrorTone(long nativePtr, int reason, String path); private native void enableSdp200Ack(long nativePtr,boolean enable); private native boolean isSdp200AckEnabled(long nativePtr); @@ -195,12 +194,7 @@ class LinphoneCoreImpl implements LinphoneCore { public synchronized LinphoneProxyConfig getDefaultProxyConfig() { isValid(); - long lNativePtr = getDefaultProxyConfig(nativePtr); - if (lNativePtr!=0) { - return new LinphoneProxyConfigImpl(this,lNativePtr); - } else { - return null; - } + return getDefaultProxyConfig(nativePtr); } public synchronized LinphoneCall invite(String uri) { @@ -228,8 +222,6 @@ class LinphoneCoreImpl implements LinphoneCore { public synchronized void removeProxyConfig(LinphoneProxyConfig proxyCfg) { isValid(); removeProxyConfig(nativePtr, ((LinphoneProxyConfigImpl)proxyCfg).nativePtr); - ((LinphoneProxyConfigImpl)proxyCfg).mCore=null; - ((LinphoneProxyConfigImpl)proxyCfg).deleteNativePtr(); } public synchronized void clearAuthInfos() { isValid(); @@ -273,10 +265,6 @@ class LinphoneCoreImpl implements LinphoneCore { return logs; } public synchronized void destroy() { - isValid(); - setAndroidPowerManager(null); - delete(nativePtr); - nativePtr = 0; } private void isValid() { @@ -1143,7 +1131,16 @@ class LinphoneCoreImpl implements LinphoneCore { } @Override public synchronized LinphoneProxyConfig createProxyConfig() { - return new LinphoneProxyConfigImpl(this,createProxyConfig(nativePtr)); + return new LinphoneProxyConfigImpl(this); + } + @Override + public synchronized LinphoneProxyConfig createProxyConfig(String identity,String proxy,String route, boolean enableRegister) throws LinphoneCoreException { + isValid(); + try { + return new LinphoneProxyConfigImpl(this,identity,proxy,route,enableRegister); + } catch(LinphoneCoreException e){ + return null; + } } @Override public synchronized void setCallErrorTone(Reason reason, String path) { diff --git a/java/impl/org/linphone/core/LinphoneProxyConfigImpl.java b/java/impl/org/linphone/core/LinphoneProxyConfigImpl.java index 5113f958c..f08980190 100644 --- a/java/impl/org/linphone/core/LinphoneProxyConfigImpl.java +++ b/java/impl/org/linphone/core/LinphoneProxyConfigImpl.java @@ -22,32 +22,33 @@ import org.linphone.core.LinphoneCore.RegistrationState; class LinphoneProxyConfigImpl implements LinphoneProxyConfig { - protected long nativePtr; + protected final long nativePtr; protected LinphoneCoreImpl mCore; Object userData; + + private native void finalize(long ptr); private native int getState(long nativePtr); private native void setExpires(long nativePtr, int delay); private native int getExpires(long nativePtr); + private native long createProxyConfig( long nativePtr); - boolean ownPtr = false; - protected LinphoneProxyConfigImpl(String identity,String proxy,String route, boolean enableRegister) throws LinphoneCoreException { - nativePtr = newLinphoneProxyConfig(); + protected LinphoneProxyConfigImpl(LinphoneCoreImpl core,String identity,String proxy,String route, boolean enableRegister) throws LinphoneCoreException { + mCore=core; + nativePtr = createProxyConfig(core.nativePtr); setIdentity(identity); setProxy(proxy); setRoute(route); enableRegister(enableRegister); - ownPtr=true; } - protected LinphoneProxyConfigImpl(LinphoneCoreImpl core,long aNativePtr) { + protected LinphoneProxyConfigImpl(LinphoneCoreImpl core) { + mCore=core; + nativePtr = createProxyConfig(core.nativePtr); + } + /*reserved for JNI */ + protected LinphoneProxyConfigImpl(LinphoneCoreImpl core, long aNativePtr) { mCore=core; nativePtr = aNativePtr; - ownPtr=false; - } - - protected LinphoneProxyConfigImpl(long aNativePtr) { - nativePtr = aNativePtr; - ownPtr=false; } private void isValid() { @@ -56,16 +57,13 @@ class LinphoneProxyConfigImpl implements LinphoneProxyConfig { } } - public void deleteNativePtr() { - nativePtr=0; - } - protected void finalize() throws Throwable { - //Log.e(LinphoneService.TAG,"fixme, should release underlying proxy config"); - if (ownPtr) delete(nativePtr); + if (nativePtr != 0) { + finalize(nativePtr); + } + super.finalize(); } private native long newLinphoneProxyConfig(); - private native void delete(long ptr); private native void edit(long ptr); private native void done(long ptr);