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 1/6] 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 2/6] 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 3/6] 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 4/6] 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 5/6] 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 6/6] 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); } }