diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/threads/DefaultThreadsService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/threads/DefaultThreadsService.kt index 6c6d6368d1..ffe6ad301e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/threads/DefaultThreadsService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/threads/DefaultThreadsService.kt @@ -27,7 +27,6 @@ import org.matrix.android.sdk.api.session.room.threads.model.ThreadSummary import org.matrix.android.sdk.internal.database.helper.enhanceWithEditions import org.matrix.android.sdk.internal.database.helper.findAllThreadsForRoomId import org.matrix.android.sdk.internal.database.mapper.ThreadSummaryMapper -import org.matrix.android.sdk.internal.database.mapper.TimelineEventMapper import org.matrix.android.sdk.internal.database.model.threads.ThreadSummaryEntity import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.di.UserId @@ -40,7 +39,6 @@ internal class DefaultThreadsService @AssistedInject constructor( private val fetchThreadTimelineTask: FetchThreadTimelineTask, private val fetchThreadSummariesTask: FetchThreadSummariesTask, @SessionDatabase private val monarchy: Monarchy, - private val timelineEventMapper: TimelineEventMapper, private val threadSummaryMapper: ThreadSummaryMapper ) : ThreadsService { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt index 3e2939a3bb..f995e29cef 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt @@ -74,7 +74,10 @@ internal class SyncResponseHandler @Inject constructor( // Handle the to device events before the room ones // to ensure to decrypt them properly - handleToDevice(syncResponse) + + relevantPlugins.measureSpan("task", "handle_to_device") { + handleToDevice(syncResponse) + } val aggregator = SyncResponsePostTreatmentAggregator() @@ -113,7 +116,6 @@ internal class SyncResponseHandler @Inject constructor( } private suspend fun handleToDevice(syncResponse: SyncResponse) { - relevantPlugins.measureSpan("task", "handle_to_device") { measureTimeMillis { Timber.v("Handle toDevice") cryptoService.receiveSyncChanges( @@ -124,7 +126,6 @@ internal class SyncResponseHandler @Inject constructor( }.also { Timber.v("Finish handling toDevice in $it ms") } - } } private suspend fun startMonarchyTransaction( diff --git a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/GetUserIdentityUseCase.kt b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/GetUserIdentityUseCase.kt index 2d88f926ff..4f62d9ea1f 100644 --- a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/GetUserIdentityUseCase.kt +++ b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/GetUserIdentityUseCase.kt @@ -24,6 +24,8 @@ import org.matrix.android.sdk.internal.crypto.model.rest.RestKeyInfo import org.matrix.android.sdk.internal.crypto.network.RequestSender import org.matrix.android.sdk.internal.crypto.verification.VerificationRequest import org.matrix.rustcomponents.sdk.crypto.CryptoStoreException +import timber.log.Timber +import org.matrix.rustcomponents.sdk.crypto.UserIdentity as InnerUserIdentity import javax.inject.Inject import javax.inject.Provider @@ -38,13 +40,18 @@ internal class GetUserIdentityUseCase @Inject constructor( @Throws(CryptoStoreException::class) suspend operator fun invoke(userId: String): UserIdentities? { val innerMachine = olmMachine.get().inner() - val identity = withContext(coroutineDispatchers.io) { - innerMachine.getIdentity(userId, 30u) + val identity = try { + withContext(coroutineDispatchers.io) { + innerMachine.getIdentity(userId, 30u) + } + } catch (error: CryptoStoreException) { + Timber.w(error, "Failed to get identity for user $userId") + return null } val adapter = moshi.adapter(RestKeyInfo::class.java) return when (identity) { - is org.matrix.rustcomponents.sdk.crypto.UserIdentity.Other -> { + is InnerUserIdentity.Other -> { val verified = innerMachine.isIdentityVerified(userId) val masterKey = adapter.fromJson(identity.masterKey)!!.toCryptoModel().apply { trustLevel = DeviceTrustLevel(verified, verified) @@ -62,7 +69,7 @@ internal class GetUserIdentityUseCase @Inject constructor( verificationRequestFactory = verificationRequestFactory ) } - is org.matrix.rustcomponents.sdk.crypto.UserIdentity.Own -> { + is InnerUserIdentity.Own -> { val verified = innerMachine.isIdentityVerified(userId) val masterKey = adapter.fromJson(identity.masterKey)!!.toCryptoModel().apply { diff --git a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt index 31795d3c4d..3ba71a006d 100644 --- a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt +++ b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt @@ -88,22 +88,36 @@ internal class RustVerificationService @Inject constructor( */ internal suspend fun onEvent(roomId: String?, event: Event) { if (roomId != null && !event.isEncrypted()) { - olmMachine.receiveUnencryptedVerificationEvent(roomId, event) + if (isVerificationEvent(event)) { + try { + olmMachine.receiveUnencryptedVerificationEvent(roomId, event) + } catch (failure: Throwable) { + Timber.w(failure, "Failed to receiveUnencryptedVerificationEvent") + } + } } when (event.getClearType()) { EventType.KEY_VERIFICATION_REQUEST -> onRequest(event, fromRoomMessage = false) - EventType.KEY_VERIFICATION_START -> onStart(event) + EventType.KEY_VERIFICATION_START -> onStart(event) EventType.KEY_VERIFICATION_READY, EventType.KEY_VERIFICATION_ACCEPT, EventType.KEY_VERIFICATION_KEY, EventType.KEY_VERIFICATION_MAC, EventType.KEY_VERIFICATION_CANCEL, - EventType.KEY_VERIFICATION_DONE -> onUpdate(event) - EventType.MESSAGE -> onRoomMessage(event) - else -> Unit + EventType.KEY_VERIFICATION_DONE -> onUpdate(event) + EventType.MESSAGE -> onRoomMessage(event) + else -> Unit } } + private fun isVerificationEvent(event: Event): Boolean { + val eventType = event.type ?: return false + val eventContent = event.content ?: return false + return EventType.isVerificationEvent(eventType) || + (eventType == EventType.MESSAGE && + eventContent[MessageContent.MSG_TYPE_JSON_KEY] == MessageType.MSGTYPE_VERIFICATION_REQUEST) + } + private suspend fun onRoomMessage(event: Event) { val messageContent = event.getClearContent()?.toModel() ?: return if (messageContent.msgType == MessageType.MSGTYPE_VERIFICATION_REQUEST) { diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/self/SelfVerificationController.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/self/SelfVerificationController.kt index 24948f9f67..1a9763de1c 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/self/SelfVerificationController.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/self/SelfVerificationController.kt @@ -34,6 +34,7 @@ import im.vector.app.features.crypto.verification.user.bottomDone import im.vector.app.features.crypto.verification.user.gotIt import im.vector.app.features.crypto.verification.user.renderAcceptDeclineRequest import im.vector.app.features.crypto.verification.user.renderCancel +import im.vector.app.features.crypto.verification.user.renderQrTransaction import im.vector.app.features.crypto.verification.user.renderSasTransaction import im.vector.app.features.crypto.verification.user.renderStartTransactionOptions import im.vector.app.features.crypto.verification.user.verifiedSuccessTile @@ -302,9 +303,7 @@ class SelfVerificationController @Inject constructor( private fun renderTransaction(state: SelfVerificationViewState, transaction: VerificationTransactionData) { when (transaction) { is VerificationTransactionData.QrTransactionData -> { - TODO("Render QR transaction $state") - // TODO - // renderQrTransaction(transaction, state.otherUserMxItem) + renderQrTransaction(transaction, null) } is VerificationTransactionData.SasTransactionData -> { renderSasTransaction(transaction) diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/user/UserVerificationController.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/user/UserVerificationController.kt index e995f33621..63945e7fb2 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/user/UserVerificationController.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/user/UserVerificationController.kt @@ -255,79 +255,6 @@ class UserVerificationController @Inject constructor( } } - private fun renderQrTransaction(transaction: VerificationTransactionData.QrTransactionData, otherUserItem: MatrixItem) { - val host = this - when (transaction.state) { - QRCodeVerificationState.Reciprocated -> { - // we are waiting for confirmation from the other side - bottomSheetVerificationNoticeItem { - id("notice") - apply { - notice(host.stringProvider.getString(R.string.qr_code_scanned_verif_waiting_notice).toEpoxyCharSequence()) - } - } - - bottomSheetVerificationBigImageItem { - id("image") - roomEncryptionTrustLevel(RoomEncryptionTrustLevel.Trusted) - } - - bottomSheetVerificationWaitingItem { - id("waiting") - title(host.stringProvider.getString(R.string.qr_code_scanned_verif_waiting, otherUserItem.getBestName())) - } - } - QRCodeVerificationState.WaitingForScanConfirmation -> { - // we need to confirm that the other party actual scanned us - bottomSheetVerificationNoticeItem { - id("notice") - apply { - val name = otherUserItem.getBestName() - notice(host.stringProvider.getString(R.string.qr_code_scanned_by_other_notice, name).toEpoxyCharSequence()) - } - } - - bottomSheetVerificationBigImageItem { - id("image") - roomEncryptionTrustLevel(RoomEncryptionTrustLevel.Trusted) - } - - bottomSheetDividerItem { - id("sep0") - } - - bottomSheetVerificationActionItem { - id("deny") - title(host.stringProvider.getString(R.string.qr_code_scanned_by_other_no)) - titleColor(host.colorProvider.getColorFromAttribute(R.attr.colorError)) - iconRes(R.drawable.ic_check_off) - iconColor(host.colorProvider.getColorFromAttribute(R.attr.colorError)) - listener { host.listener?.onUserDeniesQrCodeScanned() } - } - - bottomSheetDividerItem { - id("sep1") - } - - bottomSheetVerificationActionItem { - id("confirm") - title(host.stringProvider.getString(R.string.qr_code_scanned_by_other_yes)) - titleColor(host.colorProvider.getColorFromAttribute(R.attr.colorPrimary)) - iconRes(R.drawable.ic_check_on) - iconColor(host.colorProvider.getColorFromAttribute(R.attr.colorPrimary)) - listener { host.listener?.onUserConfirmsQrCodeScanned() } - } - } - QRCodeVerificationState.WaitingForOtherDone, - QRCodeVerificationState.Done -> { - // Done - } - QRCodeVerificationState.Cancelled -> { - // Done -// renderCancel(transaction.) - } - } - } private fun bottomDone() { val host = this diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/user/VerificationEpoxyExt.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/user/VerificationEpoxyExt.kt index 661e9ab7b3..24d193e38d 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/user/VerificationEpoxyExt.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/user/VerificationEpoxyExt.kt @@ -25,12 +25,15 @@ import im.vector.app.features.crypto.verification.epoxy.bottomSheetVerificationE import im.vector.app.features.crypto.verification.epoxy.bottomSheetVerificationNoticeItem import im.vector.app.features.crypto.verification.epoxy.bottomSheetVerificationQrCodeItem import im.vector.app.features.crypto.verification.epoxy.bottomSheetVerificationWaitingItem +import im.vector.app.features.displayname.getBestName import im.vector.lib.core.utils.epoxy.charsequence.toEpoxyCharSequence import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel import org.matrix.android.sdk.api.session.crypto.verification.CancelCode import org.matrix.android.sdk.api.session.crypto.verification.EmojiRepresentation import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest +import org.matrix.android.sdk.api.session.crypto.verification.QRCodeVerificationState import org.matrix.android.sdk.api.session.crypto.verification.SasTransactionState +import org.matrix.android.sdk.api.util.MatrixItem fun BaseEpoxyVerificationController.verifiedSuccessTile() { val host = this @@ -287,4 +290,86 @@ fun BaseEpoxyVerificationController.renderSasTransaction(transaction: Verificati } } +fun BaseEpoxyVerificationController.renderQrTransaction(transaction: VerificationTransactionData.QrTransactionData, otherUserItem: MatrixItem?) { + val host = this + when (transaction.state) { + QRCodeVerificationState.Reciprocated -> { + // we are waiting for confirmation from the other side + bottomSheetVerificationNoticeItem { + id("notice") + apply { + notice(host.stringProvider.getString(R.string.qr_code_scanned_verif_waiting_notice).toEpoxyCharSequence()) + } + } + + bottomSheetVerificationBigImageItem { + id("image") + roomEncryptionTrustLevel(RoomEncryptionTrustLevel.Trusted) + } + + bottomSheetVerificationWaitingItem { + id("waiting") + if (otherUserItem != null) { + title(host.stringProvider.getString(R.string.qr_code_scanned_verif_waiting, otherUserItem.getBestName())) + } else { + title(host.stringProvider.getString(R.string.qr_code_scanned_verif_waiting, transaction.otherDeviceId.orEmpty())) + } + } + } + QRCodeVerificationState.WaitingForScanConfirmation -> { + // we need to confirm that the other party actual scanned us + bottomSheetVerificationNoticeItem { + id("notice") + apply { + if (otherUserItem != null) { + val name = otherUserItem.getBestName() + notice(host.stringProvider.getString(R.string.qr_code_scanned_by_other_notice, name).toEpoxyCharSequence()) + } else { + notice(host.stringProvider.getString(R.string.qr_code_scanned_self_verif_notice).toEpoxyCharSequence()) + } + } + } + + bottomSheetVerificationBigImageItem { + id("image") + roomEncryptionTrustLevel(RoomEncryptionTrustLevel.Trusted) + } + + bottomSheetDividerItem { + id("sep0") + } + + bottomSheetVerificationActionItem { + id("deny") + title(host.stringProvider.getString(R.string.qr_code_scanned_by_other_no)) + titleColor(host.colorProvider.getColorFromAttribute(R.attr.colorError)) + iconRes(R.drawable.ic_check_off) + iconColor(host.colorProvider.getColorFromAttribute(R.attr.colorError)) + listener { host.listener?.onUserDeniesQrCodeScanned() } + } + + bottomSheetDividerItem { + id("sep1") + } + + bottomSheetVerificationActionItem { + id("confirm") + title(host.stringProvider.getString(R.string.qr_code_scanned_by_other_yes)) + titleColor(host.colorProvider.getColorFromAttribute(R.attr.colorPrimary)) + iconRes(R.drawable.ic_check_on) + iconColor(host.colorProvider.getColorFromAttribute(R.attr.colorPrimary)) + listener { host.listener?.onUserConfirmsQrCodeScanned() } + } + } + QRCodeVerificationState.WaitingForOtherDone, + QRCodeVerificationState.Done -> { + // Done + } + QRCodeVerificationState.Cancelled -> { + // Done +// renderCancel(transaction.) + } + } +} + class VerificationEpoxyExt