Force a refresh of the verification status when the recovery state value change.

The session can become verified when the user enters their recovery key, and in this case the callback `didFinish` is not invoked.
This commit is contained in:
Benoit Marty
2024-02-21 14:23:49 +01:00
parent 661b9d8653
commit 0927821219
2 changed files with 27 additions and 1 deletions
@@ -113,7 +113,11 @@ class RustMatrixClient(
private val innerRoomListService = syncService.roomListService() private val innerRoomListService = syncService.roomListService()
private val sessionDispatcher = dispatchers.io.limitedParallelism(64) private val sessionDispatcher = dispatchers.io.limitedParallelism(64)
private val rustSyncService = RustSyncService(syncService, sessionCoroutineScope) private val rustSyncService = RustSyncService(syncService, sessionCoroutineScope)
private val verificationService = RustSessionVerificationService(rustSyncService, sessionCoroutineScope) private val verificationService = RustSessionVerificationService(
client = client,
syncService = rustSyncService,
sessionCoroutineScope = sessionCoroutineScope,
).apply { start() }
private val pushersService = RustPushersService( private val pushersService = RustPushersService(
client = client, client = client,
dispatchers = dispatchers, dispatchers = dispatchers,
@@ -16,6 +16,7 @@
package io.element.android.libraries.matrix.impl.verification package io.element.android.libraries.matrix.impl.verification
import io.element.android.libraries.core.bool.orFalse
import io.element.android.libraries.core.data.tryOrNull import io.element.android.libraries.core.data.tryOrNull
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.verification.SessionVerificationData import io.element.android.libraries.matrix.api.verification.SessionVerificationData
@@ -24,22 +25,31 @@ import io.element.android.libraries.matrix.api.verification.SessionVerifiedStatu
import io.element.android.libraries.matrix.api.verification.VerificationEmoji import io.element.android.libraries.matrix.api.verification.VerificationEmoji
import io.element.android.libraries.matrix.api.verification.VerificationFlowState import io.element.android.libraries.matrix.api.verification.VerificationFlowState
import io.element.android.libraries.matrix.impl.sync.RustSyncService import io.element.android.libraries.matrix.impl.sync.RustSyncService
import io.element.android.libraries.matrix.impl.util.cancelAndDestroy
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.matrix.rustcomponents.sdk.Client
import org.matrix.rustcomponents.sdk.Encryption
import org.matrix.rustcomponents.sdk.RecoveryState
import org.matrix.rustcomponents.sdk.RecoveryStateListener
import org.matrix.rustcomponents.sdk.SessionVerificationController import org.matrix.rustcomponents.sdk.SessionVerificationController
import org.matrix.rustcomponents.sdk.SessionVerificationControllerDelegate import org.matrix.rustcomponents.sdk.SessionVerificationControllerDelegate
import org.matrix.rustcomponents.sdk.SessionVerificationControllerInterface import org.matrix.rustcomponents.sdk.SessionVerificationControllerInterface
import org.matrix.rustcomponents.sdk.TaskHandle
import org.matrix.rustcomponents.sdk.use import org.matrix.rustcomponents.sdk.use
import org.matrix.rustcomponents.sdk.SessionVerificationData as RustSessionVerificationData import org.matrix.rustcomponents.sdk.SessionVerificationData as RustSessionVerificationData
class RustSessionVerificationService( class RustSessionVerificationService(
client: Client,
private val syncService: RustSyncService, private val syncService: RustSyncService,
private val sessionCoroutineScope: CoroutineScope, private val sessionCoroutineScope: CoroutineScope,
) : SessionVerificationService, SessionVerificationControllerDelegate { ) : SessionVerificationService, SessionVerificationControllerDelegate {
private var recoveryStateListenerTaskHandle: TaskHandle? = null
private val encryptionService: Encryption = client.encryption()
var verificationController: SessionVerificationControllerInterface? = null var verificationController: SessionVerificationControllerInterface? = null
set(value) { set(value) {
field = value field = value
@@ -64,6 +74,16 @@ class RustSessionVerificationService(
syncState == SyncState.Running && verificationStatus == SessionVerifiedStatus.NotVerified syncState == SyncState.Running && verificationStatus == SessionVerifiedStatus.NotVerified
} }
fun start() {
recoveryStateListenerTaskHandle = encryptionService.recoveryStateListener(object : RecoveryStateListener {
override fun onUpdate(status: RecoveryState) {
sessionCoroutineScope.launch {
updateVerificationStatus(verificationController?.isVerified().orFalse())
}
}
})
}
override suspend fun requestVerification() = tryOrFail { override suspend fun requestVerification() = tryOrFail {
verificationController?.requestVerification() verificationController?.requestVerification()
} }
@@ -125,6 +145,8 @@ class RustSessionVerificationService(
} }
fun destroy() { fun destroy() {
recoveryStateListenerTaskHandle?.cancelAndDestroy()
verificationController?.setDelegate(null)
(verificationController as? SessionVerificationController)?.destroy() (verificationController as? SessionVerificationController)?.destroy()
verificationController = null verificationController = null
} }