From 6ff974b3eab925024ae9897ee9955eb6e4316b47 Mon Sep 17 00:00:00 2001
From: Benoit Marty <benoitm@matrix.org>
Date: Wed, 12 Feb 2020 11:16:21 +0100
Subject: [PATCH 1/5] Fix issue with verification when other client declares it
 can only show QR code (#988)

---
 CHANGES.md                                    |   1 +
 .../verification/qrcode/VerificationTest.kt   | 232 ++++++++++++++++++
 .../PendingVerificationRequest.kt             |  38 ++-
 .../VerificationChooseMethodViewModel.kt      |  14 +-
 4 files changed, 272 insertions(+), 13 deletions(-)
 create mode 100644 matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/qrcode/VerificationTest.kt

diff --git a/CHANGES.md b/CHANGES.md
index 1ffa3c7ebe..0920127803 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -12,6 +12,7 @@ Other changes:
 
 Bugfix 🐛:
  - Fix crash by removing all notifications after clearing cache (#878)
+ - Fix issue with verification when other client declares it can only show QR code (#988)
 
 Translations 🗣:
  -
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/qrcode/VerificationTest.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/qrcode/VerificationTest.kt
new file mode 100644
index 0000000000..adde452619
--- /dev/null
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/qrcode/VerificationTest.kt
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.matrix.android.internal.crypto.verification.qrcode
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import im.vector.matrix.android.InstrumentedTest
+import im.vector.matrix.android.api.session.crypto.sas.VerificationMethod
+import im.vector.matrix.android.api.session.crypto.sas.VerificationService
+import im.vector.matrix.android.common.CommonTestHelper
+import im.vector.matrix.android.common.CryptoTestHelper
+import im.vector.matrix.android.common.TestConstants
+import im.vector.matrix.android.internal.crypto.model.rest.UserPasswordAuth
+import im.vector.matrix.android.internal.crypto.verification.PendingVerificationRequest
+import org.amshove.kluent.shouldBe
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import java.util.concurrent.CountDownLatch
+
+@RunWith(AndroidJUnit4::class)
+@FixMethodOrder(MethodSorters.JVM)
+class VerificationTest : InstrumentedTest {
+    private val mTestHelper = CommonTestHelper(context())
+    private val mCryptoTestHelper = CryptoTestHelper(mTestHelper)
+
+    data class ExpectedResult(
+            val sasIsSupported: Boolean = false,
+            val otherCanScanQrCode: Boolean = false,
+            val otherCanShowQrCode: Boolean = false
+    )
+
+    private val sas = listOf(
+            VerificationMethod.SAS
+    )
+
+    private val sasShow = listOf(
+            VerificationMethod.SAS,
+            VerificationMethod.QR_CODE_SHOW
+    )
+
+    private val sasScan = listOf(
+            VerificationMethod.SAS,
+            VerificationMethod.QR_CODE_SCAN
+    )
+
+    private val sasShowScan = listOf(
+            VerificationMethod.SAS,
+            VerificationMethod.QR_CODE_SHOW,
+            VerificationMethod.QR_CODE_SCAN
+    )
+
+    @Test
+    fun test_aliceAndBob_sas_sas() = doTest(
+            sas,
+            sas,
+            ExpectedResult(sasIsSupported = true),
+            ExpectedResult(sasIsSupported = true)
+    )
+
+    @Test
+    fun test_aliceAndBob_sas_show() = doTest(
+            sas,
+            sasShow,
+            ExpectedResult(sasIsSupported = true),
+            ExpectedResult(sasIsSupported = true)
+    )
+
+    @Test
+    fun test_aliceAndBob_show_sas() = doTest(
+            sasShow,
+            sas,
+            ExpectedResult(sasIsSupported = true),
+            ExpectedResult(sasIsSupported = true)
+    )
+
+    @Test
+    fun test_aliceAndBob_sas_scan() = doTest(
+            sas,
+            sasScan,
+            ExpectedResult(sasIsSupported = true),
+            ExpectedResult(sasIsSupported = true)
+    )
+
+    @Test
+    fun test_aliceAndBob_scan_sas() = doTest(
+            sasScan,
+            sas,
+            ExpectedResult(sasIsSupported = true),
+            ExpectedResult(sasIsSupported = true)
+    )
+
+    @Test
+    fun test_aliceAndBob_scan_scan() = doTest(
+            sasScan,
+            sasScan,
+            ExpectedResult(sasIsSupported = true),
+            ExpectedResult(sasIsSupported = true)
+    )
+
+    @Test
+    fun test_aliceAndBob_show_show() = doTest(
+            sasShow,
+            sasShow,
+            ExpectedResult(sasIsSupported = true),
+            ExpectedResult(sasIsSupported = true)
+    )
+
+    @Test
+    fun test_aliceAndBob_show_scan() = doTest(
+            sasShow,
+            sasScan,
+            ExpectedResult(sasIsSupported = true, otherCanScanQrCode = true),
+            ExpectedResult(sasIsSupported = true, otherCanShowQrCode = true)
+    )
+
+    @Test
+    fun test_aliceAndBob_scan_show() = doTest(
+            sasScan,
+            sasShow,
+            ExpectedResult(sasIsSupported = true, otherCanShowQrCode = true),
+            ExpectedResult(sasIsSupported = true, otherCanScanQrCode = true)
+    )
+
+    @Test
+    fun test_aliceAndBob_all_all() = doTest(
+            sasShowScan,
+            sasShowScan,
+            ExpectedResult(sasIsSupported = true, otherCanShowQrCode = true, otherCanScanQrCode = true),
+            ExpectedResult(sasIsSupported = true, otherCanShowQrCode = true, otherCanScanQrCode = true)
+    )
+
+    // TODO Add tests without SAS
+
+    private fun doTest(aliceSupportedMethods: List<VerificationMethod>,
+                       bobSupportedMethods: List<VerificationMethod>,
+                       expectedResultForAlice: ExpectedResult,
+                       expectedResultForBob: ExpectedResult) {
+        val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoom()
+
+        val aliceSession = cryptoTestData.firstSession
+        val bobSession = cryptoTestData.secondSession!!
+
+        mTestHelper.doSync<Unit> { callback ->
+            aliceSession.getCrossSigningService()
+                    .initializeCrossSigning(UserPasswordAuth(
+                            user = aliceSession.myUserId,
+                            password = TestConstants.PASSWORD
+                    ), callback)
+        }
+
+        mTestHelper.doSync<Unit> { callback ->
+            bobSession.getCrossSigningService()
+                    .initializeCrossSigning(UserPasswordAuth(
+                            user = bobSession.myUserId,
+                            password = TestConstants.PASSWORD
+                    ), callback)
+        }
+
+        val aliceVerificationService = aliceSession.getVerificationService()
+        val bobVerificationService = bobSession.getVerificationService()
+
+        var aliceReadyPendingVerificationRequest: PendingVerificationRequest? = null
+        var bobReadyPendingVerificationRequest: PendingVerificationRequest? = null
+
+        val latch = CountDownLatch(2)
+        val aliceListener = object : VerificationService.VerificationListener {
+            override fun verificationRequestUpdated(pr: PendingVerificationRequest) {
+                // Step 4: Alice receive the ready request
+                if (pr.isReady) {
+                    aliceReadyPendingVerificationRequest = pr
+                    latch.countDown()
+                }
+            }
+        }
+        aliceVerificationService.addListener(aliceListener)
+
+        val bobListener = object : VerificationService.VerificationListener {
+            override fun verificationRequestCreated(pr: PendingVerificationRequest) {
+                // Step 2: Bob accepts the verification request
+                bobVerificationService.readyPendingVerificationInDMs(
+                        bobSupportedMethods,
+                        aliceSession.myUserId,
+                        cryptoTestData.roomId,
+                        pr.transactionId!!
+                )
+            }
+
+            override fun verificationRequestUpdated(pr: PendingVerificationRequest) {
+                // Step 3: Bob is ready
+                if (pr.isReady) {
+                    bobReadyPendingVerificationRequest = pr
+                    latch.countDown()
+                }
+            }
+        }
+        bobVerificationService.addListener(bobListener)
+
+        val bobUserId = bobSession.myUserId
+        // Step 1: Alice starts a verification request
+        aliceVerificationService.requestKeyVerificationInDMs(aliceSupportedMethods, bobUserId, cryptoTestData.roomId)
+        mTestHelper.await(latch)
+
+        aliceReadyPendingVerificationRequest!!.let { pr ->
+            pr.isSasSupported() shouldBe expectedResultForAlice.sasIsSupported
+            pr.otherCanShowQrCode() shouldBe expectedResultForAlice.otherCanShowQrCode
+            pr.otherCanScanQrCode() shouldBe expectedResultForAlice.otherCanScanQrCode
+        }
+
+        bobReadyPendingVerificationRequest!!.let { pr ->
+            pr.isSasSupported() shouldBe expectedResultForBob.sasIsSupported
+            pr.otherCanShowQrCode() shouldBe expectedResultForBob.otherCanShowQrCode
+            pr.otherCanScanQrCode() shouldBe expectedResultForBob.otherCanScanQrCode
+        }
+
+        cryptoTestData.close()
+    }
+}
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 3379ddd2ed..fe5f9dadb9 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
@@ -15,8 +15,8 @@
  */
 package im.vector.matrix.android.internal.crypto.verification
 
+import im.vector.matrix.android.api.extensions.orFalse
 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.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
@@ -46,11 +46,37 @@ data class PendingVerificationRequest(
 
     val isFinished: Boolean = isSuccessful || cancelConclusion != null
 
-    fun hasMethod(method: VerificationMethod): Boolean? {
-        return when (method) {
-            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)
+    /**
+     * SAS is supported if I support it and the other party support it
+     */
+    fun isSasSupported(): Boolean {
+        return requestInfo?.methods?.contains(VERIFICATION_METHOD_SAS).orFalse()
+                && readyInfo?.methods?.contains(VERIFICATION_METHOD_SAS).orFalse()
+    }
+
+    /**
+     * Other can show QR code if I can scan QR code and other can show QR code
+     */
+    fun otherCanShowQrCode(): Boolean {
+        return if (isIncoming) {
+            requestInfo?.methods?.contains(VERIFICATION_METHOD_QR_CODE_SHOW).orFalse()
+                    && readyInfo?.methods?.contains(VERIFICATION_METHOD_QR_CODE_SCAN).orFalse()
+        } else {
+            requestInfo?.methods?.contains(VERIFICATION_METHOD_QR_CODE_SCAN).orFalse()
+                    && readyInfo?.methods?.contains(VERIFICATION_METHOD_QR_CODE_SHOW).orFalse()
+        }
+    }
+
+    /**
+     * Other can scan QR code if I can show QR code and other can scan QR code
+     */
+    fun otherCanScanQrCode(): Boolean {
+        return if (isIncoming) {
+            requestInfo?.methods?.contains(VERIFICATION_METHOD_QR_CODE_SCAN).orFalse()
+                    && readyInfo?.methods?.contains(VERIFICATION_METHOD_QR_CODE_SHOW).orFalse()
+        } else {
+            requestInfo?.methods?.contains(VERIFICATION_METHOD_QR_CODE_SHOW).orFalse()
+                    && readyInfo?.methods?.contains(VERIFICATION_METHOD_QR_CODE_SCAN).orFalse()
         }
     }
 }
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 75c1b69058..17d8c1578d 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
@@ -21,9 +21,9 @@ import com.airbnb.mvrx.MvRxViewModelFactory
 import com.airbnb.mvrx.ViewModelContext
 import com.squareup.inject.assisted.Assisted
 import com.squareup.inject.assisted.AssistedInject
+import im.vector.matrix.android.api.extensions.orFalse
 import im.vector.matrix.android.api.session.Session
 import im.vector.matrix.android.api.session.crypto.sas.QrCodeVerificationTransaction
-import im.vector.matrix.android.api.session.crypto.sas.VerificationMethod
 import im.vector.matrix.android.api.session.crypto.sas.VerificationService
 import im.vector.matrix.android.api.session.crypto.sas.VerificationTransaction
 import im.vector.matrix.android.internal.crypto.verification.PendingVerificationRequest
@@ -66,9 +66,9 @@ class VerificationChooseMethodViewModel @AssistedInject constructor(
 
         setState {
             copy(
-                    otherCanShowQrCode = pvr?.hasMethod(VerificationMethod.QR_CODE_SHOW) ?: false,
-                    otherCanScanQrCode = pvr?.hasMethod(VerificationMethod.QR_CODE_SCAN) ?: false,
-                    SASModeAvailable = pvr?.hasMethod(VerificationMethod.SAS) ?: false
+                    otherCanShowQrCode = pvr?.otherCanShowQrCode().orFalse(),
+                    otherCanScanQrCode = pvr?.otherCanScanQrCode().orFalse(),
+                    SASModeAvailable = pvr?.isSasSupported().orFalse()
             )
         }
     }
@@ -103,10 +103,10 @@ class VerificationChooseMethodViewModel @AssistedInject constructor(
 
             return VerificationChooseMethodViewState(otherUserId = args.otherUserId,
                     transactionId = args.verificationId ?: "",
-                    otherCanShowQrCode = pvr?.hasMethod(VerificationMethod.QR_CODE_SHOW) ?: false,
-                    otherCanScanQrCode = pvr?.hasMethod(VerificationMethod.QR_CODE_SCAN) ?: false,
+                    otherCanShowQrCode = pvr?.otherCanShowQrCode().orFalse(),
+                    otherCanScanQrCode = pvr?.otherCanScanQrCode().orFalse(),
                     qrCodeText = (qrCodeVerificationTransaction as? QrCodeVerificationTransaction)?.qrCodeText,
-                    SASModeAvailable = pvr?.hasMethod(VerificationMethod.SAS) ?: false
+                    SASModeAvailable = pvr?.isSasSupported().orFalse()
             )
         }
     }

From 377d944228394ededdb848eb0d6abd4d319a2172 Mon Sep 17 00:00:00 2001
From: Benoit Marty <benoitm@matrix.org>
Date: Tue, 11 Feb 2020 18:08:12 +0100
Subject: [PATCH 2/5] Cleanup API

---
 .../android/api/session/crypto/sas/VerificationService.kt | 2 +-
 .../crypto/verification/DefaultVerificationService.kt     | 4 ++--
 .../internal/crypto/verification/VerificationTransport.kt | 8 +++++---
 .../verification/VerificationTransportRoomMessage.kt      | 4 ++--
 .../crypto/verification/VerificationTransportToDevice.kt  | 4 ++--
 .../verification/IncomingVerificationRequestHandler.kt    | 1 -
 .../riotx/features/home/room/detail/RoomDetailAction.kt   | 6 +++---
 .../riotx/features/home/room/detail/RoomDetailFragment.kt | 2 +-
 .../features/home/room/detail/RoomDetailViewModel.kt      | 1 -
 .../room/detail/timeline/factory/MessageItemFactory.kt    | 1 -
 .../room/detail/timeline/item/VerificationRequestItem.kt  | 8 ++------
 11 files changed, 18 insertions(+), 23 deletions(-)

diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationService.kt
index 0dd143f792..3572905019 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationService.kt
@@ -68,11 +68,11 @@ interface VerificationService {
                                otherDevices: List<String>?): PendingVerificationRequest
 
     fun declineVerificationRequestInDMs(otherUserId: String,
-                                        otherDeviceId: String,
                                         transactionId: String,
                                         roomId: String)
 
     // Only SAS method is supported for the moment
+    // TODO Parameter otherDeviceId should be removed in this case
     fun beginKeyVerificationInDMs(method: VerificationMethod,
                                   transactionId: String,
                                   roomId: String,
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultVerificationService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultVerificationService.kt
index fc14b0a23a..d7589ede5c 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultVerificationService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultVerificationService.kt
@@ -1151,9 +1151,9 @@ internal class DefaultVerificationService @Inject constructor(
         return verificationRequest
     }
 
-    override fun declineVerificationRequestInDMs(otherUserId: String, otherDeviceId: String, transactionId: String, roomId: String) {
+    override fun declineVerificationRequestInDMs(otherUserId: String, transactionId: String, roomId: String) {
         verificationTransportRoomMessageFactory.createTransport(roomId, null)
-                .cancelTransaction(transactionId, otherUserId, otherDeviceId, CancelCode.User)
+                .cancelTransaction(transactionId, otherUserId, null, CancelCode.User)
 
         getExistingVerificationRequest(otherUserId, transactionId)?.let {
             updatePendingRequest(it.copy(
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransport.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransport.kt
index bc85cddf26..ee0e66959d 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransport.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransport.kt
@@ -42,7 +42,7 @@ internal interface VerificationTransport {
 
     fun cancelTransaction(transactionId: String,
                           otherUserId: String,
-                          otherUserDeviceId: String,
+                          otherUserDeviceId: String?,
                           code: CancelCode)
 
     fun done(transactionId: String)
@@ -79,11 +79,13 @@ internal interface VerificationTransport {
 
     fun createMac(tid: String, mac: Map<String, String>, keys: String): VerificationInfoMac
 
-    fun createReady(tid: String, fromDevice: String, methods: List<String>): VerificationInfoReady
+    fun createReady(tid: String,
+                    fromDevice: String,
+                    methods: List<String>): VerificationInfoReady
 
     // TODO Refactor
     fun sendVerificationReady(keyReq: VerificationInfoReady,
                               otherUserId: String,
-                              otherDeviceId: String,
+                              otherDeviceId: String?,
                               callback: (() -> Unit)?)
 }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransportRoomMessage.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransportRoomMessage.kt
index 30d94c52d9..11093ca3ba 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransportRoomMessage.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransportRoomMessage.kt
@@ -208,7 +208,7 @@ internal class VerificationTransportRoomMessage(
         }
     }
 
-    override fun cancelTransaction(transactionId: String, otherUserId: String, otherUserDeviceId: String, code: CancelCode) {
+    override fun cancelTransaction(transactionId: String, otherUserId: String, otherUserDeviceId: String?, code: CancelCode) {
         Timber.d("## SAS canceling transaction $transactionId for reason $code")
         val event = createEventAndLocalEcho(
                 type = EventType.KEY_VERIFICATION_CANCEL,
@@ -337,7 +337,7 @@ internal class VerificationTransportRoomMessage(
 
     override fun sendVerificationReady(keyReq: VerificationInfoReady,
                                        otherUserId: String,
-                                       otherDeviceId: String,
+                                       otherDeviceId: String?,
                                        callback: (() -> Unit)?) {
         // Not applicable (send event is called directly)
         Timber.w("## SAS ignored verification ready with methods: ${keyReq.methods}")
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransportToDevice.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransportToDevice.kt
index f76f8331bc..1dae8fba68 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransportToDevice.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransportToDevice.kt
@@ -80,7 +80,7 @@ internal class VerificationTransportToDevice(
 
     override fun sendVerificationReady(keyReq: VerificationInfoReady,
                                        otherUserId: String,
-                                       otherDeviceId: String,
+                                       otherDeviceId: String?,
                                        callback: (() -> Unit)?) {
         Timber.d("## SAS sending verification ready with methods: ${keyReq.methods}")
         val contentMap = MXUsersDevicesMap<Any>()
@@ -159,7 +159,7 @@ internal class VerificationTransportToDevice(
                 .executeBy(taskExecutor)
     }
 
-    override fun cancelTransaction(transactionId: String, otherUserId: String, otherUserDeviceId: String, code: CancelCode) {
+    override fun cancelTransaction(transactionId: String, otherUserId: String, otherUserDeviceId: String?, code: CancelCode) {
         Timber.d("## SAS canceling transaction $transactionId for reason $code")
         val cancelMessage = KeyVerificationCancel.create(transactionId, code)
         val contentMap = MXUsersDevicesMap<Any>()
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/IncomingVerificationRequestHandler.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/IncomingVerificationRequestHandler.kt
index 0fbbccee8a..0ed29a9058 100644
--- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/IncomingVerificationRequestHandler.kt
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/IncomingVerificationRequestHandler.kt
@@ -145,7 +145,6 @@ class IncomingVerificationRequestHandler @Inject constructor(private val context
                         }
                         dismissedAction = Runnable {
                             session?.getVerificationService()?.declineVerificationRequestInDMs(pr.otherUserId,
-                                    pr.requestInfo?.fromDevice ?: "",
                                     pr.transactionId ?: "",
                                     pr.roomId ?: ""
                             )
diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailAction.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailAction.kt
index d0716bd047..053a0a75c6 100644
--- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailAction.kt
+++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailAction.kt
@@ -65,8 +65,8 @@ sealed class RoomDetailAction : VectorViewModelAction {
     object ClearSendQueue : RoomDetailAction()
     object ResendAll : RoomDetailAction()
 
-    data class AcceptVerificationRequest(val transactionId: String, val otherUserId: String, val otherdDeviceId: String) : RoomDetailAction()
-    data class DeclineVerificationRequest(val transactionId: String, val otherUserId: String, val otherdDeviceId: String) : RoomDetailAction()
+    data class AcceptVerificationRequest(val transactionId: String, val otherUserId: String) : RoomDetailAction()
+    data class DeclineVerificationRequest(val transactionId: String, val otherUserId: String) : RoomDetailAction()
     data class RequestVerification(val userId: String) : RoomDetailAction()
-    data class ResumeVerification(val transactionId: String, val otherUserId: String? = null, val otherdDeviceId: String? = null) : RoomDetailAction()
+    data class ResumeVerification(val transactionId: String, val otherUserId: String?) : RoomDetailAction()
 }
diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt
index 7303b7ce7f..42ce21de08 100644
--- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt
+++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt
@@ -1028,7 +1028,7 @@ class RoomDetailFragment @Inject constructor(
 
     override fun onEventCellClicked(informationData: MessageInformationData, messageContent: MessageContent?, view: View) {
         if (messageContent is MessageVerificationRequestContent) {
-            roomDetailViewModel.handle(RoomDetailAction.ResumeVerification(informationData.eventId))
+            roomDetailViewModel.handle(RoomDetailAction.ResumeVerification(informationData.eventId, null))
         }
     }
 
diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt
index 710c70a948..0a343595ea 100644
--- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt
+++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt
@@ -833,7 +833,6 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro
     private fun handleDeclineVerification(action: RoomDetailAction.DeclineVerificationRequest) {
         session.getVerificationService().declineVerificationRequestInDMs(
                 action.otherUserId,
-                action.otherdDeviceId,
                 action.transactionId,
                 room.roomId)
     }
diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MessageItemFactory.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MessageItemFactory.kt
index 65a6f5f244..aa85950e01 100644
--- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MessageItemFactory.kt
+++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MessageItemFactory.kt
@@ -181,7 +181,6 @@ class MessageItemFactory @Inject constructor(
                         VerificationRequestItem.Attributes(
                                 otherUserId = otherUserId,
                                 otherUserName = otherUserName.toString(),
-                                fromDevide = messageContent.fromDevice ?: "",
                                 referenceId = informationData.eventId,
                                 informationData = informationData,
                                 avatarRenderer = attributes.avatarRenderer,
diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/VerificationRequestItem.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/VerificationRequestItem.kt
index 24f992a001..853e40c516 100644
--- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/VerificationRequestItem.kt
+++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/VerificationRequestItem.kt
@@ -134,12 +134,9 @@ abstract class VerificationRequestItem : AbsBaseMessageItem<VerificationRequestI
         private val _clickListener = DebouncedClickListener(View.OnClickListener {
             val att = attributes ?: return@OnClickListener
             if (it == acceptButton) {
-                callback?.onTimelineItemAction(RoomDetailAction.AcceptVerificationRequest(
-                        att.referenceId,
-                        att.otherUserId,
-                        att.fromDevide))
+                callback?.onTimelineItemAction(RoomDetailAction.AcceptVerificationRequest(att.referenceId, att.otherUserId))
             } else if (it == declineButton) {
-                callback?.onTimelineItemAction(RoomDetailAction.DeclineVerificationRequest(att.referenceId, att.otherUserId, att.fromDevide))
+                callback?.onTimelineItemAction(RoomDetailAction.DeclineVerificationRequest(att.referenceId, att.otherUserId))
             }
         })
 
@@ -169,7 +166,6 @@ abstract class VerificationRequestItem : AbsBaseMessageItem<VerificationRequestI
     data class Attributes(
             val otherUserId: String,
             val otherUserName: String,
-            val fromDevide: String,
             val referenceId: String,
 //            val avatarSize: Int,
             override val informationData: MessageInformationData,

From bf02746d8739f3340c4290233532d84fcb429d1d Mon Sep 17 00:00:00 2001
From: Benoit Marty <benoitm@matrix.org>
Date: Tue, 11 Feb 2020 18:25:01 +0100
Subject: [PATCH 3/5] Clenaup VerificationService.VerificationListener

---
 .../internal/crypto/verification/SASTest.kt   | 42 -------------------
 .../session/crypto/sas/VerificationService.kt | 10 ++---
 .../crypto/keysrequest/KeyRequestHandler.kt   |  3 --
 .../IncomingVerificationRequestHandler.kt     |  6 ---
 .../settings/devices/DevicesViewModel.kt      |  1 -
 5 files changed, 4 insertions(+), 58 deletions(-)

diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/SASTest.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/SASTest.kt
index 6ae2489993..6b254efd5d 100644
--- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/SASTest.kt
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/SASTest.kt
@@ -67,13 +67,9 @@ class SASTest : InstrumentedTest {
 
         val bobTxCreatedLatch = CountDownLatch(1)
         val bobListener = object : VerificationService.VerificationListener {
-            override fun transactionCreated(tx: VerificationTransaction) {}
-
             override fun transactionUpdated(tx: VerificationTransaction) {
                 bobTxCreatedLatch.countDown()
             }
-
-            override fun markedAsManuallyVerified(userId: String, deviceId: String) {}
         }
         bobVerificationService.addListener(bobListener)
 
@@ -107,8 +103,6 @@ class SASTest : InstrumentedTest {
         val cancelLatch = CountDownLatch(1)
 
         val bobListener2 = object : VerificationService.VerificationListener {
-            override fun transactionCreated(tx: VerificationTransaction) {}
-
             override fun transactionUpdated(tx: VerificationTransaction) {
                 if (tx.transactionId == txID) {
                     val immutableState = (tx as SASDefaultVerificationTransaction).state
@@ -117,8 +111,6 @@ class SASTest : InstrumentedTest {
                     }
                 }
             }
-
-            override fun markedAsManuallyVerified(userId: String, deviceId: String) {}
         }
         bobVerificationService.addListener(bobListener2)
 
@@ -158,16 +150,12 @@ class SASTest : InstrumentedTest {
         val cancelLatch = CountDownLatch(1)
 
         val bobListener = object : VerificationService.VerificationListener {
-            override fun transactionCreated(tx: VerificationTransaction) {}
-
             override fun transactionUpdated(tx: VerificationTransaction) {
                 if (tx.transactionId == tid && tx.state is VerificationTxState.Cancelled) {
                     cancelReason = (tx.state as VerificationTxState.Cancelled).cancelCode
                     cancelLatch.countDown()
                 }
             }
-
-            override fun markedAsManuallyVerified(userId: String, deviceId: String) {}
         }
         bobSession.getVerificationService().addListener(bobListener)
 
@@ -187,15 +175,11 @@ class SASTest : InstrumentedTest {
         val aliceDevice = aliceSession.getMyDevice().deviceId
 
         val aliceListener = object : VerificationService.VerificationListener {
-            override fun transactionCreated(tx: VerificationTransaction) {}
-
             override fun transactionUpdated(tx: VerificationTransaction) {
                 if ((tx as IncomingSasVerificationTransaction).uxState === IncomingSasVerificationTransaction.UxState.SHOW_ACCEPT) {
                     (tx as IncomingSasVerificationTransaction).performAccept()
                 }
             }
-
-            override fun markedAsManuallyVerified(userId: String, deviceId: String) {}
         }
         aliceSession.getVerificationService().addListener(aliceListener)
 
@@ -339,8 +323,6 @@ class SASTest : InstrumentedTest {
                     aliceCancelledLatch.countDown()
                 }
             }
-
-            override fun markedAsManuallyVerified(userId: String, deviceId: String) {}
         }
         aliceVerificationService.addListener(aliceListener)
 
@@ -373,10 +355,6 @@ class SASTest : InstrumentedTest {
 
         val aliceAcceptedLatch = CountDownLatch(1)
         val aliceListener = object : VerificationService.VerificationListener {
-            override fun markedAsManuallyVerified(userId: String, deviceId: String) {}
-
-            override fun transactionCreated(tx: VerificationTransaction) {}
-
             override fun transactionUpdated(tx: VerificationTransaction) {
                 if ((tx as SASDefaultVerificationTransaction).state === VerificationTxState.OnAccepted) {
                     val at = tx as SASDefaultVerificationTransaction
@@ -389,16 +367,12 @@ class SASTest : InstrumentedTest {
         aliceVerificationService.addListener(aliceListener)
 
         val bobListener = object : VerificationService.VerificationListener {
-            override fun transactionCreated(tx: VerificationTransaction) {}
-
             override fun transactionUpdated(tx: VerificationTransaction) {
                 if ((tx as IncomingSasVerificationTransaction).uxState === IncomingSasVerificationTransaction.UxState.SHOW_ACCEPT) {
                     val at = tx as IncomingSasVerificationTransaction
                     at.performAccept()
                 }
             }
-
-            override fun markedAsManuallyVerified(userId: String, deviceId: String) {}
         }
         bobVerificationService.addListener(bobListener)
 
@@ -434,8 +408,6 @@ class SASTest : InstrumentedTest {
 
         val aliceSASLatch = CountDownLatch(1)
         val aliceListener = object : VerificationService.VerificationListener {
-            override fun transactionCreated(tx: VerificationTransaction) {}
-
             override fun transactionUpdated(tx: VerificationTransaction) {
                 val uxState = (tx as OutgoingSasVerificationTransaction).uxState
                 when (uxState) {
@@ -445,15 +417,11 @@ class SASTest : InstrumentedTest {
                     else                                                -> Unit
                 }
             }
-
-            override fun markedAsManuallyVerified(userId: String, deviceId: String) {}
         }
         aliceVerificationService.addListener(aliceListener)
 
         val bobSASLatch = CountDownLatch(1)
         val bobListener = object : VerificationService.VerificationListener {
-            override fun transactionCreated(tx: VerificationTransaction) {}
-
             override fun transactionUpdated(tx: VerificationTransaction) {
                 val uxState = (tx as IncomingSasVerificationTransaction).uxState
                 when (uxState) {
@@ -466,8 +434,6 @@ class SASTest : InstrumentedTest {
                     bobSASLatch.countDown()
                 }
             }
-
-            override fun markedAsManuallyVerified(userId: String, deviceId: String) {}
         }
         bobVerificationService.addListener(bobListener)
 
@@ -498,8 +464,6 @@ class SASTest : InstrumentedTest {
 
         val aliceSASLatch = CountDownLatch(1)
         val aliceListener = object : VerificationService.VerificationListener {
-            override fun transactionCreated(tx: VerificationTransaction) {}
-
             override fun transactionUpdated(tx: VerificationTransaction) {
                 val uxState = (tx as OutgoingSasVerificationTransaction).uxState
                 when (uxState) {
@@ -512,15 +476,11 @@ class SASTest : InstrumentedTest {
                     else                                                -> Unit
                 }
             }
-
-            override fun markedAsManuallyVerified(userId: String, deviceId: String) {}
         }
         aliceVerificationService.addListener(aliceListener)
 
         val bobSASLatch = CountDownLatch(1)
         val bobListener = object : VerificationService.VerificationListener {
-            override fun transactionCreated(tx: VerificationTransaction) {}
-
             override fun transactionUpdated(tx: VerificationTransaction) {
                 val uxState = (tx as IncomingSasVerificationTransaction).uxState
                 when (uxState) {
@@ -536,8 +496,6 @@ class SASTest : InstrumentedTest {
                     else                                                   -> Unit
                 }
             }
-
-            override fun markedAsManuallyVerified(userId: String, deviceId: String) {}
         }
         bobVerificationService.addListener(bobListener)
 
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationService.kt
index 3572905019..9df2dc9a89 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationService.kt
@@ -95,15 +95,13 @@ interface VerificationService {
                                  otherUserId: String,
                                  transactionId: String): Boolean
 
-    // fun transactionUpdated(tx: SasVerificationTransaction)
-
     interface VerificationListener {
-        fun transactionCreated(tx: VerificationTransaction)
-        fun transactionUpdated(tx: VerificationTransaction)
-        fun markedAsManuallyVerified(userId: String, deviceId: String) {}
-
         fun verificationRequestCreated(pr: PendingVerificationRequest) {}
         fun verificationRequestUpdated(pr: PendingVerificationRequest) {}
+
+        fun transactionCreated(tx: VerificationTransaction) {}
+        fun transactionUpdated(tx: VerificationTransaction) {}
+        fun markedAsManuallyVerified(userId: String, deviceId: String) {}
     }
 
     companion object {
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysrequest/KeyRequestHandler.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysrequest/KeyRequestHandler.kt
index 856c71f888..bc97ac5ee5 100644
--- a/vector/src/main/java/im/vector/riotx/features/crypto/keysrequest/KeyRequestHandler.kt
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysrequest/KeyRequestHandler.kt
@@ -262,9 +262,6 @@ class KeyRequestHandler @Inject constructor(private val context: Context)
         }
     }
 
-    override fun transactionCreated(tx: VerificationTransaction) {
-    }
-
     override fun transactionUpdated(tx: VerificationTransaction) {
         if (tx is SasVerificationTransaction) {
             val state = tx.state
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/IncomingVerificationRequestHandler.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/IncomingVerificationRequestHandler.kt
index 0ed29a9058..99c28b52dc 100644
--- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/IncomingVerificationRequestHandler.kt
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/IncomingVerificationRequestHandler.kt
@@ -48,8 +48,6 @@ class IncomingVerificationRequestHandler @Inject constructor(private val context
         this.session = null
     }
 
-    override fun transactionCreated(tx: VerificationTransaction) {}
-
     override fun transactionUpdated(tx: VerificationTransaction) {
         if (!tx.isToDeviceTransport()) return
         // TODO maybe check also if
@@ -111,9 +109,6 @@ class IncomingVerificationRequestHandler @Inject constructor(private val context
         }
     }
 
-    override fun markedAsManuallyVerified(userId: String, deviceId: String) {
-    }
-
     override fun verificationRequestCreated(pr: PendingVerificationRequest) {
         // For incoming request we should prompt (if not in activity where this request apply)
         if (pr.isIncoming) {
@@ -162,7 +157,6 @@ class IncomingVerificationRequestHandler @Inject constructor(private val context
         if (pr.isIncoming && (pr.isReady || pr.handledByOtherSession)) {
             PopupAlertManager.cancelAlert(uniqueIdForVerificationRequest(pr))
         }
-        super.verificationRequestUpdated(pr)
     }
 
     private fun uniqueIdForVerificationRequest(pr: PendingVerificationRequest) =
diff --git a/vector/src/main/java/im/vector/riotx/features/settings/devices/DevicesViewModel.kt b/vector/src/main/java/im/vector/riotx/features/settings/devices/DevicesViewModel.kt
index 333249f3de..1862412cb5 100644
--- a/vector/src/main/java/im/vector/riotx/features/settings/devices/DevicesViewModel.kt
+++ b/vector/src/main/java/im/vector/riotx/features/settings/devices/DevicesViewModel.kt
@@ -89,7 +89,6 @@ class DevicesViewModel @AssistedInject constructor(@Assisted initialState: Devic
         super.onCleared()
     }
 
-    override fun transactionCreated(tx: VerificationTransaction) {}
     override fun transactionUpdated(tx: VerificationTransaction) {
         if (tx.state == VerificationTxState.Verified) {
             refreshDevicesList()

From 6acfab324201271bb1d8fb5b647d2a81e8fdeaa3 Mon Sep 17 00:00:00 2001
From: Benoit Marty <benoitm@matrix.org>
Date: Wed, 12 Feb 2020 11:19:04 +0100
Subject: [PATCH 4/5] Rename VerificationListener to Listener

---
 .../internal/crypto/verification/SASTest.kt   | 22 +++++++++----------
 .../verification/qrcode/VerificationTest.kt   |  4 ++--
 .../session/crypto/sas/VerificationService.kt |  7 +++---
 .../DefaultVerificationService.kt             |  6 ++---
 .../crypto/keysrequest/KeyRequestHandler.kt   |  2 +-
 .../IncomingVerificationRequestHandler.kt     |  2 +-
 .../VerificationBottomSheetViewModel.kt       |  2 +-
 .../VerificationChooseMethodViewModel.kt      |  2 +-
 .../emoji/VerificationEmojiCodeViewModel.kt   |  2 +-
 .../settings/devices/DevicesViewModel.kt      |  2 +-
 10 files changed, 26 insertions(+), 25 deletions(-)

diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/SASTest.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/SASTest.kt
index 6b254efd5d..79670bb21e 100644
--- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/SASTest.kt
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/SASTest.kt
@@ -66,7 +66,7 @@ class SASTest : InstrumentedTest {
         val bobVerificationService = bobSession!!.getVerificationService()
 
         val bobTxCreatedLatch = CountDownLatch(1)
-        val bobListener = object : VerificationService.VerificationListener {
+        val bobListener = object : VerificationService.Listener {
             override fun transactionUpdated(tx: VerificationTransaction) {
                 bobTxCreatedLatch.countDown()
             }
@@ -102,7 +102,7 @@ class SASTest : InstrumentedTest {
         // Let's cancel from alice side
         val cancelLatch = CountDownLatch(1)
 
-        val bobListener2 = object : VerificationService.VerificationListener {
+        val bobListener2 = object : VerificationService.Listener {
             override fun transactionUpdated(tx: VerificationTransaction) {
                 if (tx.transactionId == txID) {
                     val immutableState = (tx as SASDefaultVerificationTransaction).state
@@ -149,7 +149,7 @@ class SASTest : InstrumentedTest {
         var cancelReason: CancelCode? = null
         val cancelLatch = CountDownLatch(1)
 
-        val bobListener = object : VerificationService.VerificationListener {
+        val bobListener = object : VerificationService.Listener {
             override fun transactionUpdated(tx: VerificationTransaction) {
                 if (tx.transactionId == tid && tx.state is VerificationTxState.Cancelled) {
                     cancelReason = (tx.state as VerificationTxState.Cancelled).cancelCode
@@ -174,7 +174,7 @@ class SASTest : InstrumentedTest {
         val aliceUserID = aliceSession.myUserId
         val aliceDevice = aliceSession.getMyDevice().deviceId
 
-        val aliceListener = object : VerificationService.VerificationListener {
+        val aliceListener = object : VerificationService.Listener {
             override fun transactionUpdated(tx: VerificationTransaction) {
                 if ((tx as IncomingSasVerificationTransaction).uxState === IncomingSasVerificationTransaction.UxState.SHOW_ACCEPT) {
                     (tx as IncomingSasVerificationTransaction).performAccept()
@@ -312,7 +312,7 @@ class SASTest : InstrumentedTest {
         val aliceCreatedLatch = CountDownLatch(2)
         val aliceCancelledLatch = CountDownLatch(2)
         val createdTx = mutableListOf<SASDefaultVerificationTransaction>()
-        val aliceListener = object : VerificationService.VerificationListener {
+        val aliceListener = object : VerificationService.Listener {
             override fun transactionCreated(tx: VerificationTransaction) {
                 createdTx.add(tx as SASDefaultVerificationTransaction)
                 aliceCreatedLatch.countDown()
@@ -354,7 +354,7 @@ class SASTest : InstrumentedTest {
         var startReq: KeyVerificationStart? = null
 
         val aliceAcceptedLatch = CountDownLatch(1)
-        val aliceListener = object : VerificationService.VerificationListener {
+        val aliceListener = object : VerificationService.Listener {
             override fun transactionUpdated(tx: VerificationTransaction) {
                 if ((tx as SASDefaultVerificationTransaction).state === VerificationTxState.OnAccepted) {
                     val at = tx as SASDefaultVerificationTransaction
@@ -366,7 +366,7 @@ class SASTest : InstrumentedTest {
         }
         aliceVerificationService.addListener(aliceListener)
 
-        val bobListener = object : VerificationService.VerificationListener {
+        val bobListener = object : VerificationService.Listener {
             override fun transactionUpdated(tx: VerificationTransaction) {
                 if ((tx as IncomingSasVerificationTransaction).uxState === IncomingSasVerificationTransaction.UxState.SHOW_ACCEPT) {
                     val at = tx as IncomingSasVerificationTransaction
@@ -407,7 +407,7 @@ class SASTest : InstrumentedTest {
         val bobVerificationService = bobSession!!.getVerificationService()
 
         val aliceSASLatch = CountDownLatch(1)
-        val aliceListener = object : VerificationService.VerificationListener {
+        val aliceListener = object : VerificationService.Listener {
             override fun transactionUpdated(tx: VerificationTransaction) {
                 val uxState = (tx as OutgoingSasVerificationTransaction).uxState
                 when (uxState) {
@@ -421,7 +421,7 @@ class SASTest : InstrumentedTest {
         aliceVerificationService.addListener(aliceListener)
 
         val bobSASLatch = CountDownLatch(1)
-        val bobListener = object : VerificationService.VerificationListener {
+        val bobListener = object : VerificationService.Listener {
             override fun transactionUpdated(tx: VerificationTransaction) {
                 val uxState = (tx as IncomingSasVerificationTransaction).uxState
                 when (uxState) {
@@ -463,7 +463,7 @@ class SASTest : InstrumentedTest {
         val bobVerificationService = bobSession!!.getVerificationService()
 
         val aliceSASLatch = CountDownLatch(1)
-        val aliceListener = object : VerificationService.VerificationListener {
+        val aliceListener = object : VerificationService.Listener {
             override fun transactionUpdated(tx: VerificationTransaction) {
                 val uxState = (tx as OutgoingSasVerificationTransaction).uxState
                 when (uxState) {
@@ -480,7 +480,7 @@ class SASTest : InstrumentedTest {
         aliceVerificationService.addListener(aliceListener)
 
         val bobSASLatch = CountDownLatch(1)
-        val bobListener = object : VerificationService.VerificationListener {
+        val bobListener = object : VerificationService.Listener {
             override fun transactionUpdated(tx: VerificationTransaction) {
                 val uxState = (tx as IncomingSasVerificationTransaction).uxState
                 when (uxState) {
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/qrcode/VerificationTest.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/qrcode/VerificationTest.kt
index adde452619..61ea0f35b4 100644
--- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/qrcode/VerificationTest.kt
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/qrcode/VerificationTest.kt
@@ -178,7 +178,7 @@ class VerificationTest : InstrumentedTest {
         var bobReadyPendingVerificationRequest: PendingVerificationRequest? = null
 
         val latch = CountDownLatch(2)
-        val aliceListener = object : VerificationService.VerificationListener {
+        val aliceListener = object : VerificationService.Listener {
             override fun verificationRequestUpdated(pr: PendingVerificationRequest) {
                 // Step 4: Alice receive the ready request
                 if (pr.isReady) {
@@ -189,7 +189,7 @@ class VerificationTest : InstrumentedTest {
         }
         aliceVerificationService.addListener(aliceListener)
 
-        val bobListener = object : VerificationService.VerificationListener {
+        val bobListener = object : VerificationService.Listener {
             override fun verificationRequestCreated(pr: PendingVerificationRequest) {
                 // Step 2: Bob accepts the verification request
                 bobVerificationService.readyPendingVerificationInDMs(
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationService.kt
index 9df2dc9a89..d3b33cb6f5 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationService.kt
@@ -30,9 +30,9 @@ import im.vector.matrix.android.internal.crypto.verification.PendingVerification
  */
 interface VerificationService {
 
-    fun addListener(listener: VerificationListener)
+    fun addListener(listener: Listener)
 
-    fun removeListener(listener: VerificationListener)
+    fun removeListener(listener: Listener)
 
     /**
      * Mark this device as verified manually
@@ -95,7 +95,8 @@ interface VerificationService {
                                  otherUserId: String,
                                  transactionId: String): Boolean
 
-    interface VerificationListener {
+    interface Listener {
+        // TODO javadoc
         fun verificationRequestCreated(pr: PendingVerificationRequest) {}
         fun verificationRequestUpdated(pr: PendingVerificationRequest) {}
 
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultVerificationService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultVerificationService.kt
index d7589ede5c..00ac4a6986 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultVerificationService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultVerificationService.kt
@@ -176,9 +176,9 @@ internal class DefaultVerificationService @Inject constructor(
         }
     }
 
-    private var listeners = ArrayList<VerificationService.VerificationListener>()
+    private var listeners = ArrayList<VerificationService.Listener>()
 
-    override fun addListener(listener: VerificationService.VerificationListener) {
+    override fun addListener(listener: VerificationService.Listener) {
         uiHandler.post {
             if (!listeners.contains(listener)) {
                 listeners.add(listener)
@@ -186,7 +186,7 @@ internal class DefaultVerificationService @Inject constructor(
         }
     }
 
-    override fun removeListener(listener: VerificationService.VerificationListener) {
+    override fun removeListener(listener: VerificationService.Listener) {
         uiHandler.post {
             listeners.remove(listener)
         }
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysrequest/KeyRequestHandler.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysrequest/KeyRequestHandler.kt
index bc97ac5ee5..f890aef91b 100644
--- a/vector/src/main/java/im/vector/riotx/features/crypto/keysrequest/KeyRequestHandler.kt
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysrequest/KeyRequestHandler.kt
@@ -56,7 +56,7 @@ import kotlin.collections.HashMap
 @Singleton
 class KeyRequestHandler @Inject constructor(private val context: Context)
     : RoomKeysRequestListener,
-        VerificationService.VerificationListener {
+        VerificationService.Listener {
 
     private val alertsToRequests = HashMap<String, ArrayList<IncomingRoomKeyRequest>>()
 
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/IncomingVerificationRequestHandler.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/IncomingVerificationRequestHandler.kt
index 99c28b52dc..8765dbc0d9 100644
--- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/IncomingVerificationRequestHandler.kt
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/IncomingVerificationRequestHandler.kt
@@ -34,7 +34,7 @@ import javax.inject.Singleton
  * Listens to the VerificationManager and add a new notification when an incoming request is detected.
  */
 @Singleton
-class IncomingVerificationRequestHandler @Inject constructor(private val context: Context) : VerificationService.VerificationListener {
+class IncomingVerificationRequestHandler @Inject constructor(private val context: Context) : VerificationService.Listener {
 
     private var session: Session? = null
 
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/VerificationBottomSheetViewModel.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/VerificationBottomSheetViewModel.kt
index a9f9987c7f..85b878fe16 100644
--- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/VerificationBottomSheetViewModel.kt
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/VerificationBottomSheetViewModel.kt
@@ -60,7 +60,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
                                                                    @Assisted args: VerificationBottomSheet.VerificationArgs,
                                                                    private val session: Session)
     : VectorViewModel<VerificationBottomSheetViewState, VerificationAction, VerificationBottomSheetViewEvents>(initialState),
-        VerificationService.VerificationListener {
+        VerificationService.Listener {
 
     init {
         session.getVerificationService().addListener(this)
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 17d8c1578d..bdb07ed0dc 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
@@ -45,7 +45,7 @@ data class VerificationChooseMethodViewState(
 class VerificationChooseMethodViewModel @AssistedInject constructor(
         @Assisted initialState: VerificationChooseMethodViewState,
         private val session: Session
-) : VectorViewModel<VerificationChooseMethodViewState, EmptyAction, EmptyViewEvents>(initialState), VerificationService.VerificationListener {
+) : VectorViewModel<VerificationChooseMethodViewState, EmptyAction, EmptyViewEvents>(initialState), VerificationService.Listener {
 
     override fun transactionCreated(tx: VerificationTransaction) {
         transactionUpdated(tx)
diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/emoji/VerificationEmojiCodeViewModel.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/emoji/VerificationEmojiCodeViewModel.kt
index 69d106a4b4..637b7d7cc9 100644
--- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/emoji/VerificationEmojiCodeViewModel.kt
+++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/emoji/VerificationEmojiCodeViewModel.kt
@@ -52,7 +52,7 @@ data class VerificationEmojiCodeViewState(
 class VerificationEmojiCodeViewModel @AssistedInject constructor(
         @Assisted initialState: VerificationEmojiCodeViewState,
         private val session: Session
-) : VectorViewModel<VerificationEmojiCodeViewState, EmptyAction, EmptyViewEvents>(initialState), VerificationService.VerificationListener {
+) : VectorViewModel<VerificationEmojiCodeViewState, EmptyAction, EmptyViewEvents>(initialState), VerificationService.Listener {
 
     init {
         withState { state ->
diff --git a/vector/src/main/java/im/vector/riotx/features/settings/devices/DevicesViewModel.kt b/vector/src/main/java/im/vector/riotx/features/settings/devices/DevicesViewModel.kt
index 1862412cb5..b931f5d66f 100644
--- a/vector/src/main/java/im/vector/riotx/features/settings/devices/DevicesViewModel.kt
+++ b/vector/src/main/java/im/vector/riotx/features/settings/devices/DevicesViewModel.kt
@@ -52,7 +52,7 @@ data class DevicesViewState(
 
 class DevicesViewModel @AssistedInject constructor(@Assisted initialState: DevicesViewState,
                                                    private val session: Session)
-    : VectorViewModel<DevicesViewState, DevicesAction, DevicesViewEvents>(initialState), VerificationService.VerificationListener {
+    : VectorViewModel<DevicesViewState, DevicesAction, DevicesViewEvents>(initialState), VerificationService.Listener {
 
     @AssistedInject.Factory
     interface Factory {

From 3a044bd6552348e2e05b5f7a8f1f763f81d1c75f Mon Sep 17 00:00:00 2001
From: Benoit Marty <benoitm@matrix.org>
Date: Wed, 12 Feb 2020 11:33:36 +0100
Subject: [PATCH 5/5] Add Javadoc

---
 .../session/crypto/sas/VerificationService.kt | 21 ++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationService.kt
index d3b33cb6f5..1b5f5d3dd6 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationService.kt
@@ -96,12 +96,31 @@ interface VerificationService {
                                  transactionId: String): Boolean
 
     interface Listener {
-        // TODO javadoc
+        /**
+         * Called when a verification request is created either by the user, or by the other user.
+         */
         fun verificationRequestCreated(pr: PendingVerificationRequest) {}
+
+        /**
+         * Called when a verification request is updated.
+         */
         fun verificationRequestUpdated(pr: PendingVerificationRequest) {}
 
+        /**
+         * Called when a transaction is created, either by the user or initiated by the other user.
+         */
         fun transactionCreated(tx: VerificationTransaction) {}
+
+        /**
+         * Called when a transaction is updated. You may be interested to track the state of the VerificationTransaction.
+         */
         fun transactionUpdated(tx: VerificationTransaction) {}
+
+        /**
+         * Inform the the deviceId of the userId has been marked as manually verified by the SDK.
+         * It will be called after VerificationService.markedLocallyAsManuallyVerified() is called.
+         *
+         */
         fun markedAsManuallyVerified(userId: String, deviceId: String) {}
     }