Bump rust-sdk version to rust-sdk 0.2.57 (#3735)

* Bump rust-sdk version to rust-sdk 0.2.57

* rust sdk update: Support persisted WedgeQueueError

* Trust & Decoration | Support new expected UTD causes

* Room Subscribtion settings not needed anymore (see https://github.com/matrix-org/matrix-rust-sdk/pull/4159)

* File/Attachement upload: update to support `storeInCache`

* feat(knock): update API to use reason and serverNames

* Add another `Konsist` exception

* Update screenshots

---------

Co-authored-by: Jorge Martín <jorgem@element.io>
Co-authored-by: ElementBot <android@element.io>
Co-authored-by: Benoit Marty <benoit@matrix.org>
This commit is contained in:
Valere 2024-10-24 16:45:16 +02:00 committed by GitHub
parent f44c8dd452
commit 9fb68fc58e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 223 additions and 58 deletions

View file

@ -398,7 +398,7 @@ class RustMatrixClient(
sessionDispatcher
) {
runCatching {
client.knock(roomIdOrAlias.identifier).destroy()
client.knock(roomIdOrAlias.identifier, message, serverNames).destroy()
try {
awaitRoom(roomIdOrAlias, 10.seconds, CurrentUserMembership.KNOCKED)
} catch (e: Exception) {

View file

@ -21,7 +21,12 @@ class UtdTracker(
Timber.d("onUtd for event ${info.eventId}, timeToDecryptMs: ${info.timeToDecryptMs}")
val name = when (info.cause) {
UtdCause.UNKNOWN -> Error.Name.OlmKeysNotSentError
UtdCause.MEMBERSHIP -> Error.Name.ExpectedDueToMembership
UtdCause.SENT_BEFORE_WE_JOINED -> Error.Name.ExpectedDueToMembership
UtdCause.VERIFICATION_VIOLATION -> Error.Name.ExpectedVerificationViolation
UtdCause.UNSIGNED_DEVICE,
UtdCause.UNKNOWN_DEVICE -> {
Error.Name.ExpectedSentByInsecureDevice
}
}
val event = Error(
context = null,

View file

@ -9,18 +9,13 @@ package io.element.android.libraries.matrix.impl.room
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.timeline.item.event.EventType
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext
import org.matrix.rustcomponents.sdk.RequiredState
import org.matrix.rustcomponents.sdk.RoomListService
import org.matrix.rustcomponents.sdk.RoomSubscription
import timber.log.Timber
private const val DEFAULT_TIMELINE_LIMIT = 20u
class RoomSyncSubscriber(
private val roomListService: RoomListService,
private val dispatchers: CoroutineDispatchers,
@ -28,28 +23,13 @@ class RoomSyncSubscriber(
private val subscribedRoomIds = mutableSetOf<RoomId>()
private val mutex = Mutex()
private val settings = RoomSubscription(
requiredState = listOf(
RequiredState(key = EventType.STATE_ROOM_NAME, value = ""),
RequiredState(key = EventType.STATE_ROOM_TOPIC, value = ""),
RequiredState(key = EventType.STATE_ROOM_AVATAR, value = ""),
RequiredState(key = EventType.STATE_ROOM_CANONICAL_ALIAS, value = ""),
RequiredState(key = EventType.STATE_ROOM_JOIN_RULES, value = ""),
RequiredState(key = EventType.STATE_ROOM_POWER_LEVELS, value = ""),
RequiredState(key = EventType.STATE_ROOM_PINNED_EVENT, value = ""),
),
timelineLimit = DEFAULT_TIMELINE_LIMIT,
// We don't need heroes here as they're already included in the `all_rooms` list
includeHeroes = false,
)
suspend fun subscribe(roomId: RoomId) {
mutex.withLock {
withContext(dispatchers.io) {
try {
if (!isSubscribedTo(roomId)) {
Timber.d("Subscribing to room $roomId}")
roomListService.subscribeToRooms(listOf(roomId.value), settings)
roomListService.subscribeToRooms(listOf(roomId.value))
}
subscribedRoomIds.add(roomId)
} catch (exception: Exception) {
@ -65,7 +45,7 @@ class RoomSyncSubscriber(
val roomIdsToSubscribeTo = roomIds.filterNot { isSubscribedTo(it) }
if (roomIdsToSubscribeTo.isNotEmpty()) {
Timber.d("Subscribing to rooms: $roomIds")
roomListService.subscribeToRooms(roomIdsToSubscribeTo.map { it.value }, settings)
roomListService.subscribeToRooms(roomIdsToSubscribeTo.map { it.value })
subscribedRoomIds.addAll(roomIds)
}
} catch (cancellationException: CancellationException) {

View file

@ -339,6 +339,7 @@ class RustTimeline(
formattedCaption = formattedBody?.let {
FormattedBody(body = it, format = MessageFormat.Html)
},
storeInCache = true,
progressWatcher = progressCallback?.toProgressWatcher()
)
}
@ -361,6 +362,7 @@ class RustTimeline(
formattedCaption = formattedBody?.let {
FormattedBody(body = it, format = MessageFormat.Html)
},
storeInCache = true,
progressWatcher = progressCallback?.toProgressWatcher()
)
}
@ -374,6 +376,7 @@ class RustTimeline(
// Maybe allow a caption in the future?
caption = null,
formattedCaption = null,
storeInCache = true,
progressWatcher = progressCallback?.toProgressWatcher()
)
}
@ -381,7 +384,7 @@ class RustTimeline(
override suspend fun sendFile(file: File, fileInfo: FileInfo, progressCallback: ProgressCallback?): Result<MediaUploadHandler> {
return sendAttachment(listOf(file)) {
inner.sendFile(file.path, fileInfo.map(), progressCallback?.toProgressWatcher())
inner.sendFile(file.path, fileInfo.map(), false, progressCallback?.toProgressWatcher())
}
}
@ -496,6 +499,7 @@ class RustTimeline(
// Maybe allow a caption in the future?
caption = null,
formattedCaption = null,
storeInCache = true,
progressWatcher = progressCallback?.toProgressWatcher(),
)
}

View file

@ -24,7 +24,7 @@ import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
import org.matrix.rustcomponents.sdk.EventOrTransactionId
import org.matrix.rustcomponents.sdk.EventSendState
import org.matrix.rustcomponents.sdk.QueueWedgeError
import org.matrix.rustcomponents.sdk.Reaction
import org.matrix.rustcomponents.sdk.ShieldState
import uniffi.matrix_sdk_common.ShieldStateCode
@ -78,25 +78,31 @@ fun RustEventSendState?.map(): LocalEventSendState? {
null -> null
RustEventSendState.NotSentYet -> LocalEventSendState.Sending
is RustEventSendState.SendingFailed -> {
if (isRecoverable) {
LocalEventSendState.Sending
} else {
LocalEventSendState.Failed.Unknown(error)
when (val queueWedgeError = error) {
QueueWedgeError.CrossVerificationRequired -> {
// The current device is not cross-signed (or cross signing is not setup)
LocalEventSendState.Failed.SendingFromUnverifiedDevice
}
is QueueWedgeError.IdentityViolations -> {
LocalEventSendState.Failed.VerifiedUserChangedIdentity(queueWedgeError.users.map { UserId(it) })
}
is QueueWedgeError.InsecureDevices -> {
LocalEventSendState.Failed.VerifiedUserHasUnsignedDevice(
devices = queueWedgeError.userDeviceMap.entries.associate { entry ->
UserId(entry.key) to entry.value.map { DeviceId(it) }
}
)
}
is QueueWedgeError.GenericApiError -> {
if (isRecoverable) {
LocalEventSendState.Sending
} else {
LocalEventSendState.Failed.Unknown(queueWedgeError.msg)
}
}
}
}
is RustEventSendState.Sent -> LocalEventSendState.Sent(EventId(eventId))
is RustEventSendState.VerifiedUserChangedIdentity -> {
LocalEventSendState.Failed.VerifiedUserChangedIdentity(users.map { UserId(it) })
}
is RustEventSendState.VerifiedUserHasUnsignedDevice -> {
LocalEventSendState.Failed.VerifiedUserHasUnsignedDevice(
devices = devices.entries.associate { entry ->
UserId(entry.key) to entry.value.map { DeviceId(it) }
}
)
}
EventSendState.CrossSigningNotSetup -> LocalEventSendState.Failed.CrossSigningNotSetup
EventSendState.SendingFromUnverifiedDevice -> LocalEventSendState.Failed.SendingFromUnverifiedDevice
}
}

View file

@ -140,8 +140,11 @@ private fun RustMembershipChange.map(): MembershipChange {
private fun RustUtdCause.map(): UtdCause {
return when (this) {
RustUtdCause.MEMBERSHIP -> UtdCause.Membership
RustUtdCause.SENT_BEFORE_WE_JOINED -> UtdCause.SentBeforeWeJoined
RustUtdCause.UNKNOWN -> UtdCause.Unknown
RustUtdCause.VERIFICATION_VIOLATION -> UtdCause.VerificationViolation
RustUtdCause.UNSIGNED_DEVICE -> UtdCause.UnsignedDevice
RustUtdCause.UNKNOWN_DEVICE -> UtdCause.UnknownDevice
}
}

View file

@ -74,7 +74,7 @@ class UtdTrackerTest {
UnableToDecryptInfo(
eventId = AN_EVENT_ID.value,
timeToDecryptMs = 123.toULong(),
cause = UtdCause.MEMBERSHIP,
cause = UtdCause.SENT_BEFORE_WE_JOINED,
)
)
assertThat(fakeAnalyticsService.capturedEvents).containsExactly(
@ -90,4 +90,50 @@ class UtdTrackerTest {
assertThat(fakeAnalyticsService.screenEvents).isEmpty()
assertThat(fakeAnalyticsService.trackedErrors).isEmpty()
}
@Test
fun `when onUtd is called with insecure cause, the expected analytics Event is sent`() {
val fakeAnalyticsService = FakeAnalyticsService()
val sut = UtdTracker(fakeAnalyticsService)
sut.onUtd(
UnableToDecryptInfo(
eventId = AN_EVENT_ID.value,
timeToDecryptMs = 123.toULong(),
cause = UtdCause.UNSIGNED_DEVICE,
)
)
assertThat(fakeAnalyticsService.capturedEvents).containsExactly(
Error(
context = null,
cryptoModule = Error.CryptoModule.Rust,
cryptoSDK = Error.CryptoSDK.Rust,
timeToDecryptMillis = 123,
domain = Error.Domain.E2EE,
name = Error.Name.ExpectedSentByInsecureDevice
)
)
}
@Test
fun `when onUtd is called with verification violation cause, the expected analytics Event is sent`() {
val fakeAnalyticsService = FakeAnalyticsService()
val sut = UtdTracker(fakeAnalyticsService)
sut.onUtd(
UnableToDecryptInfo(
eventId = AN_EVENT_ID.value,
timeToDecryptMs = 123.toULong(),
cause = UtdCause.VERIFICATION_VIOLATION,
)
)
assertThat(fakeAnalyticsService.capturedEvents).containsExactly(
Error(
context = null,
cryptoModule = Error.CryptoModule.Rust,
cryptoSDK = Error.CryptoSDK.Rust,
timeToDecryptMillis = 123,
domain = Error.Domain.E2EE,
name = Error.Name.ExpectedVerificationViolation
)
)
}
}