diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/verification/RustSessionVerificationService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/verification/RustSessionVerificationService.kt index d5f52cc8dc..c4d75e3050 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/verification/RustSessionVerificationService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/verification/RustSessionVerificationService.kt @@ -26,6 +26,8 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.withTimeout import org.matrix.rustcomponents.sdk.Client import org.matrix.rustcomponents.sdk.Encryption @@ -99,10 +101,7 @@ class RustSessionVerificationService( } override suspend fun requestVerification() = tryOrFail { - if (!this::verificationController.isInitialized) { - verificationController = client.getSessionVerificationController() - verificationController.setDelegate(this) - } + initVerificationControllerIfNeeded() verificationController.requestVerification() } @@ -193,6 +192,16 @@ class RustSessionVerificationService( } } + private var initControllerMutex = Mutex() + + private suspend fun initVerificationControllerIfNeeded() = initControllerMutex.withLock { + if (!this::verificationController.isInitialized) { + tryOrFail { + verificationController = client.getSessionVerificationController() + verificationController.setDelegate(this) + } + } + } private suspend fun updateVerificationStatus() { if (verificationFlowState.value == VerificationFlowState.Finished) { // Calling `encryptionService.verificationState()` performs a network call and it will deadlock if there is no network @@ -212,10 +221,7 @@ class RustSessionVerificationService( // Otherwise, just check the current verification status from the session verification controller instead Timber.d("Updating verification status: flow is pending or was finished some time ago") runCatching { - if (!this@RustSessionVerificationService::verificationController.isInitialized) { - verificationController = client.getSessionVerificationController() - verificationController.setDelegate(this@RustSessionVerificationService) - } + initVerificationControllerIfNeeded() _sessionVerifiedStatus.value = if (verificationController.isVerified()) { SessionVerifiedStatus.Verified } else {