Merge branch 'develop' into julioromano/poll_history_entry_point

This commit is contained in:
ganfra 2023-12-13 17:22:55 +01:00
commit 863d156e4d
738 changed files with 9387 additions and 1581 deletions

View file

@ -91,7 +91,7 @@ import org.matrix.rustcomponents.sdk.RoomVisibility as RustRoomVisibility
import org.matrix.rustcomponents.sdk.SyncService as ClientSyncService
@OptIn(ExperimentalCoroutinesApi::class)
class RustMatrixClient constructor(
class RustMatrixClient(
private val client: Client,
private val syncService: ClientSyncService,
private val sessionStore: SessionStore,
@ -119,10 +119,9 @@ class RustMatrixClient constructor(
.filterByPushRules()
.finish()
}
private val notificationSettings = client.getNotificationSettings()
private val notificationService = RustNotificationService(sessionId, notificationClient, dispatchers, clock)
private val notificationSettingsService = RustNotificationSettingsService(notificationSettings, dispatchers)
private val notificationSettingsService = RustNotificationSettingsService(client, dispatchers)
.apply { start() }
private val roomSyncSubscriber = RoomSyncSubscriber(innerRoomListService, dispatchers)
private val encryptionService = RustEncryptionService(
client = client,
@ -241,9 +240,8 @@ class RustMatrixClient constructor(
}
}
override suspend fun findDM(userId: UserId): MatrixRoom? {
val roomId = client.getDmRoom(userId.value)?.use { RoomId(it.id()) }
return roomId?.let { getRoom(it) }
override suspend fun findDM(userId: UserId): RoomId? {
return client.getDmRoom(userId.value)?.use { RoomId(it.id()) }
}
override suspend fun ignoreUser(userId: UserId): Result<Unit> = withContext(sessionDispatcher) {
@ -347,8 +345,7 @@ class RustMatrixClient constructor(
override fun close() {
sessionCoroutineScope.cancel()
clientDelegateTaskHandle?.cancelAndDestroy()
notificationSettings.setDelegate(null)
notificationSettings.destroy()
notificationSettingsService.destroy()
verificationService.destroy()
syncService.destroy()
innerRoomListService.destroy()

View file

@ -0,0 +1,37 @@
/*
* Copyright (c) 2023 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.element.android.libraries.matrix.impl.encryption
import io.element.android.libraries.matrix.api.encryption.RecoveryException
import io.element.android.libraries.matrix.api.exception.ClientException
import io.element.android.libraries.matrix.impl.exception.mapClientException
import org.matrix.rustcomponents.sdk.RecoveryException as RustRecoveryException
fun Throwable.mapRecoveryException(): RecoveryException {
return when (this) {
is RustRecoveryException.SecretStorage -> RecoveryException.SecretStorage(
message = errorMessage
)
is RustRecoveryException.BackupExistsOnServer -> RecoveryException.BackupExistsOnServer
is RustRecoveryException.Client -> RecoveryException.Client(
source.mapClientException()
)
else -> RecoveryException.Client(
ClientException.Other("Unknown error")
)
}
}

View file

@ -17,6 +17,7 @@
package io.element.android.libraries.matrix.impl.encryption
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.core.extensions.mapFailure
import io.element.android.libraries.matrix.api.encryption.BackupState
import io.element.android.libraries.matrix.api.encryption.BackupUploadState
import io.element.android.libraries.matrix.api.encryption.EnableRecoveryProgress
@ -110,6 +111,8 @@ internal class RustEncryptionService(
override suspend fun enableBackups(): Result<Unit> = withContext(dispatchers.io) {
runCatching {
service.enableBackups()
}.mapFailure {
it.mapRecoveryException()
}
}
@ -127,6 +130,8 @@ internal class RustEncryptionService(
)
// enableRecovery returns the encryption key, but we read it from the state flow
.let { }
}.mapFailure {
it.mapRecoveryException()
}
}
@ -164,24 +169,32 @@ internal class RustEncryptionService(
override suspend fun disableRecovery(): Result<Unit> = withContext(dispatchers.io) {
runCatching {
service.disableRecovery()
}.mapFailure {
it.mapRecoveryException()
}
}
override suspend fun isLastDevice(): Result<Boolean> = withContext(dispatchers.io) {
runCatching {
service.isLastDevice()
}.mapFailure {
it.mapRecoveryException()
}
}
override suspend fun resetRecoveryKey(): Result<String> = withContext(dispatchers.io) {
runCatching {
service.resetRecoveryKey()
}.mapFailure {
it.mapRecoveryException()
}
}
override suspend fun fixRecoveryIssues(recoveryKey: String): Result<Unit> = withContext(dispatchers.io) {
override suspend fun recover(recoveryKey: String): Result<Unit> = withContext(dispatchers.io) {
runCatching {
service.recover(recoveryKey)
}.mapFailure {
it.mapRecoveryException()
}
}
}

View file

@ -23,13 +23,13 @@ class SteadyStateExceptionMapper {
fun map(data: RustSteadyStateException): SteadyStateException {
return when (data) {
is RustSteadyStateException.BackupDisabled -> SteadyStateException.BackupDisabled(
message = data.message
message = data.message.orEmpty()
)
is RustSteadyStateException.Connection -> SteadyStateException.Connection(
message = data.message
message = data.message.orEmpty()
)
is RustSteadyStateException.Lagged -> SteadyStateException.Lagged(
message = data.message
message = data.message.orEmpty()
)
}
}

View file

@ -52,7 +52,6 @@ class NotificationMapper(
isNoisy = item.isNoisy.orFalse(),
timestamp = item.timestamp() ?: clock.epochMillis(),
content = item.event.use { notificationContentMapper.map(it) },
contentUrl = null,
hasMention = item.hasMention.orFalse(),
)
}

View file

@ -26,16 +26,16 @@ import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.withContext
import org.matrix.rustcomponents.sdk.NotificationSettings
import org.matrix.rustcomponents.sdk.Client
import org.matrix.rustcomponents.sdk.NotificationSettingsDelegate
import org.matrix.rustcomponents.sdk.NotificationSettingsException
import timber.log.Timber
class RustNotificationSettingsService(
private val notificationSettings: NotificationSettings,
client: Client,
private val dispatchers: CoroutineDispatchers,
) : NotificationSettingsService {
private val notificationSettings = client.getNotificationSettings()
private val _notificationSettingsChangeFlow = MutableSharedFlow<Unit>(extraBufferCapacity = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST)
override val notificationSettingsChangeFlow: SharedFlow<Unit> = _notificationSettingsChangeFlow.asSharedFlow()
@ -45,10 +45,15 @@ class RustNotificationSettingsService(
}
}
init {
fun start() {
notificationSettings.setDelegate(notificationSettingsDelegate)
}
fun destroy() {
notificationSettings.setDelegate(null)
notificationSettings.destroy()
}
override suspend fun getRoomNotificationSettings(roomId: RoomId, isEncrypted: Boolean, isOneToOne: Boolean): Result<RoomNotificationSettings> =
runCatching {
notificationSettings.getRoomNotificationSettings(roomId.value, isEncrypted, isOneToOne).let(RoomNotificationSettingsMapper::map)
@ -119,6 +124,18 @@ class RustNotificationSettingsService(
}
}
override suspend fun isInviteForMeEnabled(): Result<Boolean> = withContext(dispatchers.io) {
runCatching {
notificationSettings.isInviteForMeEnabled()
}
}
override suspend fun setInviteForMeEnabled(enabled: Boolean): Result<Unit> = withContext(dispatchers.io) {
runCatching {
notificationSettings.setInviteForMeEnabled(enabled)
}
}
override suspend fun getRoomsWithUserDefinedRules(): Result<List<String>> =
runCatching {
notificationSettings.getRoomsWithUserDefinedRules(enabled = true)

View file

@ -360,12 +360,6 @@ class RustMatrixRoom(
}
}
override suspend fun canUserJoinCall(userId: UserId): Result<Boolean> {
return runCatching {
innerRoom.canUserSendState(userId.value, StateEventType.ROOM_MEMBER_EVENT.map())
}
}
override suspend fun sendImage(file: File, thumbnailFile: File, imageInfo: ImageInfo, progressCallback: ProgressCallback?): Result<MediaUploadHandler> {
return sendAttachment(listOf(file, thumbnailFile)) {
innerTimeline.sendImage(file.path, thumbnailFile.path, imageInfo.map(), progressCallback?.toProgressWatcher())

View file

@ -23,6 +23,7 @@ fun StateEventType.map(): RustStateEventType = when (this) {
StateEventType.POLICY_RULE_ROOM -> RustStateEventType.POLICY_RULE_ROOM
StateEventType.POLICY_RULE_SERVER -> RustStateEventType.POLICY_RULE_SERVER
StateEventType.POLICY_RULE_USER -> RustStateEventType.POLICY_RULE_USER
StateEventType.CALL_MEMBER -> RustStateEventType.CALL_MEMBER
StateEventType.ROOM_ALIASES -> RustStateEventType.ROOM_ALIASES
StateEventType.ROOM_AVATAR -> RustStateEventType.ROOM_AVATAR
StateEventType.ROOM_CANONICAL_ALIAS -> RustStateEventType.ROOM_CANONICAL_ALIAS
@ -47,6 +48,7 @@ fun RustStateEventType.map(): StateEventType = when (this) {
RustStateEventType.POLICY_RULE_ROOM -> StateEventType.POLICY_RULE_ROOM
RustStateEventType.POLICY_RULE_SERVER -> StateEventType.POLICY_RULE_SERVER
RustStateEventType.POLICY_RULE_USER -> StateEventType.POLICY_RULE_USER
RustStateEventType.CALL_MEMBER -> StateEventType.CALL_MEMBER
RustStateEventType.ROOM_ALIASES -> StateEventType.ROOM_ALIASES
RustStateEventType.ROOM_AVATAR -> StateEventType.ROOM_AVATAR
RustStateEventType.ROOM_CANONICAL_ALIAS -> StateEventType.ROOM_CANONICAL_ALIAS

View file

@ -18,12 +18,12 @@ package io.element.android.libraries.matrix.impl.verification
import io.element.android.libraries.core.data.tryOrNull
import io.element.android.libraries.matrix.api.sync.SyncState
import io.element.android.libraries.matrix.api.verification.SessionVerificationData
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.VerificationEmoji
import io.element.android.libraries.matrix.api.verification.VerificationFlowState
import io.element.android.libraries.matrix.impl.sync.RustSyncService
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
@ -33,7 +33,8 @@ import kotlinx.coroutines.launch
import org.matrix.rustcomponents.sdk.SessionVerificationController
import org.matrix.rustcomponents.sdk.SessionVerificationControllerDelegate
import org.matrix.rustcomponents.sdk.SessionVerificationControllerInterface
import org.matrix.rustcomponents.sdk.SessionVerificationEmoji
import org.matrix.rustcomponents.sdk.use
import org.matrix.rustcomponents.sdk.SessionVerificationData as RustSessionVerificationData
class RustSessionVerificationService(
private val syncService: RustSyncService,
@ -105,12 +106,8 @@ class RustSessionVerificationService(
updateVerificationStatus(isVerified = true)
}
override fun didReceiveVerificationData(data: List<SessionVerificationEmoji>) {
val emojis = data.map { emoji ->
emoji.use { VerificationEmoji(it.symbol(), it.description()) }
}
.toImmutableList()
_verificationFlowState.value = VerificationFlowState.ReceivedVerificationData(emojis)
override fun didReceiveVerificationData(data: RustSessionVerificationData) {
_verificationFlowState.value = VerificationFlowState.ReceivedVerificationData(data.map())
}
// When the actual SAS verification starts
@ -142,3 +139,28 @@ class RustSessionVerificationService(
_sessionVerifiedStatus.value = newValue
}
}
private fun RustSessionVerificationData.map(): SessionVerificationData {
return use { sessionVerificationData ->
when (sessionVerificationData) {
is RustSessionVerificationData.Emojis -> {
SessionVerificationData.Emojis(
emojis = sessionVerificationData.emojis.mapIndexed { index, emoji ->
emoji.use { sessionVerificationEmoji ->
VerificationEmoji(
number = sessionVerificationData.indices[index].toInt(),
emoji = sessionVerificationEmoji.symbol(),
description = sessionVerificationEmoji.description(),
)
}
},
)
}
is RustSessionVerificationData.Decimals -> {
SessionVerificationData.Decimals(
decimals = sessionVerificationData.values.map { it.toInt() },
)
}
}
}
}