diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationMethod.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationMethod.kt index 8b65dd5645..b8f0f23891 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationMethod.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationMethod.kt @@ -17,9 +17,13 @@ package im.vector.matrix.android.api.session.crypto.sas /** - * Verification methods supported (or to be supported) by the matrix SDK + * Verification methods */ enum class VerificationMethod { + // Use it when your application supports the SAS verification method SAS, - SCAN + // Use it if your application is able to display QR codes + QR_CODE_SHOW, + // Use it if your application is able to scan QR codes + QR_CODE_SCAN } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/VerificationMethodValues.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/VerificationMethodValues.kt index 04fb76bedd..e3659bbde2 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/VerificationMethodValues.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/VerificationMethodValues.kt @@ -19,17 +19,25 @@ package im.vector.matrix.android.internal.crypto.model.rest import im.vector.matrix.android.api.session.crypto.sas.VerificationMethod internal const val VERIFICATION_METHOD_SAS = "m.sas.v1" -internal const val VERIFICATION_METHOD_SCAN = "m.qr_code.scan.v1" + +// Qr code +// Ref: https://github.com/uhoreg/matrix-doc/blob/qr_key_verification/proposals/1543-qr_code_key_verification.md#verification-methods +internal const val VERIFICATION_METHOD_QR_CODE_SHOW = "m.qr_code.show.v1" +internal const val VERIFICATION_METHOD_QR_CODE_SCAN = "m.qr_code.scan.v1" +internal const val VERIFICATION_METHOD_RECIPROCATE = "m.reciprocate.v1" internal fun VerificationMethod.toValue(): String { return when (this) { - VerificationMethod.SAS -> VERIFICATION_METHOD_SAS - VerificationMethod.SCAN -> VERIFICATION_METHOD_SCAN + VerificationMethod.SAS -> VERIFICATION_METHOD_SAS + VerificationMethod.QR_CODE_SCAN -> VERIFICATION_METHOD_QR_CODE_SCAN + VerificationMethod.QR_CODE_SHOW -> VERIFICATION_METHOD_QR_CODE_SHOW } } internal val supportedVerificationMethods = listOf( VERIFICATION_METHOD_SAS, - VERIFICATION_METHOD_SCAN + VERIFICATION_METHOD_QR_CODE_SHOW, + VERIFICATION_METHOD_QR_CODE_SCAN, + VERIFICATION_METHOD_RECIPROCATE ) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultSasVerificationService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultSasVerificationService.kt index 6e73169b28..1b909c11aa 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultSasVerificationService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultSasVerificationService.kt @@ -819,6 +819,7 @@ internal class DefaultSasVerificationService @Inject constructor( if (existingRequest != null) { // we need to send a ready event, with matching methods val transport = sasTransportRoomMessageFactory.createTransport(roomId, null) + // TODO We should not use supportedVerificationMethods here, because it depends on the client implementation val methods = existingRequest.requestInfo?.methods?.intersect(supportedVerificationMethods)?.toList() if (methods.isNullOrEmpty()) { Timber.i("Cannot ready this request, no common methods found txId:$transactionId") diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/PendingVerificationRequest.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/PendingVerificationRequest.kt index 0ac3847a53..531d2c8fa1 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/PendingVerificationRequest.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/PendingVerificationRequest.kt @@ -18,9 +18,10 @@ package im.vector.matrix.android.internal.crypto.verification import im.vector.matrix.android.api.session.crypto.sas.CancelCode import im.vector.matrix.android.api.session.crypto.sas.VerificationMethod import im.vector.matrix.android.api.session.room.model.message.MessageVerificationRequestContent +import im.vector.matrix.android.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SCAN +import im.vector.matrix.android.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SHOW import im.vector.matrix.android.internal.crypto.model.rest.VERIFICATION_METHOD_SAS -import im.vector.matrix.android.internal.crypto.model.rest.VERIFICATION_METHOD_SCAN -import java.util.* +import java.util.UUID /** * Stores current pending verification requests @@ -46,8 +47,9 @@ data class PendingVerificationRequest( fun hasMethod(method: VerificationMethod): Boolean? { return when (method) { - VerificationMethod.SAS -> readyInfo?.methods?.contains(VERIFICATION_METHOD_SAS) - VerificationMethod.SCAN -> readyInfo?.methods?.contains(VERIFICATION_METHOD_SCAN) + VerificationMethod.SAS -> readyInfo?.methods?.contains(VERIFICATION_METHOD_SAS) + VerificationMethod.QR_CODE_SHOW -> readyInfo?.methods?.contains(VERIFICATION_METHOD_QR_CODE_SHOW) + VerificationMethod.QR_CODE_SCAN -> readyInfo?.methods?.contains(VERIFICATION_METHOD_QR_CODE_SCAN) } } } diff --git a/vector/src/debug/java/im/vector/riotx/features/debug/DebugMenuActivity.kt b/vector/src/debug/java/im/vector/riotx/features/debug/DebugMenuActivity.kt index 767f8cf7e1..96a6f4bb2d 100644 --- a/vector/src/debug/java/im/vector/riotx/features/debug/DebugMenuActivity.kt +++ b/vector/src/debug/java/im/vector/riotx/features/debug/DebugMenuActivity.kt @@ -65,7 +65,7 @@ class DebugMenuActivity : VectorBaseActivity() { } private fun renderQrCode(text: String) { - val qrBitmap = text.toQrCode() + val qrBitmap = text.toQrCode(200, 200) debug_qr_code.setImageBitmap(qrBitmap) } diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/Config.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/Config.kt index 0e9011d532..fae7037403 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/Config.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/Config.kt @@ -20,6 +20,10 @@ import im.vector.matrix.android.api.session.crypto.sas.VerificationMethod val supportedVerificationMethods = listOf( + // RiotX supports SAS verification VerificationMethod.SAS, - VerificationMethod.SCAN + // RiotX is able to show QR codes + VerificationMethod.QR_CODE_SHOW, + // RiotX is able to scan QR codes + VerificationMethod.QR_CODE_SCAN ) diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/choose/VerificationChooseMethodController.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/choose/VerificationChooseMethodController.kt index 5cec77f368..0bf38979da 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/choose/VerificationChooseMethodController.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/choose/VerificationChooseMethodController.kt @@ -46,36 +46,40 @@ class VerificationChooseMethodController @Inject constructor( override fun buildModels() { val state = viewState ?: return - if (state.QRModeAvailable) { + if (state.otherCanScanQrCode || state.otherCanShowQrCode) { bottomSheetVerificationNoticeItem { id("notice") notice(stringProvider.getString(R.string.verification_scan_notice)) } - // Generate the QR code - val size = dimensionConverter.dpToPx(180) - val qrCodeBitmap = state.QRtext?.toQrCode(size, size) + if (state.otherCanScanQrCode && !state.QRtext.isNullOrBlank()) { + // Generate the QR code + val size = dimensionConverter.dpToPx(180) + val qrCodeBitmap = state.QRtext.toQrCode(size, size) - bottomSheetVerificationBigImageItem { - id("qr") - imageBitmap(qrCodeBitmap) + bottomSheetVerificationBigImageItem { + id("qr") + imageBitmap(qrCodeBitmap) + } + + dividerItem { + id("sep0") + } } - dividerItem { - id("sep0") - } + if (state.otherCanShowQrCode) { + bottomSheetVerificationActionItem { + id("openCamera") + title(stringProvider.getString(R.string.verification_scan_their_code)) + titleColor(colorProvider.getColor(R.color.riotx_accent)) + iconRes(R.drawable.ic_camera) + iconColor(colorProvider.getColor(R.color.riotx_accent)) + listener { listener?.openCamera() } + } - bottomSheetVerificationActionItem { - id("openCamera") - title(stringProvider.getString(R.string.verification_scan_their_code)) - titleColor(colorProvider.getColor(R.color.riotx_accent)) - iconRes(R.drawable.ic_camera) - iconColor(colorProvider.getColor(R.color.riotx_accent)) - listener { listener?.openCamera() } - } - - dividerItem { - id("sep1") + dividerItem { + id("sep1") + } } bottomSheetVerificationActionItem { diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/choose/VerificationChooseMethodViewModel.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/choose/VerificationChooseMethodViewModel.kt index cd28a2b709..87d237d9dc 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/choose/VerificationChooseMethodViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/choose/VerificationChooseMethodViewModel.kt @@ -34,7 +34,8 @@ import im.vector.riotx.features.crypto.verification.VerificationBottomSheet data class VerificationChooseMethodViewState( val otherUserId: String = "", val transactionId: String = "", - val QRModeAvailable: Boolean = false, + val otherCanShowQrCode: Boolean = false, + val otherCanScanQrCode: Boolean = false, val QRtext: String? = null, val SASModeAvailable: Boolean = false ) : MvRxState @@ -50,15 +51,14 @@ class VerificationChooseMethodViewModel @AssistedInject constructor( override fun verificationRequestUpdated(pr: PendingVerificationRequest) = withState { state -> val pvr = session.getSasVerificationService().getExistingVerificationRequest(state.otherUserId, state.transactionId) - val qrAvailable = pvr?.hasMethod(VerificationMethod.SCAN) ?: false - val emojiAvailable = pvr?.hasMethod(VerificationMethod.SAS) ?: false setState { copy( - QRModeAvailable = qrAvailable, + otherCanShowQrCode = pvr?.hasMethod(VerificationMethod.QR_CODE_SHOW) ?: false, + otherCanScanQrCode = pvr?.hasMethod(VerificationMethod.QR_CODE_SCAN) ?: false, // TODO QRtext = "https://www.example.org", - SASModeAvailable = emojiAvailable + SASModeAvailable = pvr?.hasMethod(VerificationMethod.SAS) ?: false ) } } @@ -87,15 +87,14 @@ class VerificationChooseMethodViewModel @AssistedInject constructor( val args: VerificationBottomSheet.VerificationArgs = viewModelContext.args() val session = (viewModelContext.activity as HasScreenInjector).injector().activeSessionHolder().getActiveSession() val pvr = session.getSasVerificationService().getExistingVerificationRequest(args.otherUserId, args.verificationId) - val qrAvailable = pvr?.hasMethod(VerificationMethod.SCAN) ?: false - val emojiAvailable = pvr?.hasMethod(VerificationMethod.SAS) ?: false return VerificationChooseMethodViewState(otherUserId = args.otherUserId, transactionId = args.verificationId ?: "", - QRModeAvailable = qrAvailable, + otherCanShowQrCode = pvr?.hasMethod(VerificationMethod.QR_CODE_SHOW) ?: false, + otherCanScanQrCode = pvr?.hasMethod(VerificationMethod.QR_CODE_SCAN) ?: false, // TODO QRtext = "https://www.example.org", - SASModeAvailable = emojiAvailable + SASModeAvailable = pvr?.hasMethod(VerificationMethod.SAS) ?: false ) } }