fix unhandled exceptions and cleaning

This commit is contained in:
valere 2022-12-02 12:37:37 +01:00
parent b0168dc633
commit 17b8d3c97b
7 changed files with 121 additions and 90 deletions

View file

@ -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.enhanceWithEditions
import org.matrix.android.sdk.internal.database.helper.findAllThreadsForRoomId 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.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.database.model.threads.ThreadSummaryEntity
import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.di.SessionDatabase
import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.di.UserId
@ -40,7 +39,6 @@ internal class DefaultThreadsService @AssistedInject constructor(
private val fetchThreadTimelineTask: FetchThreadTimelineTask, private val fetchThreadTimelineTask: FetchThreadTimelineTask,
private val fetchThreadSummariesTask: FetchThreadSummariesTask, private val fetchThreadSummariesTask: FetchThreadSummariesTask,
@SessionDatabase private val monarchy: Monarchy, @SessionDatabase private val monarchy: Monarchy,
private val timelineEventMapper: TimelineEventMapper,
private val threadSummaryMapper: ThreadSummaryMapper private val threadSummaryMapper: ThreadSummaryMapper
) : ThreadsService { ) : ThreadsService {

View file

@ -74,7 +74,10 @@ internal class SyncResponseHandler @Inject constructor(
// Handle the to device events before the room ones // Handle the to device events before the room ones
// to ensure to decrypt them properly // to ensure to decrypt them properly
handleToDevice(syncResponse)
relevantPlugins.measureSpan("task", "handle_to_device") {
handleToDevice(syncResponse)
}
val aggregator = SyncResponsePostTreatmentAggregator() val aggregator = SyncResponsePostTreatmentAggregator()
@ -113,7 +116,6 @@ internal class SyncResponseHandler @Inject constructor(
} }
private suspend fun handleToDevice(syncResponse: SyncResponse) { private suspend fun handleToDevice(syncResponse: SyncResponse) {
relevantPlugins.measureSpan("task", "handle_to_device") {
measureTimeMillis { measureTimeMillis {
Timber.v("Handle toDevice") Timber.v("Handle toDevice")
cryptoService.receiveSyncChanges( cryptoService.receiveSyncChanges(
@ -124,7 +126,6 @@ internal class SyncResponseHandler @Inject constructor(
}.also { }.also {
Timber.v("Finish handling toDevice in $it ms") Timber.v("Finish handling toDevice in $it ms")
} }
}
} }
private suspend fun startMonarchyTransaction( private suspend fun startMonarchyTransaction(

View file

@ -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.network.RequestSender
import org.matrix.android.sdk.internal.crypto.verification.VerificationRequest import org.matrix.android.sdk.internal.crypto.verification.VerificationRequest
import org.matrix.rustcomponents.sdk.crypto.CryptoStoreException 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.Inject
import javax.inject.Provider import javax.inject.Provider
@ -38,13 +40,18 @@ internal class GetUserIdentityUseCase @Inject constructor(
@Throws(CryptoStoreException::class) @Throws(CryptoStoreException::class)
suspend operator fun invoke(userId: String): UserIdentities? { suspend operator fun invoke(userId: String): UserIdentities? {
val innerMachine = olmMachine.get().inner() val innerMachine = olmMachine.get().inner()
val identity = withContext(coroutineDispatchers.io) { val identity = try {
innerMachine.getIdentity(userId, 30u) 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) val adapter = moshi.adapter(RestKeyInfo::class.java)
return when (identity) { return when (identity) {
is org.matrix.rustcomponents.sdk.crypto.UserIdentity.Other -> { is InnerUserIdentity.Other -> {
val verified = innerMachine.isIdentityVerified(userId) val verified = innerMachine.isIdentityVerified(userId)
val masterKey = adapter.fromJson(identity.masterKey)!!.toCryptoModel().apply { val masterKey = adapter.fromJson(identity.masterKey)!!.toCryptoModel().apply {
trustLevel = DeviceTrustLevel(verified, verified) trustLevel = DeviceTrustLevel(verified, verified)
@ -62,7 +69,7 @@ internal class GetUserIdentityUseCase @Inject constructor(
verificationRequestFactory = verificationRequestFactory verificationRequestFactory = verificationRequestFactory
) )
} }
is org.matrix.rustcomponents.sdk.crypto.UserIdentity.Own -> { is InnerUserIdentity.Own -> {
val verified = innerMachine.isIdentityVerified(userId) val verified = innerMachine.isIdentityVerified(userId)
val masterKey = adapter.fromJson(identity.masterKey)!!.toCryptoModel().apply { val masterKey = adapter.fromJson(identity.masterKey)!!.toCryptoModel().apply {

View file

@ -88,22 +88,36 @@ internal class RustVerificationService @Inject constructor(
*/ */
internal suspend fun onEvent(roomId: String?, event: Event) { internal suspend fun onEvent(roomId: String?, event: Event) {
if (roomId != null && !event.isEncrypted()) { 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()) { when (event.getClearType()) {
EventType.KEY_VERIFICATION_REQUEST -> onRequest(event, fromRoomMessage = false) 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_READY,
EventType.KEY_VERIFICATION_ACCEPT, EventType.KEY_VERIFICATION_ACCEPT,
EventType.KEY_VERIFICATION_KEY, EventType.KEY_VERIFICATION_KEY,
EventType.KEY_VERIFICATION_MAC, EventType.KEY_VERIFICATION_MAC,
EventType.KEY_VERIFICATION_CANCEL, EventType.KEY_VERIFICATION_CANCEL,
EventType.KEY_VERIFICATION_DONE -> onUpdate(event) EventType.KEY_VERIFICATION_DONE -> onUpdate(event)
EventType.MESSAGE -> onRoomMessage(event) EventType.MESSAGE -> onRoomMessage(event)
else -> Unit 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) { private suspend fun onRoomMessage(event: Event) {
val messageContent = event.getClearContent()?.toModel<MessageContent>() ?: return val messageContent = event.getClearContent()?.toModel<MessageContent>() ?: return
if (messageContent.msgType == MessageType.MSGTYPE_VERIFICATION_REQUEST) { if (messageContent.msgType == MessageType.MSGTYPE_VERIFICATION_REQUEST) {

View file

@ -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.gotIt
import im.vector.app.features.crypto.verification.user.renderAcceptDeclineRequest 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.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.renderSasTransaction
import im.vector.app.features.crypto.verification.user.renderStartTransactionOptions import im.vector.app.features.crypto.verification.user.renderStartTransactionOptions
import im.vector.app.features.crypto.verification.user.verifiedSuccessTile import im.vector.app.features.crypto.verification.user.verifiedSuccessTile
@ -302,9 +303,7 @@ class SelfVerificationController @Inject constructor(
private fun renderTransaction(state: SelfVerificationViewState, transaction: VerificationTransactionData) { private fun renderTransaction(state: SelfVerificationViewState, transaction: VerificationTransactionData) {
when (transaction) { when (transaction) {
is VerificationTransactionData.QrTransactionData -> { is VerificationTransactionData.QrTransactionData -> {
TODO("Render QR transaction $state") renderQrTransaction(transaction, null)
// TODO
// renderQrTransaction(transaction, state.otherUserMxItem)
} }
is VerificationTransactionData.SasTransactionData -> { is VerificationTransactionData.SasTransactionData -> {
renderSasTransaction(transaction) renderSasTransaction(transaction)

View file

@ -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() { private fun bottomDone() {
val host = this val host = this

View file

@ -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.bottomSheetVerificationNoticeItem
import im.vector.app.features.crypto.verification.epoxy.bottomSheetVerificationQrCodeItem import im.vector.app.features.crypto.verification.epoxy.bottomSheetVerificationQrCodeItem
import im.vector.app.features.crypto.verification.epoxy.bottomSheetVerificationWaitingItem 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 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.model.RoomEncryptionTrustLevel
import org.matrix.android.sdk.api.session.crypto.verification.CancelCode 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.EmojiRepresentation
import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest 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.session.crypto.verification.SasTransactionState
import org.matrix.android.sdk.api.util.MatrixItem
fun BaseEpoxyVerificationController.verifiedSuccessTile() { fun BaseEpoxyVerificationController.verifiedSuccessTile() {
val host = this 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 class VerificationEpoxyExt