diff --git a/.classpath b/.classpath deleted file mode 100644 index 63762c92a..000000000 --- a/.classpath +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/.gitignore b/.gitignore index f1ed51c97..358d3d4bb 100644 --- a/.gitignore +++ b/.gitignore @@ -48,6 +48,11 @@ WORK .d google-services.json .*clang* -linphone.iml +**/*.iml src/linphone-wrapper liblinphone_tester/res/raw/ +**/.classpath +**/.project +**/*.kdev4 +liblinphone-sdk/res/ +**/.vscode diff --git a/.gitmodules b/.gitmodules index cdfee6b31..379a64301 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,122 +1,122 @@ [submodule "submodules/linphone"] path = submodules/linphone - url = git://git.linphone.org/linphone.git + url = https://gitlab.linphone.org/BC/public/linphone.git [submodule "submodules/externals/gsm"] path = submodules/externals/gsm - url = git://git.linphone.org/gsm.git + url = https://gitlab.linphone.org/BC/public/external/gsm.git [submodule "submodules/externals/speex"] path = submodules/externals/speex - url = git://git.linphone.org/speex.git + url = https://gitlab.linphone.org/BC/public/external/speex.git [submodule "submodules/externals/ffmpeg"] path = submodules/externals/ffmpeg - url = git://git.linphone.org/ffmpeg.git + url = https://gitlab.linphone.org/BC/public/external/ffmpeg.git ignore = dirty [submodule "submodules/externals/x264"] path = submodules/externals/x264 - url = git://git.linphone.org/x264.git + url = https://gitlab.linphone.org/BC/public/external/x264.git ignore = dirty [submodule "submodules/msx264"] path = submodules/msx264 - url = git://git.linphone.org/msx264.git + url = https://gitlab.linphone.org/BC/public/msx264.git [submodule "submodules/externals/opencore-amr"] path = submodules/externals/opencore-amr - url = git://git.linphone.org/opencore-amr.git + url = https://gitlab.linphone.org/BC/public/external/opencore-amr.git ignore = dirty [submodule "submodules/msamr"] path = submodules/msamr - url = git://git.linphone.org/msamr.git + url = https://gitlab.linphone.org/BC/public/msamr.git [submodule "submodules/externals/libvpx"] path = submodules/externals/libvpx - url = git://git.linphone.org/libvpx.git + url = https://gitlab.linphone.org/BC/public/external/libvpx.git ignore = dirty [submodule "submodules/bzrtp"] path = submodules/bzrtp - url = git://git.linphone.org/bzrtp.git + url = https://gitlab.linphone.org/BC/public/bzrtp.git [submodule "submodules/externals/srtp"] path = submodules/externals/srtp - url = git://git.linphone.org/srtp.git + url = https://gitlab.linphone.org/BC/public/external/srtp.git [submodule "submodules/mssilk"] path = submodules/mssilk - url = git://git.linphone.org/mssilk.git + url = https://gitlab.linphone.org/BC/public/mssilk.git [submodule "submodules/bcg729"] path = submodules/bcg729 - url = git://git.linphone.org/bcg729.git + url = https://gitlab.linphone.org/BC/public/bcg729.git [submodule "submodules/belle-sip"] path = submodules/belle-sip - url = git://git.linphone.org/belle-sip.git + url = https://gitlab.linphone.org/BC/public/belle-sip.git [submodule "submodules/externals/libxml2"] path = submodules/externals/libxml2 - url = https://github.com/GNOME/libxml2.git + url = https://gitlab.linphone.org/BC/public/external/libxml2.git ignore = dirty [submodule "submodules/externals/libupnp"] path = submodules/externals/libupnp - url = git://git.linphone.org/libupnp.git + url = https://gitlab.linphone.org/BC/public/external/libupnp.git [submodule "submodules/externals/opus"] path = submodules/externals/opus - url = git://git.linphone.org/opus.git + url = https://gitlab.linphone.org/BC/public/external/opus.git ignore = dirty [submodule "submodules/mswebrtc"] path = submodules/mswebrtc - url = git://git.linphone.org/mswebrtc.git + url = https://gitlab.linphone.org/BC/public/mswebrtc.git [submodule "submodules/msopenh264"] path = submodules/msopenh264 - url = git://git.linphone.org/msopenh264.git + url = https://gitlab.linphone.org/BC/public/msopenh264.git [submodule "submodules/externals/openh264"] path = submodules/externals/openh264 - url = https://github.com/cisco/openh264 + url = https://gitlab.linphone.org/BC/public/external/openh264.git ignore = dirty [submodule "submodules/mscodec2"] path = submodules/mscodec2 - url = git://git.linphone.org/mscodec2.git + url = https://gitlab.linphone.org/BC/public/mscodec2.git [submodule "submodules/bctoolbox"] path = submodules/bctoolbox - url = git://git.linphone.org/bctoolbox.git + url = https://gitlab.linphone.org/BC/public/bctoolbox.git [submodule "submodules/externals/mbedtls"] path = submodules/externals/mbedtls - url = git://git.linphone.org/mbedtls.git + url = https://gitlab.linphone.org/BC/public/external/mbedtls.git ignore = dirty [submodule "submodules/cmake-builder"] path = submodules/cmake-builder - url = git://git.linphone.org/linphone-cmake-builder.git + url = https://gitlab.linphone.org/BC/public/linphone-cmake-builder.git [submodule "submodules/externals/bv16-floatingpoint"] path = submodules/externals/bv16-floatingpoint - url = git://git.linphone.org/bv16-floatingpoint.git + url = https://gitlab.linphone.org/BC/public/external/bv16-floatingpoint.git [submodule "submodules/belr"] path = submodules/belr - url = git://git.linphone.org/belr.git + url = https://gitlab.linphone.org/BC/public/belr.git [submodule "submodules/belcard"] path = submodules/belcard - url = git://git.linphone.org/belcard.git + url = https://gitlab.linphone.org/BC/public/belcard.git [submodule "submodules/bcunit"] path = submodules/bcunit - url = git://git.linphone.org/bcunit.git + url = https://gitlab.linphone.org/BC/public/bcunit.git [submodule "submodules/externals/vo-amrwbenc"] path = submodules/externals/vo-amrwbenc - url = git://git.linphone.org/vo-amrwbenc.git + url = https://gitlab.linphone.org/BC/public/external/vo-amrwbenc.git [submodule "submodules/externals/codec2"] path = submodules/externals/codec2 - url = git://git.linphone.org/codec2 + url = https://gitlab.linphone.org/BC/public/external/codec2.git [submodule "submodules/externals/libjpeg-turbo"] path = submodules/externals/libjpeg-turbo - url = git://git.linphone.org/libjpeg-turbo.git + url = https://gitlab.linphone.org/BC/public/external/libjpeg-turbo.git [submodule "submodules/mediastreamer2"] path = submodules/mediastreamer2 - url = git://git.linphone.org/mediastreamer2.git + url = https://gitlab.linphone.org/BC/public/mediastreamer2.git [submodule "submodules/oRTP"] path = submodules/oRTP - url = git://git.linphone.org/ortp.git + url = https://gitlab.linphone.org/BC/public/ortp.git [submodule "submodules/bcmatroska2"] path = submodules/bcmatroska2 - url = git://git.linphone.org/bcmatroska2.git + url = https://gitlab.linphone.org/BC/public/bcmatroska2.git [submodule "submodules/externals/xerces-c"] path = submodules/externals/xerces-c - url = git://git.linphone.org/xerces-c.git + url = https://gitlab.linphone.org/BC/public/external/xerces-c.git [submodule "submodules/externals/libxsd"] path = submodules/externals/libxsd - url = git://git.linphone.org/libxsd + url = https://gitlab.linphone.org/BC/public/external/libxsd.git [submodule "submodules/externals/soci"] path = submodules/externals/soci - url = git://git.linphone.org/soci + url = https://gitlab.linphone.org/BC/public/external/soci.git [submodule "submodules/externals/zxing-cpp"] path = submodules/externals/zxing-cpp - url = git://git.linphone.org/zxing-cpp.git + url = https://gitlab.linphone.org/BC/public/external/zxing-cpp.git diff --git a/.project b/.project deleted file mode 100644 index f9c163d50..000000000 --- a/.project +++ /dev/null @@ -1,33 +0,0 @@ - - - linphone-android - - - - - - com.android.ide.eclipse.adt.ResourceManagerBuilder - - - - - com.android.ide.eclipse.adt.PreCompilerBuilder - - - - - org.eclipse.jdt.core.javabuilder - - - - - com.android.ide.eclipse.adt.ApkBuilder - - - - - - com.android.ide.eclipse.adt.AndroidNature - org.eclipse.jdt.core.javanature - - diff --git a/AndroidManifest.xml b/AndroidManifest.xml index c83fd6e85..946406175 100755 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -2,8 +2,8 @@ + android:versionCode="4002" + android:versionName="4.0.1"> ${FILE}.tmp - chmod --reference ${FILE} ${FILE}.tmp - mv ${FILE}.tmp ${FILE} - echo "Done!" - else - echo "New string '${NEW_STRING}' is longer than old" \ - "string '${OLD_STRING}'. Skipping." - fi - done - fi -} - -patch_strings_in_file libs/armeabi-v7a/liblinphone-armeabi-v7a.so "./obj/local/armeabi-v7a/libffmpeg-linphone-arm.so" "libffmpeg-linphone-arm.so" -patch_strings_in_file libs/x86/liblinphone-x86.so "./obj/local/x86/libffmpeg-linphone-x86.so" "libffmpeg-linphone-x86.so" diff --git a/check_tools.sh b/check_tools.sh deleted file mode 100755 index 0c19fb138..000000000 --- a/check_tools.sh +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/sh - -error_on_quit=0 - -echo_err() { - echo "$@" >&2 - error_on_quit=1 -} - -check_installed() { - if [ -z "$(which $1)" ]; then - echo_err "Could not find $1. Please install $2." - return 1 - fi - return 0 -} - -for prog in automake autoconf pkg-config java ant yasm nasm wget; do - check_installed "$prog" "it" -done -if [ $(uname) = "Darwin" ]; then - check_installed "libtool" "libtool" -else - check_installed "libtoolize" "libtool" -fi -check_installed "ndk-build" "android NDK" -if check_installed "android" "android SDK"; then - check_installed "adb" "android SDK platform tools" - # check that at least one target is installed - if [ -z "$(android list target -c)" ]; then - echo_err "Install at least one android target in the android SDK" - fi -fi -if nasm -f elf32 2>&1 | grep -q "fatal: unrecognised output format"; then - echo_err "Invalid version of nasm: your version does not support elf32 output format. If you have installed nasm, please check that your PATH env variable is set correctly." -fi -if ! (find submodules/linphone/mediastreamer2 -mindepth 1 2>/dev/null | grep -q . \ - || find submodules/linphone/oRTP -mindepth 1 2>/dev/null | grep -q .); then - echo_err "Missing some git submodules. Did you run 'git submodule update --init --recursive'?" -fi -# Android NDK should NOT be simlinked! -if [ -L "$ANDROID_NDK" ] && [ -d "$ANDROID_NDK" ]; then - echo_err "ANDROID_NDK=$ANDROID_NDK must NOT be a symbolic link, please modify it accordingly" -fi - -if [ $error_on_quit = 0 ]; then - rm -f check_tools.mk - touch check_tools.mk - echo "JAVA=\"$(which java)\"" >> check_tools.mk - echo "ANTLR=\"$(which java)\" -jar \"submodules/externals/antlr3/antlr-3.2.jar\"" >> check_tools.mk -else - echo "Failed to detect required tools, aborting." -fi - -exit $error_on_quit diff --git a/doc/CustomsParameters.txt b/doc/CustomsParameters.txt deleted file mode 100644 index dc39dbba5..000000000 --- a/doc/CustomsParameters.txt +++ /dev/null @@ -1,72 +0,0 @@ - ********************************** - * LINPHONE customs parameters * - ********************************** - -In res/values/non_localizable_custom.xml (filled with linphone default options): - -1. Global - - * Set the default domain used by the application: - sip.linphone.orghttps://sip3.linphone.org:444/inapp.php - - * In CreateAccount, allow username instead of phone number for creating a new account - true - - * Hide buttons in assistant menu - false - false - false - - -3. Inapp - - * Enabled inapp purchase - true - - * Days before end of trial period that launch daily notification to remind user to buy an account - 5 - - * Time between two inapp notifications in seconds - 86400 - - * Hide username field in purchase view (automatically get from default account) - true - - -In res/raw/linphonerc_factory sections: - - [in-app-purchase] - * Server xmlrpc url for inapp - server_url=https://sip3.linphone.org:444/inapp.php - - * Item ids from the google play store - purchasable_items_ids=test_account_subscription - - [app] - - * Numbers of digits to enter for validation/recover account - activation_code_length=4 - - - [assistant] - - * Set the default domain used for account creation : - domain=sip.linphone.org - - * Set the default password length (min-max) : - password_max_length=-1 - password_min_length=1 - - * Set the default username length (min-max) : - username_length=-1 - username_max_length=64 - username_min_length=1 - username_regex=^[a-z0-9_.\-]*$ - - * Server xmlrpc url for accounts - xmlrpc_url=https://sip3.linphone.org:444/inapp.php diff --git a/gradle.properties b/gradle.properties index a4996c82d..a1e7a7cb6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,4 +4,4 @@ RELEASE_STORE_PASSWORD= RELEASE_KEY_ALIAS= RELEASE_KEY_PASSWORD= #source:https://docs.gradle.org/current/userguide/build_environment.html#sec:configuring_jvm_memory -org.gradle.jvmargs=-Xmx2g -XX:MaxPermSize=256m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 +org.gradle.jvmargs=-Xmx2g -XX:MaxPermSize=1024m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 diff --git a/liblinphone-sdk/build.gradle b/liblinphone-sdk/build.gradle index 9889fe322..b53e51ea1 100644 --- a/liblinphone-sdk/build.gradle +++ b/liblinphone-sdk/build.gradle @@ -33,7 +33,7 @@ apply plugin: 'com.android.library' dependencies { - compile 'org.apache.commons:commons-compress:1.16.1' + implementation 'org.apache.commons:commons-compress:1.16.1' javadocDeps 'org.apache.commons:commons-compress:1.16.1' } @@ -113,6 +113,7 @@ android { assets.srcDirs = ["${buildDir}/sdk-assets/assets/"] renderscript.srcDirs = srcDir jniLibs.srcDirs = ['../libs'] + resources.srcDir("res") java.excludes = ['**/mediastream/MediastreamerActivity.java'] diff --git a/linphoneAndroidSdk.gradle b/linphoneAndroidSdk.gradle index 34b5c80b0..1a0c5dc88 100644 --- a/linphoneAndroidSdk.gradle +++ b/linphoneAndroidSdk.gradle @@ -26,8 +26,8 @@ allprojects { apply plugin: 'com.android.library' dependencies { - compile group: 'org.apache.commons', name: 'commons-compress', version: '1.16.1' - compile 'com.android.support:support-v4:26.0.2' + implementation group: 'org.apache.commons', name: 'commons-compress', version: '1.16.1' + implementation 'com.android.support:support-v4:26.0.2' } diff --git a/patches/ffmpeg_non_versioned_soname.patch b/patches/ffmpeg_non_versioned_soname.patch deleted file mode 100644 index 34a0ecaf0..000000000 --- a/patches/ffmpeg_non_versioned_soname.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- submodules/externals/ffmpeg/library.mak.orig 2013-09-26 10:58:19.000000000 +0200 -+++ submodules/externals/ffmpeg/library.mak 2013-09-26 10:58:13.000000000 +0200 -@@ -54,7 +54,7 @@ - - $(SUBDIR)$(SLIBNAME_WITH_MAJOR): $(OBJS) $(SUBDIR)lib$(NAME).ver - $(SLIB_CREATE_DEF_CMD) -- $$(LD) $(SHFLAGS) $(LDFLAGS) $$(LD_O) $$(filter %.o,$$^) $(FFEXTRALIBS) -+ $$(LD) $(subst $$(@F),$(SLIBNAME),$(SHFLAGS)) $(LDFLAGS) $$(LD_O) $$(filter %.o,$$^) $(FFEXTRALIBS) - $(SLIB_EXTRA_CMD) - - ifdef SUBDIR diff --git a/patches/libvpx_configure_android_x86.patch b/patches/libvpx_configure_android_x86.patch deleted file mode 100644 index fa1004599..000000000 --- a/patches/libvpx_configure_android_x86.patch +++ /dev/null @@ -1,37 +0,0 @@ -diff --git a/build/make/configure.sh b/build/make/configure.sh -index c592b63..e4998d7 100644 ---- a/build/make/configure.sh -+++ b/build/make/configure.sh -@@ -1132,6 +1132,32 @@ EOF - AS=${AS:-nasm} - add_ldflags -Zhigh-mem - ;; -+ android*) -+ SDK_PATH=${sdk_path} -+ COMPILER_LOCATION=`find "${SDK_PATH}" \ -+ -name "i686-linux-android-gcc*" -print -quit` -+ TOOLCHAIN_PATH=${COMPILER_LOCATION%/*}/i686-linux-android- -+ CC=${TOOLCHAIN_PATH}gcc -+ CXX=${TOOLCHAIN_PATH}g++ -+ AR=${TOOLCHAIN_PATH}ar -+ LD=${TOOLCHAIN_PATH}gcc -+ STRIP=${TOOLCHAIN_PATH}strip -+ NM=${TOOLCHAIN_PATH}nm -+ -+ if [ -z "${alt_libc}" ]; then -+ alt_libc=`find "${SDK_PATH}" -name arch-x86 -print | \ -+ awk '{n = split($0,a,"/"); \ -+ split(a[n-1],b,"-"); \ -+ print $0 " " b[2]}' | \ -+ sort -g -k 2 | \ -+ awk '{ print $1 }' | tail -1` -+ fi -+ -+ add_cflags "--sysroot=${alt_libc}" -+ add_ldflags "--sysroot=${alt_libc}" -+ -+ soft_enable realtime_only -+ ;; - esac - - AS="${alt_as:-${AS:-auto}}" diff --git a/patches/openh264-permissive.patch b/patches/openh264-permissive.patch deleted file mode 100644 index bff18b6ce..000000000 --- a/patches/openh264-permissive.patch +++ /dev/null @@ -1,40 +0,0 @@ -commit 6b3de978d928b6c0baec3305c9803c21a4367d0c -Author: Simon Morlat -Date: Tue Apr 15 15:19:37 2014 +0200 - - permissive mode: allow reference frames to be used even if there were lost slices. - -diff --git a/codec/decoder/core/src/manage_dec_ref.cpp b/codec/decoder/core/src/manage_dec_ref.cpp -index dcf61ca..5582ec9 100644 ---- a/codec/decoder/core/src/manage_dec_ref.cpp -+++ b/codec/decoder/core/src/manage_dec_ref.cpp -@@ -165,6 +165,7 @@ int32_t WelsReorderRefList (PWelsDecoderContext pCtx) { - && (pSliceHeader->iSpsId != ppRefList[i]->iSpsId)) { //check; - WelsLog (pCtx, WELS_LOG_WARNING, "WelsReorderRefList()-1::::BASE LAYER::::iSpsId:%d, ref_sps_id:%d\n", - pSliceHeader->iSpsId, ppRefList[i]->iSpsId); -+ return ERR_NONE; - pCtx->iErrorCode = dsNoParamSets; //cross-IDR reference frame selection, SHOULD request IDR.-- - return ERR_INFO_REFERENCE_PIC_LOST; - } else { - -commit a1f3b95ad18d0788c2c803fac80e78d6365673ce -Author: Simon Morlat -Date: Tue Apr 15 17:54:58 2014 +0200 - - permissive mode (2) - -diff --git a/codec/decoder/core/src/decoder_core.cpp b/codec/decoder/core/src/decoder_core.cpp -index a14e971..e742dbf 100644 ---- a/codec/decoder/core/src/decoder_core.cpp -+++ b/codec/decoder/core/src/decoder_core.cpp -@@ -1738,8 +1738,8 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, int3 - if ((iLastIdD < 0) || //case 1: first layer - (iLastIdD == iCurrIdD)) { //case 2: same uiDId - InitDqLayerInfo (dq_cur, &pLayerInfo, pNalCur, pCtx->pDec); -- -- if (!dq_cur->sLayerInfo.pSps->bGapsInFrameNumValueAllowedFlag) { -+ if (0){ -+ //if (!dq_cur->sLayerInfo.pSps->bGapsInFrameNumValueAllowedFlag) { - const bool kbIdrFlag = dq_cur->sLayerInfo.sNalHeaderExt.bIdrFlag - || (dq_cur->sLayerInfo.sNalHeaderExt.sNalUnitHeader.eNalUnitType == NAL_UNIT_CODED_SLICE_IDR); - // Subclause 8.2.5.2 Decoding process for gaps in frame_num diff --git a/patches/x264_log2f_fix.patch b/patches/x264_log2f_fix.patch deleted file mode 100644 index e5d0647a0..000000000 --- a/patches/x264_log2f_fix.patch +++ /dev/null @@ -1,41 +0,0 @@ -diff -urN submodules/externals/x264/common/osdep.h.orig submodules/externals/x264/common/osdep.h ---- submodules/externals/x264/common/osdep.h.orig 2014-02-06 13:56:59.243663951 +0100 -+++ submodules/externals/x264/common/osdep.h 2014-02-06 13:57:17.215685078 +0100 -@@ -35,11 +35,6 @@ - - #include "config.h" - --#if !HAVE_LOG2F --#define log2f(x) (logf(x)/0.693147180559945f) --#define log2(x) (log(x)/0.693147180559945) --#endif -- - #ifdef _WIN32 - #include // _setmode() - #include // _O_BINARY -@@ -55,6 +60,11 @@ - #include - #endif - -+#if !HAVE_LOG2F -+#define log2f(x) (logf(x)/0.693147180559945f) -+#define log2(x) (log(x)/0.693147180559945) -+#endif -+ - #if (defined(__GNUC__) || defined(__INTEL_COMPILER)) && (ARCH_X86 || ARCH_X86_64) - #define HAVE_X86_INLINE_ASM 1 - #endif -diff -urN submodules/externals/x264/configure.orig submodules/externals/x264/configure ---- submodules/externals/x264/configure.orig 2014-02-06 13:56:59.231663937 +0100 -+++ submodules/externals/x264/configure 2014-02-06 13:57:17.219685083 +0100 -@@ -816,10 +816,6 @@ - fi - [ "$thread" != "no" ] && define HAVE_THREAD - --if cc_check "math.h" "-Werror" "return log2f(2);" ; then -- define HAVE_LOG2F --fi -- - if [ "$vis" = "yes" ] ; then - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -I/usr/X11R6/include" diff --git a/prepare.py b/prepare.py index a16d7c6b9..7898dcb7e 100755 --- a/prepare.py +++ b/prepare.py @@ -250,6 +250,7 @@ java-clean: copy-libs: +\trm -rf liblinphone-sdk/res \trm -rf libs-debug/armeabi \trm -rf libs/armeabi \tif test -d "liblinphone-sdk/android-arm"; then \\ @@ -267,6 +268,10 @@ copy-libs: \t\tcp -f liblinphone-sdk/android-arm/bin/gdbserver libs/armeabi && \\ \t\tcp -f liblinphone-sdk/android-arm/bin/gdb.setup libs/armeabi; \\ \tfi +\tif test -f "liblinphone-sdk/android-arm/lib/wrap.sh"; then \\ +\t\tmkdir -p liblinphone-sdk/res/lib/armeabi && \\ +\t\tcp -f liblinphone-sdk/android-arm/lib/wrap.sh liblinphone-sdk/res/lib/armeabi; \\ +\tfi \trm -rf libs-debug/armeabi-v7a \trm -rf libs/armeabi-v7a \tif test -d "liblinphone-sdk/android-armv7"; then \\ @@ -284,6 +289,10 @@ copy-libs: \t\tcp -f liblinphone-sdk/android-armv7/bin/gdbserver libs/armeabi-v7a && \\ \t\tcp -f liblinphone-sdk/android-armv7/bin/gdb.setup libs/armeabi-v7a; \\ \tfi +\tif test -f "liblinphone-sdk/android-armv7/lib/wrap.sh"; then \\ +\t\tmkdir -p liblinphone-sdk/res/lib/armeabi-v7a && \\ +\t\tcp -f liblinphone-sdk/android-armv7/lib/wrap.sh liblinphone-sdk/res/lib/armeabi-v7a; \\ +\tfi \trm -rf libs-debug/arm64-v8a \trm -rf libs/arm64-v8a \tif test -d "liblinphone-sdk/android-arm64"; then \\ @@ -301,6 +310,10 @@ copy-libs: \t\tcp -f liblinphone-sdk/android-arm64/bin/gdbserver libs/arm64-v8a && \\ \t\tcp -f liblinphone-sdk/android-arm64/bin/gdb.setup libs/arm64-v8a; \\ \tfi +\tif test -f "liblinphone-sdk/android-arm64/lib/wrap.sh"; then \\ +\t\tmkdir -p liblinphone-sdk/res/lib/arm64-v8a && \\ +\t\tcp -f liblinphone-sdk/android-arm64/lib/wrap.sh liblinphone-sdk/res/lib/arm64-v8a; \\ +\tfi \trm -rf libs-debug/x86 \trm -rf libs/x86 \tif test -d "liblinphone-sdk/android-x86"; then \\ @@ -318,6 +331,10 @@ copy-libs: \t\tcp -f liblinphone-sdk/android-x86/bin/gdbserver libs/x86 && \\ \t\tcp -f liblinphone-sdk/android-x86/bin/gdb.setup libs/x86; \\ \tfi +\tif test -f "liblinphone-sdk/android-x86/lib/wrap.sh"; then \\ +\t\tmkdir -p liblinphone-sdk/res/lib/x86 && \\ +\t\tcp -f liblinphone-sdk/android-x86/lib/wrap.sh liblinphone-sdk/res/lib/x86; \\ +\tfi copy-libs-mediastreamer: \trm -rf submodules/mediastreamer2/java/libs/armeabi @@ -362,7 +379,9 @@ release: java-clean build copy-libs unsigned: java-clean build copy-libs \t./gradlew assemblePackaged -generate-sdk: liblinphone-android-sdk +generate-release-sdk: liblinphone-android-sdk-release + +generate-sdk: liblinphone-android-sdk-debug generate-javadoc: \t./gradlew -q androidJavadocsJar @@ -374,12 +393,18 @@ debug-sdk: java-clean build copy-libs generate-javadoc generate-apk liblinphone-android-sdk: java-clean build copy-libs generate-javadoc release \t./gradlew -q sdkZip -linphone-android-sdk: java-clean build copy-libs +linphone-android-sdk: java-clean build copy-libs \t./gradlew -b linphoneAndroidSdk.gradle androidJavadocsJar \t./gradlew -b linphoneAndroidSdk.gradle sourcesJar + +linphone-android-sdk-release: linphone-android-sdk \t./gradlew -b linphoneAndroidSdk.gradle assembleRelease \t./gradlew -b linphoneAndroidSdk.gradle sdkZip +linphone-android-sdk-debug: linphone-android-sdk +\t./gradlew -b linphoneAndroidSdk.gradle debugRelease +\t./gradlew -b linphoneAndroidSdk.gradle sdkZip + mediastreamer2-sdk: build copy-libs-mediastreamer \t@cd $(TOPDIR)/submodules/mediastreamer2/java && \\ \t./gradlew -b mediastreamerSdk.gradle assembleRelease diff --git a/res/layout/chat.xml b/res/layout/chat.xml index bc66da93e..23a82e9a7 100644 --- a/res/layout/chat.xml +++ b/res/layout/chat.xml @@ -179,13 +179,13 @@ android:choiceMode="multipleChoice" android:stackFromBottom="true" android:transcriptMode="normal" - android:dividerHeight="10dp" android:cacheColorHint="@color/transparent" - android:listSelector="@color/transparent" + android:listSelector="@color/transparent" android:layout_above="@id/remote_composing" android:layout_width="match_parent" android:layout_height="match_parent" - android:layout_margin="10dp" + android:layout_marginRight="10dp" + android:layout_marginLeft="10dp" android:layout_below="@+id/top"/> diff --git a/res/layout/chat_bubble.xml b/res/layout/chat_bubble.xml index 1933f372a..a2a6dd2d7 100644 --- a/res/layout/chat_bubble.xml +++ b/res/layout/chat_bubble.xml @@ -19,6 +19,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_toLeftOf="@id/delete_message" + android:layout_marginTop="5dp" + android:layout_marginBottom="5dp" android:gravity="center_vertical"> + + OK Yes Link your account + An update is available the libre SIP client diff --git a/src/android/org/linphone/LinphoneManager.java b/src/android/org/linphone/LinphoneManager.java index 3a2307f0e..ca3243775 100644 --- a/src/android/org/linphone/LinphoneManager.java +++ b/src/android/org/linphone/LinphoneManager.java @@ -1,26 +1,8 @@ -/* -LinphoneManager.java -Copyright (C) 2010 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; /* LinphoneManager.java -Copyright (C) 2017 Belledonne Communications, Grenoble, France +Copyright (C) 2018 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 @@ -45,6 +27,7 @@ import android.app.ProgressDialog; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager.NameNotFoundException; @@ -709,6 +692,9 @@ public class LinphoneManager implements CoreListener, SensorEventListener, Accou String versionName = mServiceContext.getPackageManager().getPackageInfo(mServiceContext.getPackageName(), 0).versionName; if (versionName == null) { versionName = String.valueOf(mServiceContext.getPackageManager().getPackageInfo(mServiceContext.getPackageName(), 0).versionCode); + } else { + //Api to check version can't use version code + mLc.checkForUpdate(versionName); } mLc.setUserAgent("LinphoneAndroid", versionName); } catch (NameNotFoundException e) { @@ -1641,7 +1627,29 @@ public class LinphoneManager implements CoreListener, SensorEventListener, Accou @Override public void onVersionUpdateCheckResultReceived(Core lc, VersionUpdateCheckResult result, String version, String url) { - + if (result == VersionUpdateCheckResult.NewVersionAvailable) { + final String urlToUse = url; + final String versionAv = version; + mHandler.postDelayed(new Runnable() { + @Override + public void run() { + AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); + builder.setMessage(getString(R.string.update_available) + ": " + versionAv); + builder.setCancelable(false); + builder.setNeutralButton(getString(R.string.ok), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + if (urlToUse != null) { + Intent urlIntent = new Intent(Intent.ACTION_VIEW); + urlIntent.setData(Uri.parse(urlToUse)); + getContext().startActivity(urlIntent); + } + } + }); + builder.show(); + } + }, 1000); + } } @Override diff --git a/src/android/org/linphone/LinphonePreferences.java b/src/android/org/linphone/LinphonePreferences.java index dc3d573f4..fe59e44b5 100644 --- a/src/android/org/linphone/LinphonePreferences.java +++ b/src/android/org/linphone/LinphonePreferences.java @@ -152,6 +152,7 @@ public class LinphonePreferences { // Accounts settings private ProxyConfig getProxyConfig(int n) { + if (getLc() == null) return null; ProxyConfig[] prxCfgs = getLc().getProxyConfigList(); if (n < 0 || n >= prxCfgs.length) return null; @@ -171,6 +172,7 @@ public class LinphonePreferences { * Useful to edit a authInfo (you should call saveAuthInfo after the modifications to save them). */ private AuthInfo getClonedAuthInfo(int n) { + if (getLc() == null) return null; AuthInfo authInfo = getAuthInfo(n); if (authInfo == null) return null; @@ -185,6 +187,7 @@ public class LinphonePreferences { * Useful to save the changes made to a cloned authInfo. */ private void saveAuthInfo(AuthInfo authInfo) { + if (getLc() == null) return; getLc().addAuthInfo(authInfo); } @@ -339,8 +342,12 @@ public class LinphonePreferences { proxy = tempProxy; } } + Address proxyAddr = Factory.instance().createAddress(proxy); Address identityAddr = Factory.instance().createAddress(identity); + if (proxyAddr == null || identityAddr == null) { + throw new CoreException("Proxy or Identity address is null !"); + } if (tempDisplayName != null) { identityAddr.setDisplayName(tempDisplayName); @@ -539,6 +546,7 @@ public class LinphonePreferences { } private void setAccountPassword(int n, String password, String ha1) { + if (getLc() == null) return; String user = getAccountUsername(n); String domain = getAccountDomain(n); String userid = null; @@ -632,6 +640,8 @@ public class LinphonePreferences { } Address proxyAddr = Factory.instance().createAddress(proxy); + if (proxyAddr == null) return; + if (!proxy.contains("transport=")) { proxyAddr.setTransport(getAccountTransport(n)); } @@ -758,6 +768,7 @@ public class LinphonePreferences { } public void setDefaultAccount(int accountIndex) { + if (getLc() == null) return; ProxyConfig[] prxCfgs = getLc().getProxyConfigList(); if (accountIndex >= 0 && accountIndex < prxCfgs.length) getLc().setDefaultProxyConfig(prxCfgs[accountIndex]); @@ -787,6 +798,7 @@ public class LinphonePreferences { } public void setAccountEnabled(int n, boolean enabled) { + if (getLc() == null) return; ProxyConfig prxCfg = getProxyConfig(n); if (prxCfg == null) { LinphoneUtils.displayErrorAlert(getString(R.string.error), mContext); @@ -815,6 +827,7 @@ public class LinphonePreferences { } public void resetDefaultProxyConfig(){ + if (getLc() == null) return; int count = getLc().getProxyConfigList().length; for (int i = 0; i < count; i++) { if (isAccountEnabled(i)) { @@ -829,6 +842,7 @@ public class LinphonePreferences { } public void deleteAccount(int n) { + if (getLc() == null) return; ProxyConfig proxyCfg = getProxyConfig(n); if (proxyCfg != null) getLc().removeProxyConfig(proxyCfg); @@ -849,10 +863,12 @@ public class LinphonePreferences { // Audio settings public void setEchoCancellation(boolean enable) { + if (getLc() == null) return; getLc().enableEchoCancellation(enable); } public boolean echoCancellationEnabled() { + if (getLc() == null) return false; return getLc().echoCancellationEnabled(); } @@ -879,42 +895,50 @@ public class LinphonePreferences { } public boolean isVideoEnabled() { + if (getLc() == null) return false; return getLc().videoSupported() && getLc().videoEnabled(); } public void enableVideo(boolean enable) { + if (getLc() == null) return; getLc().enableVideoCapture(enable); getLc().enableVideoDisplay(enable); } public boolean shouldInitiateVideoCall() { + if (getLc() == null) return false; return getLc().getVideoActivationPolicy().getAutomaticallyInitiate(); } public void setInitiateVideoCall(boolean initiate) { + if (getLc() == null) return; VideoActivationPolicy vap = getLc().getVideoActivationPolicy(); vap.setAutomaticallyInitiate(initiate); getLc().setVideoActivationPolicy(vap); } public boolean shouldAutomaticallyAcceptVideoRequests() { + if (getLc() == null) return false; VideoActivationPolicy vap = getLc().getVideoActivationPolicy(); return vap.getAutomaticallyAccept(); } public void setAutomaticallyAcceptVideoRequests(boolean accept) { + if (getLc() == null) return; VideoActivationPolicy vap = getLc().getVideoActivationPolicy(); vap.setAutomaticallyAccept(accept); getLc().setVideoActivationPolicy(vap); } public String getVideoPreset() { + if (getLc() == null) return null; String preset = getLc().getVideoPreset(); if (preset == null) preset = "default"; return preset; } public void setVideoPreset(String preset) { + if (getLc() == null) return; if (preset.equals("default")) preset = null; getLc().setVideoPreset(preset); preset = getVideoPreset(); @@ -930,22 +954,27 @@ public class LinphonePreferences { } public void setPreferredVideoSize(String preferredVideoSize) { + if (getLc() == null) return; getLc().setPreferredVideoSizeByName(preferredVideoSize); } public int getPreferredVideoFps() { + if (getLc() == null) return 0; return (int)getLc().getPreferredFramerate(); } public void setPreferredVideoFps(int fps) { + if (getLc() == null) return; getLc().setPreferredFramerate(fps); } public int getBandwidthLimit() { + if (getLc() == null) return 0; return getLc().getDownloadBandwidth(); } public void setBandwidthLimit(int bandwidth) { + if (getLc() == null) return; getLc().setUploadBandwidth(bandwidth); getLc().setDownloadBandwidth(bandwidth); } @@ -953,34 +982,42 @@ public class LinphonePreferences { // Call settings public boolean useRfc2833Dtmfs() { + if (getLc() == null) return false; return getLc().getUseRfc2833ForDtmf(); } public void sendDtmfsAsRfc2833(boolean use) { + if (getLc() == null) return; getLc().setUseRfc2833ForDtmf(use); } public boolean useSipInfoDtmfs() { + if (getLc() == null) return false; return getLc().getUseInfoForDtmf(); } public void sendDTMFsAsSipInfo(boolean use) { + if (getLc() == null) return; getLc().setUseInfoForDtmf(use); } public int getIncTimeout() { + if (getLc() == null) return 0; return getLc().getIncTimeout(); } public void setIncTimeout(int timeout) { + if (getLc() == null) return; getLc().setIncTimeout(timeout); } public int getInCallTimeout() { + if (getLc() == null) return 0; return getLc().getInCallTimeout(); } public void setInCallTimeout(int timeout) { + if (getLc() == null) return; getLc().setInCallTimeout(timeout); } @@ -1030,6 +1067,7 @@ public class LinphonePreferences { } public String getSipPort() { + if (getLc() == null) return null; Transports transports = getLc().getTransports(); int port; if (transports.getUdpPort() > 0) @@ -1040,6 +1078,7 @@ public class LinphonePreferences { } public void setSipPort(int port) { + if (getLc() == null) return; Transports transports = getLc().getTransports(); transports.setUdpPort(port); transports.setTcpPort(port); @@ -1048,6 +1087,7 @@ public class LinphonePreferences { } private NatPolicy getOrCreateNatPolicy() { + if (getLc() == null) return null; NatPolicy nat = getLc().getNatPolicy(); if (nat == null) { nat = getLc().createNatPolicy(); @@ -1061,6 +1101,7 @@ public class LinphonePreferences { } public void setStunServer(String stun) { + if (getLc() == null) return; NatPolicy nat = getOrCreateNatPolicy(); nat.setStunServer(stun); @@ -1070,6 +1111,7 @@ public class LinphonePreferences { } public void setIceEnabled(boolean enabled) { + if (getLc() == null) return; NatPolicy nat = getOrCreateNatPolicy(); nat.enableIce(enabled); nat.enableStun(enabled); @@ -1077,12 +1119,14 @@ public class LinphonePreferences { } public void setTurnEnabled(boolean enabled) { + if (getLc() == null) return; NatPolicy nat = getOrCreateNatPolicy(); nat.enableTurn(enabled); getLc().setNatPolicy(nat); } public void setUpnpEnabled(boolean enabled) { + if (getLc() == null) return; NatPolicy nat = getOrCreateNatPolicy(); nat.enableUpnp(enabled); getLc().setNatPolicy(nat); @@ -1109,6 +1153,7 @@ public class LinphonePreferences { } public void setTurnUsername(String username) { + if (getLc() == null) return; NatPolicy nat = getOrCreateNatPolicy(); AuthInfo authInfo = getLc().findAuthInfo(null, nat.getStunServerUsername(), null); @@ -1127,6 +1172,7 @@ public class LinphonePreferences { } public void setTurnPassword(String password) { + if (getLc() == null) return; NatPolicy nat = getOrCreateNatPolicy(); AuthInfo authInfo = getLc().findAuthInfo(null, nat.getStunServerUsername(), null); @@ -1142,10 +1188,12 @@ public class LinphonePreferences { } public MediaEncryption getMediaEncryption() { + if (getLc() == null) return null; return getLc().getMediaEncryption(); } public void setMediaEncryption(MediaEncryption menc) { + if (getLc() == null) return; if (menc == null) return; @@ -1166,6 +1214,7 @@ public class LinphonePreferences { String appId = getString(R.string.push_sender_id); if (regId != null && lc.getProxyConfigList().length > 0) { for (ProxyConfig lpc : lc.getProxyConfigList()) { + if (lpc == null) continue; if (!lpc.isPushNotificationAllowed()) { lpc.edit(); lpc.setContactUriParameters(null); @@ -1215,10 +1264,12 @@ public class LinphonePreferences { } public void useIpv6(Boolean enable) { + if (getLc() == null) return; getLc().enableIpv6(enable); } public boolean isUsingIpv6() { + if (getLc() == null) return false; return getLc().ipv6Enabled(); } // End of network settings @@ -1259,14 +1310,17 @@ public class LinphonePreferences { } public String getSharingPictureServerUrl() { + if (getLc() == null) return null; return getLc().getFileTransferServer(); } public void setSharingPictureServerUrl(String url) { + if (getLc() == null) return; getLc().setFileTransferServer(url); } public void setRemoteProvisioningUrl(String url) { + if (getLc() == null) return; if (url != null && url.length() == 0) { url = null; } @@ -1274,26 +1328,31 @@ public class LinphonePreferences { } public String getRemoteProvisioningUrl() { + if (getLc() == null) return null; return getLc().getProvisioningUri(); } public void setDefaultDisplayName(String displayName) { + if (getLc() == null) return; Address primary = getLc().getPrimaryContactParsed(); primary.setDisplayName(displayName); getLc().setPrimaryContact(primary.asString()); } public String getDefaultDisplayName() { + if (getLc() == null) return null; return getLc().getPrimaryContactParsed().getDisplayName(); } public void setDefaultUsername(String username) { + if (getLc() == null) return; Address primary = getLc().getPrimaryContactParsed(); primary.setUsername(username); getLc().setPrimaryContact(primary.asString()); } public String getDefaultUsername() { + if (getLc() == null) return null; return getLc().getPrimaryContactParsed().getUsername(); } // End of advanced settings @@ -1302,6 +1361,7 @@ public class LinphonePreferences { private TunnelConfig tunnelConfig = null; public TunnelConfig getTunnelConfig() { + if (getLc() == null) return null; if(getLc().tunnelAvailable()) { Tunnel tunnel = getLc().getTunnel(); if (tunnelConfig == null) { @@ -1384,10 +1444,12 @@ public class LinphonePreferences { } public boolean adaptiveRateControlEnabled() { + if (getLc() == null) return false; return getLc().adaptiveRateControlEnabled(); } public void enableAdaptiveRateControl(boolean enabled) { + if (getLc() == null) return; getLc().enableAdaptiveRateControl(enabled); } @@ -1501,10 +1563,12 @@ public class LinphonePreferences { } public LimeState limeEnabled() { + if (getLc() == null) return LimeState.Disabled; return getLc().limeEnabled(); } public void enableLime(LimeState lime) { + if (getLc() == null) return; getLc().enableLime(lime); } diff --git a/src/android/org/linphone/LinphoneService.java b/src/android/org/linphone/LinphoneService.java index 3f0a4bdaa..fc5bf8f5f 100644 --- a/src/android/org/linphone/LinphoneService.java +++ b/src/android/org/linphone/LinphoneService.java @@ -310,59 +310,13 @@ public final class LinphoneService extends Service { stopForegroundCompat(NOTIF_ID); } - @SuppressWarnings("unchecked") @Override - public void onCreate() { - super.onCreate(); - mLastNotificationId = 8; // To not interfere with other notifs ids - mChatNotifMap = new HashMap(); - - setupActivityMonitor(); - // In case restart after a crash. Main in LinphoneActivity - mNotificationTitle = getString(R.string.service_name); - - // Needed in order for the two next calls to succeed, libraries must have been loaded first - LinphonePreferences.instance().setContext(getBaseContext()); - Factory.instance().setLogCollectionPath(getFilesDir().getAbsolutePath()); - boolean isDebugEnabled = LinphonePreferences.instance().isDebugEnabled(); - LinphoneUtils.initLoggingService(isDebugEnabled, getString(R.string.app_name)); - - // Dump some debugging information to the logs - Log.i(START_LINPHONE_LOGS); - dumpDeviceInformation(); - dumpInstalledLinphoneInformation(); - - //Disable service notification for Android O - if ((Version.sdkAboveOrEqual(Version.API26_O_80))) { - LinphonePreferences.instance().setServiceNotificationVisibility(false); - mDisableRegistrationStatus = true; - } - - mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); - mNM.cancel(INCALL_NOTIF_ID); // in case of crash the icon is not removed - Compatibility.CreateChannel(this); - - Intent notifIntent = new Intent(this, incomingReceivedActivity); - notifIntent.putExtra("Notification", true); - mNotifContentIntent = PendingIntent.getActivity(this, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT); - - Bitmap bm = null; - try { - bm = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher); - } catch (Exception e) { - } - mNotif = Compatibility.createNotification(this, mNotificationTitle, "", R.drawable.linphone_notification_icon, R.mipmap.ic_launcher, bm, mNotifContentIntent, true,notifcationsPriority); + public int onStartCommand(Intent intent, int flags, int startId) { + super.onStartCommand(intent, flags, startId); LinphoneManager.createAndStart(LinphoneService.this); instance = this; // instance is ready once linphone manager has been created - incomingReceivedActivityName = LinphonePreferences.instance().getActivityToLaunchOnIncomingReceived(); - try { - incomingReceivedActivity = (Class) Class.forName(incomingReceivedActivityName); - } catch (ClassNotFoundException e) { - Log.e(e); - } - LinphoneManager.getLc().addListener(mListener = new CoreListenerStub() { @Override public void onCallStateChanged(Core lc, Call call, Call.State state, String message) { @@ -451,12 +405,8 @@ public final class LinphoneService extends Service { } }); - - try { - mStartForeground = getClass().getMethod("startForeground", mStartFgSign); - mStopForeground = getClass().getMethod("stopForeground", mStopFgSign); - } catch (NoSuchMethodException e) { - Log.e(e, "Couldn't find startForeground or stopForeground"); + if (displayServiceNotification() || (Version.sdkAboveOrEqual(Version.API26_O_80) && intent.getBooleanExtra("ForceStartForeground", false))) { + startForegroundCompat(NOTIF_ID, mNotif); } if (!Version.sdkAboveOrEqual(Version.API26_O_80) @@ -464,10 +414,6 @@ public final class LinphoneService extends Service { getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true, ContactsManager.getInstance()); } - if (displayServiceNotification()) { - startForegroundCompat(NOTIF_ID, mNotif); - } - if (!mTestDelayElapsed) { // Only used when testing. Simulates a 5 seconds delay for launching service mHandler.postDelayed(new Runnable() { @@ -478,11 +424,71 @@ public final class LinphoneService extends Service { } //make sure the application will at least wakes up every 10 mn - Intent intent = new Intent(this, KeepAliveReceiver.class); - PendingIntent keepAlivePendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_ONE_SHOT); + Intent keepAliveIntent = new Intent(this, KeepAliveReceiver.class); + PendingIntent keepAlivePendingIntent = PendingIntent.getBroadcast(this, 0, keepAliveIntent, PendingIntent.FLAG_ONE_SHOT); AlarmManager alarmManager = ((AlarmManager) this.getSystemService(Context.ALARM_SERVICE)); Compatibility.scheduleAlarm(alarmManager, AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 600000, keepAlivePendingIntent); + return START_STICKY; + } + + @SuppressWarnings("unchecked") + @Override + public void onCreate() { + super.onCreate(); + mLastNotificationId = 8; // To not interfere with other notifs ids + mChatNotifMap = new HashMap(); + + setupActivityMonitor(); + // In case restart after a crash. Main in LinphoneActivity + mNotificationTitle = getString(R.string.service_name); + + // Needed in order for the two next calls to succeed, libraries must have been loaded first + LinphonePreferences.instance().setContext(getBaseContext()); + Factory.instance().setLogCollectionPath(getFilesDir().getAbsolutePath()); + boolean isDebugEnabled = LinphonePreferences.instance().isDebugEnabled(); + LinphoneUtils.initLoggingService(isDebugEnabled, getString(R.string.app_name)); + + // Dump some debugging information to the logs + Log.i(START_LINPHONE_LOGS); + dumpDeviceInformation(); + dumpInstalledLinphoneInformation(); + + //Disable service notification for Android O + if ((Version.sdkAboveOrEqual(Version.API26_O_80))) { + LinphonePreferences.instance().setServiceNotificationVisibility(false); + mDisableRegistrationStatus = true; + } + + mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); + mNM.cancel(INCALL_NOTIF_ID); // in case of crash the icon is not removed + Compatibility.CreateChannel(this); + + Intent notifIntent = new Intent(this, incomingReceivedActivity); + notifIntent.putExtra("Notification", true); + mNotifContentIntent = PendingIntent.getActivity(this, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT); + + Bitmap bm = null; + try { + bm = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher); + } catch (Exception e) { + } + mNotif = Compatibility.createNotification(this, mNotificationTitle, "", R.drawable.linphone_notification_icon, R.mipmap.ic_launcher, bm, mNotifContentIntent, true,notifcationsPriority); + + incomingReceivedActivityName = LinphonePreferences.instance().getActivityToLaunchOnIncomingReceived(); + try { + incomingReceivedActivity = (Class) Class.forName(incomingReceivedActivityName); + } catch (ClassNotFoundException e) { + Log.e(e); + } + + try { + mStartForeground = getClass().getMethod("startForeground", mStartFgSign); + mStopForeground = getClass().getMethod("stopForeground", mStopFgSign); + } catch (NoSuchMethodException e) { + Log.e(e, "Couldn't find startForeground or stopForeground"); + } + mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE); } diff --git a/src/android/org/linphone/LinphoneUtils.java b/src/android/org/linphone/LinphoneUtils.java index badb3532e..ab6057a1e 100644 --- a/src/android/org/linphone/LinphoneUtils.java +++ b/src/android/org/linphone/LinphoneUtils.java @@ -843,6 +843,8 @@ public final class LinphoneUtils { } public static Spanned getTextWithHttpLinks(String text) { + if (text == null) return null; + if (text.contains("<")) { text = text.replace("<", "<"); } diff --git a/src/android/org/linphone/activities/LinphoneActivity.java b/src/android/org/linphone/activities/LinphoneActivity.java index 9ae6da739..136e1c55d 100644 --- a/src/android/org/linphone/activities/LinphoneActivity.java +++ b/src/android/org/linphone/activities/LinphoneActivity.java @@ -279,8 +279,11 @@ public class LinphoneActivity extends LinphoneGenericActivity implements OnClick } }; - int missedCalls = (LinphoneManager.isInstanciated()) ? LinphoneManager.getLc().getMissedCallsCount() : 0; - displayMissedCalls(missedCalls); + Core lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); + if (lc != null) { + int missedCalls = lc.getMissedCallsCount(); + displayMissedCalls(missedCalls); + } int rotation = getWindowManager().getDefaultDisplay().getRotation(); switch (rotation) { diff --git a/src/android/org/linphone/call/CallActivity.java b/src/android/org/linphone/call/CallActivity.java index e97a50ef5..fb8f2d218 100644 --- a/src/android/org/linphone/call/CallActivity.java +++ b/src/android/org/linphone/call/CallActivity.java @@ -521,7 +521,10 @@ public class CallActivity extends LinphoneGenericActivity implements OnClickList } }); - initCallStatsRefresher(LinphoneManager.getLc().getCurrentCall(), findViewById(R.id.incall_stats)); + Core lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); + if (lc != null) { + initCallStatsRefresher(lc.getCurrentCall(), findViewById(R.id.incall_stats)); + } } private void refreshIncallUi(){ diff --git a/src/android/org/linphone/chat/ChatBubbleViewHolder.java b/src/android/org/linphone/chat/ChatBubbleViewHolder.java index 0977a0a3a..e350e9599 100644 --- a/src/android/org/linphone/chat/ChatBubbleViewHolder.java +++ b/src/android/org/linphone/chat/ChatBubbleViewHolder.java @@ -38,6 +38,7 @@ public class ChatBubbleViewHolder { public TextView eventMessage; public RelativeLayout bubbleLayout; + public LinearLayout separatorLayout; public LinearLayout background; public ImageView contactPicture; public ImageView contactPictureMask; @@ -67,6 +68,7 @@ public class ChatBubbleViewHolder { eventMessage = view.findViewById(R.id.event_text); bubbleLayout = view.findViewById(R.id.bubble); + separatorLayout = view.findViewById(R.id.separator); background = view.findViewById(R.id.background); contactPicture = view.findViewById(R.id.contact_picture); contactPictureMask = view.findViewById(R.id.mask); diff --git a/src/android/org/linphone/chat/ChatEventsAdapter.java b/src/android/org/linphone/chat/ChatEventsAdapter.java index 509d9b246..d9f2f4ca6 100644 --- a/src/android/org/linphone/chat/ChatEventsAdapter.java +++ b/src/android/org/linphone/chat/ChatEventsAdapter.java @@ -56,6 +56,7 @@ import org.linphone.core.Address; import org.linphone.core.ChatMessage; import org.linphone.core.ChatMessageListenerStub; import org.linphone.core.Content; +import org.linphone.core.Event; import org.linphone.core.EventLog; import org.linphone.core.LimeState; import org.linphone.mediastream.Log; @@ -73,6 +74,9 @@ import java.util.List; import static android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION; public class ChatEventsAdapter extends ListSelectionAdapter { + private static int MARGIN_BETWEEN_MESSAGES = 10; + private static int SIDE_MARGIN = 100; + private Context mContext; private List mHistory; private List mParticipants; @@ -177,6 +181,7 @@ public class ChatEventsAdapter extends ListSelectionAdapter { holder.eventLayout.setVisibility(View.GONE); holder.bubbleLayout.setVisibility(View.GONE); + holder.separatorLayout.setVisibility(i == 0 ? View.GONE : View.VISIBLE); // Hide separator if first item in list holder.delete.setVisibility(isEditionEnabled() ? View.VISIBLE : View.GONE); holder.messageText.setVisibility(View.GONE); holder.messageImage.setVisibility(View.GONE); @@ -200,8 +205,21 @@ public class ChatEventsAdapter extends ListSelectionAdapter { EventLog event = (EventLog)getItem(i); if (event.getType() == EventLog.Type.ConferenceChatMessage) { holder.bubbleLayout.setVisibility(View.VISIBLE); - final ChatMessage message = event.getChatMessage(); + + if (i > 0) { + EventLog previousEvent = (EventLog)getItem(i-1); + if (previousEvent.getType() == EventLog.Type.ConferenceChatMessage) { + ChatMessage previousMessage = previousEvent.getChatMessage(); + if (previousMessage.getFromAddress().weakEqual(message.getFromAddress())) { + holder.separatorLayout.setVisibility(View.GONE); + } + } else { + // No separator if previous event is not a message + holder.separatorLayout.setVisibility(View.GONE); + } + } + holder.messageId = message.getMessageId(); message.setUserData(holder); @@ -253,10 +271,10 @@ public class ChatEventsAdapter extends ListSelectionAdapter { if (isEditionEnabled()) { layoutParams.addRule(RelativeLayout.LEFT_OF, holder.delete.getId()); - layoutParams.setMargins(100, 10, 10, 10); + layoutParams.setMargins(SIDE_MARGIN, MARGIN_BETWEEN_MESSAGES/2, 0, MARGIN_BETWEEN_MESSAGES/2); } else { layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); - layoutParams.setMargins(100, 10, 10, 10); + layoutParams.setMargins(SIDE_MARGIN, MARGIN_BETWEEN_MESSAGES/2, 0, MARGIN_BETWEEN_MESSAGES/2); } holder.background.setBackgroundResource(R.drawable.resizable_chat_bubble_outgoing); @@ -274,10 +292,10 @@ public class ChatEventsAdapter extends ListSelectionAdapter { if (isEditionEnabled()) { layoutParams.addRule(RelativeLayout.LEFT_OF, holder.delete.getId()); - layoutParams.setMargins(100, 10, 10, 10); + layoutParams.setMargins(SIDE_MARGIN, MARGIN_BETWEEN_MESSAGES/2, 0, MARGIN_BETWEEN_MESSAGES/2); } else { layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT); - layoutParams.setMargins(10, 10, 100, 10); + layoutParams.setMargins(0, MARGIN_BETWEEN_MESSAGES/2, SIDE_MARGIN, MARGIN_BETWEEN_MESSAGES/2); } holder.background.setBackgroundResource(R.drawable.resizable_chat_bubble_incoming); diff --git a/src/android/org/linphone/chat/GroupChatFragment.java b/src/android/org/linphone/chat/GroupChatFragment.java index b7b42af43..564da2880 100644 --- a/src/android/org/linphone/chat/GroupChatFragment.java +++ b/src/android/org/linphone/chat/GroupChatFragment.java @@ -278,7 +278,7 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con removeVirtualKeyboardVisiblityListener(); LinphoneManager.getInstance().setCurrentChatRoomAddress(null); if (mChatRoom != null) mChatRoom.removeListener(this); - mEventsAdapter.clear(); + if (mEventsAdapter != null) mEventsAdapter.clear(); super.onPause(); } @@ -387,28 +387,29 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con ChatMessage message = event.getChatMessage(); String messageId = message.getMessageId(); - switch(item.getItemId()) { - case R.id.resend: - mEventsAdapter.removeItem(info.position); - message.resend(); - return true; - case R.id.imdn_infos: - LinphoneActivity.instance().goToChatMessageImdnInfos(getRemoteSipUri(), messageId); - return true; - case R.id.copy_text: - if (message.hasTextContent()) { - ClipboardManager clipboard = (ClipboardManager) getActivity().getSystemService(Context.CLIPBOARD_SERVICE); - ClipData clip = ClipData.newPlainText("Message", message.getTextContent()); - clipboard.setPrimaryClip(clip); - } - return true; - case R.id.delete_message: - mChatRoom.deleteMessage(message); - mEventsAdapter.removeItem(info.position); - return true; - default: - return super.onContextItemSelected(item); + if (item.getItemId() == R.id.resend) { + mEventsAdapter.removeItem(info.position); + message.resend(); + return true; } + if (item.getItemId() == R.id.imdn_infos) { + LinphoneActivity.instance().goToChatMessageImdnInfos(getRemoteSipUri(), messageId); + return true; + } + if (item.getItemId() == R.id.copy_text) { + if (message.hasTextContent()) { + ClipboardManager clipboard = (ClipboardManager) getActivity().getSystemService(Context.CLIPBOARD_SERVICE); + ClipData clip = ClipData.newPlainText("Message", message.getTextContent()); + clipboard.setPrimaryClip(clip); + } + return true; + } + if (item.getItemId() == R.id.delete_message) { + mChatRoom.deleteMessage(message); + mEventsAdapter.removeItem(info.position); + return true; + } + return super.onContextItemSelected(item); } /** @@ -510,7 +511,7 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con getContactsForParticipants(); - mRemoteComposing.setVisibility(View.INVISIBLE); + mRemoteComposing.setVisibility(View.GONE); } private void displayChatRoomHeader() { diff --git a/src/android/org/linphone/contacts/ContactDetailsFragment.java b/src/android/org/linphone/contacts/ContactDetailsFragment.java index d830dd381..2325435cf 100644 --- a/src/android/org/linphone/contacts/ContactDetailsFragment.java +++ b/src/android/org/linphone/contacts/ContactDetailsFragment.java @@ -75,19 +75,21 @@ public class ContactDetailsFragment extends Fragment implements OnClickListener String tag = (String)v.getTag(); Core lc = LinphoneManager.getLc(); Address participant = Factory.instance().createAddress(tag); - ChatRoom room = lc.findOneToOneChatRoom(lc.getDefaultProxyConfig().getContact(), participant); - if (room != null) { - LinphoneActivity.instance().goToChat(room.getPeerAddress().asStringUriOnly(), null); - } else { - ProxyConfig lpc = lc.getDefaultProxyConfig(); - if (lpc != null && lpc.getConferenceFactoryUri() != null && !LinphonePreferences.instance().useBasicChatRoomFor1To1()) { - mWaitLayout.setVisibility(View.VISIBLE); - mChatRoom = lc.createClientGroupChatRoom(getString(R.string.dummy_group_chat_subject), true); - mChatRoom.addListener(mChatRoomCreationListener); - mChatRoom.addParticipant(participant); - } else { - room = lc.getChatRoom(participant); + ProxyConfig defaultProxyConfig = lc.getDefaultProxyConfig(); + if (defaultProxyConfig != null) { + ChatRoom room = lc.findOneToOneChatRoom(defaultProxyConfig.getContact(), participant); + if (room != null) { LinphoneActivity.instance().goToChat(room.getPeerAddress().asStringUriOnly(), null); + } else { + if (defaultProxyConfig.getConferenceFactoryUri() != null && !LinphonePreferences.instance().useBasicChatRoomFor1To1()) { + mWaitLayout.setVisibility(View.VISIBLE); + mChatRoom = lc.createClientGroupChatRoom(getString(R.string.dummy_group_chat_subject), true); + mChatRoom.addListener(mChatRoomCreationListener); + mChatRoom.addParticipant(participant); + } else { + room = lc.getChatRoom(participant); + LinphoneActivity.instance().goToChat(room.getPeerAddress().asStringUriOnly(), null); + } } } } diff --git a/src/android/org/linphone/contacts/LinphoneContact.java b/src/android/org/linphone/contacts/LinphoneContact.java index 0c5f5399a..54b9671bf 100644 --- a/src/android/org/linphone/contacts/LinphoneContact.java +++ b/src/android/org/linphone/contacts/LinphoneContact.java @@ -414,9 +414,10 @@ public class LinphoneContact implements Serializable, Comparable 0) { + if (mAdapter != null && mAdapter.getCount() > 0) { mAdapter.enableEdition(true); mTopBar.setVisibility(View.GONE); mEditTopBar.setVisibility(View.VISIBLE); diff --git a/submodules/belle-sip b/submodules/belle-sip index 0f999ecc3..11f4c9c61 160000 --- a/submodules/belle-sip +++ b/submodules/belle-sip @@ -1 +1 @@ -Subproject commit 0f999ecc3d304923b6338d3f48d44ac8ddfd9be8 +Subproject commit 11f4c9c61feece2d46909ae62e91ac1bace64c2c diff --git a/submodules/cmake-builder b/submodules/cmake-builder index 213000a18..f58510c8c 160000 --- a/submodules/cmake-builder +++ b/submodules/cmake-builder @@ -1 +1 @@ -Subproject commit 213000a187fa7d5ed912e4c1dc05e9ae0ab8f054 +Subproject commit f58510c8ce6cd89dadff2b29574d03b05c6efcc9 diff --git a/submodules/externals/openh264 b/submodules/externals/openh264 index 9e75838c8..852d23c72 160000 --- a/submodules/externals/openh264 +++ b/submodules/externals/openh264 @@ -1 +1 @@ -Subproject commit 9e75838c8638c48a32b15c73c9da7b1fe942fd5f +Subproject commit 852d23c72acd537b75e4b95af93b866925d31bda diff --git a/submodules/linphone b/submodules/linphone index 61e38e370..852166f0a 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit 61e38e3704e1a37c9e884897ca5597158725b202 +Subproject commit 852166f0a30613f6ea26172f00fe2446b7195c99 diff --git a/submodules/mediastreamer2 b/submodules/mediastreamer2 index 1e53888bb..52d316934 160000 --- a/submodules/mediastreamer2 +++ b/submodules/mediastreamer2 @@ -1 +1 @@ -Subproject commit 1e53888bb49135c528a0bb32494bfb5ceaddb5f8 +Subproject commit 52d3169349b55b27090ecb81f88d10ebb65fa469 diff --git a/submodules/oRTP b/submodules/oRTP index 3afc47570..a88be02b9 160000 --- a/submodules/oRTP +++ b/submodules/oRTP @@ -1 +1 @@ -Subproject commit 3afc47570a1c9f34bd2f1a759ae00fb7ecd26a0e +Subproject commit a88be02b93e2274ae3fcf80e1e0032adc43c0448