Update dependency org.matrix.rustcomponents:sdk-android to v25.7.7 (#4989)

Make sure we distinguish between notification events that were filtered out and those that couldn't be resolved.

---

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jorge Martín <jorgem@element.io>
This commit is contained in:
renovate[bot] 2025-07-07 17:56:51 +02:00 committed by GitHub
parent f4032e291b
commit 4b10920507
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 313 additions and 200 deletions

View file

@ -12,26 +12,29 @@ 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.exception.NotificationResolverException
import io.element.android.libraries.matrix.api.notification.GetNotificationDataResult
import io.element.android.libraries.matrix.api.notification.NotificationService
import io.element.android.services.toolbox.api.systemclock.SystemClock
import kotlinx.coroutines.withContext
import org.matrix.rustcomponents.sdk.BatchNotificationResult
import org.matrix.rustcomponents.sdk.NotificationClient
import org.matrix.rustcomponents.sdk.NotificationItemsRequest
import org.matrix.rustcomponents.sdk.NotificationStatus
import org.matrix.rustcomponents.sdk.use
import timber.log.Timber
class RustNotificationService(
private val sessionId: SessionId,
private val notificationClient: NotificationClient,
private val dispatchers: CoroutineDispatchers,
private val clock: SystemClock,
clock: SystemClock,
) : NotificationService {
private val notificationMapper: NotificationMapper = NotificationMapper(clock)
override suspend fun getNotifications(
ids: Map<RoomId, List<EventId>>
): Result<Map<EventId, NotificationData>> = withContext(dispatchers.io) {
): GetNotificationDataResult = withContext(dispatchers.io) {
runCatchingExceptions {
val requests = ids.map { (roomId, eventIds) ->
NotificationItemsRequest(
@ -42,34 +45,41 @@ class RustNotificationService(
val items = notificationClient.getNotifications(requests)
buildMap {
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) {
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
)
)
for (rawEventId in eventIds) {
val roomId = RoomId(requests.find { it.eventIds.contains(rawEventId) }?.roomId!!)
val eventId = EventId(rawEventId)
items[rawEventId].use { result ->
when (result) {
is BatchNotificationResult.Ok -> {
when (val status = result.status) {
is NotificationStatus.Event -> {
put(eventId, Result.success(notificationMapper.map(sessionId, eventId, roomId, status.item)))
}
is NotificationStatus.EventNotFound -> {
Timber.e("Could not retrieve event for notification with $eventId - event not found")
put(eventId, Result.failure(NotificationResolverException.EventNotFound))
}
is NotificationStatus.EventFilteredOut -> {
Timber.d("Could not retrieve event for notification with $eventId - event filtered out")
put(eventId, Result.failure(NotificationResolverException.EventFilteredOut))
}
}
}
is BatchNotificationResult.Error -> {
Timber.e("Error while retrieving notification with $rawEventId - ${result.message}")
put(
eventId,
Result.failure(NotificationResolverException.UnknownError(result.message))
)
}
null -> {
Timber.e("The notification data for $rawEventId was not in the retrieved results. This is unexpected.")
put(
eventId,
Result.failure(NotificationResolverException.UnknownError("Notification data not found"))
)
}
}
}
}
}

View file

@ -16,6 +16,7 @@ import org.matrix.rustcomponents.sdk.NotificationEvent
import org.matrix.rustcomponents.sdk.NotificationItem
import org.matrix.rustcomponents.sdk.NotificationRoomInfo
import org.matrix.rustcomponents.sdk.NotificationSenderInfo
import org.matrix.rustcomponents.sdk.NotificationStatus
import org.matrix.rustcomponents.sdk.TimelineEvent
fun aRustNotificationItem(
@ -34,6 +35,12 @@ fun aRustNotificationItem(
threadId = threadId?.value,
)
fun aRustBatchNotificationResult(
notificationStatus: NotificationStatus = NotificationStatus.Event(aRustNotificationItem()),
) = org.matrix.rustcomponents.sdk.BatchNotificationResult.Ok(
status = notificationStatus,
)
fun aRustNotificationSenderInfo(
displayName: String? = A_USER_NAME,
avatarUrl: String? = null,

View file

@ -7,16 +7,16 @@
package io.element.android.libraries.matrix.impl.fixtures.fakes
import org.matrix.rustcomponents.sdk.BatchNotificationResult
import org.matrix.rustcomponents.sdk.NoPointer
import org.matrix.rustcomponents.sdk.NotificationClient
import org.matrix.rustcomponents.sdk.NotificationItem
import org.matrix.rustcomponents.sdk.NotificationItemsRequest
class FakeFfiNotificationClient(
var notificationItemResult: Map<String, NotificationItem> = emptyMap(),
var notificationItemResult: Map<String, BatchNotificationResult> = emptyMap(),
val closeResult: () -> Unit = { }
) : NotificationClient(NoPointer) {
override suspend fun getNotifications(requests: List<NotificationItemsRequest>): Map<String, NotificationItem> {
override suspend fun getNotifications(requests: List<NotificationItemsRequest>): Map<String, BatchNotificationResult> {
return notificationItemResult
}

View file

@ -8,9 +8,10 @@
package io.element.android.libraries.matrix.impl.notification
import com.google.common.truth.Truth.assertThat
import io.element.android.libraries.matrix.api.exception.NotificationResolverException
import io.element.android.libraries.matrix.api.notification.NotificationContent
import io.element.android.libraries.matrix.api.timeline.item.event.TextMessageType
import io.element.android.libraries.matrix.impl.fixtures.factories.aRustNotificationItem
import io.element.android.libraries.matrix.impl.fixtures.factories.aRustBatchNotificationResult
import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeFfiNotificationClient
import io.element.android.libraries.matrix.test.AN_EVENT_ID
import io.element.android.libraries.matrix.test.A_MESSAGE
@ -30,12 +31,12 @@ class RustNotificationServiceTest {
@Test
fun test() = runTest {
val notificationClient = FakeFfiNotificationClient(
notificationItemResult = mapOf(AN_EVENT_ID.value to aRustNotificationItem()),
notificationItemResult = mapOf(AN_EVENT_ID.value to aRustBatchNotificationResult()),
)
val sut = createRustNotificationService(
notificationClient = notificationClient,
)
val result = sut.getNotifications(mapOf(A_ROOM_ID to listOf(AN_EVENT_ID))).getOrThrow()[AN_EVENT_ID]!!
val result = sut.getNotifications(mapOf(A_ROOM_ID to listOf(AN_EVENT_ID))).getOrThrow()[AN_EVENT_ID]!!.getOrThrow()
assertThat(result.isEncrypted).isTrue()
assertThat(result.content).isEqualTo(
NotificationContent.MessageLike.RoomMessage(
@ -56,10 +57,8 @@ class RustNotificationServiceTest {
val sut = createRustNotificationService(
notificationClient = notificationClient,
)
val result = sut.getNotifications(mapOf(A_ROOM_ID to listOf(AN_EVENT_ID))).getOrThrow()[AN_EVENT_ID]!!
assertThat(result.content).isEqualTo(
NotificationContent.MessageLike.UnableToResolve
)
val exception = sut.getNotifications(mapOf(A_ROOM_ID to listOf(AN_EVENT_ID))).getOrThrow()[AN_EVENT_ID]!!.exceptionOrNull()
assertThat(exception).isInstanceOf(NotificationResolverException::class.java)
}
@Test