Merge pull request #5466 from element-hq/feature/bma/replaceFunByVal

Replace fun by val in MatrixClient
This commit is contained in:
Benoit Marty 2025-10-06 22:34:39 +02:00 committed by GitHub
commit 52acb2ca38
38 changed files with 170 additions and 196 deletions

View file

@ -141,8 +141,8 @@ class LoggedInFlowNode(
} }
private val loggedInFlowProcessor = LoggedInEventProcessor( private val loggedInFlowProcessor = LoggedInEventProcessor(
snackbarDispatcher, snackbarDispatcher = snackbarDispatcher,
matrixClient.roomMembershipObserver(), roomMembershipObserver = matrixClient.roomMembershipObserver,
) )
private val verificationListener = object : SessionVerificationServiceListener { private val verificationListener = object : SessionVerificationServiceListener {
@ -189,7 +189,7 @@ class LoggedInFlowNode(
// TODO We do not support Space yet, so directly navigate to main space // TODO We do not support Space yet, so directly navigate to main space
appNavigationStateService.onNavigateToSpace(id, MAIN_SPACE) appNavigationStateService.onNavigateToSpace(id, MAIN_SPACE)
loggedInFlowProcessor.observeEvents(sessionCoroutineScope) loggedInFlowProcessor.observeEvents(sessionCoroutineScope)
matrixClient.sessionVerificationService().setListener(verificationListener) matrixClient.sessionVerificationService.setListener(verificationListener)
mediaPreviewConfigMigration() mediaPreviewConfigMigration()
sessionCoroutineScope.launch { sessionCoroutineScope.launch {
@ -218,7 +218,7 @@ class LoggedInFlowNode(
appNavigationStateService.onLeavingSpace(id) appNavigationStateService.onLeavingSpace(id)
appNavigationStateService.onLeavingSession(id) appNavigationStateService.onLeavingSession(id)
loggedInFlowProcessor.stopObserving() loggedInFlowProcessor.stopObserving()
matrixClient.sessionVerificationService().setListener(null) matrixClient.sessionVerificationService.setListener(null)
} }
) )
setupSendingQueue() setupSendingQueue()

View file

@ -109,7 +109,10 @@ class MatrixSessionCache(
} }
private fun onNewMatrixClient(matrixClient: MatrixClient) { private fun onNewMatrixClient(matrixClient: MatrixClient) {
val syncOrchestrator = syncOrchestratorFactory.create(matrixClient) val syncOrchestrator = syncOrchestratorFactory.create(
syncService = matrixClient.syncService,
sessionCoroutineScope = matrixClient.sessionCoroutineScope,
)
sessionIdsToMatrixSession[matrixClient.sessionId] = InMemoryMatrixSession( sessionIdsToMatrixSession[matrixClient.sessionId] = InMemoryMatrixSession(
matrixClient = matrixClient, matrixClient = matrixClient,
syncOrchestrator = syncOrchestrator, syncOrchestrator = syncOrchestrator,

View file

@ -15,9 +15,10 @@ import io.element.android.features.networkmonitor.api.NetworkMonitor
import io.element.android.features.networkmonitor.api.NetworkStatus import io.element.android.features.networkmonitor.api.NetworkStatus
import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.core.coroutine.childScope import io.element.android.libraries.core.coroutine.childScope
import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.sync.SyncService
import io.element.android.libraries.matrix.api.sync.SyncState import io.element.android.libraries.matrix.api.sync.SyncState
import io.element.android.services.appnavstate.api.AppForegroundStateService import io.element.android.services.appnavstate.api.AppForegroundStateService
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.debounce
@ -32,21 +33,23 @@ import kotlin.time.Duration.Companion.seconds
@AssistedInject @AssistedInject
class SyncOrchestrator( class SyncOrchestrator(
@Assisted matrixClient: MatrixClient, @Assisted private val syncService: SyncService,
@Assisted sessionCoroutineScope: CoroutineScope,
private val appForegroundStateService: AppForegroundStateService, private val appForegroundStateService: AppForegroundStateService,
private val networkMonitor: NetworkMonitor, private val networkMonitor: NetworkMonitor,
dispatchers: CoroutineDispatchers, dispatchers: CoroutineDispatchers,
) { ) {
@AssistedFactory @AssistedFactory
interface Factory { interface Factory {
fun create(matrixClient: MatrixClient): SyncOrchestrator fun create(
syncService: SyncService,
sessionCoroutineScope: CoroutineScope,
): SyncOrchestrator
} }
private val syncService = matrixClient.syncService()
private val tag = "SyncOrchestrator" private val tag = "SyncOrchestrator"
private val coroutineScope = matrixClient.sessionCoroutineScope.childScope(dispatchers.io, tag) private val coroutineScope = sessionCoroutineScope.childScope(dispatchers.io, tag)
private val started = AtomicBoolean(false) private val started = AtomicBoolean(false)

View file

@ -11,7 +11,6 @@ import io.element.android.appnav.di.SyncOrchestrator
import io.element.android.features.networkmonitor.api.NetworkStatus import io.element.android.features.networkmonitor.api.NetworkStatus
import io.element.android.features.networkmonitor.test.FakeNetworkMonitor import io.element.android.features.networkmonitor.test.FakeNetworkMonitor
import io.element.android.libraries.matrix.api.sync.SyncState import io.element.android.libraries.matrix.api.sync.SyncState
import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.matrix.test.sync.FakeSyncService import io.element.android.libraries.matrix.test.sync.FakeSyncService
import io.element.android.services.appnavstate.test.FakeAppForegroundStateService import io.element.android.services.appnavstate.test.FakeAppForegroundStateService
import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.WarmUpRule
@ -385,7 +384,8 @@ class SyncOrchestratorTest {
networkMonitor: FakeNetworkMonitor = FakeNetworkMonitor(), networkMonitor: FakeNetworkMonitor = FakeNetworkMonitor(),
appForegroundStateService: FakeAppForegroundStateService = FakeAppForegroundStateService(), appForegroundStateService: FakeAppForegroundStateService = FakeAppForegroundStateService(),
) = SyncOrchestrator( ) = SyncOrchestrator(
matrixClient = FakeMatrixClient(syncService = syncService, sessionCoroutineScope = backgroundScope), syncService = syncService,
sessionCoroutineScope = backgroundScope,
networkMonitor = networkMonitor, networkMonitor = networkMonitor,
appForegroundStateService = appForegroundStateService, appForegroundStateService = appForegroundStateService,
dispatchers = testCoroutineDispatchers(), dispatchers = testCoroutineDispatchers(),

View file

@ -10,12 +10,13 @@ package io.element.android.appnav.di
import com.bumble.appyx.core.state.MutableSavedStateMapImpl import com.bumble.appyx.core.state.MutableSavedStateMapImpl
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import io.element.android.features.networkmonitor.test.FakeNetworkMonitor import io.element.android.features.networkmonitor.test.FakeNetworkMonitor
import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.sync.SyncService
import io.element.android.libraries.matrix.test.A_SESSION_ID import io.element.android.libraries.matrix.test.A_SESSION_ID
import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.matrix.test.auth.FakeMatrixAuthenticationService import io.element.android.libraries.matrix.test.auth.FakeMatrixAuthenticationService
import io.element.android.services.appnavstate.test.FakeAppForegroundStateService import io.element.android.services.appnavstate.test.FakeAppForegroundStateService
import io.element.android.tests.testutils.testCoroutineDispatchers import io.element.android.tests.testutils.testCoroutineDispatchers
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.runTest
import org.junit.Test import org.junit.Test
@ -117,9 +118,13 @@ class MatrixSessionCacheTest {
} }
private fun TestScope.createSyncOrchestratorFactory() = object : SyncOrchestrator.Factory { private fun TestScope.createSyncOrchestratorFactory() = object : SyncOrchestrator.Factory {
override fun create(matrixClient: MatrixClient): SyncOrchestrator { override fun create(
syncService: SyncService,
sessionCoroutineScope: CoroutineScope,
): SyncOrchestrator {
return SyncOrchestrator( return SyncOrchestrator(
matrixClient, syncService = syncService,
sessionCoroutineScope = sessionCoroutineScope,
appForegroundStateService = FakeAppForegroundStateService(), appForegroundStateService = FakeAppForegroundStateService(),
networkMonitor = FakeNetworkMonitor(), networkMonitor = FakeNetworkMonitor(),
dispatchers = testCoroutineDispatchers(), dispatchers = testCoroutineDispatchers(),

View file

@ -242,7 +242,7 @@ class CallScreenPresenter(
} }
coroutineScope.launch { coroutineScope.launch {
Timber.d("Observing sync state in-call for sessionId: ${roomCallType.sessionId}") Timber.d("Observing sync state in-call for sessionId: ${roomCallType.sessionId}")
client.syncService().syncState client.syncService.syncState
.collect { state -> .collect { state ->
if (state != SyncState.Running) { if (state != SyncState.Running) {
appForegroundStateService.updateIsInCallState(true) appForegroundStateService.updateIsInCallState(true)

View file

@ -39,7 +39,6 @@ import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.fullscreenintent.api.FullScreenIntentPermissionsState import io.element.android.libraries.fullscreenintent.api.FullScreenIntentPermissionsState
import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.encryption.EncryptionService
import io.element.android.libraries.matrix.api.encryption.RecoveryState import io.element.android.libraries.matrix.api.encryption.RecoveryState
import io.element.android.libraries.matrix.api.roomlist.RoomList import io.element.android.libraries.matrix.api.roomlist.RoomList
import io.element.android.libraries.matrix.api.timeline.ReceiptType import io.element.android.libraries.matrix.api.timeline.ReceiptType
@ -84,7 +83,7 @@ class RoomListPresenter(
private val appPreferencesStore: AppPreferencesStore, private val appPreferencesStore: AppPreferencesStore,
private val seenInvitesStore: SeenInvitesStore, private val seenInvitesStore: SeenInvitesStore,
) : Presenter<RoomListState> { ) : Presenter<RoomListState> {
private val encryptionService: EncryptionService = client.encryptionService() private val encryptionService = client.encryptionService
@Composable @Composable
override fun present(): RoomListState { override fun present(): RoomListState {

View file

@ -616,7 +616,7 @@ class RoomListPresenterTest {
roomLastMessageFormatter = roomLastMessageFormatter, roomLastMessageFormatter = roomLastMessageFormatter,
), ),
coroutineDispatchers = testCoroutineDispatchers(), coroutineDispatchers = testCoroutineDispatchers(),
notificationSettingsService = client.notificationSettingsService(), notificationSettingsService = client.notificationSettingsService,
sessionCoroutineScope = backgroundScope, sessionCoroutineScope = backgroundScope,
dateTimeObserver = FakeDateTimeObserver(), dateTimeObserver = FakeDateTimeObserver(),
), ),

View file

@ -82,7 +82,7 @@ class CreateAccountPresenter(
tryOrNull { tryOrNull {
// Wait until the session is verified // Wait until the session is verified
val client = clientProvider.getOrRestore(sessionId).getOrThrow() val client = clientProvider.getOrRestore(sessionId).getOrThrow()
val sessionVerificationService = client.sessionVerificationService() val sessionVerificationService = client.sessionVerificationService
withTimeout(10.seconds) { sessionVerificationService.sessionVerifiedStatus.first { it.isVerified() } } withTimeout(10.seconds) { sessionVerificationService.sessionVerifiedStatus.first { it.isVerified() } }
} }
loggedInState.value = AsyncAction.Success(sessionId) loggedInState.value = AsyncAction.Success(sessionId)

View file

@ -62,9 +62,9 @@ import io.element.android.libraries.dateformatter.api.DateFormatter
import io.element.android.libraries.dateformatter.api.DateFormatterMode import io.element.android.libraries.dateformatter.api.DateFormatterMode
import io.element.android.libraries.dateformatter.api.toHumanReadableDuration import io.element.android.libraries.dateformatter.api.toHumanReadableDuration
import io.element.android.libraries.di.RoomScope import io.element.android.libraries.di.RoomScope
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.EventId 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.RoomId
import io.element.android.libraries.matrix.api.core.SessionId
import io.element.android.libraries.matrix.api.core.ThreadId import io.element.android.libraries.matrix.api.core.ThreadId
import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias
@ -73,6 +73,7 @@ import io.element.android.libraries.matrix.api.permalink.PermalinkData
import io.element.android.libraries.matrix.api.room.BaseRoom import io.element.android.libraries.matrix.api.room.BaseRoom
import io.element.android.libraries.matrix.api.room.alias.matches import io.element.android.libraries.matrix.api.room.alias.matches
import io.element.android.libraries.matrix.api.room.joinedRoomMembers import io.element.android.libraries.matrix.api.room.joinedRoomMembers
import io.element.android.libraries.matrix.api.roomlist.RoomListService
import io.element.android.libraries.matrix.api.timeline.Timeline import io.element.android.libraries.matrix.api.timeline.Timeline
import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo
import io.element.android.libraries.matrix.ui.messages.RoomMemberProfilesCache import io.element.android.libraries.matrix.ui.messages.RoomMemberProfilesCache
@ -95,7 +96,8 @@ import kotlinx.parcelize.Parcelize
class MessagesFlowNode( class MessagesFlowNode(
@Assisted buildContext: BuildContext, @Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
private val matrixClient: MatrixClient, private val roomListService: RoomListService,
private val sessionId: SessionId,
private val sendLocationEntryPoint: SendLocationEntryPoint, private val sendLocationEntryPoint: SendLocationEntryPoint,
private val showLocationEntryPoint: ShowLocationEntryPoint, private val showLocationEntryPoint: ShowLocationEntryPoint,
private val createPollEntryPoint: CreatePollEntryPoint, private val createPollEntryPoint: CreatePollEntryPoint,
@ -194,7 +196,7 @@ class MessagesFlowNode(
} }
.launchIn(lifecycleScope) .launchIn(lifecycleScope)
matrixClient.roomListService roomListService
.allRooms .allRooms
.summaries .summaries
.onEach { .onEach {
@ -221,11 +223,13 @@ class MessagesFlowNode(
} }
override fun onPreviewAttachments(attachments: ImmutableList<Attachment>, inReplyToEventId: EventId?) { override fun onPreviewAttachments(attachments: ImmutableList<Attachment>, inReplyToEventId: EventId?) {
backstack.push(NavTarget.AttachmentPreview( backstack.push(
attachment = attachments.first(), NavTarget.AttachmentPreview(
timelineMode = Timeline.Mode.Live, attachment = attachments.first(),
inReplyToEventId = inReplyToEventId, timelineMode = Timeline.Mode.Live,
)) inReplyToEventId = inReplyToEventId,
)
)
} }
override fun onUserDataClick(userId: UserId) { override fun onUserDataClick(userId: UserId) {
@ -262,7 +266,7 @@ class MessagesFlowNode(
override fun onJoinCallClick(roomId: RoomId) { override fun onJoinCallClick(roomId: RoomId) {
val callType = CallType.RoomCall( val callType = CallType.RoomCall(
sessionId = matrixClient.sessionId, sessionId = sessionId,
roomId = roomId, roomId = roomId,
) )
analyticsService.captureInteraction(Interaction.Name.MobileRoomCallButton) analyticsService.captureInteraction(Interaction.Name.MobileRoomCallButton)
@ -348,18 +352,20 @@ class MessagesFlowNode(
} }
is NavTarget.CreatePoll -> { is NavTarget.CreatePoll -> {
createPollEntryPoint.nodeBuilder(this, buildContext) createPollEntryPoint.nodeBuilder(this, buildContext)
.params(CreatePollEntryPoint.Params( .params(
timelineMode = navTarget.timelineMode, CreatePollEntryPoint.Params(
mode = CreatePollMode.NewPoll timelineMode = navTarget.timelineMode,
)) mode = CreatePollMode.NewPoll
)
)
.build() .build()
} }
is NavTarget.EditPoll -> { is NavTarget.EditPoll -> {
createPollEntryPoint.nodeBuilder(this, buildContext) createPollEntryPoint.nodeBuilder(this, buildContext)
.params( .params(
CreatePollEntryPoint.Params( CreatePollEntryPoint.Params(
timelineMode = navTarget.timelineMode, timelineMode = navTarget.timelineMode,
mode = CreatePollMode.EditPoll(eventId = navTarget.eventId) mode = CreatePollMode.EditPoll(eventId = navTarget.eventId)
) )
) )
.build() .build()
@ -412,11 +418,13 @@ class MessagesFlowNode(
} }
override fun onPreviewAttachments(attachments: ImmutableList<Attachment>, inReplyToEventId: EventId?) { override fun onPreviewAttachments(attachments: ImmutableList<Attachment>, inReplyToEventId: EventId?) {
backstack.push(NavTarget.AttachmentPreview( backstack.push(
attachment = attachments.first(), NavTarget.AttachmentPreview(
timelineMode = Timeline.Mode.Thread(navTarget.threadRootId), attachment = attachments.first(),
inReplyToEventId = inReplyToEventId, timelineMode = Timeline.Mode.Thread(navTarget.threadRootId),
)) inReplyToEventId = inReplyToEventId,
)
)
} }
override fun onUserDataClick(userId: UserId) { override fun onUserDataClick(userId: UserId) {
@ -453,7 +461,7 @@ class MessagesFlowNode(
override fun onJoinCallClick(roomId: RoomId) { override fun onJoinCallClick(roomId: RoomId) {
val callType = CallType.RoomCall( val callType = CallType.RoomCall(
sessionId = matrixClient.sessionId, sessionId = sessionId,
roomId = roomId, roomId = roomId,
) )
analyticsService.captureInteraction(Interaction.Name.MobileRoomCallButton) analyticsService.captureInteraction(Interaction.Name.MobileRoomCallButton)

View file

@ -30,9 +30,10 @@ import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.permalink.PermalinkData import io.element.android.libraries.matrix.api.permalink.PermalinkData
import io.element.android.libraries.matrix.api.timeline.Timeline import io.element.android.libraries.matrix.api.timeline.Timeline
import io.element.android.libraries.matrix.test.AN_EVENT_ID import io.element.android.libraries.matrix.test.AN_EVENT_ID
import io.element.android.libraries.matrix.test.A_SESSION_ID
import io.element.android.libraries.matrix.test.A_USER_ID import io.element.android.libraries.matrix.test.A_USER_ID
import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.matrix.test.room.FakeBaseRoom import io.element.android.libraries.matrix.test.room.FakeBaseRoom
import io.element.android.libraries.matrix.test.roomlist.FakeRoomListService
import io.element.android.libraries.matrix.ui.messages.RoomMemberProfilesCache import io.element.android.libraries.matrix.ui.messages.RoomMemberProfilesCache
import io.element.android.libraries.matrix.ui.messages.RoomNamesCache import io.element.android.libraries.matrix.ui.messages.RoomNamesCache
import io.element.android.libraries.mediaviewer.api.MediaViewerEntryPoint import io.element.android.libraries.mediaviewer.api.MediaViewerEntryPoint
@ -60,7 +61,8 @@ class DefaultMessagesEntryPointTest {
MessagesFlowNode( MessagesFlowNode(
buildContext = buildContext, buildContext = buildContext,
plugins = plugins, plugins = plugins,
matrixClient = FakeMatrixClient(), roomListService = FakeRoomListService(),
sessionId = A_SESSION_ID,
sendLocationEntryPoint = object : SendLocationEntryPoint { sendLocationEntryPoint = object : SendLocationEntryPoint {
override fun builder(timelineMode: Timeline.Mode) = lambdaError() override fun builder(timelineMode: Timeline.Mode) = lambdaError()
}, },

View file

@ -176,8 +176,8 @@ class DefaultBugReporter(
.addFormDataPart("branch_name", buildMeta.gitBranchName) .addFormDataPart("branch_name", buildMeta.gitBranchName)
userId?.let { userId?.let {
matrixClientProvider.getOrNull(it)?.let { client -> matrixClientProvider.getOrNull(it)?.let { client ->
val curveKey = client.encryptionService().deviceCurve25519() val curveKey = client.encryptionService.deviceCurve25519()
val edKey = client.encryptionService().deviceEd25519() val edKey = client.encryptionService.deviceEd25519()
if (curveKey != null && edKey != null) { if (curveKey != null && edKey != null) {
builder.addFormDataPart("device_keys", "curve25519:$curveKey, ed25519:$edKey") builder.addFormDataPart("device_keys", "curve25519:$curveKey, ed25519:$edKey")
} }

View file

@ -143,12 +143,12 @@ class RoomDetailsPresenter(
} }
RoomDetailsEvent.MuteNotification -> { RoomDetailsEvent.MuteNotification -> {
scope.launch(dispatchers.io) { scope.launch(dispatchers.io) {
client.notificationSettingsService().muteRoom(room.roomId) notificationSettingsService.muteRoom(room.roomId)
} }
} }
RoomDetailsEvent.UnmuteNotification -> { RoomDetailsEvent.UnmuteNotification -> {
scope.launch(dispatchers.io) { scope.launch(dispatchers.io) {
client.notificationSettingsService().unmuteRoom(room.roomId, isEncrypted, room.isOneToOne) notificationSettingsService.unmuteRoom(room.roomId, isEncrypted, room.isOneToOne)
} }
} }
is RoomDetailsEvent.SetFavorite -> scope.setFavorite(event.isFavorite) is RoomDetailsEvent.SetFavorite -> scope.setFavorite(event.isFavorite)

View file

@ -104,7 +104,7 @@ class RoomDetailsPresenterTest {
client = matrixClient, client = matrixClient,
room = room, room = room,
featureFlagService = featureFlagService, featureFlagService = featureFlagService,
notificationSettingsService = matrixClient.notificationSettingsService(), notificationSettingsService = matrixClient.notificationSettingsService,
roomMembersDetailsPresenterFactory = roomMemberDetailsPresenterFactory, roomMembersDetailsPresenterFactory = roomMemberDetailsPresenterFactory,
leaveRoomPresenter = { leaveRoomState }, leaveRoomPresenter = { leaveRoomState },
roomCallStatePresenter = { aStandByCallState() }, roomCallStatePresenter = { aStandByCallState() },

View file

@ -10,7 +10,7 @@ package io.element.android.features.securebackup.impl.reset
import dev.zacsweers.metro.Inject import dev.zacsweers.metro.Inject
import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.di.annotations.SessionCoroutineScope import io.element.android.libraries.di.annotations.SessionCoroutineScope
import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.encryption.EncryptionService
import io.element.android.libraries.matrix.api.encryption.IdentityResetHandle import io.element.android.libraries.matrix.api.encryption.IdentityResetHandle
import io.element.android.libraries.matrix.api.verification.SessionVerificationService import io.element.android.libraries.matrix.api.verification.SessionVerificationService
import io.element.android.libraries.matrix.api.verification.SessionVerifiedStatus import io.element.android.libraries.matrix.api.verification.SessionVerifiedStatus
@ -24,7 +24,7 @@ import kotlinx.coroutines.launch
@Inject @Inject
class ResetIdentityFlowManager( class ResetIdentityFlowManager(
private val matrixClient: MatrixClient, private val encryptionService: EncryptionService,
@SessionCoroutineScope private val sessionCoroutineScope: CoroutineScope, @SessionCoroutineScope private val sessionCoroutineScope: CoroutineScope,
private val sessionVerificationService: SessionVerificationService, private val sessionVerificationService: SessionVerificationService,
) { ) {
@ -46,7 +46,7 @@ class ResetIdentityFlowManager(
resetHandleFlow.value = AsyncData.Loading() resetHandleFlow.value = AsyncData.Loading()
sessionCoroutineScope.launch { sessionCoroutineScope.launch {
matrixClient.encryptionService().startIdentityReset() encryptionService.startIdentityReset()
.onSuccess { handle -> .onSuccess { handle ->
resetHandleFlow.value = AsyncData.Success(handle) resetHandleFlow.value = AsyncData.Success(handle)
} }

View file

@ -12,7 +12,6 @@ import com.google.common.truth.Truth.assertThat
import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.matrix.api.encryption.IdentityResetHandle import io.element.android.libraries.matrix.api.encryption.IdentityResetHandle
import io.element.android.libraries.matrix.api.verification.SessionVerifiedStatus import io.element.android.libraries.matrix.api.verification.SessionVerifiedStatus
import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService
import io.element.android.libraries.matrix.test.encryption.FakeIdentityPasswordResetHandle import io.element.android.libraries.matrix.test.encryption.FakeIdentityPasswordResetHandle
import io.element.android.libraries.matrix.test.verification.FakeSessionVerificationService import io.element.android.libraries.matrix.test.verification.FakeSessionVerificationService
@ -130,10 +129,9 @@ class ResetIdentityFlowManagerTest {
private fun TestScope.createFlowManager( private fun TestScope.createFlowManager(
encryptionService: FakeEncryptionService = FakeEncryptionService(), encryptionService: FakeEncryptionService = FakeEncryptionService(),
client: FakeMatrixClient = FakeMatrixClient(encryptionService = encryptionService),
sessionVerificationService: FakeSessionVerificationService = FakeSessionVerificationService(), sessionVerificationService: FakeSessionVerificationService = FakeSessionVerificationService(),
) = ResetIdentityFlowManager( ) = ResetIdentityFlowManager(
matrixClient = client, encryptionService = encryptionService,
sessionCoroutineScope = this, sessionCoroutineScope = this,
sessionVerificationService = sessionVerificationService, sessionVerificationService = sessionVerificationService,
) )

View file

@ -32,8 +32,8 @@ import io.element.android.libraries.architecture.createNode
import io.element.android.libraries.architecture.inputs import io.element.android.libraries.architecture.inputs
import io.element.android.libraries.di.DependencyInjectionGraphOwner import io.element.android.libraries.di.DependencyInjectionGraphOwner
import io.element.android.libraries.di.SessionScope import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.spaces.SpaceService
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
@ContributesNode(SessionScope::class) @ContributesNode(SessionScope::class)
@ -41,7 +41,7 @@ import kotlinx.parcelize.Parcelize
class SpaceFlowNode( class SpaceFlowNode(
@Assisted val buildContext: BuildContext, @Assisted val buildContext: BuildContext,
@Assisted plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
matrixClient: MatrixClient, spaceService: SpaceService,
graphFactory: SpaceFlowGraph.Factory, graphFactory: SpaceFlowGraph.Factory,
) : BaseFlowNode<SpaceFlowNode.NavTarget>( ) : BaseFlowNode<SpaceFlowNode.NavTarget>(
backstack = BackStack( backstack = BackStack(
@ -53,7 +53,7 @@ class SpaceFlowNode(
), DependencyInjectionGraphOwner { ), DependencyInjectionGraphOwner {
private val inputs: SpaceEntryPoint.Inputs = inputs() private val inputs: SpaceEntryPoint.Inputs = inputs()
private val callback = plugins.filterIsInstance<SpaceEntryPoint.Callback>().single() private val callback = plugins.filterIsInstance<SpaceEntryPoint.Callback>().single()
private val spaceRoomList = matrixClient.spaceService.spaceRoomList(inputs.roomId) private val spaceRoomList = spaceService.spaceRoomList(inputs.roomId)
override val graph = graphFactory.create(spaceRoomList) override val graph = graphFactory.create(spaceRoomList)
sealed interface NavTarget : Parcelable { sealed interface NavTarget : Parcelable {

View file

@ -15,7 +15,6 @@ import io.element.android.features.space.api.SpaceEntryPoint
import io.element.android.features.space.impl.di.FakeSpaceFlowGraph import io.element.android.features.space.impl.di.FakeSpaceFlowGraph
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.matrix.test.A_ROOM_ID
import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.matrix.test.spaces.FakeSpaceRoomList import io.element.android.libraries.matrix.test.spaces.FakeSpaceRoomList
import io.element.android.libraries.matrix.test.spaces.FakeSpaceService import io.element.android.libraries.matrix.test.spaces.FakeSpaceService
import io.element.android.tests.testutils.lambda.lambdaError import io.element.android.tests.testutils.lambda.lambdaError
@ -38,10 +37,8 @@ class DefaultSpaceEntryPointTest {
SpaceFlowNode( SpaceFlowNode(
buildContext = buildContext, buildContext = buildContext,
plugins = plugins, plugins = plugins,
matrixClient = FakeMatrixClient( spaceService = FakeSpaceService(
spaceService = FakeSpaceService( spaceRoomListResult = { _: RoomId -> FakeSpaceRoomList(A_ROOM_ID) }
spaceRoomListResult = { _: RoomId -> FakeSpaceRoomList(A_ROOM_ID) }
)
), ),
graphFactory = FakeSpaceFlowGraph.Factory graphFactory = FakeSpaceFlowGraph.Factory
) )

View file

@ -49,9 +49,18 @@ interface MatrixClient {
val userProfile: StateFlow<MatrixUser> val userProfile: StateFlow<MatrixUser>
val roomListService: RoomListService val roomListService: RoomListService
val spaceService: SpaceService val spaceService: SpaceService
val mediaLoader: MatrixMediaLoader val syncService: SyncService
val sessionVerificationService: SessionVerificationService
val pushersService: PushersService
val notificationService: NotificationService
val notificationSettingsService: NotificationSettingsService
val encryptionService: EncryptionService
val roomDirectoryService: RoomDirectoryService
val mediaPreviewService: MediaPreviewService
val matrixMediaLoader: MatrixMediaLoader
val sessionCoroutineScope: CoroutineScope val sessionCoroutineScope: CoroutineScope
val ignoredUsersFlow: StateFlow<ImmutableList<UserId>> val ignoredUsersFlow: StateFlow<ImmutableList<UserId>>
val roomMembershipObserver: RoomMembershipObserver
suspend fun getJoinedRoom(roomId: RoomId): JoinedRoom? suspend fun getJoinedRoom(roomId: RoomId): JoinedRoom?
suspend fun getRoom(roomId: RoomId): BaseRoom? suspend fun getRoom(roomId: RoomId): BaseRoom?
suspend fun findDM(userId: UserId): Result<RoomId?> suspend fun findDM(userId: UserId): Result<RoomId?>
@ -68,14 +77,6 @@ interface MatrixClient {
suspend fun joinRoom(roomId: RoomId): Result<RoomInfo?> suspend fun joinRoom(roomId: RoomId): Result<RoomInfo?>
suspend fun joinRoomByIdOrAlias(roomIdOrAlias: RoomIdOrAlias, serverNames: List<String>): Result<RoomInfo?> suspend fun joinRoomByIdOrAlias(roomIdOrAlias: RoomIdOrAlias, serverNames: List<String>): Result<RoomInfo?>
suspend fun knockRoom(roomIdOrAlias: RoomIdOrAlias, message: String, serverNames: List<String>): Result<RoomInfo?> suspend fun knockRoom(roomIdOrAlias: RoomIdOrAlias, message: String, serverNames: List<String>): Result<RoomInfo?>
fun syncService(): SyncService
fun sessionVerificationService(): SessionVerificationService
fun pushersService(): PushersService
fun notificationService(): NotificationService
fun notificationSettingsService(): NotificationSettingsService
fun encryptionService(): EncryptionService
fun roomDirectoryService(): RoomDirectoryService
fun mediaPreviewService(): MediaPreviewService
suspend fun getCacheSize(): Long suspend fun getCacheSize(): Long
/** /**
@ -97,7 +98,6 @@ interface MatrixClient {
suspend fun getUserProfile(): Result<MatrixUser> suspend fun getUserProfile(): Result<MatrixUser>
suspend fun getAccountManagementUrl(action: AccountManagementAction?): Result<String?> suspend fun getAccountManagementUrl(action: AccountManagementAction?): Result<String?>
suspend fun uploadMedia(mimeType: String, data: ByteArray): Result<String> suspend fun uploadMedia(mimeType: String, data: ByteArray): Result<String>
fun roomMembershipObserver(): RoomMembershipObserver
/** /**
* Get a room info flow for a given room ID. * Get a room info flow for a given room ID.

View file

@ -23,13 +23,8 @@ import io.element.android.libraries.matrix.api.core.RoomIdOrAlias
import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.createroom.CreateRoomParameters import io.element.android.libraries.matrix.api.createroom.CreateRoomParameters
import io.element.android.libraries.matrix.api.createroom.RoomPreset import io.element.android.libraries.matrix.api.createroom.RoomPreset
import io.element.android.libraries.matrix.api.encryption.EncryptionService
import io.element.android.libraries.matrix.api.media.MatrixMediaLoader import io.element.android.libraries.matrix.api.media.MatrixMediaLoader
import io.element.android.libraries.matrix.api.media.MediaPreviewService
import io.element.android.libraries.matrix.api.notification.NotificationService
import io.element.android.libraries.matrix.api.notificationsettings.NotificationSettingsService
import io.element.android.libraries.matrix.api.oidc.AccountManagementAction import io.element.android.libraries.matrix.api.oidc.AccountManagementAction
import io.element.android.libraries.matrix.api.pusher.PushersService
import io.element.android.libraries.matrix.api.room.BaseRoom import io.element.android.libraries.matrix.api.room.BaseRoom
import io.element.android.libraries.matrix.api.room.CurrentUserMembership import io.element.android.libraries.matrix.api.room.CurrentUserMembership
import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.JoinedRoom
@ -39,16 +34,13 @@ import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.RoomMembershipObserver import io.element.android.libraries.matrix.api.room.RoomMembershipObserver
import io.element.android.libraries.matrix.api.room.alias.ResolvedRoomAlias import io.element.android.libraries.matrix.api.room.alias.ResolvedRoomAlias
import io.element.android.libraries.matrix.api.room.join.JoinRule import io.element.android.libraries.matrix.api.room.join.JoinRule
import io.element.android.libraries.matrix.api.roomdirectory.RoomDirectoryService
import io.element.android.libraries.matrix.api.roomdirectory.RoomVisibility import io.element.android.libraries.matrix.api.roomdirectory.RoomVisibility
import io.element.android.libraries.matrix.api.roomlist.RoomListService import io.element.android.libraries.matrix.api.roomlist.RoomListService
import io.element.android.libraries.matrix.api.spaces.SpaceService import io.element.android.libraries.matrix.api.spaces.SpaceService
import io.element.android.libraries.matrix.api.sync.SlidingSyncVersion import io.element.android.libraries.matrix.api.sync.SlidingSyncVersion
import io.element.android.libraries.matrix.api.sync.SyncService
import io.element.android.libraries.matrix.api.sync.SyncState import io.element.android.libraries.matrix.api.sync.SyncState
import io.element.android.libraries.matrix.api.user.MatrixSearchUserResults import io.element.android.libraries.matrix.api.user.MatrixSearchUserResults
import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.matrix.api.verification.SessionVerificationService
import io.element.android.libraries.matrix.impl.encryption.RustEncryptionService import io.element.android.libraries.matrix.impl.encryption.RustEncryptionService
import io.element.android.libraries.matrix.impl.exception.mapClientException import io.element.android.libraries.matrix.impl.exception.mapClientException
import io.element.android.libraries.matrix.impl.mapper.map import io.element.android.libraries.matrix.impl.mapper.map
@ -128,11 +120,10 @@ import org.matrix.rustcomponents.sdk.SyncService as ClientSyncService
class RustMatrixClient( class RustMatrixClient(
private val innerClient: Client, private val innerClient: Client,
private val baseDirectory: File,
private val sessionStore: SessionStore, private val sessionStore: SessionStore,
private val appCoroutineScope: CoroutineScope,
private val sessionDelegate: RustClientSessionDelegate, private val sessionDelegate: RustClientSessionDelegate,
private val innerSyncService: ClientSyncService, private val innerSyncService: ClientSyncService,
appCoroutineScope: CoroutineScope,
dispatchers: CoroutineDispatchers, dispatchers: CoroutineDispatchers,
baseCacheDirectory: File, baseCacheDirectory: File,
clock: SystemClock, clock: SystemClock,
@ -147,29 +138,29 @@ class RustMatrixClient(
private val innerRoomListService = innerSyncService.roomListService() private val innerRoomListService = innerSyncService.roomListService()
private val innerSpaceService = innerClient.spaceService() private val innerSpaceService = innerClient.spaceService()
private val roomMembershipObserver = RoomMembershipObserver() override val roomMembershipObserver = RoomMembershipObserver()
private val rustSyncService = RustSyncService( override val syncService = RustSyncService(
inner = innerSyncService, inner = innerSyncService,
dispatcher = sessionDispatcher, dispatcher = sessionDispatcher,
sessionCoroutineScope = sessionCoroutineScope sessionCoroutineScope = sessionCoroutineScope
) )
private val pushersService = RustPushersService( override val pushersService = RustPushersService(
client = innerClient, client = innerClient,
dispatchers = dispatchers, dispatchers = dispatchers,
) )
private val notificationProcessSetup = NotificationProcessSetup.SingleProcess(innerSyncService) private val notificationProcessSetup = NotificationProcessSetup.SingleProcess(innerSyncService)
private val innerNotificationClient = runBlocking { innerClient.notificationClient(notificationProcessSetup) } private val innerNotificationClient = runBlocking { innerClient.notificationClient(notificationProcessSetup) }
private val notificationService = RustNotificationService(sessionId, innerNotificationClient, dispatchers, clock) override val notificationService = RustNotificationService(sessionId, innerNotificationClient, dispatchers, clock)
private val notificationSettingsService = RustNotificationSettingsService(innerClient, sessionCoroutineScope, dispatchers) override val notificationSettingsService = RustNotificationSettingsService(innerClient, sessionCoroutineScope, dispatchers)
private val encryptionService = RustEncryptionService( override val encryptionService = RustEncryptionService(
client = innerClient, client = innerClient,
syncService = rustSyncService, syncService = syncService,
sessionCoroutineScope = sessionCoroutineScope, sessionCoroutineScope = sessionCoroutineScope,
dispatchers = dispatchers, dispatchers = dispatchers,
) )
private val roomDirectoryService = RustRoomDirectoryService( override val roomDirectoryService = RustRoomDirectoryService(
client = innerClient, client = innerClient,
sessionDispatcher = sessionDispatcher, sessionDispatcher = sessionDispatcher,
) )
@ -196,9 +187,9 @@ class RustMatrixClient(
sessionDispatcher = sessionDispatcher, sessionDispatcher = sessionDispatcher,
) )
private val verificationService = RustSessionVerificationService( override val sessionVerificationService = RustSessionVerificationService(
client = innerClient, client = innerClient,
isSyncServiceReady = rustSyncService.syncState.map { it == SyncState.Running }, isSyncServiceReady = syncService.syncState.map { it == SyncState.Running },
sessionCoroutineScope = sessionCoroutineScope, sessionCoroutineScope = sessionCoroutineScope,
) )
@ -221,13 +212,13 @@ class RustMatrixClient(
featureFlagService = featureFlagService, featureFlagService = featureFlagService,
) )
override val mediaLoader: MatrixMediaLoader = RustMediaLoader( override val matrixMediaLoader: MatrixMediaLoader = RustMediaLoader(
baseCacheDirectory = baseCacheDirectory, baseCacheDirectory = baseCacheDirectory,
dispatchers = dispatchers, dispatchers = dispatchers,
innerClient = innerClient, innerClient = innerClient,
) )
private val mediaPreviewService = RustMediaPreviewService( override val mediaPreviewService = RustMediaPreviewService(
sessionCoroutineScope = sessionCoroutineScope, sessionCoroutineScope = sessionCoroutineScope,
innerClient = innerClient, innerClient = innerClient,
sessionDispatcher = sessionDispatcher, sessionDispatcher = sessionDispatcher,
@ -538,33 +529,17 @@ class RustMatrixClient(
}.mapFailure { it.mapClientException() } }.mapFailure { it.mapClientException() }
} }
override fun syncService(): SyncService = rustSyncService
override fun sessionVerificationService(): SessionVerificationService = verificationService
override fun pushersService(): PushersService = pushersService
override fun notificationService(): NotificationService = notificationService
override fun encryptionService(): EncryptionService = encryptionService
override fun notificationSettingsService(): NotificationSettingsService = notificationSettingsService
override fun roomDirectoryService(): RoomDirectoryService = roomDirectoryService
override fun mediaPreviewService(): MediaPreviewService = mediaPreviewService
internal suspend fun destroy() { internal suspend fun destroy() {
innerNotificationClient.close() innerNotificationClient.close()
roomFactory.destroy() roomFactory.destroy()
rustSyncService.destroy() syncService.destroy()
notificationSettingsService.destroy() notificationSettingsService.destroy()
notificationProcessSetup.destroy() notificationProcessSetup.destroy()
sessionCoroutineScope.cancel() sessionCoroutineScope.cancel()
clientDelegateTaskHandle?.cancelAndDestroy() clientDelegateTaskHandle?.cancelAndDestroy()
verificationService.destroy() sessionVerificationService.destroy()
sessionDelegate.clearCurrentClient() sessionDelegate.clearCurrentClient()
innerRoomListService.close() innerRoomListService.close()
@ -575,7 +550,7 @@ class RustMatrixClient(
} }
override suspend fun getCacheSize(): Long { override suspend fun getCacheSize(): Long {
return baseDirectory.getCacheSize() return getCacheSize(includeCryptoDb = false)
} }
override suspend fun clearCache() { override suspend fun clearCache() {
@ -674,8 +649,6 @@ class RustMatrixClient(
} }
} }
override fun roomMembershipObserver(): RoomMembershipObserver = roomMembershipObserver
override fun getRoomInfoFlow(roomId: RoomId): Flow<Optional<RoomInfo>> { override fun getRoomInfoFlow(roomId: RoomId): Flow<Optional<RoomInfo>> {
return mxCallbackFlow { return mxCallbackFlow {
val roomNotFound = innerRoomListService.roomOrNull(roomId.value).use { it == null } val roomNotFound = innerRoomListService.roomOrNull(roomId.value).use { it == null }
@ -740,7 +713,7 @@ class RustMatrixClient(
} }
} }
private suspend fun File.getCacheSize( private suspend fun getCacheSize(
includeCryptoDb: Boolean = false, includeCryptoDb: Boolean = false,
): Long = withContext(sessionDispatcher) { ): Long = withContext(sessionDispatcher) {
val sessionDirectory = sessionPathsProvider.provides(sessionId) ?: return@withContext 0L val sessionDirectory = sessionPathsProvider.provides(sessionId) ?: return@withContext 0L

View file

@ -9,7 +9,6 @@ package io.element.android.libraries.matrix.impl
import dev.zacsweers.metro.Inject import dev.zacsweers.metro.Inject
import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.di.BaseDirectory
import io.element.android.libraries.di.CacheDirectory import io.element.android.libraries.di.CacheDirectory
import io.element.android.libraries.di.annotations.AppCoroutineScope import io.element.android.libraries.di.annotations.AppCoroutineScope
import io.element.android.libraries.featureflag.api.FeatureFlagService import io.element.android.libraries.featureflag.api.FeatureFlagService
@ -43,7 +42,6 @@ import java.io.File
@Inject @Inject
class RustMatrixClientFactory( class RustMatrixClientFactory(
@BaseDirectory private val baseDirectory: File,
@CacheDirectory private val cacheDirectory: File, @CacheDirectory private val cacheDirectory: File,
@AppCoroutineScope @AppCoroutineScope
private val appCoroutineScope: CoroutineScope, private val appCoroutineScope: CoroutineScope,
@ -87,7 +85,6 @@ class RustMatrixClientFactory(
return RustMatrixClient( return RustMatrixClient(
innerClient = client, innerClient = client,
baseDirectory = baseDirectory,
sessionStore = sessionStore, sessionStore = sessionStore,
appCoroutineScope = appCoroutineScope, appCoroutineScope = appCoroutineScope,
sessionDelegate = sessionDelegate, sessionDelegate = sessionDelegate,
@ -136,13 +133,15 @@ class RustMatrixClientFactory(
) )
.enableShareHistoryOnInvite(featureFlagService.isFeatureEnabled(FeatureFlags.EnableKeyShareOnInvite)) .enableShareHistoryOnInvite(featureFlagService.isFeatureEnabled(FeatureFlags.EnableKeyShareOnInvite))
.threadsEnabled(featureFlagService.isFeatureEnabled(FeatureFlags.Threads), threadSubscriptions = false) .threadsEnabled(featureFlagService.isFeatureEnabled(FeatureFlags.Threads), threadSubscriptions = false)
.requestConfig(RequestConfig( .requestConfig(
timeout = 30_000uL, RequestConfig(
retryLimit = 0u, timeout = 30_000uL,
// Use default values for the rest retryLimit = 0u,
maxConcurrentRequests = null, // Use default values for the rest
maxRetryTime = null, maxConcurrentRequests = null,
)) maxRetryTime = null,
)
)
.run { .run {
// Apply sliding sync version settings // Apply sliding sync version settings
when (slidingSyncType) { when (slidingSyncType) {

View file

@ -21,6 +21,7 @@ import io.element.android.libraries.matrix.api.notificationsettings.Notification
import io.element.android.libraries.matrix.api.room.RoomMembershipObserver import io.element.android.libraries.matrix.api.room.RoomMembershipObserver
import io.element.android.libraries.matrix.api.roomdirectory.RoomDirectoryService import io.element.android.libraries.matrix.api.roomdirectory.RoomDirectoryService
import io.element.android.libraries.matrix.api.roomlist.RoomListService import io.element.android.libraries.matrix.api.roomlist.RoomListService
import io.element.android.libraries.matrix.api.spaces.SpaceService
import io.element.android.libraries.matrix.api.sync.SyncService import io.element.android.libraries.matrix.api.sync.SyncService
import io.element.android.libraries.matrix.api.verification.SessionVerificationService import io.element.android.libraries.matrix.api.verification.SessionVerificationService
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
@ -35,17 +36,17 @@ object SessionMatrixModule {
@Provides @Provides
fun providesSessionVerificationService(matrixClient: MatrixClient): SessionVerificationService { fun providesSessionVerificationService(matrixClient: MatrixClient): SessionVerificationService {
return matrixClient.sessionVerificationService() return matrixClient.sessionVerificationService
} }
@Provides @Provides
fun providesNotificationSettingsService(matrixClient: MatrixClient): NotificationSettingsService { fun providesNotificationSettingsService(matrixClient: MatrixClient): NotificationSettingsService {
return matrixClient.notificationSettingsService() return matrixClient.notificationSettingsService
} }
@Provides @Provides
fun provideRoomMembershipObserver(matrixClient: MatrixClient): RoomMembershipObserver { fun provideRoomMembershipObserver(matrixClient: MatrixClient): RoomMembershipObserver {
return matrixClient.roomMembershipObserver() return matrixClient.roomMembershipObserver
} }
@Provides @Provides
@ -55,32 +56,37 @@ object SessionMatrixModule {
@Provides @Provides
fun providesSyncService(matrixClient: MatrixClient): SyncService { fun providesSyncService(matrixClient: MatrixClient): SyncService {
return matrixClient.syncService() return matrixClient.syncService
} }
@Provides @Provides
fun providesEncryptionService(matrixClient: MatrixClient): EncryptionService { fun providesEncryptionService(matrixClient: MatrixClient): EncryptionService {
return matrixClient.encryptionService() return matrixClient.encryptionService
} }
@Provides @Provides
fun provideMediaLoader(matrixClient: MatrixClient): MatrixMediaLoader { fun providesMatrixMediaLoader(matrixClient: MatrixClient): MatrixMediaLoader {
return matrixClient.mediaLoader return matrixClient.matrixMediaLoader
} }
@SessionCoroutineScope @SessionCoroutineScope
@Provides @Provides
fun provideSessionCoroutineScope(matrixClient: MatrixClient): CoroutineScope { fun providesSessionCoroutineScope(matrixClient: MatrixClient): CoroutineScope {
return matrixClient.sessionCoroutineScope return matrixClient.sessionCoroutineScope
} }
@Provides @Provides
fun providesRoomDirectoryService(matrixClient: MatrixClient): RoomDirectoryService { fun providesRoomDirectoryService(matrixClient: MatrixClient): RoomDirectoryService {
return matrixClient.roomDirectoryService() return matrixClient.roomDirectoryService
} }
@Provides @Provides
fun providesMediaPreviewService(matrixClient: MatrixClient): MediaPreviewService { fun providesMediaPreviewService(matrixClient: MatrixClient): MediaPreviewService {
return matrixClient.mediaPreviewService() return matrixClient.mediaPreviewService
}
@Provides
fun providesSpaceService(matrixClient: MatrixClient): SpaceService {
return matrixClient.spaceService
} }
} }

View file

@ -46,7 +46,7 @@ import org.matrix.rustcomponents.sdk.BackupUploadState as RustBackupUploadState
import org.matrix.rustcomponents.sdk.EnableRecoveryProgress as RustEnableRecoveryProgress import org.matrix.rustcomponents.sdk.EnableRecoveryProgress as RustEnableRecoveryProgress
import org.matrix.rustcomponents.sdk.SteadyStateException as RustSteadyStateException import org.matrix.rustcomponents.sdk.SteadyStateException as RustSteadyStateException
internal class RustEncryptionService( class RustEncryptionService(
client: Client, client: Client,
syncService: RustSyncService, syncService: RustSyncService,
sessionCoroutineScope: CoroutineScope, sessionCoroutineScope: CoroutineScope,

View file

@ -36,14 +36,12 @@ class RustMatrixClientFactoryTest {
} }
fun TestScope.createRustMatrixClientFactory( fun TestScope.createRustMatrixClientFactory(
baseDirectory: File = File("/base"),
cacheDirectory: File = File("/cache"), cacheDirectory: File = File("/cache"),
sessionStore: SessionStore = InMemorySessionStore( sessionStore: SessionStore = InMemorySessionStore(
updateUserProfileResult = { _, _, _ -> }, updateUserProfileResult = { _, _, _ -> },
), ),
clientBuilderProvider: ClientBuilderProvider = FakeClientBuilderProvider(), clientBuilderProvider: ClientBuilderProvider = FakeClientBuilderProvider(),
) = RustMatrixClientFactory( ) = RustMatrixClientFactory(
baseDirectory = baseDirectory,
cacheDirectory = cacheDirectory, cacheDirectory = cacheDirectory,
appCoroutineScope = backgroundScope, appCoroutineScope = backgroundScope,
coroutineDispatchers = testCoroutineDispatchers(), coroutineDispatchers = testCoroutineDispatchers(),

View file

@ -102,7 +102,6 @@ class RustMatrixClientTest {
), ),
) = RustMatrixClient( ) = RustMatrixClient(
innerClient = client, innerClient = client,
baseDirectory = File(""),
sessionStore = sessionStore, sessionStore = sessionStore,
appCoroutineScope = backgroundScope, appCoroutineScope = backgroundScope,
sessionDelegate = aRustClientSessionDelegate( sessionDelegate = aRustClientSessionDelegate(

View file

@ -53,7 +53,6 @@ class RustMatrixAuthenticationServiceTest {
val baseDirectory = File("/base") val baseDirectory = File("/base")
val cacheDirectory = File("/cache") val cacheDirectory = File("/cache")
val rustMatrixClientFactory = createRustMatrixClientFactory( val rustMatrixClientFactory = createRustMatrixClientFactory(
baseDirectory = baseDirectory,
cacheDirectory = cacheDirectory, cacheDirectory = cacheDirectory,
sessionStore = sessionStore, sessionStore = sessionStore,
clientBuilderProvider = clientBuilderProvider, clientBuilderProvider = clientBuilderProvider,

View file

@ -32,6 +32,7 @@ import io.element.android.libraries.matrix.api.roomdirectory.RoomDirectoryServic
import io.element.android.libraries.matrix.api.roomlist.RoomListService import io.element.android.libraries.matrix.api.roomlist.RoomListService
import io.element.android.libraries.matrix.api.spaces.SpaceService import io.element.android.libraries.matrix.api.spaces.SpaceService
import io.element.android.libraries.matrix.api.sync.SlidingSyncVersion import io.element.android.libraries.matrix.api.sync.SlidingSyncVersion
import io.element.android.libraries.matrix.api.sync.SyncService
import io.element.android.libraries.matrix.api.user.MatrixSearchUserResults import io.element.android.libraries.matrix.api.user.MatrixSearchUserResults
import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.matrix.api.verification.SessionVerificationService import io.element.android.libraries.matrix.api.verification.SessionVerificationService
@ -68,15 +69,16 @@ class FakeMatrixClient(
private val userAvatarUrl: String? = AN_AVATAR_URL, private val userAvatarUrl: String? = AN_AVATAR_URL,
override val roomListService: RoomListService = FakeRoomListService(), override val roomListService: RoomListService = FakeRoomListService(),
override val spaceService: SpaceService = FakeSpaceService(), override val spaceService: SpaceService = FakeSpaceService(),
override val mediaLoader: MatrixMediaLoader = FakeMatrixMediaLoader(), override val matrixMediaLoader: MatrixMediaLoader = FakeMatrixMediaLoader(),
private val sessionVerificationService: FakeSessionVerificationService = FakeSessionVerificationService(), override val sessionVerificationService: SessionVerificationService = FakeSessionVerificationService(),
private val pushersService: FakePushersService = FakePushersService(), override val pushersService: PushersService = FakePushersService(),
private val notificationService: FakeNotificationService = FakeNotificationService(), override val notificationService: NotificationService = FakeNotificationService(),
private val notificationSettingsService: FakeNotificationSettingsService = FakeNotificationSettingsService(), override val notificationSettingsService: NotificationSettingsService = FakeNotificationSettingsService(),
private val syncService: FakeSyncService = FakeSyncService(), override val syncService: SyncService = FakeSyncService(),
private val encryptionService: FakeEncryptionService = FakeEncryptionService(), override val encryptionService: EncryptionService = FakeEncryptionService(),
private val roomDirectoryService: RoomDirectoryService = FakeRoomDirectoryService(), override val roomDirectoryService: RoomDirectoryService = FakeRoomDirectoryService(),
private val mediaPreviewService: MediaPreviewService = FakeMediaPreviewService(), override val mediaPreviewService: MediaPreviewService = FakeMediaPreviewService(),
override val roomMembershipObserver: RoomMembershipObserver = RoomMembershipObserver(),
private val accountManagementUrlResult: (AccountManagementAction?) -> Result<String?> = { lambdaError() }, private val accountManagementUrlResult: (AccountManagementAction?) -> Result<String?> = { lambdaError() },
private val resolveRoomAliasResult: (RoomAlias) -> Result<Optional<ResolvedRoomAlias>> = { private val resolveRoomAliasResult: (RoomAlias) -> Result<Optional<ResolvedRoomAlias>> = {
Result.success( Result.success(
@ -174,10 +176,6 @@ class FakeMatrixClient(
return searchUserResults[searchTerm] ?: Result.failure(IllegalStateException("No response defined for $searchTerm")) return searchUserResults[searchTerm] ?: Result.failure(IllegalStateException("No response defined for $searchTerm"))
} }
override fun syncService() = syncService
override fun roomDirectoryService() = roomDirectoryService
override suspend fun getCacheSize(): Long { override suspend fun getCacheSize(): Long {
return 0 return 0
} }
@ -238,19 +236,6 @@ class FakeMatrixClient(
return knockRoomLambda(roomIdOrAlias, message, serverNames) return knockRoomLambda(roomIdOrAlias, message, serverNames)
} }
override fun sessionVerificationService(): SessionVerificationService = sessionVerificationService
override fun pushersService(): PushersService = pushersService
override fun notificationService(): NotificationService = notificationService
override fun notificationSettingsService(): NotificationSettingsService = notificationSettingsService
override fun encryptionService(): EncryptionService = encryptionService
override fun mediaPreviewService(): MediaPreviewService = mediaPreviewService
override fun roomMembershipObserver(): RoomMembershipObserver {
return RoomMembershipObserver()
}
// Mocks // Mocks
fun givenCreateRoomResult(result: Result<RoomId>) { fun givenCreateRoomResult(result: Result<RoomId>) {

View file

@ -11,10 +11,10 @@ import coil3.ImageLoader
import coil3.fetch.Fetcher import coil3.fetch.Fetcher
import coil3.request.Options import coil3.request.Options
import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarData
import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.media.MatrixMediaLoader
internal class AvatarDataFetcherFactory( internal class AvatarDataFetcherFactory(
private val client: MatrixClient private val matrixMediaLoader: MatrixMediaLoader
) : Fetcher.Factory<AvatarData> { ) : Fetcher.Factory<AvatarData> {
override fun create( override fun create(
data: AvatarData, data: AvatarData,
@ -22,7 +22,7 @@ internal class AvatarDataFetcherFactory(
imageLoader: ImageLoader imageLoader: ImageLoader
): Fetcher { ): Fetcher {
return CoilMediaFetcher( return CoilMediaFetcher(
mediaLoader = client.mediaLoader, mediaLoader = matrixMediaLoader,
mediaData = data.toMediaRequestData(), mediaData = data.toMediaRequestData(),
) )
} }

View file

@ -18,11 +18,11 @@ import dev.zacsweers.metro.ContributesBinding
import dev.zacsweers.metro.Inject import dev.zacsweers.metro.Inject
import dev.zacsweers.metro.Provider import dev.zacsweers.metro.Provider
import io.element.android.libraries.di.annotations.ApplicationContext import io.element.android.libraries.di.annotations.ApplicationContext
import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.media.MatrixMediaLoader
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
interface LoggedInImageLoaderFactory { interface LoggedInImageLoaderFactory {
fun newImageLoader(matrixClient: MatrixClient): ImageLoader fun newImageLoader(matrixMediaLoader: MatrixMediaLoader): ImageLoader
} }
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
@ -31,7 +31,7 @@ class DefaultLoggedInImageLoaderFactory(
@ApplicationContext private val context: Context, @ApplicationContext private val context: Context,
private val okHttpClient: Provider<OkHttpClient>, private val okHttpClient: Provider<OkHttpClient>,
) : LoggedInImageLoaderFactory { ) : LoggedInImageLoaderFactory {
override fun newImageLoader(matrixClient: MatrixClient): ImageLoader { override fun newImageLoader(matrixMediaLoader: MatrixMediaLoader): ImageLoader {
return ImageLoader.Builder(context) return ImageLoader.Builder(context)
.components { .components {
add( add(
@ -50,8 +50,8 @@ class DefaultLoggedInImageLoaderFactory(
} }
add(AvatarDataKeyer()) add(AvatarDataKeyer())
add(MediaRequestDataKeyer()) add(MediaRequestDataKeyer())
add(AvatarDataFetcherFactory(matrixClient)) add(AvatarDataFetcherFactory(matrixMediaLoader))
add(MediaRequestDataFetcherFactory(matrixClient)) add(MediaRequestDataFetcherFactory(matrixMediaLoader))
} }
.build() .build()
} }

View file

@ -49,7 +49,7 @@ class DefaultImageLoaderHolder(
return synchronized(map) { return synchronized(map) {
map.getOrPut(client.sessionId) { map.getOrPut(client.sessionId) {
loggedInImageLoaderFactory loggedInImageLoaderFactory
.newImageLoader(client) .newImageLoader(client.matrixMediaLoader)
} }
} }
} }

View file

@ -10,10 +10,10 @@ package io.element.android.libraries.matrix.ui.media
import coil3.ImageLoader import coil3.ImageLoader
import coil3.fetch.Fetcher import coil3.fetch.Fetcher
import coil3.request.Options import coil3.request.Options
import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.media.MatrixMediaLoader
internal class MediaRequestDataFetcherFactory( internal class MediaRequestDataFetcherFactory(
private val client: MatrixClient private val matrixMediaLoader: MatrixMediaLoader,
) : Fetcher.Factory<MediaRequestData> { ) : Fetcher.Factory<MediaRequestData> {
override fun create( override fun create(
data: MediaRequestData, data: MediaRequestData,
@ -21,7 +21,7 @@ internal class MediaRequestDataFetcherFactory(
imageLoader: ImageLoader imageLoader: ImageLoader
): Fetcher { ): Fetcher {
return CoilMediaFetcher( return CoilMediaFetcher(
mediaLoader = client.mediaLoader, mediaLoader = matrixMediaLoader,
mediaData = data, mediaData = data,
) )
} }

View file

@ -17,7 +17,7 @@ import io.element.android.libraries.matrix.api.MatrixClient
@Composable @Composable
fun MatrixClient.rememberHideInvitesAvatar(): State<Boolean> { fun MatrixClient.rememberHideInvitesAvatar(): State<Boolean> {
return remember { return remember {
mediaPreviewService() mediaPreviewService
.mediaPreviewConfigFlow .mediaPreviewConfigFlow
.mapState { config -> config.hideInviteAvatar } .mapState { config -> config.hideInviteAvatar }
}.collectAsState() }.collectAsState()

View file

@ -10,7 +10,7 @@ package io.element.android.libraries.matrix.ui.media
import androidx.test.platform.app.InstrumentationRegistry import androidx.test.platform.app.InstrumentationRegistry
import coil3.ImageLoader import coil3.ImageLoader
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.media.MatrixMediaLoader
import io.element.android.libraries.matrix.test.A_SESSION_ID import io.element.android.libraries.matrix.test.A_SESSION_ID
import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.sessionstorage.test.observer.FakeSessionObserver import io.element.android.libraries.sessionstorage.test.observer.FakeSessionObserver
@ -27,7 +27,7 @@ class DefaultImageLoaderHolderTest {
@Test @Test
fun `get - returns the same ImageLoader for the same client`() { fun `get - returns the same ImageLoader for the same client`() {
val context = InstrumentationRegistry.getInstrumentation().context val context = InstrumentationRegistry.getInstrumentation().context
val lambda = lambdaRecorder<MatrixClient, ImageLoader> { ImageLoader.Builder(context).build() } val lambda = lambdaRecorder<MatrixMediaLoader, ImageLoader> { ImageLoader.Builder(context).build() }
val holder = DefaultImageLoaderHolder( val holder = DefaultImageLoaderHolder(
loggedInImageLoaderFactory = FakeLoggedInImageLoaderFactory(lambda), loggedInImageLoaderFactory = FakeLoggedInImageLoaderFactory(lambda),
@ -39,14 +39,14 @@ class DefaultImageLoaderHolderTest {
assert(imageLoader1 === imageLoader2) assert(imageLoader1 === imageLoader2)
lambda.assertions() lambda.assertions()
.isCalledOnce() .isCalledOnce()
.with(value(client)) .with(value(client.matrixMediaLoader))
} }
@Test @Test
fun `when session is deleted, the image loader is deleted`() = runTest { fun `when session is deleted, the image loader is deleted`() = runTest {
val context = InstrumentationRegistry.getInstrumentation().context val context = InstrumentationRegistry.getInstrumentation().context
val lambda = val lambda =
lambdaRecorder<MatrixClient, ImageLoader> { ImageLoader.Builder(context).build() } lambdaRecorder<MatrixMediaLoader, ImageLoader> { ImageLoader.Builder(context).build() }
val sessionObserver = FakeSessionObserver() val sessionObserver = FakeSessionObserver()
val holder = DefaultImageLoaderHolder( val holder = DefaultImageLoaderHolder(
loggedInImageLoaderFactory = FakeLoggedInImageLoaderFactory(lambda), loggedInImageLoaderFactory = FakeLoggedInImageLoaderFactory(lambda),
@ -65,7 +65,7 @@ class DefaultImageLoaderHolderTest {
fun `when session is created, nothing happen`() = runTest { fun `when session is created, nothing happen`() = runTest {
val context = InstrumentationRegistry.getInstrumentation().context val context = InstrumentationRegistry.getInstrumentation().context
val lambda = val lambda =
lambdaRecorder<MatrixClient, ImageLoader> { ImageLoader.Builder(context).build() } lambdaRecorder<MatrixMediaLoader, ImageLoader> { ImageLoader.Builder(context).build() }
val sessionObserver = FakeSessionObserver() val sessionObserver = FakeSessionObserver()
DefaultImageLoaderHolder( DefaultImageLoaderHolder(
loggedInImageLoaderFactory = FakeLoggedInImageLoaderFactory(lambda), loggedInImageLoaderFactory = FakeLoggedInImageLoaderFactory(lambda),

View file

@ -8,12 +8,12 @@
package io.element.android.libraries.matrix.ui.media package io.element.android.libraries.matrix.ui.media
import coil3.ImageLoader import coil3.ImageLoader
import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.media.MatrixMediaLoader
class FakeLoggedInImageLoaderFactory( class FakeLoggedInImageLoaderFactory(
private val newImageLoaderLambda: (MatrixClient) -> ImageLoader private val newImageLoaderLambda: (MatrixMediaLoader) -> ImageLoader
) : LoggedInImageLoaderFactory { ) : LoggedInImageLoaderFactory {
override fun newImageLoader(matrixClient: MatrixClient): ImageLoader { override fun newImageLoader(matrixMediaLoader: MatrixMediaLoader): ImageLoader {
return newImageLoaderLambda(matrixClient) return newImageLoaderLambda(matrixMediaLoader)
} }
} }

View file

@ -50,7 +50,7 @@ class DefaultPusherSubscriber(
Timber.tag(loggerTag.value) Timber.tag(loggerTag.value)
.d("Unnecessary to register again the same pusher, but do it in case the pusher has been removed from the server") .d("Unnecessary to register again the same pusher, but do it in case the pusher has been removed from the server")
} }
return matrixClient.pushersService() return matrixClient.pushersService
.setHttpPusher( .setHttpPusher(
createHttpPusher(pushKey, gateway, matrixClient.sessionId) createHttpPusher(pushKey, gateway, matrixClient.sessionId)
) )
@ -100,7 +100,7 @@ class DefaultPusherSubscriber(
gateway: String, gateway: String,
): Result<Unit> { ): Result<Unit> {
val userDataStore = userPushStoreFactory.getOrCreate(matrixClient.sessionId) val userDataStore = userPushStoreFactory.getOrCreate(matrixClient.sessionId)
return matrixClient.pushersService() return matrixClient.pushersService
.unsetHttpPusher( .unsetHttpPusher(
unsetHttpPusherData = UnsetHttpPusherData( unsetHttpPusherData = UnsetHttpPusherData(
pushKey = pushKey, pushKey = pushKey,

View file

@ -98,7 +98,7 @@ class DefaultNotifiableEventResolver(
val ids = notificationEventRequests.groupBy { it.roomId }.mapValues { (_, value) -> value.map { it.eventId } } val ids = notificationEventRequests.groupBy { it.roomId }.mapValues { (_, value) -> value.map { it.eventId } }
// TODO this notificationData is not always valid at the moment, sometimes the Rust SDK can't fetch the matching event // TODO this notificationData is not always valid at the moment, sometimes the Rust SDK can't fetch the matching event
val notificationsResult = client.notificationService().getNotifications(ids) val notificationsResult = client.notificationService.getNotifications(ids)
if (notificationsResult.isFailure) { if (notificationsResult.isFailure) {
val exception = notificationsResult.exceptionOrNull() val exception = notificationsResult.exceptionOrNull()
@ -131,7 +131,7 @@ class DefaultNotifiableEventResolver(
): Result<ResolvedPushEvent> = runCatchingExceptions { ): Result<ResolvedPushEvent> = runCatchingExceptions {
when (val content = this.content) { when (val content = this.content) {
is NotificationContent.MessageLike.RoomMessage -> { is NotificationContent.MessageLike.RoomMessage -> {
val showMediaPreview = client.mediaPreviewService().getMediaPreviewValue() == MediaPreviewValue.On val showMediaPreview = client.mediaPreviewService.getMediaPreviewValue() == MediaPreviewValue.On
val senderDisambiguatedDisplayName = getDisambiguatedDisplayName(content.senderId) val senderDisambiguatedDisplayName = getDisambiguatedDisplayName(content.senderId)
val messageBody = descriptionFromMessageContent(content, senderDisambiguatedDisplayName) val messageBody = descriptionFromMessageContent(content, senderDisambiguatedDisplayName)
val notifiableMessageEvent = buildNotifiableMessageEvent( val notifiableMessageEvent = buildNotifiableMessageEvent(

View file

@ -30,7 +30,7 @@ class DefaultOnMissedCallNotificationHandler(
) { ) {
// Resolve the event and add a notification for it, at this point it should no longer be a ringing one // Resolve the event and add a notification for it, at this point it should no longer be a ringing one
val notificationData = matrixClientProvider.getOrRestore(sessionId).getOrNull() val notificationData = matrixClientProvider.getOrRestore(sessionId).getOrNull()
?.notificationService() ?.notificationService
?.getNotifications(mapOf(roomId to listOf(eventId))) ?.getNotifications(mapOf(roomId to listOf(eventId)))
?.getOrNull() ?.getOrNull()
?.get(eventId) ?.get(eventId)

View file

@ -72,7 +72,7 @@ class DefaultNotificationMediaRepo(
): DefaultNotificationMediaRepo ): DefaultNotificationMediaRepo
} }
private val matrixMediaLoader = client.mediaLoader private val matrixMediaLoader = client.matrixMediaLoader
override suspend fun getMediaFile( override suspend fun getMediaFile(
mediaSource: MediaSource, mediaSource: MediaSource,