fix(deps): update dependency org.matrix.rustcomponents:sdk-android to v25.5.26 (#4781)

Adapt SDK changes:
- `RoomListItem` is gone, we should use `Room` now.
- `SyncService.withUtdHook` has been replaced with `Client.setUtdDelegate`.
- `ClientDelegate.didRefreshTokens` has been removed. It wasn't in use since a long time ago.
- `TracingConfiguration` for the SDK now contains a `sentryDsn` parameter.

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-05-27 11:29:40 +02:00
committed by GitHub
parent f8d7b4dfc9
commit dd95557782
18 changed files with 76 additions and 115 deletions

View File

@@ -169,7 +169,7 @@ jsoup = "org.jsoup:jsoup:1.20.1"
appyx_core = { module = "com.bumble.appyx:core", version.ref = "appyx" }
molecule-runtime = "app.cash.molecule:molecule-runtime:2.1.0"
timber = "com.jakewharton.timber:timber:5.0.1"
matrix_sdk = "org.matrix.rustcomponents:sdk-android:25.5.21"
matrix_sdk = "org.matrix.rustcomponents:sdk-android:25.5.26"
matrix_richtexteditor = { module = "io.element.android:wysiwyg", version.ref = "wysiwyg" }
matrix_richtexteditor_compose = { module = "io.element.android:wysiwyg-compose", version.ref = "wysiwyg" }
sqldelight-driver-android = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" }

View File

@@ -120,10 +120,6 @@ class RustClientSessionDelegate(
}
}
override fun didRefreshTokens() {
// This is done in `saveSessionInKeychain(Session)` instead.
}
override fun retrieveSessionFromKeychain(userId: String): Session {
// This should never be called, as it's only used for multi-process setups
error("retrieveSessionFromKeychain should never be called for Android")

View File

@@ -189,7 +189,6 @@ class RustMatrixClient(
private val roomMembershipObserver = RoomMembershipObserver()
private val roomFactory = RustRoomFactory(
innerClient = innerClient,
roomListService = roomListService,
innerRoomListService = innerRoomListService,
sessionId = sessionId,

View File

@@ -72,8 +72,9 @@ class RustMatrixClientFactory @Inject constructor(
suspend fun create(client: Client): RustMatrixClient {
val (anonymizedAccessToken, anonymizedRefreshToken) = client.session().anonymizedTokens()
client.setUtdDelegate(UtdTracker(analyticsService))
val syncService = client.syncService()
.withUtdHook(UtdTracker(analyticsService))
.withOfflineMode()
.finish()

View File

@@ -212,6 +212,7 @@ class JoinedRustRoom(
internalIdPrefix = internalIdPrefix,
dateDividerMode = dateDividerMode,
trackReadReceipts = trackReadReceipts,
reportUtds = true,
)
).let { innerTimeline ->
val mode = when (createTimelineParams) {

View File

@@ -11,7 +11,6 @@ import io.element.android.libraries.core.coroutine.parallelMap
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.room.ForwardEventException
import io.element.android.libraries.matrix.impl.roomlist.fullRoomWithTimeline
import io.element.android.libraries.matrix.impl.roomlist.roomOrNull
import io.element.android.libraries.matrix.impl.timeline.runWithTimelineListenerRegistered
import kotlinx.coroutines.CancellationException
@@ -49,10 +48,7 @@ class RoomContentForwarder(
val content = (messageLikeContent.kind as? MsgLikeKind.Message)?.content
?: throw ForwardEventException(toRoomIds)
val targetSlidingSyncRooms = toRoomIds.mapNotNull { roomId -> roomListService.roomOrNull(roomId.value) }
val targetRooms = targetSlidingSyncRooms.map { slidingSyncRoom ->
slidingSyncRoom.use { it.fullRoomWithTimeline(null) }
}
val targetRooms = toRoomIds.mapNotNull { roomId -> roomListService.roomOrNull(roomId.value) }
val failedForwardingTo = mutableSetOf<RoomId>()
targetRooms.parallelMap { room ->
room.use { targetRoom ->

View File

@@ -20,7 +20,6 @@ import io.element.android.libraries.matrix.api.room.RoomMembershipObserver
import io.element.android.libraries.matrix.api.roomlist.RoomListService
import io.element.android.libraries.matrix.api.roomlist.awaitLoaded
import io.element.android.libraries.matrix.impl.room.preview.RoomPreviewInfoMapper
import io.element.android.libraries.matrix.impl.roomlist.fullRoomWithTimeline
import io.element.android.libraries.matrix.impl.roomlist.roomOrNull
import io.element.android.services.toolbox.api.systemclock.SystemClock
import kotlinx.coroutines.CoroutineScope
@@ -28,10 +27,12 @@ import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext
import org.matrix.rustcomponents.sdk.Client
import org.matrix.rustcomponents.sdk.DateDividerMode
import org.matrix.rustcomponents.sdk.Membership
import org.matrix.rustcomponents.sdk.Room
import org.matrix.rustcomponents.sdk.RoomListItem
import org.matrix.rustcomponents.sdk.TimelineConfiguration
import org.matrix.rustcomponents.sdk.TimelineFilter
import org.matrix.rustcomponents.sdk.TimelineFocus
import timber.log.Timber
import java.util.concurrent.atomic.AtomicBoolean
import org.matrix.rustcomponents.sdk.RoomListService as InnerRoomListService
@@ -39,7 +40,6 @@ import org.matrix.rustcomponents.sdk.RoomListService as InnerRoomListService
class RustRoomFactory(
private val sessionId: SessionId,
private val deviceId: DeviceId,
private val innerClient: Client,
private val notificationSettingsService: NotificationSettingsService,
private val sessionCoroutineScope: CoroutineScope,
private val dispatchers: CoroutineDispatchers,
@@ -79,16 +79,11 @@ class RustRoomFactory(
Timber.d("Room factory is destroyed, returning null for $roomId")
return@withContext null
}
val roomListItem = awaitRoomListItem(roomId) ?: return@withContext null
getBaseRoom(roomListItem)
val room = awaitRoomInRoomList(roomId) ?: return@withContext null
getBaseRoom(room)
}
}
private suspend fun getBaseRoom(roomListItem: RoomListItem): RustBaseRoom? {
val sdkRoom = innerClient.getRoom(roomListItem.id()) ?: return null
return getBaseRoom(sdkRoom)
}
private suspend fun getBaseRoom(sdkRoom: Room): RustBaseRoom {
val initialRoomInfo = sdkRoom.roomInfo()
return RustBaseRoom(
@@ -110,18 +105,27 @@ class RustRoomFactory(
Timber.d("Room factory is destroyed, returning null for $roomId")
return@withContext null
}
val roomListItem = awaitRoomListItem(roomId) ?: return@withContext null
val sdkRoom = awaitRoomInRoomList(roomId) ?: return@withContext null
if (roomListItem.membership() == Membership.JOINED) {
// Init the live timeline in the SDK from the RoomListItem
val sdkRoom = roomListItem.fullRoomWithTimeline(eventFilters)
if (sdkRoom.membership() == Membership.JOINED) {
// Init the live timeline in the SDK from the Room
val timeline = sdkRoom.timelineWithConfiguration(
TimelineConfiguration(
focus = TimelineFocus.Live,
filter = eventFilters?.let(TimelineFilter::EventTypeFilter) ?: TimelineFilter.All,
internalIdPrefix = "live",
dateDividerMode = DateDividerMode.DAILY,
trackReadReceipts = true,
reportUtds = true,
)
)
GetRoomResult.Joined(
JoinedRustRoom(
baseRoom = getBaseRoom(sdkRoom),
notificationSettingsService = notificationSettingsService,
roomContentForwarder = roomContentForwarder,
liveInnerTimeline = sdkRoom.timeline(),
liveInnerTimeline = timeline,
coroutineDispatchers = dispatchers,
systemClock = systemClock,
featureFlagService = featureFlagService,
@@ -129,7 +133,7 @@ class RustRoomFactory(
)
} else {
val preview = try {
roomListItem.previewRoom(via = emptyList())
sdkRoom.previewRoom(via = emptyList())
} catch (e: Exception) {
Timber.e(e, "Failed to get room preview for $roomId")
return@withContext null
@@ -138,7 +142,7 @@ class RustRoomFactory(
GetRoomResult.NotJoined(
NotJoinedRustRoom(
sessionId = sessionId,
localRoom = getBaseRoom(roomListItem),
localRoom = getBaseRoom(sdkRoom),
previewInfo = RoomPreviewInfoMapper.map(preview.info()),
)
)
@@ -147,22 +151,22 @@ class RustRoomFactory(
}
/**
* Get the Rust room list item for a room, retrying after the room list is loaded if necessary.
* Get the Rust room for a room, retrying after the room list is loaded if necessary.
*/
private suspend fun awaitRoomListItem(roomId: RoomId): RoomListItem? {
var roomListItem = innerRoomListService.roomOrNull(roomId.value)
if (roomListItem == null) {
private suspend fun awaitRoomInRoomList(roomId: RoomId): Room? {
var sdkRoom = innerRoomListService.roomOrNull(roomId.value)
if (sdkRoom == null) {
// ... otherwise, lets wait for the SS to load all rooms and check again.
roomListService.allRooms.awaitLoaded()
roomListItem = innerRoomListService.roomOrNull(roomId.value)
sdkRoom = innerRoomListService.roomOrNull(roomId.value)
}
if (roomListItem == null) {
if (sdkRoom == null) {
Timber.d("Room not found for $roomId")
return null
}
return roomListItem
return sdkRoom
}
}

View File

@@ -19,11 +19,11 @@ import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import org.matrix.rustcomponents.sdk.Room
import org.matrix.rustcomponents.sdk.RoomListEntriesDynamicFilterKind
import org.matrix.rustcomponents.sdk.RoomListEntriesListener
import org.matrix.rustcomponents.sdk.RoomListEntriesUpdate
import org.matrix.rustcomponents.sdk.RoomListInterface
import org.matrix.rustcomponents.sdk.RoomListItem
import org.matrix.rustcomponents.sdk.RoomListLoadingState
import org.matrix.rustcomponents.sdk.RoomListLoadingStateListener
import org.matrix.rustcomponents.sdk.RoomListServiceInterface
@@ -114,7 +114,7 @@ internal fun RoomListServiceInterface.syncIndicator(): Flow<RoomListServiceSyncI
)
}.buffer(Channel.UNLIMITED)
internal fun RoomListServiceInterface.roomOrNull(roomId: String): RoomListItem? {
internal fun RoomListServiceInterface.roomOrNull(roomId: String): Room? {
return tryOrNull(
onError = { Timber.e(it, "Failed finding room with id=$roomId.") }
) {

View File

@@ -1,20 +0,0 @@
/*
* Copyright 2024 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.libraries.matrix.impl.roomlist
import org.matrix.rustcomponents.sdk.Room
import org.matrix.rustcomponents.sdk.RoomListItem
import org.matrix.rustcomponents.sdk.TimelineEventTypeFilter
/** Returns a `Room` with an initialized timeline using the given [filter]. */
suspend fun RoomListItem.fullRoomWithTimeline(filter: TimelineEventTypeFilter? = null): Room {
if (!isTimelineInitialized()) {
initTimeline(filter, "live")
}
return fullRoom()
}

View File

@@ -10,16 +10,16 @@ package io.element.android.libraries.matrix.impl.roomlist
import io.element.android.libraries.matrix.api.roomlist.RoomSummary
import io.element.android.libraries.matrix.impl.room.RoomInfoMapper
import io.element.android.libraries.matrix.impl.room.message.RoomMessageFactory
import org.matrix.rustcomponents.sdk.RoomListItem
import org.matrix.rustcomponents.sdk.Room
import org.matrix.rustcomponents.sdk.use
class RoomSummaryFactory(
private val roomMessageFactory: RoomMessageFactory = RoomMessageFactory(),
private val roomInfoMapper: RoomInfoMapper = RoomInfoMapper(),
) {
suspend fun create(roomListItem: RoomListItem): RoomSummary {
val roomInfo = roomListItem.roomInfo().let(roomInfoMapper::map)
val latestRoomMessage = roomListItem.latestEvent().use { event ->
suspend fun create(room: Room): RoomSummary {
val roomInfo = room.roomInfo().let(roomInfoMapper::map)
val latestRoomMessage = room.latestEvent().use { event ->
roomMessageFactory.create(event)
}
return RoomSummary(

View File

@@ -12,8 +12,8 @@ import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext
import org.matrix.rustcomponents.sdk.Room
import org.matrix.rustcomponents.sdk.RoomListEntriesUpdate
import org.matrix.rustcomponents.sdk.RoomListItem
import org.matrix.rustcomponents.sdk.RoomListServiceInterface
import org.matrix.rustcomponents.sdk.use
import timber.log.Timber
@@ -95,20 +95,16 @@ class RoomSummaryListProcessor(
}
}
private suspend fun buildSummaryForRoomListEntry(entry: RoomListItem): RoomSummary {
return buildRoomSummaryForRoomListItem(entry)
private suspend fun buildSummaryForRoomListEntry(entry: Room): RoomSummary {
return entry.use { roomSummaryDetailsFactory.create(room = it) }
}
private suspend fun buildRoomSummaryForIdentifier(identifier: String): RoomSummary? {
return roomListService.roomOrNull(identifier)?.use { roomListItem ->
buildRoomSummaryForRoomListItem(roomListItem)
return roomListService.roomOrNull(identifier)?.let { room ->
buildSummaryForRoomListEntry(room)
}
}
private suspend fun buildRoomSummaryForRoomListItem(roomListItem: RoomListItem): RoomSummary {
return roomSummaryDetailsFactory.create(roomListItem = roomListItem)
}
private suspend fun updateRoomSummaries(block: suspend MutableList<RoomSummary>.() -> Unit) = withContext(coroutineContext) {
mutex.withLock {
val current = roomSummaries.replayCache.lastOrNull()

View File

@@ -53,4 +53,5 @@ fun TracingConfiguration.map(): org.matrix.rustcomponents.sdk.TracingConfigurati
extraTargets = extraTargets,
traceLogPacks = traceLogPacks.map(),
writeToFiles = writesToFilesConfiguration.toTracingFileConfiguration(),
sentryDsn = null,
)

View File

@@ -25,6 +25,7 @@ import org.matrix.rustcomponents.sdk.RoomDirectorySearch
import org.matrix.rustcomponents.sdk.Session
import org.matrix.rustcomponents.sdk.SyncServiceBuilder
import org.matrix.rustcomponents.sdk.TaskHandle
import org.matrix.rustcomponents.sdk.UnableToDecryptDelegate
class FakeRustClient(
private val userId: String = A_USER_ID.value,
@@ -34,6 +35,7 @@ class FakeRustClient(
private val encryption: Encryption = FakeRustEncryption(),
private val session: Session = aRustSession(),
private val clearCachesResult: () -> Unit = { lambdaError() },
private val withUtdHook: (UnableToDecryptDelegate) -> Unit = { lambdaError() },
private val closeResult: () -> Unit = {},
) : Client(NoPointer) {
override fun userId(): String = userId
@@ -58,5 +60,6 @@ class FakeRustClient(
override suspend fun deletePusher(identifiers: PusherIdentifiers) = Unit
override suspend fun clearCaches() = simulateLongTask { clearCachesResult() }
override suspend fun setUtdDelegate(utdDelegate: UnableToDecryptDelegate) = withUtdHook(utdDelegate)
override fun close() = closeResult()
}

View File

@@ -47,6 +47,6 @@ class FakeRustClientBuilder : ClientBuilder(NoPointer) {
}
override suspend fun build(): Client {
return FakeRustClient()
return FakeRustClient(withUtdHook = {})
}
}

View File

@@ -8,16 +8,21 @@
package io.element.android.libraries.matrix.impl.fixtures.fakes
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.impl.fixtures.factories.aRustRoomInfo
import io.element.android.libraries.matrix.test.A_ROOM_ID
import io.element.android.tests.testutils.lambda.lambdaError
import org.matrix.rustcomponents.sdk.EventTimelineItem
import org.matrix.rustcomponents.sdk.NoPointer
import org.matrix.rustcomponents.sdk.Room
import org.matrix.rustcomponents.sdk.RoomInfo
import org.matrix.rustcomponents.sdk.RoomMembersIterator
class FakeRustRoom(
private val roomId: RoomId = A_ROOM_ID,
private val getMembers: () -> RoomMembersIterator = { lambdaError() },
private val getMembersNoSync: () -> RoomMembersIterator = { lambdaError() },
private val latestEventLambda: () -> EventTimelineItem? = { lambdaError() },
private val roomInfo: RoomInfo = aRustRoomInfo(id = roomId.value),
) : Room(NoPointer) {
override fun id(): String {
return roomId.value
@@ -31,6 +36,14 @@ class FakeRustRoom(
return getMembersNoSync()
}
override suspend fun roomInfo(): RoomInfo {
return roomInfo
}
override suspend fun latestEvent(): EventTimelineItem? {
return latestEventLambda()
}
override fun close() {
// No-op
}

View File

@@ -1,33 +0,0 @@
/*
* Copyright 2024 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.libraries.matrix.impl.fixtures.fakes
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.impl.fixtures.factories.aRustRoomInfo
import org.matrix.rustcomponents.sdk.EventTimelineItem
import org.matrix.rustcomponents.sdk.NoPointer
import org.matrix.rustcomponents.sdk.RoomInfo
import org.matrix.rustcomponents.sdk.RoomListItem
class FakeRustRoomListItem(
private val roomId: RoomId,
private val roomInfo: RoomInfo = aRustRoomInfo(id = roomId.value),
private val latestEvent: EventTimelineItem? = null,
) : RoomListItem(NoPointer) {
override fun id(): String {
return roomId.value
}
override suspend fun roomInfo(): RoomInfo {
return roomInfo
}
override suspend fun latestEvent(): EventTimelineItem? {
return latestEvent
}
}

View File

@@ -10,10 +10,8 @@ package io.element.android.libraries.matrix.impl.fixtures.fakes
import org.matrix.rustcomponents.sdk.NoPointer
import org.matrix.rustcomponents.sdk.SyncService
import org.matrix.rustcomponents.sdk.SyncServiceBuilder
import org.matrix.rustcomponents.sdk.UnableToDecryptDelegate
class FakeRustSyncServiceBuilder : SyncServiceBuilder(NoPointer) {
override suspend fun withUtdHook(delegate: UnableToDecryptDelegate): SyncServiceBuilder = this
override fun withOfflineMode(): SyncServiceBuilder = this
override suspend fun finish(): SyncService = FakeRustSyncService()
}

View File

@@ -8,8 +8,9 @@
package io.element.android.libraries.matrix.impl.roomlist
import com.google.common.truth.Truth.assertThat
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.roomlist.RoomSummary
import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeRustRoomListItem
import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeRustRoom
import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeRustRoomListService
import io.element.android.libraries.matrix.test.A_ROOM_ID
import io.element.android.libraries.matrix.test.A_ROOM_ID_2
@@ -30,7 +31,7 @@ class RoomSummaryListProcessorTest {
summaries.value = listOf(aRoomSummary())
val processor = createProcessor()
val newEntry = FakeRustRoomListItem(A_ROOM_ID_2)
val newEntry = aRustRoom(A_ROOM_ID_2)
processor.postUpdate(listOf(RoomListEntriesUpdate.Append(listOf(newEntry, newEntry, newEntry))))
assertThat(summaries.value.count()).isEqualTo(4)
@@ -41,7 +42,7 @@ class RoomSummaryListProcessorTest {
fun `PushBack adds a new entry at the end of the list`() = runTest {
summaries.value = listOf(aRoomSummary())
val processor = createProcessor()
processor.postUpdate(listOf(RoomListEntriesUpdate.PushBack(FakeRustRoomListItem(A_ROOM_ID_2))))
processor.postUpdate(listOf(RoomListEntriesUpdate.PushBack(aRustRoom(A_ROOM_ID_2))))
assertThat(summaries.value.count()).isEqualTo(2)
assertThat(summaries.value.last().roomId).isEqualTo(A_ROOM_ID_2)
@@ -51,7 +52,7 @@ class RoomSummaryListProcessorTest {
fun `PushFront inserts a new entry at the start of the list`() = runTest {
summaries.value = listOf(aRoomSummary())
val processor = createProcessor()
processor.postUpdate(listOf(RoomListEntriesUpdate.PushFront(FakeRustRoomListItem(A_ROOM_ID_2))))
processor.postUpdate(listOf(RoomListEntriesUpdate.PushFront(aRustRoom(A_ROOM_ID_2))))
assertThat(summaries.value.count()).isEqualTo(2)
assertThat(summaries.value.first().roomId).isEqualTo(A_ROOM_ID_2)
@@ -63,7 +64,7 @@ class RoomSummaryListProcessorTest {
val processor = createProcessor()
val index = 0
processor.postUpdate(listOf(RoomListEntriesUpdate.Set(index.toUInt(), FakeRustRoomListItem(A_ROOM_ID_2))))
processor.postUpdate(listOf(RoomListEntriesUpdate.Set(index.toUInt(), aRustRoom(A_ROOM_ID_2))))
assertThat(summaries.value.count()).isEqualTo(1)
assertThat(summaries.value[index].roomId).isEqualTo(A_ROOM_ID_2)
@@ -75,7 +76,7 @@ class RoomSummaryListProcessorTest {
val processor = createProcessor()
val index = 0
processor.postUpdate(listOf(RoomListEntriesUpdate.Insert(index.toUInt(), FakeRustRoomListItem(A_ROOM_ID_2))))
processor.postUpdate(listOf(RoomListEntriesUpdate.Insert(index.toUInt(), aRustRoom(A_ROOM_ID_2))))
assertThat(summaries.value.count()).isEqualTo(2)
assertThat(summaries.value[index].roomId).isEqualTo(A_ROOM_ID_2)
@@ -163,12 +164,17 @@ class RoomSummaryListProcessorTest {
val processor = createProcessor()
val index = 0
processor.postUpdate(listOf(RoomListEntriesUpdate.Reset(listOf(FakeRustRoomListItem(A_ROOM_ID_3)))))
processor.postUpdate(listOf(RoomListEntriesUpdate.Reset(listOf(aRustRoom(A_ROOM_ID_3)))))
assertThat(summaries.value.count()).isEqualTo(1)
assertThat(summaries.value[index].roomId).isEqualTo(A_ROOM_ID_3)
}
private fun aRustRoom(roomId: RoomId = A_ROOM_ID) = FakeRustRoom(
roomId = roomId,
latestEventLambda = { null },
)
private fun TestScope.createProcessor() = RoomSummaryListProcessor(
summaries,
FakeRustRoomListService(),