From 142fdca15504216b6a52e08594c2e35872b0cdbf Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 15 Jun 2018 22:07:38 +0200 Subject: [PATCH] Fix loading of ms2 plugins on Android. The nativeLibraryDir is found from java API and used directly in LinphoneCore instanciation, thanks to the AndroidPlatformHelper class. --- coreapi/linphonecore.c | 5 +-- .../android-platform-helpers.cpp | 17 ++++++++- tester/setup_tester.c | 37 +++++++++++++++++++ .../classes/tools/AndroidPlatformHelper.java | 6 +++ 4 files changed, 61 insertions(+), 4 deletions(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index e81b45e11..7787940b2 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -2286,9 +2286,6 @@ static void linphone_core_init(LinphoneCore * lc, LinphoneCoreCbs *cbs, LpConfig lc->ringstream_autorelease=TRUE; // We need the Sal on the Android platform helper init - msplugins_dir = linphone_factory_get_msplugins_dir(lfactory); - image_resources_dir = linphone_factory_get_image_resources_dir(lfactory); - lc->sal=new Sal(NULL); lc->sal->setRefresherRetryAfter(lp_config_get_int(lc->config, "sip", "refresher_retry_after", 60000)); lc->sal->setHttpProxyHost(L_C_TO_STRING(linphone_core_get_http_proxy_host(lc))); @@ -2306,6 +2303,8 @@ static void linphone_core_init(LinphoneCore * lc, LinphoneCoreCbs *cbs, LpConfig if (lc->platform_helper == NULL) lc->platform_helper = new LinphonePrivate::StubbedPlatformHelpers(lc); + msplugins_dir = linphone_factory_get_msplugins_dir(lfactory); + image_resources_dir = linphone_factory_get_image_resources_dir(lfactory); // MS Factory MUST be created after Android has been set, otherwise no camera will be detected ! lc->factory = ms_factory_new_with_voip_and_directories(msplugins_dir, image_resources_dir); lc->sal->setFactory(lc->factory); diff --git a/src/core/platform-helpers/android-platform-helpers.cpp b/src/core/platform-helpers/android-platform-helpers.cpp index ca28fe20f..58b61c3bc 100644 --- a/src/core/platform-helpers/android-platform-helpers.cpp +++ b/src/core/platform-helpers/android-platform-helpers.cpp @@ -49,6 +49,7 @@ public: private: int callVoidMethod (jmethodID id); static jmethodID getMethodId (JNIEnv *env, jclass klass, const char *method, const char *signature); + string getNativeLibraryDir(); jobject mJavaHelper; jmethodID mWifiLockAcquireId; jmethodID mWifiLockReleaseId; @@ -60,6 +61,7 @@ private: jmethodID mGetPowerManagerId; jmethodID mGetDataPathId; jmethodID mGetConfigPathId; + jmethodID mGetNativeLibraryDirId; }; static const char *GetStringUTFChars (JNIEnv *env, jstring string) { @@ -102,6 +104,7 @@ AndroidPlatformHelpers::AndroidPlatformHelpers (LinphoneCore *lc, void *systemCo mGetPowerManagerId = getMethodId(env, klass, "getPowerManager", "()Ljava/lang/Object;"); mGetDataPathId = getMethodId(env, klass, "getDataPath", "()Ljava/lang/String;"); mGetConfigPathId = getMethodId(env, klass, "getConfigPath", "()Ljava/lang/String;"); + mGetNativeLibraryDirId = getMethodId(env, klass, "getNativeLibraryDir", "()Ljava/lang/String;"); jmethodID initCoreId = getMethodId(env, klass, "initCore", "(J)V"); env->CallVoidMethod(mJavaHelper, initCoreId, lc); @@ -110,7 +113,7 @@ AndroidPlatformHelpers::AndroidPlatformHelpers (LinphoneCore *lc, void *systemCo belle_sip_wake_lock_init(env, pm); linphone_factory_set_top_resources_dir(linphone_factory_get() , getDataPath().append("share").c_str()); - + linphone_factory_set_msplugins_dir(linphone_factory_get(), getNativeLibraryDir().c_str()); lInfo() << "AndroidPlatformHelpers is fully initialised."; } @@ -191,6 +194,18 @@ string AndroidPlatformHelpers::getDataPath () { return dataPath + "/"; } +string AndroidPlatformHelpers::getNativeLibraryDir () { + JNIEnv *env = ms_get_jni_env(); + string libPath; + jstring jlib_path = (jstring)env->CallObjectMethod(mJavaHelper, mGetNativeLibraryDirId); + if (jlib_path){ + const char *lib_path = GetStringUTFChars(env, jlib_path); + libPath = lib_path; + ReleaseStringUTFChars(env, jlib_path, lib_path); + } + return libPath; +} + string AndroidPlatformHelpers::getConfigPath () { JNIEnv *env = ms_get_jni_env(); jstring jconfig_path = (jstring)env->CallObjectMethod(mJavaHelper, mGetConfigPathId); diff --git a/tester/setup_tester.c b/tester/setup_tester.c index 590a3c41b..994e24e98 100644 --- a/tester/setup_tester.c +++ b/tester/setup_tester.c @@ -25,6 +25,10 @@ #include "linphone/api/c-magic-search.h" #include "tester_utils.h" +#ifdef __APPLE__ +#include "TargetConditionals.h" +#endif + #define S_SIZE_FRIEND 12 static const unsigned int sSizeFriend = S_SIZE_FRIEND; static const char *sFriends[S_SIZE_FRIEND] = { @@ -1368,6 +1372,38 @@ static void search_friend_large_database(void) { free(dbPath); } + +/*the webrtc AEC implementation is brought to mediastreamer2 by a plugin. + * We finally check here that if the plugin is correctly loaded and the right choice of echo canceller implementation is made*/ +static void echo_canceller_check(void){ + LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE); + MSFactory *factory = linphone_core_get_ms_factory(manager->lc); + const char *expected_filter = "MSSpeexEC"; + AudioStream *as = audio_stream_new2(factory, NULL, 43000, 43001); + const char *ec_filter = NULL; + + BC_ASSERT_PTR_NOT_NULL(as); + if (as){ + MSFilter *ecf = as->ec; + BC_ASSERT_PTR_NOT_NULL(ecf); + if (ecf){ + ec_filter = ecf->desc->name; + } + } + BC_ASSERT_PTR_NOT_NULL(ec_filter); + +#if defined(__linux) || (defined(__APPLE__) && !TARGET_OS_IPHONE) || defined(_WIN32) + expected_filter = "MSWebRTCAEC"; +#elif defined(__ANDROID__) + expected_filter = "MSWebRTCAECM"; +#endif + if (ec_filter){ + BC_ASSERT_STRING_EQUAL(ec_filter, expected_filter); + } + audio_stream_stop(as); + linphone_core_manager_destroy(manager); +} + test_t setup_tests[] = { TEST_NO_TAG("Version check", linphone_version_test), TEST_NO_TAG("Linphone Address", linphone_address_test), @@ -1385,6 +1421,7 @@ test_t setup_tests[] = { TEST_NO_TAG("Codec usability", codec_usability_test), TEST_NO_TAG("Codec setup", codec_setup), TEST_NO_TAG("Custom tones setup", custom_tones_setup), + TEST_NO_TAG("Appropriate software echo canceller check", echo_canceller_check), TEST_ONE_TAG("Return friend list in alphabetical order", search_friend_in_alphabetical_order, "MagicSearch"), TEST_ONE_TAG("Search friend without filter and domain", search_friend_without_filter, "MagicSearch"), TEST_ONE_TAG("Search friend with domain and without filter", search_friend_with_domain_without_filter, "MagicSearch"), diff --git a/wrappers/java/classes/tools/AndroidPlatformHelper.java b/wrappers/java/classes/tools/AndroidPlatformHelper.java index ab7c50d47..ccd20b7ee 100644 --- a/wrappers/java/classes/tools/AndroidPlatformHelper.java +++ b/wrappers/java/classes/tools/AndroidPlatformHelper.java @@ -29,6 +29,7 @@ import android.net.wifi.WifiManager; import android.net.wifi.WifiManager.MulticastLock; import android.net.wifi.WifiManager.WifiLock; import android.content.Context; +import android.content.pm.ApplicationInfo; import android.net.ConnectivityManager; import android.net.Network; import android.net.NetworkInfo; @@ -132,6 +133,11 @@ public class AndroidPlatformHelper { public String getCachePath() { return mContext.getCacheDir().getAbsolutePath(); } + + public String getNativeLibraryDir(){ + ApplicationInfo info = mContext.getApplicationInfo(); + return info.nativeLibraryDir; + } public void acquireWifiLock() { Log.i("acquireWifiLock()");