Changes related to chat messages aggregation in SDK

This commit is contained in:
Sylvain Berfini 2022-07-06 11:52:14 +02:00
parent 7c267dad25
commit 5642d4c8c3
9 changed files with 118 additions and 76 deletions

View file

@ -16,6 +16,8 @@ auto_answer_replacing_calls=1
ping_with_options=0 ping_with_options=0
use_cpim=1 use_cpim=1
zrtp_key_agreements_suites=MS_ZRTP_KEY_AGREEMENT_K255_KYB512 zrtp_key_agreements_suites=MS_ZRTP_KEY_AGREEMENT_K255_KYB512
chat_messages_aggregation_delay=1000
chat_messages_aggregation=1
[sound] [sound]
#remove this property for any application that is not Linphone public version itself #remove this property for any application that is not Linphone public version itself

View file

@ -61,7 +61,7 @@ class ChatBubbleActivity : GenericActivity() {
} }
private val listener = object : ChatRoomListenerStub() { private val listener = object : ChatRoomListenerStub() {
override fun onChatMessageReceived(chatRoom: ChatRoom, eventLog: EventLog) { override fun onChatMessagesReceived(chatRoom: ChatRoom, eventLogs: Array<out EventLog>) {
chatRoom.markAsRead() chatRoom.markAsRead()
} }
} }

View file

@ -56,31 +56,10 @@ class ChatMessagesListViewModel(private val chatRoom: ChatRoom) : ViewModel() {
} }
private val chatRoomListener: ChatRoomListenerStub = object : ChatRoomListenerStub() { private val chatRoomListener: ChatRoomListenerStub = object : ChatRoomListenerStub() {
override fun onChatMessageReceived(chatRoom: ChatRoom, eventLog: EventLog) { override fun onChatMessagesReceived(chatRoom: ChatRoom, eventLogs: Array<out EventLog>) {
if (eventLog.type == EventLog.Type.ConferenceChatMessage) { for (eventLog in eventLogs) {
val chatMessage = eventLog.chatMessage addChatMessageEventLog(eventLog)
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)
} }
override fun onChatMessageSending(chatRoom: ChatRoom, eventLog: 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.orEmpty().forEach(EventLogData::destroy)
events.value = getEvents() 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)
}
} }

View file

@ -150,7 +150,7 @@ class ChatRoomViewModel(val chatRoom: ChatRoom) : ViewModel(), ContactDataInterf
subject.value = chatRoom.subject subject.value = chatRoom.subject
} }
override fun onChatMessageReceived(chatRoom: ChatRoom, eventLog: EventLog) { override fun onChatMessagesReceived(chatRoom: ChatRoom, eventLogs: Array<out EventLog>) {
updateUnreadMessageCount() updateUnreadMessageCount()
} }

View file

@ -56,19 +56,15 @@ class ChatRoomsListViewModel : MessageNotifierViewModel() {
} }
override fun onMessageSent(core: Core, chatRoom: ChatRoom, message: ChatMessage) { override fun onMessageSent(core: Core, chatRoom: ChatRoom, message: ChatMessage) {
when (findChatRoomIndex(chatRoom)) { onChatRoomMessageEvent(chatRoom)
-1 -> updateChatRooms()
0 -> chatRoomIndexUpdatedEvent.value = Event(0)
else -> reorderChatRooms()
}
} }
override fun onMessageReceived(core: Core, chatRoom: ChatRoom, message: ChatMessage) { override fun onMessagesReceived(
when (findChatRoomIndex(chatRoom)) { core: Core,
-1 -> updateChatRooms() chatRoom: ChatRoom,
0 -> chatRoomIndexUpdatedEvent.value = Event(0) messages: Array<out ChatMessage>
else -> reorderChatRooms() ) {
} onChatRoomMessageEvent(chatRoom)
} }
override fun onChatRoomRead(core: Core, chatRoom: ChatRoom) { override fun onChatRoomRead(core: Core, chatRoom: ChatRoom) {
@ -168,4 +164,12 @@ class ChatRoomsListViewModel : MessageNotifierViewModel() {
} }
return -1 return -1
} }
private fun onChatRoomMessageEvent(chatRoom: ChatRoom) {
when (findChatRoomIndex(chatRoom)) {
-1 -> updateChatRooms()
0 -> chatRoomIndexUpdatedEvent.value = Event(0)
else -> reorderChatRooms()
}
}
} }

