Merge pull request #4810 from vector-im/feature/adm/voip-mute-notification

Fixing duplicated/empty notifications when joining/muting/leaving a VOIP call
This commit is contained in:
Benoit Marty 2021-12-30 11:31:06 +01:00 committed by GitHub
commit f124eba665
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 58 additions and 50 deletions

1
changelog.d/4804.bugfix Normal file
View File

@ -0,0 +1 @@
Fixing encrypted non message events showing up as notification messages (eg when a participant joins, mutes or leaves a voice call)

View File

@ -66,12 +66,10 @@ class NotifiableEventResolver @Inject constructor(
return resolveStateRoomEvent(event, session, canBeReplaced = false, isNoisy = isNoisy) return resolveStateRoomEvent(event, session, canBeReplaced = false, isNoisy = isNoisy)
} }
val timelineEvent = session.getRoom(roomID)?.getTimeLineEvent(eventId) ?: return null val timelineEvent = session.getRoom(roomID)?.getTimeLineEvent(eventId) ?: return null
when (event.getClearType()) { return when (event.getClearType()) {
EventType.MESSAGE -> { EventType.MESSAGE,
return resolveMessageEvent(timelineEvent, session, canBeReplaced = false, isNoisy = isNoisy)
}
EventType.ENCRYPTED -> { EventType.ENCRYPTED -> {
return resolveMessageEvent(timelineEvent, session, canBeReplaced = false, isNoisy = isNoisy) resolveMessageEvent(timelineEvent, session, canBeReplaced = false, isNoisy = isNoisy)
} }
else -> { else -> {
// If the event can be displayed, display it as is // If the event can be displayed, display it as is
@ -79,7 +77,7 @@ class NotifiableEventResolver @Inject constructor(
// TODO Better event text display // TODO Better event text display
val bodyPreview = event.type ?: EventType.MISSING_TYPE val bodyPreview = event.type ?: EventType.MISSING_TYPE
return SimpleNotifiableEvent( SimpleNotifiableEvent(
session.myUserId, session.myUserId,
eventId = event.eventId!!, eventId = event.eventId!!,
editedEventId = timelineEvent.getEditedEventId(), editedEventId = timelineEvent.getEditedEventId(),
@ -126,18 +124,18 @@ class NotifiableEventResolver @Inject constructor(
} }
} }
private suspend fun resolveMessageEvent(event: TimelineEvent, session: Session, canBeReplaced: Boolean, isNoisy: Boolean): NotifiableEvent { private suspend fun resolveMessageEvent(event: TimelineEvent, session: Session, canBeReplaced: Boolean, isNoisy: Boolean): NotifiableEvent? {
// The event only contains an eventId, and roomId (type is m.room.*) , we need to get the displayable content (names, avatar, text, etc...) // The event only contains an eventId, and roomId (type is m.room.*) , we need to get the displayable content (names, avatar, text, etc...)
val room = session.getRoom(event.root.roomId!! /*roomID cannot be null*/) val room = session.getRoom(event.root.roomId!! /*roomID cannot be null*/)
if (room == null) { return if (room == null) {
Timber.e("## Unable to resolve room for eventId [$event]") Timber.e("## Unable to resolve room for eventId [$event]")
// Ok room is not known in store, but we can still display something // Ok room is not known in store, but we can still display something
val body = displayableEventFormatter.format(event, isDm = false, appendAuthor = false) val body = displayableEventFormatter.format(event, isDm = false, appendAuthor = false)
val roomName = stringProvider.getString(R.string.notification_unknown_room_name) val roomName = stringProvider.getString(R.string.notification_unknown_room_name)
val senderDisplayName = event.senderInfo.disambiguatedDisplayName val senderDisplayName = event.senderInfo.disambiguatedDisplayName
return NotifiableMessageEvent( NotifiableMessageEvent(
eventId = event.root.eventId!!, eventId = event.root.eventId!!,
editedEventId = event.getEditedEventId(), editedEventId = event.getEditedEventId(),
canBeReplaced = canBeReplaced, canBeReplaced = canBeReplaced,
@ -152,51 +150,60 @@ class NotifiableEventResolver @Inject constructor(
matrixID = session.myUserId matrixID = session.myUserId
) )
} else { } else {
if (event.root.isEncrypted() && event.root.mxDecryptionResult == null) { event.attemptToDecryptIfNeeded(session)
// TODO use a global event decryptor? attache to session and that listen to new sessionId? // only convert encrypted messages to NotifiableMessageEvents
// for now decrypt sync when (event.root.getClearType()) {
try { EventType.MESSAGE -> {
val result = session.cryptoService().decryptEvent(event.root, event.root.roomId + UUID.randomUUID().toString()) val body = displayableEventFormatter.format(event, isDm = room.roomSummary()?.isDirect.orFalse(), appendAuthor = false).toString()
event.root.mxDecryptionResult = OlmDecryptionResult( val roomName = room.roomSummary()?.displayName ?: ""
payload = result.clearEvent, val senderDisplayName = event.senderInfo.disambiguatedDisplayName
senderKey = result.senderCurve25519Key,
keysClaimed = result.claimedEd25519Key?.let { mapOf("ed25519" to it) }, NotifiableMessageEvent(
forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain eventId = event.root.eventId!!,
editedEventId = event.getEditedEventId(),
canBeReplaced = canBeReplaced,
timestamp = event.root.originServerTs ?: 0,
noisy = isNoisy,
senderName = senderDisplayName,
senderId = event.root.senderId,
body = body,
imageUri = event.fetchImageIfPresent(session),
roomId = event.root.roomId!!,
roomName = roomName,
roomIsDirect = room.roomSummary()?.isDirect ?: false,
roomAvatarPath = session.contentUrlResolver()
.resolveThumbnail(room.roomSummary()?.avatarUrl,
250,
250,
ContentUrlResolver.ThumbnailMethod.SCALE),
senderAvatarPath = session.contentUrlResolver()
.resolveThumbnail(event.senderInfo.avatarUrl,
250,
250,
ContentUrlResolver.ThumbnailMethod.SCALE),
matrixID = session.myUserId,
soundName = null
) )
} catch (e: MXCryptoError) {
} }
else -> null
} }
}
}
val body = displayableEventFormatter.format(event, isDm = room.roomSummary()?.isDirect.orFalse(), appendAuthor = false).toString() private fun TimelineEvent.attemptToDecryptIfNeeded(session: Session) {
val roomName = room.roomSummary()?.displayName ?: "" if (root.isEncrypted() && root.mxDecryptionResult == null) {
val senderDisplayName = event.senderInfo.disambiguatedDisplayName // TODO use a global event decryptor? attache to session and that listen to new sessionId?
// for now decrypt sync
return NotifiableMessageEvent( try {
eventId = event.root.eventId!!, val result = session.cryptoService().decryptEvent(root, root.roomId + UUID.randomUUID().toString())
editedEventId = event.getEditedEventId(), root.mxDecryptionResult = OlmDecryptionResult(
canBeReplaced = canBeReplaced, payload = result.clearEvent,
timestamp = event.root.originServerTs ?: 0, senderKey = result.senderCurve25519Key,
noisy = isNoisy, keysClaimed = result.claimedEd25519Key?.let { mapOf("ed25519" to it) },
senderName = senderDisplayName, forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain
senderId = event.root.senderId, )
body = body, } catch (e: MXCryptoError) {
imageUri = event.fetchImageIfPresent(session), }
roomId = event.root.roomId!!,
roomName = roomName,
roomIsDirect = room.roomSummary()?.isDirect ?: false,
roomAvatarPath = session.contentUrlResolver()
.resolveThumbnail(room.roomSummary()?.avatarUrl,
250,
250,
ContentUrlResolver.ThumbnailMethod.SCALE),
senderAvatarPath = session.contentUrlResolver()
.resolveThumbnail(event.senderInfo.avatarUrl,
250,
250,
ContentUrlResolver.ThumbnailMethod.SCALE),
matrixID = session.myUserId,
soundName = null
)
} }
} }