From a08aacea3f1dd21dc9fe00d8af995386fec33f26 Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Wed, 4 Feb 2015 12:12:46 +0100 Subject: [PATCH] add android support for multicast rtp --- coreapi/linphonecall.c | 10 +++--- coreapi/linphonecore.c | 34 ++++++++++++++----- coreapi/linphonecore_jni.cc | 27 +++++++++++---- coreapi/private.h | 5 +++ .../core/LinphoneCoreFactoryImpl.java | 4 ++- .../org/linphone/core/LinphoneCoreImpl.java | 19 +++++++++-- 6 files changed, 77 insertions(+), 22 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index eb6f3ed76..a7382b51b 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -785,8 +785,9 @@ static void linphone_call_init_common(LinphoneCall *call, LinphoneAddress *from, strncpy(call->local_audio_ip,call->localip,sizeof(call->local_audio_ip)); strncpy(call->local_video_ip,call->localip,sizeof(call->local_video_ip)); #ifdef ANDROID - ms_message("Call [%p] aquires wifi lock"); - linphone_core_wifi_lock_aquire(call->lc); + ms_message("Call [%p] acquires both wifi and multicast lock",call); + linphone_core_wifi_lock_acquire(call->core); + linphone_core_multicast_lock_acquire(call->core); /*does no affect battery more than regular rtp traffic*/ #endif } @@ -1333,8 +1334,9 @@ static void linphone_call_destroy(LinphoneCall *obj){ sal_error_info_reset(&obj->non_op_error); #ifdef ANDROID - ms_message("Call [%p] releases wifi lock"); - linphone_core_wifi_lock_release(obj->lc); + ms_message("Call [%p] releases wifi/multicast lock",obj); + linphone_core_wifi_lock_release(obj->core); + linphone_core_multicast_lock_release(obj->core); #endif } diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 59209d868..5d567fdee 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -7321,17 +7321,35 @@ void linphone_core_enable_video_multicast(LinphoneCore *lc, bool_t yesno) { bool_t linphone_core_video_multicast_enabled(const LinphoneCore *lc) { return lc->rtp_conf.video_multicast_enabled; } + #ifdef ANDROID -void linphone_core_wifi_lock_acquire(LinphoneCore *lc) { +static int linphone_core_call_void_method(jobject obj, jmethodID id) { JNIEnv *env=ms_get_jni_env(); - if (env && lc->wifi_lock) - env->CallVoidMethod(lc->wifi_lock,lc->wifi_lock_aquire_id); + if (env && obj) { + (*env)->CallVoidMethod(env,obj,id); + if ((*env)->ExceptionCheck(env)) { + (*env)->ExceptionClear(env); + return -1; + } else + return 0; + } else + return -1; +} + +void linphone_core_wifi_lock_acquire(LinphoneCore *lc) { + if (linphone_core_call_void_method(lc->wifi_lock,lc->wifi_lock_acquire_id)) + ms_warning("No wifi lock configured or not usable for core [%p]",lc); } void linphone_core_wifi_lock_release(LinphoneCore *lc) { - JNIEnv *env=ms_get_jni_env(); - if (env && lc->wifi_lock) - env->CallVoidMethod(lc->wifi_lock,lc->wifi_lock_release_id); - + if (linphone_core_call_void_method(lc->wifi_lock,lc->wifi_lock_release_id)) + ms_warning("No wifi lock configured or not usable for core [%p]",lc); +} +void linphone_core_multicast_lock_acquire(LinphoneCore *lc) { + if (linphone_core_call_void_method(lc->multicast_lock,lc->multicast_lock_acquire_id)) + ms_warning("No multicast lock configured or not usable for core [%p]",lc); +} +void linphone_core_multicast_lock_release(LinphoneCore *lc) { + if (linphone_core_call_void_method(lc->multicast_lock,lc->multicast_lock_release_id)) + ms_warning("No wifi lock configured or not usable for core [%p]",lc); } #endif - diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 80c105b37..6bcc51ccc 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -3979,19 +3979,34 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setAndroidPowerManager(J #endif } -extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setAndroidWifiLock(JNIEnv *env, jobject thiz, jlong lc, jobject wifi_lock) { +extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setAndroidWifiLock(JNIEnv *env, jobject thiz, jlong ptr, jobject wifi_lock) { #ifdef ANDROID + LinphoneCore *lc=(LinphoneCore*)ptr; if (lc->wifi_lock) env->DeleteGlobalRef(lc->wifi_lock); - if(wm != NULL) { + if (wifi_lock != NULL) { lc->wifi_lock=env->NewGlobalRef(wifi_lock); - jclass wifiLockClass = env->FindClass(env, "android/net/wifi/WifiManager/WifiLock"); - lc->wifi_lock_aquire_id = env->GetMethodID(wifiLockClass, "acquire", "()V"); + jclass wifiLockClass = env->FindClass("android/net/wifi/WifiManager$WifiLock"); + lc->wifi_lock_acquire_id = env->GetMethodID(wifiLockClass, "acquire", "()V"); lc->wifi_lock_release_id = env->GetMethodID(wifiLockClass, "release", "()V"); } else { - lc->wifi_manager=NULL; + lc->wifi_lock=NULL; + } +#endif +} +extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setAndroidMulticastLock(JNIEnv *env, jobject thiz, jlong ptr, jobject multicast_lock) { +#ifdef ANDROID + LinphoneCore *lc=(LinphoneCore*)ptr; + if (lc->multicast_lock) + env->DeleteGlobalRef(lc->multicast_lock); + if (multicast_lock != NULL) { + lc->multicast_lock=env->NewGlobalRef(multicast_lock); + jclass multicastLockClass = env->FindClass("android/net/wifi/WifiManager$MulticastLock"); + lc->multicast_lock_acquire_id = env->GetMethodID(multicastLockClass, "acquire", "()V"); + lc->multicast_lock_release_id = env->GetMethodID(multicastLockClass, "release", "()V"); + } else { + lc->multicast_lock=NULL; } - #endif } diff --git a/coreapi/private.h b/coreapi/private.h index 83d41ae7f..f5b378008 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -802,6 +802,9 @@ struct _LinphoneCore jobject wifi_lock; jmethodID wifi_lock_acquire_id; jmethodID wifi_lock_release_id; + jobject multicast_lock; + jmethodID multicast_lock_acquire_id; + jmethodID multicast_lock_release_id; #endif }; @@ -1102,6 +1105,8 @@ void set_playback_gain_db(AudioStream *st, float gain); #ifdef ANDROID void linphone_core_wifi_lock_acquire(LinphoneCore *lc); void linphone_core_wifi_lock_release(LinphoneCore *lc); +void linphone_core_multicast_lock_acquire(LinphoneCore *lc); +void linphone_core_multicast_lock_release(LinphoneCore *lc); #endif #ifdef __cplusplus diff --git a/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java b/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java index fb019db3d..03e8f7ef3 100644 --- a/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java +++ b/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java @@ -88,7 +88,9 @@ public class LinphoneCoreFactoryImpl extends LinphoneCoreFactory { MediastreamerAndroidContext.setContext(context); File user = userConfig == null ? null : new File(userConfig); File factory = factoryConfig == null ? null : new File(factoryConfig); - return new LinphoneCoreImpl(listener, user, factory, userdata); + LinphoneCore lc = new LinphoneCoreImpl(listener, user, factory, userdata); + if(context!=null) lc.setContext(context); + return lc; } catch (IOException e) { throw new LinphoneCoreException("Cannot create LinphoneCore",e); } diff --git a/java/impl/org/linphone/core/LinphoneCoreImpl.java b/java/impl/org/linphone/core/LinphoneCoreImpl.java index d210be6fa..4b35f4780 100644 --- a/java/impl/org/linphone/core/LinphoneCoreImpl.java +++ b/java/impl/org/linphone/core/LinphoneCoreImpl.java @@ -26,11 +26,15 @@ import java.io.IOException; import org.linphone.core.LinphoneCall.State; import org.linphone.core.LinphoneCoreListener; import org.linphone.mediastream.Log; +import org.linphone.mediastream.Version; import org.linphone.mediastream.video.AndroidVideoWindowImpl; import org.linphone.mediastream.video.capture.hwconf.Hacks; import android.content.Context; import android.media.AudioManager; +import android.net.wifi.WifiManager; +import android.net.wifi.WifiManager.MulticastLock; +import android.net.wifi.WifiManager.WifiLock; public class LinphoneCoreImpl implements LinphoneCore { @@ -157,7 +161,8 @@ public class LinphoneCoreImpl implements LinphoneCore { private native boolean isSdp200AckEnabled(long nativePtr); private native void stopRinging(long nativePtr); private native static void setAndroidPowerManager(Object pm); - private native void setAndroidWifiLock(long nativePtr,Object pm); + private native void setAndroidWifiLock(long nativePtr,Object wifi_lock); + private native void setAndroidMulticastLock(long nativePtr,Object multicast_lock); LinphoneCoreImpl(LinphoneCoreListener listener, File userConfig, File factoryConfig, Object userdata) throws IOException { mListener = listener; @@ -186,8 +191,16 @@ public class LinphoneCoreImpl implements LinphoneCore { mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); setAndroidPowerManager(mContext.getSystemService(Context.POWER_SERVICE)); if (Version.sdkAboveOrEqual(Version.API12_HONEYCOMB_MR1_31X)) { - WifiManager wifiManager=(WifiManager) getSystemService(Context.WIFI_SERVICE); - setAndroidWifiLock(nativePtr,wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, this.getPackageName()+"-"+nativePtr+"-wifi-call-lock")); + WifiManager wifiManager=(WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); + WifiLock lock = wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "linphonecore ["+ nativePtr+"] wifi-lock"); + lock.setReferenceCounted(true); + setAndroidWifiLock(nativePtr,lock); + } + if (Version.sdkAboveOrEqual(Version.API14_ICE_CREAM_SANDWICH_40)) { + WifiManager wifiManager=(WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); + MulticastLock lock = wifiManager.createMulticastLock("linphonecore ["+ nativePtr+"] multicast-lock"); + lock.setReferenceCounted(true); + setAndroidMulticastLock(nativePtr,lock); } }