View file

@ -70,7 +70,11 @@ class TabsViewModel : ViewModel() {
updateUnreadChatCount() updateUnreadChatCount()
} }
override fun onMessageReceived(core: Core, chatRoom: ChatRoom, message: ChatMessage) { override fun onMessagesReceived(
core: Core,
chatRoom: ChatRoom,
messages: Array<out ChatMessage>
) {
updateUnreadChatCount() updateUnreadChatCount()
} }

View file

@ -77,7 +77,11 @@ class CallsViewModel : ViewModel() {
updateUnreadChatCount() updateUnreadChatCount()
} }
override fun onMessageReceived(core: Core, chatRoom: ChatRoom, message: ChatMessage) { override fun onMessagesReceived(
core: Core,
chatRoom: ChatRoom,
messages: Array<out ChatMessage>
) {
updateUnreadChatCount() updateUnreadChatCount()
} }

View file

@ -247,18 +247,13 @@ class CoreContext(
} }
} }
override fun onMessageReceived(core: Core, chatRoom: ChatRoom, message: ChatMessage) { override fun onMessagesReceived(
if (core.maxSizeForAutoDownloadIncomingFiles != -1) { core: Core,
var hasFile = false chatRoom: ChatRoom,
for (content in message.contents) { messages: Array<out ChatMessage>
if (content.isFile) { ) {
hasFile = true for (message in messages) {
break exportFileInMessage(message)
}
}
if (hasFile) {
exportFilesInMessageToMediaStore(message)
}
} }
} }
} }
@ -817,7 +812,22 @@ class CoreContext(
/* Coroutine related */ /* 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) { if (message.isEphemeral) {
Log.w("[Context] Do not make ephemeral file(s) public") Log.w("[Context] Do not make ephemeral file(s) public")
return return

View file

@ -139,11 +139,16 @@ class NotificationsManager(private val context: Context) {
} }
} }
override fun onMessageReceived(core: Core, room: ChatRoom, message: ChatMessage) { override fun onMessagesReceived(
if (message.isOutgoing || corePreferences.disableChat) return core: Core,
room: ChatRoom,
messages: Array<out ChatMessage>
) {
Log.i("[Notifications Manager] Received ${messages.size} aggregated messages")
if (corePreferences.disableChat) return
if (corePreferences.preventInterfaceFromShowingUp) { 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 return
} }
@ -160,24 +165,6 @@ class NotificationsManager(private val context: Context) {
return 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 (corePreferences.chatRoomShortcuts) {
if (ShortcutsHelper.isShortcutToChatRoomAlreadyCreated(context, room)) { if (ShortcutsHelper.isShortcutToChatRoomAlreadyCreated(context, room)) {
Log.i("[Notifications Manager] Chat room shortcut already exists") 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) { override fun onChatRoomRead(core: Core, chatRoom: ChatRoom) {
@ -661,7 +653,7 @@ class NotificationsManager(private val context: Context) {
notify(notifiable.notificationId, notification, CHAT_TAG) 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) val notifiable = getNotifiableForRoom(room)
if (notifiable.messages.isNotEmpty() || room.unreadMessagesCount == 1) { if (notifiable.messages.isNotEmpty() || room.unreadMessagesCount == 1) {
val friend = coreContext.contactsManager.findContactByAddress(message.fromAddress) val friend = coreContext.contactsManager.findContactByAddress(message.fromAddress)
@ -682,7 +674,27 @@ class NotificationsManager(private val context: Context) {
notifiable.groupTitle = room.subject notifiable.groupTitle = room.subject
} }
displayChatNotifiable(room, notifiable) return notifiable
}
private fun createChatNotifiable(room: ChatRoom, messages: Array<out ChatMessage>): 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 { private fun getNotifiableForRoom(room: ChatRoom): Notifiable {