diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/notification/NotificationData.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/notification/NotificationData.kt index 338193ed44..f90b70171e 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/notification/NotificationData.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/notification/NotificationData.kt @@ -68,6 +68,7 @@ sealed interface NotificationContent { ) : MessageLike data object RoomEncrypted : MessageLike + data object UnableToResolve : MessageLike data class RoomMessage( val senderId: UserId, val messageType: MessageType diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationService.kt index bab7cdea02..b88b53454a 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationService.kt @@ -12,6 +12,7 @@ import io.element.android.libraries.core.extensions.runCatchingExceptions import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.SessionId +import io.element.android.libraries.matrix.api.notification.NotificationContent import io.element.android.libraries.matrix.api.notification.NotificationData import io.element.android.libraries.matrix.api.notification.NotificationService import io.element.android.services.toolbox.api.systemclock.SystemClock @@ -24,7 +25,7 @@ class RustNotificationService( private val sessionId: SessionId, private val notificationClient: NotificationClient, private val dispatchers: CoroutineDispatchers, - clock: SystemClock, + private val clock: SystemClock, ) : NotificationService { private val notificationMapper: NotificationMapper = NotificationMapper(clock) @@ -43,11 +44,32 @@ class RustNotificationService( val eventIds = requests.flatMap { it.eventIds } for (eventId in eventIds) { val item = items[eventId] + val roomId = RoomId(requests.find { it.eventIds.contains(eventId) }?.roomId!!) if (item != null) { - val roomId = RoomId(requests.find { it.eventIds.contains(eventId) }?.roomId!!) put(EventId(eventId), notificationMapper.map(sessionId, EventId(eventId), roomId, item)) } else { Timber.e("Could not retrieve event for notification with $eventId") + put( + EventId(eventId), + NotificationData( + sessionId = sessionId, + eventId = EventId(eventId), + threadId = null, + roomId = roomId, + senderAvatarUrl = null, + senderDisplayName = null, + senderIsNameAmbiguous = false, + roomAvatarUrl = null, + roomDisplayName = null, + isDirect = false, + isDm = false, + isEncrypted = false, + isNoisy = false, + timestamp = clock.epochMillis(), + content = NotificationContent.MessageLike.UnableToResolve, + hasMention = false + ) + ) } } } diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolver.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolver.kt index d5eef83564..9a6b119a26 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolver.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolver.kt @@ -225,6 +225,11 @@ class DefaultNotifiableEventResolver @Inject constructor( val fallbackNotifiableEvent = fallbackNotifiableEvent(userId, roomId, eventId) ResolvedPushEvent.Event(fallbackNotifiableEvent) } + NotificationContent.MessageLike.UnableToResolve -> { + Timber.tag(loggerTag.value).w("Unable to resolve notification -> fallback") + val fallbackNotifiableEvent = fallbackNotifiableEvent(userId, roomId, eventId) + ResolvedPushEvent.Event(fallbackNotifiableEvent) + } is NotificationContent.MessageLike.RoomRedaction -> { // Note: this case will be handled below val redactedEventId = content.redactedEventId diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandler.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandler.kt index d42ca28c88..70ad155c61 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandler.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandler.kt @@ -25,6 +25,7 @@ import io.element.android.libraries.push.impl.history.onUnableToRetrieveSession import io.element.android.libraries.push.impl.notifications.NotificationEventRequest import io.element.android.libraries.push.impl.notifications.NotificationResolverQueue import io.element.android.libraries.push.impl.notifications.channels.NotificationChannels +import io.element.android.libraries.push.impl.notifications.model.FallbackNotifiableEvent import io.element.android.libraries.push.impl.notifications.model.NotifiableEvent import io.element.android.libraries.push.impl.notifications.model.NotifiableRingingCallEvent import io.element.android.libraries.push.impl.notifications.model.ResolvedPushEvent @@ -87,13 +88,24 @@ class DefaultPushHandler @Inject constructor( } else { result.fold( onSuccess = { - pushHistoryService.onSuccess( - providerInfo = request.providerInfo, - eventId = request.eventId, - roomId = request.roomId, - sessionId = request.sessionId, - comment = "Push handled successfully", - ) + if (it is ResolvedPushEvent.Event && it.notifiableEvent is FallbackNotifiableEvent) { + pushHistoryService.onUnableToResolveEvent( + providerInfo = request.providerInfo, + eventId = request.eventId, + roomId = request.roomId, + sessionId = request.sessionId, + reason = "Unable to resolve event, showing fallback notification", + ) + mutableBatteryOptimizationStore.showBatteryOptimizationBanner() + } else { + pushHistoryService.onSuccess( + providerInfo = request.providerInfo, + eventId = request.eventId, + roomId = request.roomId, + sessionId = request.sessionId, + comment = "Push handled successfully", + ) + } }, onFailure = { exception -> pushHistoryService.onUnableToResolveEvent(