From 01c8735cafb608dcd42073d16a0eb17e8427c075 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 12 Jan 2023 16:53:52 +0100 Subject: [PATCH] Reworked how Persons are used + fixed timestamp issue in chat message notification + fixed chat room being marked as read when answering in the notification --- .../org/linphone/contact/ContactsManager.kt | 24 +++- .../NotificationBroadcastReceiver.kt | 2 +- .../notifications/NotificationsManager.kt | 104 ++++++++---------- 3 files changed, 65 insertions(+), 65 deletions(-) diff --git a/app/src/main/java/org/linphone/contact/ContactsManager.kt b/app/src/main/java/org/linphone/contact/ContactsManager.kt index 4fa3075fa..394195db6 100644 --- a/app/src/main/java/org/linphone/contact/ContactsManager.kt +++ b/app/src/main/java/org/linphone/contact/ContactsManager.kt @@ -26,6 +26,7 @@ import android.content.ContentResolver import android.content.ContentUris import android.content.Context import android.graphics.Bitmap +import android.graphics.BitmapFactory import android.graphics.drawable.Drawable import android.net.Uri import android.provider.ContactsContract @@ -41,6 +42,7 @@ import org.linphone.R import org.linphone.core.* import org.linphone.core.tools.Log import org.linphone.utils.ImageUtils +import org.linphone.utils.LinphoneUtils import org.linphone.utils.PermissionHelper interface ContactsUpdatedListener { @@ -70,6 +72,7 @@ class ContactsManager(private val context: Context) { val contactAvatar: IconCompat val groupAvatar: IconCompat + val groupBitmap: Bitmap private val localFriends = arrayListOf() @@ -93,6 +96,7 @@ class ContactsManager(private val context: Context) { contactAvatar = IconCompat.createWithResource(context, R.drawable.voip_single_contact_avatar_alt) groupAvatar = IconCompat.createWithResource(context, R.drawable.voip_multiple_contacts_avatar_alt) + groupBitmap = BitmapFactory.decodeResource(context.resources, R.drawable.voip_multiple_contacts_avatar_alt) val core = coreContext.core for (list in core.friendsLists) { @@ -120,7 +124,7 @@ class ContactsManager(private val context: Context) { for (account in coreContext.core.accountList) { val friend = coreContext.core.createFriend() - friend.name = account.params.identityAddress?.displayName ?: account.params.identityAddress?.username + friend.name = LinphoneUtils.getDisplayName(account.params.identityAddress) val address = account.params.identityAddress ?: continue friend.address = address @@ -137,6 +141,17 @@ class ContactsManager(private val context: Context) { } } + @Synchronized + fun getMePerson(localAddress: Address): Person { + val friend = localFriends.find { localFriend -> + localFriend.addresses.find { address -> + address.weakEqual(localAddress) + } != null + } + return friend?.getPerson() + ?: Person.Builder().setName(LinphoneUtils.getDisplayName(localAddress)).build() + } + @Synchronized fun getAndroidContactIdFromUri(uri: Uri): String? { val projection = arrayOf(ContactsContract.Data.CONTACT_ID) @@ -381,14 +396,13 @@ fun Friend.getPerson(): Person { coreContext.context, getThumbnailUri() ) - val icon = + personBuilder.setIcon( if (bm == null) { coreContext.contactsManager.contactAvatar } else IconCompat.createWithAdaptiveBitmap(bm) - if (icon != null) { - personBuilder.setIcon(icon) - } + ) + personBuilder.setKey(refKey) personBuilder.setUri(nativeUri) personBuilder.setImportant(starred) return personBuilder.build() diff --git a/app/src/main/java/org/linphone/notifications/NotificationBroadcastReceiver.kt b/app/src/main/java/org/linphone/notifications/NotificationBroadcastReceiver.kt index 3397178fe..5e4163307 100644 --- a/app/src/main/java/org/linphone/notifications/NotificationBroadcastReceiver.kt +++ b/app/src/main/java/org/linphone/notifications/NotificationBroadcastReceiver.kt @@ -76,7 +76,6 @@ class NotificationBroadcastReceiver : BroadcastReceiver() { return } - room.markAsRead() if (intent.action == NotificationsManager.INTENT_REPLY_NOTIF_ACTION) { val reply = getMessageText(intent)?.toString() if (reply == null) { @@ -90,6 +89,7 @@ class NotificationBroadcastReceiver : BroadcastReceiver() { msg.send() Log.i("[Notification Broadcast Receiver] Reply sent for notif id $notificationId") } else { + room.markAsRead() if (!coreContext.notificationsManager.dismissChatNotification(room)) { Log.w("[Notification Broadcast Receiver] Notifications Manager failed to cancel notification") val notificationManager = context.getSystemService(NotificationManager::class.java) diff --git a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt index abf234c39..701edde1f 100644 --- a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt +++ b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt @@ -480,19 +480,18 @@ class NotificationsManager(private val context: Context) { } fun getPerson(friend: Friend?, displayName: String, picture: Bitmap?): Person { - return if (friend != null) { - friend.getPerson() - } else { - val builder = Person.Builder().setName(displayName) - val userIcon = - if (picture != null) { - IconCompat.createWithAdaptiveBitmap(picture) - } else { - coreContext.contactsManager.contactAvatar - } - if (userIcon != null) builder.setIcon(userIcon) - builder.build() - } + return friend?.getPerson() + ?: Person.Builder() + .setName(displayName) + .setIcon( + if (picture != null) { + IconCompat.createWithAdaptiveBitmap(picture) + } else { + coreContext.contactsManager.contactAvatar + } + ) + .setKey(displayName) + .build() } fun displayIncomingCallNotification(call: Call, useAsForeground: Boolean) { @@ -665,41 +664,18 @@ class NotificationsManager(private val context: Context) { ) val id = LinphoneUtils.getChatRoomId(room.localAddress, room.peerAddress) - val notification = createMessageNotification(notifiable, pendingIntent, bubbleIntent, id) + val me = coreContext.contactsManager.getMePerson(room.localAddress) + val notification = createMessageNotification(notifiable, pendingIntent, bubbleIntent, id, me) notify(notifiable.notificationId, notification, CHAT_TAG) } - 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) - val notifiableMessage = getNotifiableMessage(message, friend) - notifiable.messages.add(notifiableMessage) - } else { - for (chatMessage in room.unreadHistory) { - val friend = coreContext.contactsManager.findContactByAddress(chatMessage.fromAddress) - val notifiableMessage = getNotifiableMessage(chatMessage, 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 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) + val notifiableMessage = getNotifiableMessage(message, friend, notifiable) notifiable.messages.add(notifiableMessage) } @@ -727,7 +703,7 @@ class NotificationsManager(private val context: Context) { return notifiable } - private fun getNotifiableMessage(message: ChatMessage, friend: Friend?): NotifiableMessage { + private fun getNotifiableMessage(message: ChatMessage, friend: Friend?, notifiable: Notifiable): NotifiableMessage { val roundPicture = ImageUtils.getRoundBitmapFromUri(context, friend?.getThumbnailUri()) val displayName = friend?.name ?: LinphoneUtils.getDisplayName(message.fromAddress) var text = "" @@ -752,7 +728,7 @@ class NotificationsManager(private val context: Context) { text, friend, displayName, - message.time, + message.time * 1000, /* Linphone timestamps are in seconds */ senderAvatar = roundPicture, isOutgoing = message.isOutgoing ) @@ -784,10 +760,11 @@ class NotificationsManager(private val context: Context) { Log.i("[Notifications Manager] Updating message notification with reply for notification ${notifiable.notificationId}") val text = message.contents.find { content -> content.isText }?.utf8Text ?: "" + val senderAddress = message.fromAddress val reply = NotifiableMessage( text, null, - notifiable.myself ?: LinphoneUtils.getDisplayName(message.fromAddress), + notifiable.myself ?: LinphoneUtils.getDisplayName(senderAddress), System.currentTimeMillis(), isOutgoing = true ) @@ -836,38 +813,43 @@ class NotificationsManager(private val context: Context) { notifiable: Notifiable, pendingIntent: PendingIntent, bubbleIntent: PendingIntent, - id: String + id: String, + me: Person ): Notification { - val me = Person.Builder().setName(notifiable.myself).build() val style = NotificationCompat.MessagingStyle(me) - val largeIcon: Bitmap? = notifiable.messages.lastOrNull()?.senderAvatar + val allPersons = arrayListOf() + var lastPersonAvatar: Bitmap? = null var lastPerson: Person? = null for (message in notifiable.messages) { val friend = message.friend - val person = getPerson(friend, message.sender, message.senderAvatar) + val person = if (message.isOutgoing) + me + else + getPerson(friend, message.sender, message.senderAvatar) - // We don't want to see our own avatar if (!message.isOutgoing) { + // We don't want to see our own avatar lastPerson = person + lastPersonAvatar = message.senderAvatar + + if (allPersons.find { it.key == person.key } == null) { + allPersons.add(person) + } } - val msg = if (!corePreferences.hideChatMessageContentInNotification) { - NotificationCompat.MessagingStyle.Message(message.message, message.time, person) - } else { + val msg = if (corePreferences.hideChatMessageContentInNotification) { NotificationCompat.MessagingStyle.Message(AppUtils.getString(R.string.chat_message_notification_hidden_content), message.time, person) - } - - if (message.filePath != null && !corePreferences.hideChatMessageContentInNotification) { - msg.setData(message.fileMime, message.filePath) + } else { + val tmp = NotificationCompat.MessagingStyle.Message(message.message, message.time, person) + if (message.filePath != null) tmp.setData(message.fileMime, message.filePath) + tmp } style.addMessage(msg) } - if (notifiable.isGroup) { - style.conversationTitle = notifiable.groupTitle - } + style.conversationTitle = if (notifiable.isGroup) notifiable.groupTitle else lastPerson?.name style.isGroupConversation = notifiable.isGroup val icon = lastPerson?.icon ?: coreContext.contactsManager.contactAvatar @@ -875,11 +857,12 @@ class NotificationsManager(private val context: Context) { .setDesiredHeightResId(R.dimen.chat_message_bubble_desired_height) .build() + val largeIcon = if (notifiable.isGroup) coreContext.contactsManager.groupBitmap else lastPersonAvatar val notificationBuilder = NotificationCompat.Builder(context, context.getString(R.string.notification_channel_chat_id)) - .addPerson(lastPerson) .setSmallIcon(R.drawable.topbar_chat_notification) .setAutoCancel(true) .setLargeIcon(largeIcon) + .setColor(ContextCompat.getColor(context, R.color.primary_color)) .setCategory(NotificationCompat.CATEGORY_MESSAGE) .setGroup(CHAT_NOTIFICATIONS_GROUP) .setVisibility(NotificationCompat.VISIBILITY_PRIVATE) @@ -887,12 +870,15 @@ class NotificationsManager(private val context: Context) { .setWhen(System.currentTimeMillis()) .setShowWhen(true) .setStyle(style) - .setColor(ContextCompat.getColor(context, R.color.primary_color)) .addAction(getReplyMessageAction(notifiable)) .addAction(getMarkMessageAsReadAction(notifiable)) .setShortcutId(id) .setLocusId(LocusIdCompat(id)) + for (person in allPersons) { + notificationBuilder.addPerson(person) + } + if (!corePreferences.preventInterfaceFromShowingUp) { notificationBuilder.setContentIntent(pendingIntent) }