diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt index fc53540c5f..699dbf1d92 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt @@ -119,7 +119,7 @@ interface CryptoService { fun shouldEncryptForInvitedMembers(roomId: String): Boolean - fun downloadKeys(userIds: List, forceDownload: Boolean, callback: MatrixCallback>) + suspend fun downloadKeys(userIds: List, forceDownload: Boolean = false): MXUsersDevicesMap fun getCryptoDeviceInfo(userId: String): List diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index cc74805d28..e188bc2ca3 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -30,6 +30,7 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock +import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.MatrixCoroutineDispatchers import org.matrix.android.sdk.api.NoOpMatrixCallback @@ -178,7 +179,13 @@ internal class DefaultCryptoService @Inject constructor( this.callback = object : MatrixCallback { override fun onSuccess(data: Unit) { // bg refresh of crypto device - downloadKeys(listOf(userId), true, NoOpMatrixCallback()) + cryptoCoroutineScope.launch { + try { + downloadKeys(listOf(userId), true) + } catch (failure: Throwable) { + Timber.w(failure, "setDeviceName: Failed to refresh of crypto device") + } + } callback.onSuccess(data) } @@ -1005,11 +1012,9 @@ internal class DefaultCryptoService @Inject constructor( // TODO } - override fun downloadKeys(userIds: List, forceDownload: Boolean, callback: MatrixCallback>) { - cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { - runCatching { - olmMachine.ensureUserDevicesMap(userIds, forceDownload) - }.foldToCallback(callback) + override suspend fun downloadKeys(userIds: List, forceDownload: Boolean): MXUsersDevicesMap { + return withContext(coroutineDispatchers.crypto) { + olmMachine.ensureUserDevicesMap(userIds, forceDownload) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomBodyBuilder.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomBodyBuilder.kt index 9b56354672..d8be0c1506 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomBodyBuilder.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomBodyBuilder.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.internal.session.room.create import org.matrix.android.sdk.api.extensions.tryOrNull +import org.matrix.android.sdk.api.session.crypto.CryptoService import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.identity.IdentityServiceError @@ -24,7 +25,6 @@ import org.matrix.android.sdk.api.session.identity.toMedium import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams import org.matrix.android.sdk.api.util.MimeTypes import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM -import org.matrix.android.sdk.internal.crypto.OlmMachineProvider import org.matrix.android.sdk.internal.di.AuthenticatedIdentity import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.network.token.AccessTokenProvider @@ -40,7 +40,7 @@ import javax.inject.Inject internal class CreateRoomBodyBuilder @Inject constructor( private val ensureIdentityTokenTask: EnsureIdentityTokenTask, // private val deviceListManager: DeviceListManager, - private val olmMachineProvider: OlmMachineProvider, + private val cryptoService: CryptoService, private val identityStore: IdentityStore, private val fileUploader: FileUploader, @UserId @@ -181,20 +181,20 @@ internal class CreateRoomBodyBuilder @Inject constructor( params.invite3pids.isEmpty() && params.invitedUserIds.isNotEmpty() && params.invitedUserIds.let { userIds -> - val keys = olmMachineProvider.olmMachine.ensureUserDevicesMap(userIds, forceDownload = false) - // deviceListManager.downloadKeys(userIds, forceDownload = false) + val keys = cryptoService.downloadKeys(userIds, forceDownload = false) + // deviceListManager.downloadKeys(userIds, forceDownload = false) - userIds.all { userId -> - keys.map[userId].let { deviceMap -> - if (deviceMap.isNullOrEmpty()) { - // A user has no device, so do not enable encryption - false - } else { - // Check that every user's device have at least one key - deviceMap.values.all { !it.keys.isNullOrEmpty() } + userIds.all { userId -> + keys.map[userId].let { deviceMap -> + if (deviceMap.isNullOrEmpty()) { + // A user has no device, so do not enable encryption + false + } else { + // Check that every user's device have at least one key + deviceMap.values.all { !it.keys.isNullOrEmpty() } + } + } } } - } - } } } diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysrequest/KeyRequestHandler.kt b/vector/src/main/java/im/vector/app/features/crypto/keysrequest/KeyRequestHandler.kt index 85250a94ce..949037bc3c 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysrequest/KeyRequestHandler.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysrequest/KeyRequestHandler.kt @@ -22,7 +22,13 @@ import im.vector.app.core.date.DateFormatKind import im.vector.app.core.date.VectorDateFormatter import im.vector.app.features.popup.DefaultVectorAlert import im.vector.app.features.popup.PopupAlertManager -import org.matrix.android.sdk.api.MatrixCallback +import im.vector.app.features.session.coroutineScope +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.cancel +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.keyshare.GossipingRequestListener import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTransaction @@ -34,7 +40,6 @@ import org.matrix.android.sdk.internal.crypto.IncomingRoomKeyRequest import org.matrix.android.sdk.internal.crypto.IncomingSecretShareRequest import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo -import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo import timber.log.Timber import javax.inject.Inject @@ -48,6 +53,7 @@ import javax.inject.Singleton * depending on user action) */ +// TODO Do we ever request to users anymore? @Singleton class KeyRequestHandler @Inject constructor( private val context: Context, @@ -60,13 +66,18 @@ class KeyRequestHandler @Inject constructor( var session: Session? = null + var scope: CoroutineScope? = null + fun start(session: Session) { this.session = session + scope = CoroutineScope(SupervisorJob() + session.coroutineScope.coroutineContext) session.cryptoService().verificationService().addListener(this) session.cryptoService().addRoomKeysRequestListener(this) } fun stop() { + scope?.cancel() + scope = null session?.cryptoService()?.verificationService()?.removeListener(this) session?.cryptoService()?.removeRoomKeysRequestListener(this) session = null @@ -104,15 +115,16 @@ class KeyRequestHandler @Inject constructor( alertsToRequests[mappingKey] = ArrayList().apply { this.add(request) } - // Add a notification for every incoming request - session?.cryptoService()?.downloadKeys(listOf(userId), false, object : MatrixCallback> { - override fun onSuccess(data: MXUsersDevicesMap) { + scope?.launch { + try { + val data = session?.cryptoService()?.downloadKeys(listOf(userId), false) + ?: return@launch val deviceInfo = data.getObject(userId, deviceId) if (null == deviceInfo) { Timber.e("## displayKeyShareDialog() : No details found for device $userId:$deviceId") // ignore - return + return@launch } if (deviceInfo.isUnknown) { @@ -122,20 +134,23 @@ class KeyRequestHandler @Inject constructor( // can we get more info on this device? session?.cryptoService()?.getMyDevicesInfo()?.firstOrNull { it.deviceId == deviceId }?.let { - postAlert(context, userId, deviceId, true, deviceInfo, it) + withContext(Dispatchers.Main) { + postAlert(context, userId, deviceId, true, deviceInfo, it) + } } ?: run { - postAlert(context, userId, deviceId, true, deviceInfo) + withContext(Dispatchers.Main) { + postAlert(context, userId, deviceId, true, deviceInfo) + } } } else { - postAlert(context, userId, deviceId, false, deviceInfo) + withContext(Dispatchers.Main) { + postAlert(context, userId, deviceId, false, deviceInfo) + } } - } - - override fun onFailure(failure: Throwable) { - // ignore + } catch (failure: Throwable) { Timber.e(failure, "## displayKeyShareDialog : downloadKeys") } - }) + } } private fun postAlert(context: Context, diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt index 59b9cafd6e..782bde4e5e 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt @@ -47,8 +47,6 @@ import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams import org.matrix.android.sdk.api.util.toMatrixItem import org.matrix.android.sdk.flow.flow -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo -import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.util.awaitCallback import timber.log.Timber import kotlin.coroutines.Continuation @@ -181,9 +179,7 @@ class HomeActivityViewModel @AssistedInject constructor( val session = activeSessionHolder.getSafeActiveSession() ?: return@launch tryOrNull("## MaybeBootstrapCrossSigning: Failed to download keys") { - awaitCallback> { - session.cryptoService().downloadKeys(listOf(session.myUserId), true, it) - } + session.cryptoService().downloadKeys(listOf(session.myUserId), true) } // From there we are up to date with server diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt index 67ed2e18f2..c8b595a5ed 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt @@ -169,7 +169,7 @@ class DevicesViewModel @AssistedInject constructor( refreshSource.stream().throttleFirst(4_000) .onEach { session.cryptoService().fetchDevicesList(NoOpMatrixCallback()) - session.cryptoService().downloadKeys(listOf(session.myUserId), true, NoOpMatrixCallback()) + session.cryptoService().downloadKeys(listOf(session.myUserId), true) } .launchIn(viewModelScope) // then force download