From 5642d4c8c34f04c2416a0195957269e42fe8d5ac Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 6 Jul 2022 11:52:14 +0200 Subject: [PATCH] Changes related to chat messages aggregation in SDK --- app/src/main/assets/linphonerc_factory | 2 + .../chat_bubble/ChatBubbleActivity.kt | 2 +- .../viewmodels/ChatMessagesListViewModel.kt | 54 +++++++++-------- .../main/chat/viewmodels/ChatRoomViewModel.kt | 2 +- .../chat/viewmodels/ChatRoomsListViewModel.kt | 26 ++++---- .../main/viewmodels/TabsViewModel.kt | 6 +- .../voip/viewmodels/CallsViewModel.kt | 6 +- .../java/org/linphone/core/CoreContext.kt | 36 +++++++---- .../notifications/NotificationsManager.kt | 60 +++++++++++-------- 9 files changed, 118 insertions(+), 76 deletions(-) diff --git a/app/src/main/assets/linphonerc_factory b/app/src/main/assets/linphonerc_factory index 1c1e4c8e8..277e26f87 100644 --- a/app/src/main/assets/linphonerc_factory +++ b/app/src/main/assets/linphonerc_factory @@ -16,6 +16,8 @@ auto_answer_replacing_calls=1 ping_with_options=0 use_cpim=1 zrtp_key_agreements_suites=MS_ZRTP_KEY_AGREEMENT_K255_KYB512 +chat_messages_aggregation_delay=1000 +chat_messages_aggregation=1 [sound] #remove this property for any application that is not Linphone public version itself diff --git a/app/src/main/java/org/linphone/activities/chat_bubble/ChatBubbleActivity.kt b/app/src/main/java/org/linphone/activities/chat_bubble/ChatBubbleActivity.kt index 9dfa3387c..29ea39d61 100644 --- a/app/src/main/java/org/linphone/activities/chat_bubble/ChatBubbleActivity.kt +++ b/app/src/main/java/org/linphone/activities/chat_bubble/ChatBubbleActivity.kt @@ -61,7 +61,7 @@ class ChatBubbleActivity : GenericActivity() { } private val listener = object : ChatRoomListenerStub() { - override fun onChatMessageReceived(chatRoom: ChatRoom, eventLog: EventLog) { + override fun onChatMessagesReceived(chatRoom: ChatRoom, eventLogs: Array) { chatRoom.markAsRead() } } diff --git a/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatMessagesListViewModel.kt b/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatMessagesListViewModel.kt index 978000344..3f3893bab 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatMessagesListViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatMessagesListViewModel.kt @@ -56,31 +56,10 @@ class ChatMessagesListViewModel(private val chatRoom: ChatRoom) : ViewModel() { } private val chatRoomListener: ChatRoomListenerStub = object : ChatRoomListenerStub() { - override fun onChatMessageReceived(chatRoom: ChatRoom, eventLog: EventLog) { - if (eventLog.type == EventLog.Type.ConferenceChatMessage) { - val chatMessage = eventLog.chatMessage - chatMessage ?: return - chatMessage.userData = events.value.orEmpty().size - - val existingEvent = events.value.orEmpty().find { data -> - data.eventLog == eventLog - } - if (existingEvent != null) { - Log.w("[Chat Messages] Found already present chat message, don't add it it's probably the result of an auto download") - return - } - - if (!PermissionHelper.get().hasWriteExternalStoragePermission()) { - for (content in chatMessage.contents) { - if (content.isFileTransfer) { - Log.i("[Chat Messages] Android < 10 detected and WRITE_EXTERNAL_STORAGE permission isn't granted yet") - requestWriteExternalStoragePermissionEvent.value = Event(true) - } - } - } + override fun onChatMessagesReceived(chatRoom: ChatRoom, eventLogs: Array) { + for (eventLog in eventLogs) { + addChatMessageEventLog(eventLog) } - - addEvent(eventLog) } override fun onChatMessageSending(chatRoom: ChatRoom, eventLog: EventLog) { @@ -245,4 +224,31 @@ class ChatMessagesListViewModel(private val chatRoom: ChatRoom) : ViewModel() { events.value.orEmpty().forEach(EventLogData::destroy) events.value = getEvents() } + + private fun addChatMessageEventLog(eventLog: EventLog) { + if (eventLog.type == EventLog.Type.ConferenceChatMessage) { + val chatMessage = eventLog.chatMessage + chatMessage ?: return + chatMessage.userData = events.value.orEmpty().size + + val existingEvent = events.value.orEmpty().find { data -> + data.eventLog == eventLog + } + if (existingEvent != null) { + Log.w("[Chat Messages] Found already present chat message, don't add it it's probably the result of an auto download") + return + } + + if (!PermissionHelper.get().hasWriteExternalStoragePermission()) { + for (content in chatMessage.contents) { + if (content.isFileTransfer) { + Log.i("[Chat Messages] Android < 10 detected and WRITE_EXTERNAL_STORAGE permission isn't granted yet") + requestWriteExternalStoragePermissionEvent.value = Event(true) + } + } + } + } + + addEvent(eventLog) + } } diff --git a/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatRoomViewModel.kt b/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatRoomViewModel.kt index 9012eecc2..89f6537dc 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatRoomViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatRoomViewModel.kt @@ -150,7 +150,7 @@ class ChatRoomViewModel(val chatRoom: ChatRoom) : ViewModel(), ContactDataInterf subject.value = chatRoom.subject } - override fun onChatMessageReceived(chatRoom: ChatRoom, eventLog: EventLog) { + override fun onChatMessagesReceived(chatRoom: ChatRoom, eventLogs: Array) { updateUnreadMessageCount() } diff --git a/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatRoomsListViewModel.kt b/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatRoomsListViewModel.kt index 45ed2fa60..be15d21ef 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatRoomsListViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatRoomsListViewModel.kt @@ -56,19 +56,15 @@ class ChatRoomsListViewModel : MessageNotifierViewModel() { } override fun onMessageSent(core: Core, chatRoom: ChatRoom, message: ChatMessage) { - when (findChatRoomIndex(chatRoom)) { - -1 -> updateChatRooms() - 0 -> chatRoomIndexUpdatedEvent.value = Event(0) - else -> reorderChatRooms() - } + onChatRoomMessageEvent(chatRoom) } - override fun onMessageReceived(core: Core, chatRoom: ChatRoom, message: ChatMessage) { - when (findChatRoomIndex(chatRoom)) { - -1 -> updateChatRooms() - 0 -> chatRoomIndexUpdatedEvent.value = Event(0) - else -> reorderChatRooms() - } + override fun onMessagesReceived( + core: Core, + chatRoom: ChatRoom, + messages: Array + ) { + onChatRoomMessageEvent(chatRoom) } override fun onChatRoomRead(core: Core, chatRoom: ChatRoom) { @@ -168,4 +164,12 @@ class ChatRoomsListViewModel : MessageNotifierViewModel() { } return -1 } + + private fun onChatRoomMessageEvent(chatRoom: ChatRoom) { + when (findChatRoomIndex(chatRoom)) { + -1 -> updateChatRooms() + 0 -> chatRoomIndexUpdatedEvent.value = Event(0) + else -> reorderChatRooms() + } + } } diff --git a/app/src/main/java/org/linphone/activities/main/viewmodels/TabsViewModel.kt b/app/src/main/java/org/linphone/activities/main/viewmodels/TabsViewModel.kt index d6578e55d..b55e0252c 100644 --- a/app/src/main/java/org/linphone/activities/main/viewmodels/TabsViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/viewmodels/TabsViewModel.kt @@ -70,7 +70,11 @@ class TabsViewModel : ViewModel() { updateUnreadChatCount() } - override fun onMessageReceived(core: Core, chatRoom: ChatRoom, message: ChatMessage) { + override fun onMessagesReceived( + core: Core, + chatRoom: ChatRoom, + messages: Array + ) { updateUnreadChatCount() } diff --git a/app/src/main/java/org/linphone/activities/voip/viewmodels/CallsViewModel.kt b/app/src/main/java/org/linphone/activities/voip/viewmodels/CallsViewModel.kt index a484d30b7..43244ca0b 100644 --- a/app/src/main/java/org/linphone/activities/voip/viewmodels/CallsViewModel.kt +++ b/app/src/main/java/org/linphone/activities/voip/viewmodels/CallsViewModel.kt @@ -77,7 +77,11 @@ class CallsViewModel : ViewModel() { updateUnreadChatCount() } - override fun onMessageReceived(core: Core, chatRoom: ChatRoom, message: ChatMessage) { + override fun onMessagesReceived( + core: Core, + chatRoom: ChatRoom, + messages: Array + ) { updateUnreadChatCount() } diff --git a/app/src/main/java/org/linphone/core/CoreContext.kt b/app/src/main/java/org/linphone/core/CoreContext.kt index 01353b836..9692c3399 100644 --- a/app/src/main/java/org/linphone/core/CoreContext.kt +++ b/app/src/main/java/org/linphone/core/CoreContext.kt @@ -247,18 +247,13 @@ class CoreContext( } } - override fun onMessageReceived(core: Core, chatRoom: ChatRoom, message: ChatMessage) { - if (core.maxSizeForAutoDownloadIncomingFiles != -1) { - var hasFile = false - for (content in message.contents) { - if (content.isFile) { - hasFile = true - break - } - } - if (hasFile) { - exportFilesInMessageToMediaStore(message) - } + override fun onMessagesReceived( + core: Core, + chatRoom: ChatRoom, + messages: Array + ) { + for (message in messages) { + exportFileInMessage(message) } } } @@ -817,7 +812,22 @@ class CoreContext( /* Coroutine related */ - fun exportFilesInMessageToMediaStore(message: ChatMessage) { + private fun exportFileInMessage(message: ChatMessage) { + if (core.maxSizeForAutoDownloadIncomingFiles != -1) { + var hasFile = false + for (content in message.contents) { + if (content.isFile) { + hasFile = true + break + } + } + if (hasFile) { + exportFilesInMessageToMediaStore(message) + } + } + } + + private fun exportFilesInMessageToMediaStore(message: ChatMessage) { if (message.isEphemeral) { Log.w("[Context] Do not make ephemeral file(s) public") return diff --git a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt index 175a345cb..65e9f98b2 100644 --- a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt +++ b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt @@ -139,11 +139,16 @@ class NotificationsManager(private val context: Context) { } } - override fun onMessageReceived(core: Core, room: ChatRoom, message: ChatMessage) { - if (message.isOutgoing || corePreferences.disableChat) return + override fun onMessagesReceived( + core: Core, + room: ChatRoom, + messages: Array + ) { + Log.i("[Notifications Manager] Received ${messages.size} aggregated messages") + if (corePreferences.disableChat) return if (corePreferences.preventInterfaceFromShowingUp) { - Log.w("[Context] We were asked to not show the chat notifications") + Log.w("[Notifications Manager] We were asked to not show the chat notifications") return } @@ -160,24 +165,6 @@ class NotificationsManager(private val context: Context) { return } - if (message.errorInfo.reason == Reason.UnsupportedContent) { - Log.w("[Notifications Manager] Received message with unsupported content, do not notify") - return - } - - if (message.contents.find { content -> - content.isFile or content.isFileTransfer or content.isText - } == null - ) { - Log.w("[Notifications Manager] Received message with neither text or attachment, do not notify") - return - } - - if (message.isRead) { - Log.w("[Notifications Manager] Received message is already marked as read, do not notify") - return - } - if (corePreferences.chatRoomShortcuts) { if (ShortcutsHelper.isShortcutToChatRoomAlreadyCreated(context, room)) { Log.i("[Notifications Manager] Chat room shortcut already exists") @@ -187,7 +174,12 @@ class NotificationsManager(private val context: Context) { } } - displayIncomingChatNotification(room, message) + val notifiable = createChatNotifiable(room, messages) + if (notifiable.messages.isNotEmpty()) { + displayChatNotifiable(room, notifiable) + } else { + Log.w("[Notifications Manager] No message to display in received aggregated messages") + } } override fun onChatRoomRead(core: Core, chatRoom: ChatRoom) { @@ -661,7 +653,7 @@ class NotificationsManager(private val context: Context) { notify(notifiable.notificationId, notification, CHAT_TAG) } - private fun displayIncomingChatNotification(room: ChatRoom, message: ChatMessage) { + private fun createChatNotifiable(room: ChatRoom, message: ChatMessage): Notifiable { val notifiable = getNotifiableForRoom(room) if (notifiable.messages.isNotEmpty() || room.unreadMessagesCount == 1) { val friend = coreContext.contactsManager.findContactByAddress(message.fromAddress) @@ -682,7 +674,27 @@ class NotificationsManager(private val context: Context) { notifiable.groupTitle = room.subject } - displayChatNotifiable(room, notifiable) + return notifiable + } + + private fun createChatNotifiable(room: ChatRoom, messages: Array): Notifiable { + val notifiable = getNotifiableForRoom(room) + + for (message in messages) { + if (message.isRead || message.isOutgoing) continue + val friend = coreContext.contactsManager.findContactByAddress(message.fromAddress) + val notifiableMessage = getNotifiableMessage(message, friend) + notifiable.messages.add(notifiableMessage) + } + + if (room.hasCapability(ChatRoomCapabilities.OneToOne.toInt())) { + notifiable.isGroup = false + } else { + notifiable.isGroup = true + notifiable.groupTitle = room.subject + } + + return notifiable } private fun getNotifiableForRoom(room: ChatRoom): Notifiable {