diff --git a/coreapi/CMakeLists.txt b/coreapi/CMakeLists.txt index f0a3bfdd6..11a8604fc 100644 --- a/coreapi/CMakeLists.txt +++ b/coreapi/CMakeLists.txt @@ -47,6 +47,7 @@ list(APPEND LINPHONE_PRIVATE_HEADER_FILES sqlite3_bctbx_vfs.h vcard_private.h xml2lpc.h + platform-helpers.h ) set(LINPHONE_SOURCE_FILES_C @@ -110,6 +111,8 @@ set(LINPHONE_SOURCE_FILES_C set(LINPHONE_SOURCE_FILES_CXX conference.cc tester_utils.cpp + platform-helpers.cpp + android-helpers.cpp ) set(LINPHONE_INCLUDE_DIRS ${LINPHONE_INCLUDE_DIRS}) if(ENABLE_JAVA_WRAPPER) diff --git a/coreapi/android-helpers.cpp b/coreapi/android-helpers.cpp new file mode 100644 index 000000000..bc1970a68 --- /dev/null +++ b/coreapi/android-helpers.cpp @@ -0,0 +1,182 @@ +/* +linphone +Copyright (C) 2017 Belledonne Communications SARL + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + + + +#include "private.h" +#include "platform-helpers.h" +#include + + + +#ifdef __ANDROID__ + +namespace LinphonePrivate{ + +class AndroidPlatformHelpers : public PlatformHelpers{ +public: + AndroidPlatformHelpers(LinphoneCore *lc, void *system_context); + virtual void setDnsServers(); + virtual void acquireWifiLock(); + virtual void releaseWifiLock(); + virtual void acquireMcastLock(); + virtual void releaseMcastLock(); + virtual void acquireCpuLock(); + virtual void releaseCpuLock(); + ~AndroidPlatformHelpers(); +private: + int callVoidMethod(jmethodID id); + static jmethodID getMethodId(JNIEnv *env, jclass klass, const char *method, const char *signature); + jobject mJavaHelper; + jmethodID mWifiLockAcquireId; + jmethodID mWifiLockReleaseId; + jmethodID mMcastLockAcquireId; + jmethodID mMcastLockReleaseId; + jmethodID mCpuLockAcquireId; + jmethodID mCpuLockReleaseId; + jmethodID mGetDnsServersId; + jmethodID mGetPowerManagerId; + +}; + +jmethodID AndroidPlatformHelpers::getMethodId(JNIEnv *env, jclass klass, const char *method, const char *signature){ + jmethodID id = env->GetMethodID(klass, method, signature); + if (id == 0){ + ms_fatal("Could not find java method '%s %s'", method, signature); + } + return id; +} + +AndroidPlatformHelpers::AndroidPlatformHelpers(LinphoneCore *lc, void *system_context) : PlatformHelpers(lc) { + JNIEnv *env=ms_get_jni_env(); + jclass klass = env->FindClass("org/linphone/core/util/AndroidPlatformHelper"); + if (!klass){ + ms_fatal("Could not find java AndroidPlatformHelper class"); + return; + } + jmethodID ctor = env->GetMethodID(klass,"", "(Ljava/lang/Object;)V"); + mJavaHelper = env->NewObject(klass, ctor, (jobject)system_context); + if (!mJavaHelper){ + ms_error("Could not instanciate AndroidPlatformHelper object."); + return; + } + mJavaHelper = (jobject) env->NewGlobalRef(mJavaHelper); + + mWifiLockAcquireId = getMethodId(env, klass, "acquireWifiLock", "()V"); + mWifiLockReleaseId = getMethodId(env, klass, "releaseWifiLock", "()V"); + mMcastLockAcquireId = getMethodId(env, klass, "acquireMcastLock", "()V"); + mMcastLockReleaseId = getMethodId(env, klass, "releaseMcastLock", "()V"); + mCpuLockAcquireId = getMethodId(env, klass, "acquireCpuLock", "()V"); + mCpuLockReleaseId = getMethodId(env, klass, "releaseCpuLock", "()V"); + mGetDnsServersId = getMethodId(env, klass, "getDnsServers", "()[Ljava/lang/String;"); + mGetPowerManagerId = getMethodId(env, klass, "getPowerManager", "()Ljava/lang/Object;"); + + jobject pm = env->CallObjectMethod(mJavaHelper,mGetPowerManagerId); + belle_sip_wake_lock_init(env, pm); + + ms_message("AndroidPlatformHelpers is fully initialised"); +} + +AndroidPlatformHelpers::~AndroidPlatformHelpers(){ + if (mJavaHelper){ + JNIEnv *env = ms_get_jni_env(); + belle_sip_wake_lock_uninit(env); + env->DeleteGlobalRef(mJavaHelper); + mJavaHelper = NULL; + } +} + + +void AndroidPlatformHelpers::setDnsServers(){ + if (!mJavaHelper) return; + JNIEnv *env=ms_get_jni_env(); + if (env && mJavaHelper) { + jobjectArray jservers = (jobjectArray)env->CallObjectMethod(mJavaHelper,mGetDnsServersId); + bctbx_list_t *l = NULL; + if (env->ExceptionCheck()) { + env->ExceptionClear(); + ms_error("AndroidPlatformHelpers::setDnsServers() exception"); + return; + } + if (jservers != NULL){ + int count = env->GetArrayLength(jservers); + + for (int i=0; i < count; i++) { + jstring jserver = (jstring) env->GetObjectArrayElement(jservers, i); + const char *str = env->GetStringUTFChars(jserver, NULL); + if (str){ + l = bctbx_list_append(l, ms_strdup(str)); + env->ReleaseStringUTFChars(jserver, str); + } + } + } + linphone_core_set_dns_servers(mCore, l); + bctbx_list_free_with_data(l, ms_free); + } +} + +void AndroidPlatformHelpers::acquireWifiLock(){ + callVoidMethod(mWifiLockAcquireId); +} + +void AndroidPlatformHelpers::releaseWifiLock(){ + callVoidMethod(mWifiLockReleaseId); +} + +void AndroidPlatformHelpers::acquireMcastLock(){ + callVoidMethod(mMcastLockAcquireId); +} + +void AndroidPlatformHelpers::releaseMcastLock(){ + callVoidMethod(mMcastLockReleaseId); +} + +void AndroidPlatformHelpers::acquireCpuLock(){ + callVoidMethod(mCpuLockAcquireId); +} + +void AndroidPlatformHelpers::releaseCpuLock(){ + callVoidMethod(mCpuLockReleaseId); +} + + +int AndroidPlatformHelpers::callVoidMethod(jmethodID id) { + JNIEnv *env=ms_get_jni_env(); + if (env && mJavaHelper) { + env->CallVoidMethod(mJavaHelper,id); + if (env->ExceptionCheck()) { + env->ExceptionClear(); + return -1; + } else + return 0; + } else + return -1; +} + +PlatformHelpers *createAndroidPlatformHelpers(LinphoneCore *lc, void *system_context){ + return new AndroidPlatformHelpers(lc, system_context); +} + +}//end of namespace + + + + +#endif + diff --git a/coreapi/factory.c b/coreapi/factory.c index c85976ff5..80a0a42e7 100644 --- a/coreapi/factory.c +++ b/coreapi/factory.c @@ -32,7 +32,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #define PACKAGE_DATA_DIR "." #endif -extern LinphoneCore *_linphone_core_new_with_config(LinphoneCoreCbs *cbs, struct _LpConfig *config, void *userdata); extern LinphoneAddress *_linphone_address_new(const char *addr); typedef belle_sip_object_t_vptr_t LinphoneFactory_vptr_t; @@ -149,16 +148,26 @@ void linphone_factory_clean(void){ } } -LinphoneCore *linphone_factory_create_core(const LinphoneFactory *factory, LinphoneCoreCbs *cbs, - const char *config_path, const char *factory_config_path) { +LinphoneCore *linphone_factory_create_core_2(const LinphoneFactory *factory, LinphoneCoreCbs *cbs, + const char *config_path, const char *factory_config_path, void *user_data, void *system_context) { + bctbx_init_logger(FALSE); LpConfig *config = lp_config_new_with_factory(config_path, factory_config_path); - LinphoneCore *lc = _linphone_core_new_with_config(cbs, config, NULL); + LinphoneCore *lc = _linphone_core_new_with_config(cbs, config, user_data, system_context); lp_config_unref(config); return lc; } +LinphoneCore *linphone_factory_create_core(const LinphoneFactory *factory, LinphoneCoreCbs *cbs, + const char *config_path, const char *factory_config_path){ + return linphone_factory_create_core_2(factory, cbs, config_path, factory_config_path, NULL, NULL); +} + LinphoneCore *linphone_factory_create_core_with_config(const LinphoneFactory *factory, LinphoneCoreCbs *cbs, LinphoneConfig *config) { - return _linphone_core_new_with_config(cbs, config, NULL); + return _linphone_core_new_with_config(cbs, config, NULL, NULL); +} + +LinphoneCore *linphone_factory_create_core_with_config_2(const LinphoneFactory *factory, LinphoneCoreCbs *cbs, LinphoneConfig *config, void *user_data, void *system_context) { + return _linphone_core_new_with_config(cbs, config, user_data, system_context); } LinphoneCoreCbs *linphone_factory_create_core_cbs(const LinphoneFactory *factory) { @@ -369,4 +378,4 @@ void linphone_factory_set_log_collection_path(LinphoneFactory *factory, const ch void linphone_factory_enable_log_collection(LinphoneFactory *factory, LinphoneLogCollectionState state) { linphone_core_enable_log_collection(state); -} \ No newline at end of file +} diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 9962d373a..a290202a0 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -120,9 +120,3 @@ const char* linphone_privacy_to_string(LinphonePrivacy privacy) { default: return "Unknown privacy mode"; } } - -void set_playback_gain_db(AudioStream *st, float gain){ - if (st->volrecv){ - ms_filter_call_method(st->volrecv,MS_VOLUME_SET_DB_GAIN,&gain); - }else ms_warning("Could not apply playback gain: gain control wasn't activated."); -} diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 2fb96205c..555d70537 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -2191,6 +2191,7 @@ static void linphone_core_init(LinphoneCore * lc, LinphoneCoreCbs *cbs, LpConfig lc->config=lp_config_ref(config); lc->data=userdata; lc->ringstream_autorelease=TRUE; + lc->platform_helper = new LinphonePrivate::StubbedPlatformHelpers(lc); linphone_task_list_init(&lc->hooks); @@ -2268,9 +2269,21 @@ static void linphone_core_init(LinphoneCore * lc, LinphoneCoreCbs *cbs, LpConfig lc->group_chat_rooms = bctbx_mmap_cchar_new(); } -LinphoneCore *_linphone_core_new_with_config(LinphoneCoreCbs *cbs, struct _LpConfig *config, void *userdata) { +static void _linphone_core_set_platform_helpers(LinphoneCore *lc, LinphonePrivate::PlatformHelpers *ph){ + if (lc->platform_helper) delete getPlatformHelpers(lc); + lc->platform_helper = ph; +} + +static void _linphone_core_set_system_context(LinphoneCore *lc, void *system_context){ +#ifdef __ANDROID__ + _linphone_core_set_platform_helpers(lc, LinphonePrivate::createAndroidPlatformHelpers(lc, system_context)); +#endif +} + +LinphoneCore *_linphone_core_new_with_config(LinphoneCoreCbs *cbs, struct _LpConfig *config, void *userdata, void *system_context) { LinphoneCore *core = belle_sip_object_new(LinphoneCore); linphone_core_init(core, cbs, config, userdata); + _linphone_core_set_system_context(core, system_context); return core; } @@ -2280,7 +2293,7 @@ LinphoneCore *linphone_core_new_with_config(const LinphoneCoreVTable *vtable, st LinphoneCore *core = NULL; if (vtable != NULL) *local_vtable = *vtable; _linphone_core_cbs_set_v_table(cbs, local_vtable, TRUE); - core = _linphone_core_new_with_config(cbs, config, userdata); + core = _linphone_core_new_with_config(cbs, config, userdata, NULL); linphone_core_cbs_unref(cbs); return core; } @@ -6074,6 +6087,7 @@ static void linphone_core_uninit(LinphoneCore *lc) bctbx_list_free_with_data(lc->vtable_refs,(void (*)(void *))v_table_reference_destroy); ms_bandwidth_controller_destroy(lc->bw_controller); ms_factory_destroy(lc->factory); + if (lc->platform_helper) delete getPlatformHelpers(lc); bctbx_uninit_logger(); } @@ -6096,6 +6110,11 @@ static void set_sip_network_reachable(LinphoneCore* lc,bool_t is_sip_reachable, if (lc->sip_network_reachable==is_sip_reachable) return; // no change, ignore. lc->network_reachable_to_be_notified=TRUE; + + if (is_sip_reachable){ + getPlatformHelpers(lc)->setDnsServers(); + } + ms_message("SIP network reachability state is now [%s]",is_sip_reachable?"UP":"DOWN"); for(elem=linphone_core_get_proxy_config_list(lc);elem!=NULL;elem=elem->next){ LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)elem->data; @@ -6896,40 +6915,6 @@ const char * linphone_core_get_video_preset(const LinphoneCore *lc) { return lp_config_get_string(lc->config, "video", "preset", NULL); } -#ifdef __ANDROID__ -static int linphone_core_call_void_method(jobject obj, jmethodID id) { - JNIEnv *env=ms_get_jni_env(); - if (env && obj) { - env->CallVoidMethod(obj,id); - if (env->ExceptionCheck()) { - env->ExceptionClear(); - 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) { - 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 LINPHONE_PUBLIC const char *linphone_core_log_collection_upload_state_to_string(const LinphoneCoreLogCollectionUploadState lcus) { diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 27002061b..8a3687f07 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -1635,7 +1635,7 @@ extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_newLinphoneCore(JNIEnv* ,jobject jlistener ,jstring juserConfig ,jstring jfactoryConfig - ,jobject juserdata){ + ,jobject juserdata, jobject context){ const char* userConfig = GetStringUTFChars(env, juserConfig); const char* factoryConfig = GetStringUTFChars(env, jfactoryConfig); @@ -1645,11 +1645,12 @@ extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_newLinphoneCore(JNIEnv* LinphoneCoreVTable *vTable = linphone_core_v_table_new(); LinphoneCoreData* ldata = new LinphoneCoreData(env, thiz, vTable, jlistener, ljb); linphone_core_v_table_set_user_data(vTable, ldata); - + LinphoneCoreCbs *cbs = linphone_factory_create_core_cbs(linphone_factory_get()); + _linphone_core_cbs_set_v_table(cbs, vTable, TRUE); jobject core = env->NewGlobalRef(thiz); ljb->setCore(core); - LinphoneCore *lc = linphone_core_new(vTable, userConfig, factoryConfig, ljb); + LinphoneCore *lc = linphone_factory_create_core_2(linphone_factory_get(), cbs, userConfig, factoryConfig, ljb, context); jlong nativePtr = (jlong)lc; ReleaseStringUTFChars(env, juserConfig, userConfig); @@ -1661,18 +1662,8 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_delete(JNIEnv* env, jobj LinphoneCore *lc=(LinphoneCore*)native_ptr; LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); - jobject multicast_lock = lc->multicast_lock; - jobject multicast_lock_class = lc->multicast_lock_class; - jobject wifi_lock = lc->wifi_lock; - jobject wifi_lock_class = lc->wifi_lock_class; - linphone_core_destroy(lc); - if (wifi_lock) env->DeleteGlobalRef(wifi_lock); - if (wifi_lock_class) env->DeleteGlobalRef(wifi_lock_class); - if (multicast_lock) env->DeleteGlobalRef(multicast_lock); - if (multicast_lock_class) env->DeleteGlobalRef(multicast_lock_class); - if (ljb) { jobject core = ljb->getCore(); if (core) { @@ -5949,43 +5940,9 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setAndroidPowerManager(J /*released in Java_org_linphone_core_LinphoneCoreImpl_delete*/ 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); - env->DeleteGlobalRef(lc->wifi_lock_class); - } - if (wifi_lock != NULL) { - lc->wifi_lock=env->NewGlobalRef(wifi_lock); - lc->wifi_lock_class = env->FindClass("android/net/wifi/WifiManager$WifiLock"); - lc->wifi_lock_class = (jclass)env->NewGlobalRef(lc->wifi_lock_class); /*to make sure methodid are preserved*/ - lc->wifi_lock_acquire_id = env->GetMethodID(lc->wifi_lock_class, "acquire", "()V"); - lc->wifi_lock_release_id = env->GetMethodID(lc->wifi_lock_class, "release", "()V"); - } else { - lc->wifi_lock=NULL; - lc->wifi_lock_class=NULL; - } -#endif } /*released in Java_org_linphone_core_LinphoneCoreImpl_delete*/ 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); - env->DeleteGlobalRef(lc->multicast_lock_class); - } - if (multicast_lock != NULL) { - lc->multicast_lock=env->NewGlobalRef(multicast_lock); - lc->multicast_lock_class = env->FindClass("android/net/wifi/WifiManager$MulticastLock"); - lc->multicast_lock_class = (jclass)env->NewGlobalRef(lc->multicast_lock_class);/*to make sure methodid are preserved*/ - lc->multicast_lock_acquire_id = env->GetMethodID(lc->multicast_lock_class, "acquire", "()V"); - lc->multicast_lock_release_id = env->GetMethodID(lc->multicast_lock_class, "release", "()V"); - } else { - lc->multicast_lock=NULL; - lc->multicast_lock_class=NULL; - } -#endif } extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_getAudioDscp(JNIEnv* env,jobject thiz,jlong ptr){ diff --git a/coreapi/platform-helpers.cpp b/coreapi/platform-helpers.cpp new file mode 100644 index 000000000..05bbc00e6 --- /dev/null +++ b/coreapi/platform-helpers.cpp @@ -0,0 +1,49 @@ +/* +linphone +Copyright (C) 2017 Belledonne Communications SARL + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "private.h" + + +namespace LinphonePrivate{ + +PlatformHelpers::~PlatformHelpers(){ +} + +StubbedPlatformHelpers::StubbedPlatformHelpers(LinphoneCore *lc) : PlatformHelpers(lc){ +} + +void StubbedPlatformHelpers::setDnsServers(){ +} +void StubbedPlatformHelpers::acquireWifiLock(){ +} +void StubbedPlatformHelpers::releaseWifiLock(){ +} +void StubbedPlatformHelpers::acquireMcastLock(){ +} +void StubbedPlatformHelpers::releaseMcastLock(){ +} +void StubbedPlatformHelpers::acquireCpuLock(){ +} +void StubbedPlatformHelpers::releaseCpuLock(){ +} + +StubbedPlatformHelpers::~StubbedPlatformHelpers(){ +} + +} \ No newline at end of file diff --git a/coreapi/platform-helpers.h b/coreapi/platform-helpers.h new file mode 100644 index 000000000..8d4b6acf4 --- /dev/null +++ b/coreapi/platform-helpers.h @@ -0,0 +1,64 @@ +/* +linphone +Copyright (C) 2017 Belledonne Communications SARL + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef platform_helpers_h +#define platform_helpers_h + + +namespace LinphonePrivate{ + +/** + * This interface aims at abstracting some features offered by the platform, most often mobile platforms. + * A per platform implementation is to be made to implement these features, if available on the platform + */ +class PlatformHelpers{ + public: + //This method shall retrieve DNS server list from the platform and assign it to the core. + virtual void setDnsServers() = 0; + virtual void acquireWifiLock() = 0; + virtual void releaseWifiLock() = 0; + virtual void acquireMcastLock() = 0; + virtual void releaseMcastLock() = 0; + virtual void acquireCpuLock() = 0; + virtual void releaseCpuLock() = 0; + virtual ~PlatformHelpers(); + protected: + PlatformHelpers(LinphoneCore *lc) : mCore(lc){ + } + LinphoneCore *mCore; +}; + +class StubbedPlatformHelpers : public PlatformHelpers{ +public: + StubbedPlatformHelpers(LinphoneCore *lc); + virtual void setDnsServers(); + virtual void acquireWifiLock(); + virtual void releaseWifiLock(); + virtual void acquireMcastLock(); + virtual void releaseMcastLock(); + virtual void acquireCpuLock(); + virtual void releaseCpuLock(); + virtual ~StubbedPlatformHelpers(); +}; + +PlatformHelpers *createAndroidPlatformHelpers(LinphoneCore *lc, void *system_context); + +}//end of namespace + +#endif diff --git a/coreapi/private.h b/coreapi/private.h index eca250923..4cf7346a0 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -31,6 +31,7 @@ #include "linphone/tunnel.h" #include "linphone/core_utils.h" #include "linphone/conference.h" + #include "address/address.h" #include "c-wrapper/internal/c-sal.h" #include "core/core.h" @@ -39,6 +40,11 @@ #include "sal/message-op.h" #include "sal/presence-op.h" #include "sal/register-op.h" + +#ifdef __cplusplus +#include "platform-helpers.h" +#endif + #include "linphone/sipsetup.h" #include "quality_reporting.h" #include "linphone/ringtoneplayer.h" @@ -815,6 +821,8 @@ struct _LinphoneCore // For migration purposes LinphonePrivate::Core cppCore; + void *platform_helper; /*is a LinphonePrivate::PlatformHelpers but cannot be used as is because private.h is compiled as C in testers.*/ + LinphoneGlobalState state; struct _LpConfig *config; MSList *default_audio_codecs; @@ -920,16 +928,6 @@ struct _LinphoneCore LinphoneContent *log_collection_upload_information; LinphoneCoreCbs *current_cbs; // the latest LinphoneCoreCbs object to call a callback, see linphone_core_get_current_cbs() LinphoneRingtonePlayer *ringtoneplayer; -#ifdef __ANDROID__ - jobject wifi_lock; - jclass wifi_lock_class; - jmethodID wifi_lock_acquire_id; - jmethodID wifi_lock_release_id; - jobject multicast_lock; - jclass multicast_lock_class; - jmethodID multicast_lock_acquire_id; - jmethodID multicast_lock_release_id; -#endif LinphoneVcardContext *vcard_context; /*for tests only*/ @@ -945,6 +943,10 @@ struct _LinphoneCore MSBandwidthController *bw_controller; }; +#ifdef __cplusplus +#define getPlatformHelpers(lc) static_cast(lc->platform_helper) +#endif + struct _LinphoneEvent{ belle_sip_object_t base; @@ -1078,6 +1080,8 @@ LINPHONE_PUBLIC int linphone_core_get_call_history_size(LinphoneCore *lc); int linphone_core_get_edge_bw(LinphoneCore *lc); int linphone_core_get_edge_ptime(LinphoneCore *lc); +LinphoneCore *_linphone_core_new_with_config(LinphoneCoreCbs *cbs, struct _LpConfig *config, void *userdata, void *system_context); + int linphone_upnp_init(LinphoneCore *lc); void linphone_upnp_destroy(LinphoneCore *lc); @@ -1501,12 +1505,6 @@ SalStreamDir sal_dir_from_call_params_dir(LinphoneMediaDirection cpdir); */ void ** linphone_content_get_cryptoContext_address(LinphoneContent *content); -#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 struct _VTableReference{ LinphoneCoreCbs *cbs; diff --git a/include/linphone/factory.h b/include/linphone/factory.h index 26a5aa29b..7db488fbe 100644 --- a/include/linphone/factory.h +++ b/include/linphone/factory.h @@ -66,6 +66,32 @@ LINPHONE_PUBLIC void linphone_factory_clean(void); LINPHONE_PUBLIC LinphoneCore *linphone_factory_create_core(const LinphoneFactory *factory, LinphoneCoreCbs *cbs, const char *config_path, const char *factory_config_path); + +/** + * Instanciate a #LinphoneCore object. + * + * The LinphoneCore object is the primary handle for doing all phone actions. + * It should be unique within your application. + * @param factory The #LinphoneFactory singleton. + * @param cbs a #LinphoneCoreCbs object holding your application callbacks. A reference + * will be taken on it until the destruciton of the core or the unregistration + * with linphone_core_remove_cbs(). + * @param config_path a path to a config file. If it does not exists it will be created. + * The config file is used to store all settings, call logs, friends, proxies... so that all these settings + * become persistent over the life of the LinphoneCore object. + * It is allowed to set a NULL config file. In that case LinphoneCore will not store any settings. + * @param factory_config_path a path to a read-only config file that can be used to + * to store hard-coded preference such as proxy settings or internal preferences. + * The settings in this factory file always override the one in the normal config file. + * It is OPTIONAL, use NULL if unneeded. + * @param user_data an application pointer associated with the returned core. + * @param system_context a pointer to a system object required by the core to operate. Currently it is required to pass an android Context on android, pass NULL on other platforms. + * @see linphone_core_new_with_config + */ +LINPHONE_PUBLIC LinphoneCore *linphone_factory_create_core_2(const LinphoneFactory *factory, LinphoneCoreCbs *cbs, + const char *config_path, const char *factory_config_path, void *user_data, void *system_context); + + /** * Instantiates a LinphoneCore object with a given LpConfig. * @@ -80,6 +106,22 @@ LINPHONE_PUBLIC LinphoneCore *linphone_factory_create_core(const LinphoneFactory */ LINPHONE_PUBLIC LinphoneCore *linphone_factory_create_core_with_config(const LinphoneFactory *factory, LinphoneCoreCbs *cbs, LinphoneConfig *config); +/** + * Instantiates a LinphoneCore object with a given LpConfig. + * + * @param factory The #LinphoneFactory singleton. + * The LinphoneCore object is the primary handle for doing all phone actions. + * It should be unique within your application. + * @param cbs a #LinphoneCoreCbs object holding your application callbacks. A reference + * will be taken on it until the destruciton of the core or the unregistration + * with linphone_core_remove_cbs(). + * @param config a pointer to an LpConfig object holding the configuration of the LinphoneCore to be instantiated. + * @param user_data an application pointer associated with the returned core. + * @param system_context a pointer to a system object required by the core to operate. Currently it is required to pass an android Context on android, pass NULL on other platforms. + * @see linphone_core_new + */ +LINPHONE_PUBLIC LinphoneCore *linphone_factory_create_core_with_config_2(const LinphoneFactory *factory, LinphoneCoreCbs *cbs, LinphoneConfig *config, void *user_data, void *system_context); + /** * Instanciate a #LinphoneCoreCbs object. * @return a new #LinphoneCoreCbs. diff --git a/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java b/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java index 915e6e0c0..ba951efb4 100644 --- a/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java +++ b/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java @@ -107,9 +107,8 @@ public class LinphoneCoreFactoryImpl extends LinphoneCoreFactory { MediastreamerAndroidContext.setContext(context); File user = userConfig == null ? null : new File(userConfig); File factory = factoryConfig == null ? null : new File(factoryConfig); - LinphoneCore lc = new LinphoneCoreImpl(listener, user, factory, userdata); + LinphoneCore lc = new LinphoneCoreImpl(listener, user, factory, userdata, context); lc.enableDownloadOpenH264(openh264DownloadEnabled); - if (context != null) lc.setContext(context); return lc; } catch (IOException e) { throw new LinphoneCoreException("Cannot create LinphoneCore",e); @@ -123,9 +122,8 @@ public class LinphoneCoreFactoryImpl extends LinphoneCoreFactory { boolean openh264DownloadEnabled = false; if (context != null) openh264DownloadEnabled = loadingDownloadedOpenH264(fcontext); MediastreamerAndroidContext.setContext(context); - LinphoneCore lc = new LinphoneCoreImpl(listener); + LinphoneCore lc = new LinphoneCoreImpl(listener, context); lc.enableDownloadOpenH264(openh264DownloadEnabled); - 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 671fb1fcc..cd076e837 100644 --- a/java/impl/org/linphone/core/LinphoneCoreImpl.java +++ b/java/impl/org/linphone/core/LinphoneCoreImpl.java @@ -47,7 +47,7 @@ class LinphoneCoreImpl implements LinphoneCore { private AudioManager mAudioManager = null; private boolean openh264DownloadEnabled = false; private boolean mSpeakerEnabled = false; - private native long newLinphoneCore(LinphoneCoreListener listener,String userConfig,String factoryConfig,Object userdata); + private native long newLinphoneCore(LinphoneCoreListener listener,String userConfig,String factoryConfig,Object userdata, Object context); private native void iterate(long nativePtr); private native LinphoneProxyConfig getDefaultProxyConfig(long nativePtr); @@ -196,15 +196,17 @@ class LinphoneCoreImpl implements LinphoneCore { private native Object createFriendWithAddress(long nativePtr, String address); private native int getIncomingTimeout(long nativePtr); - LinphoneCoreImpl(LinphoneCoreListener listener, File userConfig, File factoryConfig, Object userdata) throws IOException { + LinphoneCoreImpl(LinphoneCoreListener listener, File userConfig, File factoryConfig, Object userdata, Object context) throws IOException { mListener = listener; String user = userConfig == null ? null : userConfig.getCanonicalPath(); String factory = factoryConfig == null ? null : factoryConfig.getCanonicalPath(); - nativePtr = newLinphoneCore(listener, user, factory, userdata); + nativePtr = newLinphoneCore(listener, user, factory, userdata, context); + setContext(context); } - LinphoneCoreImpl(LinphoneCoreListener listener) throws IOException { + LinphoneCoreImpl(LinphoneCoreListener listener, Object context) throws IOException { mListener = listener; - nativePtr = newLinphoneCore(listener,null,null,null); + nativePtr = newLinphoneCore(listener,null,null,null, context); + setContext(context); } protected void finalize() throws Throwable { @@ -223,19 +225,7 @@ class LinphoneCoreImpl implements LinphoneCore { ApplicationInfo info = mContext.getApplicationInfo(); reloadMsPlugins(info.nativeLibraryDir); mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); - setAndroidPowerManager(mContext.getSystemService(Context.POWER_SERVICE)); - if (Version.sdkAboveOrEqual(Version.API12_HONEYCOMB_MR1_31X)) { - 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); - } + } public Context getContext() { diff --git a/java/impl/org/linphone/core/util/AndroidPlatformHelper.java b/java/impl/org/linphone/core/util/AndroidPlatformHelper.java new file mode 100644 index 000000000..aeb44e15b --- /dev/null +++ b/java/impl/org/linphone/core/util/AndroidPlatformHelper.java @@ -0,0 +1,114 @@ +/* +AndroidPlatformHelper.java +Copyright (C) 2017 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + + +package org.linphone.core.util; + +import org.linphone.mediastream.Log; + +import android.net.wifi.WifiManager; +import android.net.wifi.WifiManager.MulticastLock; +import android.net.wifi.WifiManager.WifiLock; +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.Network; +import android.net.NetworkInfo; +import android.os.PowerManager; +import android.os.PowerManager.WakeLock; + +import java.net.InetAddress; +import java.util.List; +import android.os.Build; + +/** + * This class is instanciated directly by the linphone library in order to access specific features only accessible in java. +**/ + +public class AndroidPlatformHelper{ + private WifiManager.WifiLock mWifiLock; + private WifiManager.MulticastLock mMcastLock; + private ConnectivityManager mConnectivityManager; + private PowerManager mPowerManager; + private WakeLock mWakeLock; + + public AndroidPlatformHelper(Object ctx_obj){ + Context ctx = (Context) ctx_obj; + WifiManager wifiMgr = ctx.getSystemService(WifiManager.class); + mPowerManager = (PowerManager) ctx.getSystemService(Context.POWER_SERVICE); + mConnectivityManager = (ConnectivityManager) ctx.getSystemService(Context.CONNECTIVITY_SERVICE); + + mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "AndroidPlatformHelper"); + mWakeLock.setReferenceCounted(true); + mMcastLock = wifiMgr.createMulticastLock("AndroidPlatformHelper"); + mMcastLock.setReferenceCounted(true); + mWifiLock = wifiMgr.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "AndroidPlatformHelper"); + mWifiLock.setReferenceCounted(true); + } + + public Object getPowerManager(){ + return mPowerManager; + } + + public String[] getDnsServers() { + if (mConnectivityManager == null || Build.VERSION.SDK_INT < Build.VERSION_CODES.M) + return null; + + if (mConnectivityManager.getActiveNetwork() == null + || mConnectivityManager.getLinkProperties(mConnectivityManager.getActiveNetwork()) == null) + return null; + + int i = 0; + List inetServers = null; + inetServers = mConnectivityManager.getLinkProperties(mConnectivityManager.getActiveNetwork()).getDnsServers(); + + String[] servers = new String[inetServers.size()]; + + for (InetAddress address : inetServers) { + servers[i++] = address.getHostAddress(); + } + Log.i("getDnsServers() returning"); + return servers; + } + public void acquireWifiLock(){ + Log.i("acquireWifiLock()"); + mWifiLock.acquire(); + } + public void releaseWifiLock(){ + Log.i("releaseWifiLock()"); + mWifiLock.release(); + } + public void acquireMcastLock(){ + Log.i("acquireMcastLock()"); + mMcastLock.acquire(); + } + public void releaseMcastLock(){ + Log.i("releaseMcastLock()"); + mMcastLock.release(); + } + public void acquireCpuLock(){ + Log.i("acquireCpuLock()"); + mWakeLock.acquire(); + } + public void releaseCpuLock(){ + Log.i("releaseCpuLock()"); + mWakeLock.release(); + } +}; + +