From 4038a51e133759d45b1d6b22f287751393afc0d7 Mon Sep 17 00:00:00 2001 From: Erwan Croze Date: Thu, 12 Jul 2018 09:17:48 +0200 Subject: [PATCH 01/14] Update gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 5a8923c0d..358d3d4bb 100644 --- a/.gitignore +++ b/.gitignore @@ -54,3 +54,5 @@ liblinphone_tester/res/raw/ **/.classpath **/.project **/*.kdev4 +liblinphone-sdk/res/ +**/.vscode From 3aff3070e707d31ef893a7a19a29777c4f985d21 Mon Sep 17 00:00:00 2001 From: Erwan Croze Date: Thu, 12 Jul 2018 14:54:06 +0200 Subject: [PATCH 02/14] Fix prepare.py clean file after used of sanitizer --- prepare.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/prepare.py b/prepare.py index 0b954b293..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 \\ @@ -392,7 +393,7 @@ 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 From 8f28583e9bf71a221c5e2d0562fb14ade88523c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Grisez?= Date: Mon, 16 Jul 2018 18:06:02 +0200 Subject: [PATCH 03/14] Update mediastreamer2 and cmake-builder --- submodules/cmake-builder | 2 +- submodules/mediastreamer2 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/submodules/cmake-builder b/submodules/cmake-builder index 456993edd..f58510c8c 160000 --- a/submodules/cmake-builder +++ b/submodules/cmake-builder @@ -1 +1 @@ -Subproject commit 456993eddd5f4724ff2b59487fb57aa5a85d782a +Subproject commit f58510c8ce6cd89dadff2b29574d03b05c6efcc9 diff --git a/submodules/mediastreamer2 b/submodules/mediastreamer2 index 75a861960..52d316934 160000 --- a/submodules/mediastreamer2 +++ b/submodules/mediastreamer2 @@ -1 +1 @@ -Subproject commit 75a86196030bb6efd9d67d42c0b25f17b4ec4e25 +Subproject commit 52d3169349b55b27090ecb81f88d10ebb65fa469 From 7a33c85a1ff50485f3138b0affa4ea7391b70c23 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 18 Jul 2018 17:10:13 +0200 Subject: [PATCH 04/14] Added reduced space between messages from same person --- res/layout/chat.xml | 6 ++-- res/layout/chat_bubble.xml | 9 ++++++ .../linphone/chat/ChatBubbleViewHolder.java | 2 ++ .../org/linphone/chat/ChatEventsAdapter.java | 28 +++++++++++++++---- .../org/linphone/chat/GroupChatFragment.java | 2 +- 5 files changed, 38 insertions(+), 9 deletions(-) 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"> + + 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 83c29c7d4..2c822a055 100644 --- a/src/android/org/linphone/chat/GroupChatFragment.java +++ b/src/android/org/linphone/chat/GroupChatFragment.java @@ -511,7 +511,7 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con getContactsForParticipants(); - mRemoteComposing.setVisibility(View.INVISIBLE); + mRemoteComposing.setVisibility(View.GONE); } private void displayChatRoomHeader() { From 0938a88a1dd19b3a2077ece7bf60382cb9b5507b Mon Sep 17 00:00:00 2001 From: Erwan Croze Date: Thu, 19 Jul 2018 09:57:35 +0200 Subject: [PATCH 05/14] Add check for new version --- res/raw/linphonerc_factory | 3 +- res/values/strings.xml | 1 + src/android/org/linphone/LinphoneManager.java | 28 ++++++++++++++++++- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/res/raw/linphonerc_factory b/res/raw/linphonerc_factory index 92ee60ca2..24084a6d7 100644 --- a/res/raw/linphonerc_factory +++ b/res/raw/linphonerc_factory @@ -17,7 +17,7 @@ auto_answer_replacing_calls=1 ping_with_options=0 rls_uri= use_cpim=1 -linphone_specs=groupchat +linphone_specs=groupchat [rtp] audio_rtp_port=7076 @@ -42,6 +42,7 @@ history_max_size=100 enable_basic_to_client_group_chat_room_migration=0 enable_simple_group_chat_message_state=0 aggregate_imdn=1 +version_check_url_root=https://www.linphone.org/releases [app] activation_code_length=4 diff --git a/res/values/strings.xml b/res/values/strings.xml index 72e66e0ba..0796484a1 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -52,6 +52,7 @@ 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 b157eb9e6..4046e3ecb 100644 --- a/src/android/org/linphone/LinphoneManager.java +++ b/src/android/org/linphone/LinphoneManager.java @@ -27,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; @@ -691,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) { @@ -1618,7 +1622,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 From cb4b134a08fae42f8e3a145fa6b082eae5f4ce5b Mon Sep 17 00:00:00 2001 From: Erwan Croze Date: Mon, 23 Jul 2018 15:02:44 +0200 Subject: [PATCH 06/14] Disable gradle daemon --- gradle.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/gradle.properties b/gradle.properties index a1e7a7cb6..9094139ff 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,3 +5,4 @@ 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=1024m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 +org.gradle.daemon=false From a9f238035978e16077aa6b168facf80496cef8ce Mon Sep 17 00:00:00 2001 From: Erwan Croze Date: Mon, 23 Jul 2018 15:48:14 +0200 Subject: [PATCH 07/14] Revert "Disable gradle daemon" This reverts commit cb4b134a08fae42f8e3a145fa6b082eae5f4ce5b. --- gradle.properties | 1 - 1 file changed, 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 9094139ff..a1e7a7cb6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,4 +5,3 @@ 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=1024m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -org.gradle.daemon=false From 2c62a0428609ca23ee065ab6ff9b2ce83d3479f1 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 24 Jul 2018 13:30:54 +0200 Subject: [PATCH 08/14] Attempt to fix issue with startForeground for Android 8+ --- src/android/org/linphone/LinphoneService.java | 126 +++++++++--------- .../org/linphone/receivers/BootReceiver.java | 1 + 2 files changed, 67 insertions(+), 60 deletions(-) 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/receivers/BootReceiver.java b/src/android/org/linphone/receivers/BootReceiver.java index 360382a8d..340206aec 100644 --- a/src/android/org/linphone/receivers/BootReceiver.java +++ b/src/android/org/linphone/receivers/BootReceiver.java @@ -42,6 +42,7 @@ public class BootReceiver extends BroadcastReceiver { if (autostart) { Intent lLinphoneServiceIntent = new Intent(Intent.ACTION_MAIN); lLinphoneServiceIntent.setClass(context, LinphoneService.class); + lLinphoneServiceIntent.putExtra("ForceStartForeground", true); Compatibility.startService(context, lLinphoneServiceIntent); } } From ff5e176cfca1935ec1537add60862b9811cc1ecd Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 24 Jul 2018 15:58:56 +0200 Subject: [PATCH 09/14] Try to prevent as many NullPointerException as possible (from Google Play Console) --- .../org/linphone/LinphonePreferences.java | 64 +++++++++++++++++++ src/android/org/linphone/LinphoneUtils.java | 2 + .../linphone/activities/LinphoneActivity.java | 7 +- .../org/linphone/call/CallActivity.java | 5 +- .../org/linphone/chat/GroupChatFragment.java | 2 +- .../contacts/ContactDetailsFragment.java | 26 ++++---- .../linphone/contacts/LinphoneContact.java | 3 +- .../contacts/LinphoneNumberOrAddress.java | 5 +- .../contacts/SearchContactsListAdapter.java | 2 +- .../fragments/HistoryListFragment.java | 4 +- .../linphone/fragments/SettingsFragment.java | 61 ++++++++++-------- .../receivers/PhoneStateChangedReceiver.java | 5 +- .../org/linphone/ui/ListSelectionHelper.java | 2 +- 13 files changed, 138 insertions(+), 50 deletions(-) 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/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/GroupChatFragment.java b/src/android/org/linphone/chat/GroupChatFragment.java index 2c822a055..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(); } 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); From 7e28c55e7f441daf02c856aa520cef06e632e988 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 24 Jul 2018 16:13:36 +0200 Subject: [PATCH 10/14] Replace compile with implementation to fix warning from gradle --- liblinphone-sdk/build.gradle | 2 +- linphoneAndroidSdk.gradle | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/liblinphone-sdk/build.gradle b/liblinphone-sdk/build.gradle index 1151c0c8d..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' } 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' } From 99d3abca0b70a4448c7e3035741fdbbc9e07d113 Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Wed, 25 Jul 2018 16:48:07 +0200 Subject: [PATCH 11/14] update linphone sub --- submodules/linphone | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/linphone b/submodules/linphone index d1a8d275b..852166f0a 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit d1a8d275b553c82b56a21ebb32d34024b0adbb99 +Subproject commit 852166f0a30613f6ea26172f00fe2446b7195c99 From c8936dd204c72ffe0ceae567d2dd94aca1a5eb27 Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Wed, 25 Jul 2018 16:48:07 +0200 Subject: [PATCH 12/14] update linphone & belle-sip subs --- submodules/belle-sip | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From 49ff05f850d10ba190c7829576984dc4ef27cb74 Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Thu, 26 Jul 2018 11:08:04 +0200 Subject: [PATCH 13/14] update tools.build to 3.1.0 for tester --- liblinphone_tester/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/liblinphone_tester/build.gradle b/liblinphone_tester/build.gradle index 2e93960ab..f58bbc87a 100644 --- a/liblinphone_tester/build.gradle +++ b/liblinphone_tester/build.gradle @@ -13,7 +13,7 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:2.3.3' + classpath 'com.android.tools.build:gradle:3.1.0' } } From 7bbec3271fbe239d26e2b18bbce203f418440d38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Turnel?= Date: Thu, 26 Jul 2018 17:10:36 +0200 Subject: [PATCH 14/14] Update submodule linphone --- submodules/linphone | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/linphone b/submodules/linphone index 852166f0a..d0232344c 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit 852166f0a30613f6ea26172f00fe2446b7195c99 +Subproject commit d0232344c705a482feb5ca272abcb044303ef284