mirror of
https://github.com/element-hq/element-android
synced 2024-11-24 18:35:40 +03:00
clean klint
This commit is contained in:
parent
9a79297e14
commit
2c568b4de9
35 changed files with 78 additions and 92 deletions
|
@ -25,7 +25,14 @@ import im.vector.matrix.android.api.session.Session
|
||||||
import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupService
|
import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupService
|
||||||
import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupState
|
import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupState
|
||||||
import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupStateListener
|
import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupStateListener
|
||||||
import im.vector.matrix.android.common.*
|
import im.vector.matrix.android.common.CommonTestHelper
|
||||||
|
import im.vector.matrix.android.common.CryptoTestData
|
||||||
|
import im.vector.matrix.android.common.CryptoTestHelper
|
||||||
|
import im.vector.matrix.android.common.SessionTestParams
|
||||||
|
import im.vector.matrix.android.common.TestConstants
|
||||||
|
import im.vector.matrix.android.common.TestMatrixCallback
|
||||||
|
import im.vector.matrix.android.common.assertDictEquals
|
||||||
|
import im.vector.matrix.android.common.assertListEquals
|
||||||
import im.vector.matrix.android.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM_BACKUP
|
import im.vector.matrix.android.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM_BACKUP
|
||||||
import im.vector.matrix.android.internal.crypto.MegolmSessionData
|
import im.vector.matrix.android.internal.crypto.MegolmSessionData
|
||||||
import im.vector.matrix.android.internal.crypto.OutgoingRoomKeyRequest
|
import im.vector.matrix.android.internal.crypto.OutgoingRoomKeyRequest
|
||||||
|
@ -36,12 +43,18 @@ import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.KeysVersio
|
||||||
import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.KeysVersionResult
|
import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.KeysVersionResult
|
||||||
import im.vector.matrix.android.internal.crypto.model.ImportRoomKeysResult
|
import im.vector.matrix.android.internal.crypto.model.ImportRoomKeysResult
|
||||||
import im.vector.matrix.android.internal.crypto.model.OlmInboundGroupSessionWrapper
|
import im.vector.matrix.android.internal.crypto.model.OlmInboundGroupSessionWrapper
|
||||||
import org.junit.Assert.*
|
import org.junit.Assert.assertEquals
|
||||||
|
import org.junit.Assert.assertFalse
|
||||||
|
import org.junit.Assert.assertNotNull
|
||||||
|
import org.junit.Assert.assertNull
|
||||||
|
import org.junit.Assert.assertTrue
|
||||||
|
import org.junit.Assert.fail
|
||||||
import org.junit.FixMethodOrder
|
import org.junit.FixMethodOrder
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import org.junit.runners.MethodSorters
|
import org.junit.runners.MethodSorters
|
||||||
import java.util.*
|
import java.util.ArrayList
|
||||||
|
import java.util.Collections
|
||||||
import java.util.concurrent.CountDownLatch
|
import java.util.concurrent.CountDownLatch
|
||||||
|
|
||||||
@RunWith(AndroidJUnit4::class)
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
@ -298,7 +311,10 @@ class KeysBackupTest : InstrumentedTest {
|
||||||
val decryption = keysBackup.pkDecryptionFromRecoveryKey(keyBackupCreationInfo.recoveryKey)
|
val decryption = keysBackup.pkDecryptionFromRecoveryKey(keyBackupCreationInfo.recoveryKey)
|
||||||
assertNotNull(decryption)
|
assertNotNull(decryption)
|
||||||
// - Check decryptKeyBackupData() returns stg
|
// - Check decryptKeyBackupData() returns stg
|
||||||
val sessionData = keysBackup.decryptKeyBackupData(keyBackupData, session.olmInboundGroupSession!!.sessionIdentifier(), cryptoTestData.roomId, decryption!!)
|
val sessionData = keysBackup
|
||||||
|
.decryptKeyBackupData(keyBackupData,
|
||||||
|
session.olmInboundGroupSession!!.sessionIdentifier(),
|
||||||
|
cryptoTestData.roomId, decryption!!)
|
||||||
assertNotNull(sessionData)
|
assertNotNull(sessionData)
|
||||||
// - Compare the decrypted megolm key with the original one
|
// - Compare the decrypted megolm key with the original one
|
||||||
assertKeysEquals(session.exportKeys(), sessionData)
|
assertKeysEquals(session.exportKeys(), sessionData)
|
||||||
|
|
|
@ -21,7 +21,6 @@ import im.vector.matrix.android.api.MatrixCallback
|
||||||
import im.vector.matrix.android.api.util.Optional
|
import im.vector.matrix.android.api.util.Optional
|
||||||
import im.vector.matrix.android.internal.crypto.crosssigning.DeviceTrustResult
|
import im.vector.matrix.android.internal.crypto.crosssigning.DeviceTrustResult
|
||||||
import im.vector.matrix.android.internal.crypto.crosssigning.UserTrustResult
|
import im.vector.matrix.android.internal.crypto.crosssigning.UserTrustResult
|
||||||
import im.vector.matrix.android.internal.crypto.model.rest.SignatureUploadResponse
|
|
||||||
import im.vector.matrix.android.internal.crypto.model.rest.UserPasswordAuth
|
import im.vector.matrix.android.internal.crypto.model.rest.UserPasswordAuth
|
||||||
|
|
||||||
interface CrossSigningService {
|
interface CrossSigningService {
|
||||||
|
|
|
@ -33,5 +33,4 @@ interface SasVerificationTransaction : VerificationTransaction {
|
||||||
fun userHasVerifiedShortCode()
|
fun userHasVerifiedShortCode()
|
||||||
|
|
||||||
fun shortCodeDoesNotMatch()
|
fun shortCodeDoesNotMatch()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,11 @@ interface VerificationService {
|
||||||
/**
|
/**
|
||||||
* Request a key verification from another user using toDevice events.
|
* Request a key verification from another user using toDevice events.
|
||||||
*/
|
*/
|
||||||
fun requestKeyVerificationInDMs(methods: List<VerificationMethod>, otherUserId: String, roomId: String, localId: String? = LocalEcho.createLocalEchoId()): PendingVerificationRequest
|
fun requestKeyVerificationInDMs(methods: List<VerificationMethod>,
|
||||||
|
otherUserId: String,
|
||||||
|
roomId: String,
|
||||||
|
localId: String? = LocalEcho.createLocalEchoId()
|
||||||
|
): PendingVerificationRequest
|
||||||
|
|
||||||
fun declineVerificationRequestInDMs(otherUserId: String, otherDeviceId: String, transactionId: String, roomId: String)
|
fun declineVerificationRequestInDMs(otherUserId: String, otherDeviceId: String, transactionId: String, roomId: String)
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
package im.vector.matrix.android.internal.crypto
|
package im.vector.matrix.android.internal.crypto
|
||||||
|
|
||||||
import com.zhuinden.monarchy.Monarchy
|
|
||||||
import dagger.Binds
|
import dagger.Binds
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
|
|
|
@ -155,7 +155,6 @@ internal class DefaultCryptoService @Inject constructor(
|
||||||
private val cryptoCoroutineScope: CoroutineScope
|
private val cryptoCoroutineScope: CoroutineScope
|
||||||
) : CryptoService {
|
) : CryptoService {
|
||||||
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
verificationService.cryptoService = this
|
verificationService.cryptoService = this
|
||||||
}
|
}
|
||||||
|
@ -188,7 +187,7 @@ internal class DefaultCryptoService @Inject constructor(
|
||||||
.configureWith(SetDeviceNameTask.Params(deviceId, deviceName)) {
|
.configureWith(SetDeviceNameTask.Params(deviceId, deviceName)) {
|
||||||
this.callback = object : MatrixCallback<Unit> {
|
this.callback = object : MatrixCallback<Unit> {
|
||||||
override fun onSuccess(data: Unit) {
|
override fun onSuccess(data: Unit) {
|
||||||
//bg refresh of crypto device
|
// bg refresh of crypto device
|
||||||
downloadKeys(listOf(credentials.userId), true, object : MatrixCallback<MXUsersDevicesMap<CryptoDeviceInfo>> {})
|
downloadKeys(listOf(credentials.userId), true, object : MatrixCallback<MXUsersDevicesMap<CryptoDeviceInfo>> {})
|
||||||
callback.onSuccess(data)
|
callback.onSuccess(data)
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,6 @@ import im.vector.matrix.android.internal.crypto.MXOlmDevice
|
||||||
import im.vector.matrix.android.internal.crypto.MyDeviceInfoHolder
|
import im.vector.matrix.android.internal.crypto.MyDeviceInfoHolder
|
||||||
import im.vector.matrix.android.internal.crypto.model.CryptoCrossSigningKey
|
import im.vector.matrix.android.internal.crypto.model.CryptoCrossSigningKey
|
||||||
import im.vector.matrix.android.internal.crypto.model.KeyUsage
|
import im.vector.matrix.android.internal.crypto.model.KeyUsage
|
||||||
import im.vector.matrix.android.internal.crypto.model.rest.KeysQueryResponse
|
|
||||||
import im.vector.matrix.android.internal.crypto.model.rest.UploadSignatureQueryBuilder
|
import im.vector.matrix.android.internal.crypto.model.rest.UploadSignatureQueryBuilder
|
||||||
import im.vector.matrix.android.internal.crypto.model.rest.UserPasswordAuth
|
import im.vector.matrix.android.internal.crypto.model.rest.UserPasswordAuth
|
||||||
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
|
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
|
||||||
|
@ -245,7 +244,7 @@ internal class DefaultCrossSigningService @Inject constructor(
|
||||||
|
|
||||||
resetTrustOnKeyChange()
|
resetTrustOnKeyChange()
|
||||||
uploadSignaturesTask.configureWith(UploadSignaturesTask.Params(uploadSignatureQueryBuilder.build())) {
|
uploadSignaturesTask.configureWith(UploadSignaturesTask.Params(uploadSignatureQueryBuilder.build())) {
|
||||||
//this.retryCount = 3
|
// this.retryCount = 3
|
||||||
this.constraints = TaskConstraints(true)
|
this.constraints = TaskConstraints(true)
|
||||||
this.callback = object : MatrixCallback<Unit> {
|
this.callback = object : MatrixCallback<Unit> {
|
||||||
override fun onSuccess(data: Unit) {
|
override fun onSuccess(data: Unit) {
|
||||||
|
@ -254,7 +253,7 @@ internal class DefaultCrossSigningService @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(failure: Throwable) {
|
override fun onFailure(failure: Throwable) {
|
||||||
//Clear
|
// Clear
|
||||||
Timber.e(failure, "## CrossSigning - Failed to upload signatures")
|
Timber.e(failure, "## CrossSigning - Failed to upload signatures")
|
||||||
clearSigningKeys()
|
clearSigningKeys()
|
||||||
}
|
}
|
||||||
|
@ -584,8 +583,13 @@ internal class DefaultCrossSigningService @Inject constructor(
|
||||||
*/
|
*/
|
||||||
|
|
||||||
val otherSSKSignature = otherDevice.signatures?.get(otherUserId)?.get("ed25519:${otherKeys.selfSigningKey()?.unpaddedBase64PublicKey}")
|
val otherSSKSignature = otherDevice.signatures?.get(otherUserId)?.get("ed25519:${otherKeys.selfSigningKey()?.unpaddedBase64PublicKey}")
|
||||||
?: return legacyFallbackTrust(locallyTrusted, DeviceTrustResult.MissingDeviceSignature(otherDeviceId, otherKeys.selfSigningKey()?.unpaddedBase64PublicKey
|
?: return legacyFallbackTrust(
|
||||||
?: ""))
|
locallyTrusted,
|
||||||
|
DeviceTrustResult.MissingDeviceSignature(otherDeviceId, otherKeys.selfSigningKey()
|
||||||
|
?.unpaddedBase64PublicKey
|
||||||
|
?: ""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
// Check bob's device is signed by bob's SSK
|
// Check bob's device is signed by bob's SSK
|
||||||
try {
|
try {
|
||||||
|
@ -606,7 +610,6 @@ internal class DefaultCrossSigningService @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onUsersDeviceUpdate(users: List<String>) {
|
override fun onUsersDeviceUpdate(users: List<String>) {
|
||||||
|
|
||||||
Timber.d("## CrossSigning - onUsersDeviceUpdate for ${users.size} users")
|
Timber.d("## CrossSigning - onUsersDeviceUpdate for ${users.size} users")
|
||||||
users.forEach { otherUserId ->
|
users.forEach { otherUserId ->
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,11 @@ data class UploadSignatureQueryBuilder(
|
||||||
fun build(): Map<String, Map<String, @JvmSuppressWildcards Any>> {
|
fun build(): Map<String, Map<String, @JvmSuppressWildcards Any>> {
|
||||||
val map = HashMap<String, HashMap<String, Any>>()
|
val map = HashMap<String, HashMap<String, Any>>()
|
||||||
|
|
||||||
val usersList = (deviceInfoList.map { it.userId } + signingKeyInfoList.mapNotNull { it.userId }).distinct()
|
val usersList = (
|
||||||
|
deviceInfoList.map { it.userId }
|
||||||
|
+ signingKeyInfoList
|
||||||
|
.map { it.userId }
|
||||||
|
).distinct()
|
||||||
|
|
||||||
usersList.forEach { userID ->
|
usersList.forEach { userID ->
|
||||||
val userMap = HashMap<String, Any>()
|
val userMap = HashMap<String, Any>()
|
||||||
|
|
|
@ -365,7 +365,11 @@ internal class RealmCryptoStore(private val realmConfiguration: RealmConfigurati
|
||||||
|
|
||||||
override fun getLiveDeviceList(userId: String): LiveData<List<CryptoDeviceInfo>> {
|
override fun getLiveDeviceList(userId: String): LiveData<List<CryptoDeviceInfo>> {
|
||||||
val liveData = monarchy.findAllMappedWithChanges(
|
val liveData = monarchy.findAllMappedWithChanges(
|
||||||
{ realm: Realm -> realm.where<UserEntity>().equalTo(UserEntityFields.USER_ID, userId) },
|
{ realm: Realm ->
|
||||||
|
realm
|
||||||
|
.where<UserEntity>()
|
||||||
|
.equalTo(UserEntityFields.USER_ID, userId)
|
||||||
|
},
|
||||||
{ entity ->
|
{ entity ->
|
||||||
entity.devices.map { CryptoMapper.mapToModel(it) }
|
entity.devices.map { CryptoMapper.mapToModel(it) }
|
||||||
}
|
}
|
||||||
|
@ -929,7 +933,7 @@ internal class RealmCryptoStore(private val realmConfiguration: RealmConfigurati
|
||||||
val xInfoEntities = realm.where(CrossSigningInfoEntity::class.java)
|
val xInfoEntities = realm.where(CrossSigningInfoEntity::class.java)
|
||||||
.findAll()
|
.findAll()
|
||||||
xInfoEntities?.forEach { info ->
|
xInfoEntities?.forEach { info ->
|
||||||
//Need to ignore mine
|
// Need to ignore mine
|
||||||
if (info.userId != credentials.userId) {
|
if (info.userId != credentials.userId) {
|
||||||
info.crossSigningKeys.forEach {
|
info.crossSigningKeys.forEach {
|
||||||
it.trustLevelEntity = null
|
it.trustLevelEntity = null
|
||||||
|
@ -969,7 +973,10 @@ internal class RealmCryptoStore(private val realmConfiguration: RealmConfigurati
|
||||||
|
|
||||||
override fun getLiveCrossSigningInfo(userId: String): LiveData<Optional<MXCrossSigningInfo>> {
|
override fun getLiveCrossSigningInfo(userId: String): LiveData<Optional<MXCrossSigningInfo>> {
|
||||||
val liveData = monarchy.findAllMappedWithChanges(
|
val liveData = monarchy.findAllMappedWithChanges(
|
||||||
{ realm: Realm -> realm.where<CrossSigningInfoEntity>().equalTo(UserEntityFields.USER_ID, userId) },
|
{ realm: Realm ->
|
||||||
|
realm.where<CrossSigningInfoEntity>()
|
||||||
|
.equalTo(UserEntityFields.USER_ID, userId)
|
||||||
|
},
|
||||||
{ entity ->
|
{ entity ->
|
||||||
MXCrossSigningInfo(
|
MXCrossSigningInfo(
|
||||||
userId = userId,
|
userId = userId,
|
||||||
|
|
|
@ -49,7 +49,6 @@ internal object RealmCryptoStoreMigration : RealmMigration {
|
||||||
.addField(TrustLevelEntityFields.LOCALLY_VERIFIED, Boolean::class.java)
|
.addField(TrustLevelEntityFields.LOCALLY_VERIFIED, Boolean::class.java)
|
||||||
.setNullable(TrustLevelEntityFields.LOCALLY_VERIFIED, true)
|
.setNullable(TrustLevelEntityFields.LOCALLY_VERIFIED, true)
|
||||||
|
|
||||||
|
|
||||||
val keyInfoEntitySchema = realm.schema.create("KeyInfoEntity")
|
val keyInfoEntitySchema = realm.schema.create("KeyInfoEntity")
|
||||||
.addField(KeyInfoEntityFields.PUBLIC_KEY_BASE64, String::class.java)
|
.addField(KeyInfoEntityFields.PUBLIC_KEY_BASE64, String::class.java)
|
||||||
.addField(KeyInfoEntityFields.SIGNATURES, String::class.java)
|
.addField(KeyInfoEntityFields.SIGNATURES, String::class.java)
|
||||||
|
|
|
@ -34,8 +34,7 @@ internal class DefaultUploadSignaturesTask @Inject constructor(
|
||||||
private val eventBus: EventBus
|
private val eventBus: EventBus
|
||||||
) : UploadSignaturesTask {
|
) : UploadSignaturesTask {
|
||||||
|
|
||||||
override suspend fun execute(params: UploadSignaturesTask.Params): Unit {
|
override suspend fun execute(params: UploadSignaturesTask.Params) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val response = executeRequest<SignatureUploadResponse>(eventBus) {
|
val response = executeRequest<SignatureUploadResponse>(eventBus) {
|
||||||
apiCall = cryptoApi.uploadSignatures(params.signatures)
|
apiCall = cryptoApi.uploadSignatures(params.signatures)
|
||||||
|
|
|
@ -400,8 +400,9 @@ internal class DefaultVerificationService @Inject constructor(
|
||||||
?.filterIsInstance(SasVerificationTransaction::class.java)
|
?.filterIsInstance(SasVerificationTransaction::class.java)
|
||||||
?.takeIf { it.isNotEmpty() }
|
?.takeIf { it.isNotEmpty() }
|
||||||
?.also {
|
?.also {
|
||||||
// Multiple keyshares between two devices: any two devices may only have at most one key verification in flight at a time.
|
// Multiple keyshares between two devices:
|
||||||
Timber.v("## SAS onStartRequestReceived - There is already a transaction with this user ${startReq.transactionID}")
|
// any two devices may only have at most one key verification in flight at a time.
|
||||||
|
Timber.v("## SAS onStartRequestReceived - Already a transaction with this user ${startReq.transactionID}")
|
||||||
}
|
}
|
||||||
?.forEach {
|
?.forEach {
|
||||||
it.cancel(CancelCode.UnexpectedMessage)
|
it.cancel(CancelCode.UnexpectedMessage)
|
||||||
|
@ -443,7 +444,7 @@ internal class DefaultVerificationService @Inject constructor(
|
||||||
return CancelCode.UnexpectedMessage
|
return CancelCode.UnexpectedMessage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else ->{
|
else -> {
|
||||||
Timber.e("## SAS onStartRequestReceived - unknown method ${startReq.method}")
|
Timber.e("## SAS onStartRequestReceived - unknown method ${startReq.method}")
|
||||||
return CancelCode.UnknownMethod
|
return CancelCode.UnknownMethod
|
||||||
}
|
}
|
||||||
|
@ -882,7 +883,9 @@ internal class DefaultVerificationService @Inject constructor(
|
||||||
val methodValues = if (crossSigningService.isCrossSigningEnabled()) {
|
val methodValues = if (crossSigningService.isCrossSigningEnabled()) {
|
||||||
// Add reciprocate method if application declares it can scan or show QR codes
|
// Add reciprocate method if application declares it can scan or show QR codes
|
||||||
// Not sure if it ok to do that (?)
|
// Not sure if it ok to do that (?)
|
||||||
val reciprocateMethod = methods.firstOrNull { it == VerificationMethod.QR_CODE_SCAN || it == VerificationMethod.QR_CODE_SHOW }?.let { listOf(VERIFICATION_METHOD_RECIPROCATE) }.orEmpty()
|
val reciprocateMethod = methods
|
||||||
|
.firstOrNull { it == VerificationMethod.QR_CODE_SCAN || it == VerificationMethod.QR_CODE_SHOW }
|
||||||
|
?.let { listOf(VERIFICATION_METHOD_RECIPROCATE) }.orEmpty()
|
||||||
methods.map { it.toValue() } + reciprocateMethod
|
methods.map { it.toValue() } + reciprocateMethod
|
||||||
} else {
|
} else {
|
||||||
// Filter out SCAN and SHOW qr code method
|
// Filter out SCAN and SHOW qr code method
|
||||||
|
|
|
@ -27,7 +27,6 @@ import im.vector.matrix.android.api.session.events.model.EventType
|
||||||
import im.vector.matrix.android.internal.crypto.actions.SetDeviceVerificationAction
|
import im.vector.matrix.android.internal.crypto.actions.SetDeviceVerificationAction
|
||||||
import im.vector.matrix.android.internal.crypto.crosssigning.DeviceTrustLevel
|
import im.vector.matrix.android.internal.crypto.crosssigning.DeviceTrustLevel
|
||||||
import im.vector.matrix.android.internal.crypto.model.MXKey
|
import im.vector.matrix.android.internal.crypto.model.MXKey
|
||||||
import im.vector.matrix.android.internal.crypto.model.rest.SignatureUploadResponse
|
|
||||||
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
|
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
|
||||||
import im.vector.matrix.android.internal.extensions.toUnsignedInt
|
import im.vector.matrix.android.internal.extensions.toUnsignedInt
|
||||||
import im.vector.matrix.android.internal.util.withoutPrefix
|
import im.vector.matrix.android.internal.util.withoutPrefix
|
||||||
|
|
|
@ -24,7 +24,6 @@ import im.vector.matrix.android.api.session.crypto.sas.VerificationTxState
|
||||||
import im.vector.matrix.android.api.session.events.model.EventType
|
import im.vector.matrix.android.api.session.events.model.EventType
|
||||||
import im.vector.matrix.android.internal.crypto.actions.SetDeviceVerificationAction
|
import im.vector.matrix.android.internal.crypto.actions.SetDeviceVerificationAction
|
||||||
import im.vector.matrix.android.internal.crypto.crosssigning.DeviceTrustLevel
|
import im.vector.matrix.android.internal.crypto.crosssigning.DeviceTrustLevel
|
||||||
import im.vector.matrix.android.internal.crypto.model.rest.SignatureUploadResponse
|
|
||||||
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
|
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
|
||||||
import im.vector.matrix.android.internal.crypto.verification.DefaultVerificationTransaction
|
import im.vector.matrix.android.internal.crypto.verification.DefaultVerificationTransaction
|
||||||
import im.vector.matrix.android.internal.crypto.verification.VerificationInfo
|
import im.vector.matrix.android.internal.crypto.verification.VerificationInfo
|
||||||
|
@ -135,7 +134,6 @@ internal class DefaultQrCodeVerificationTransaction(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!canTrustOtherUserMasterKey && toVerifyDeviceIds.isEmpty()) {
|
if (!canTrustOtherUserMasterKey && toVerifyDeviceIds.isEmpty()) {
|
||||||
|
|
|
@ -66,7 +66,6 @@ abstract class GenericItemWithValue : VectorEpoxyModel<GenericItemWithValue.Hold
|
||||||
holder.titleIcon.isVisible = false
|
holder.titleIcon.isVisible = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
holder.valueText.setTextOrHide(value)
|
holder.valueText.setTextOrHide(value)
|
||||||
|
|
||||||
if (valueColorInt != null) {
|
if (valueColorInt != null) {
|
||||||
|
|
|
@ -139,7 +139,9 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
|
||||||
copy(
|
copy(
|
||||||
roomId = data,
|
roomId = data,
|
||||||
pendingRequest = Success(
|
pendingRequest = Success(
|
||||||
session.getVerificationService().requestKeyVerificationInDMs(supportedVerificationMethods, otherUserId, data, pendingLocalId)
|
session
|
||||||
|
.getVerificationService()
|
||||||
|
.requestKeyVerificationInDMs(supportedVerificationMethods, otherUserId, data, pendingLocalId)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -153,7 +155,12 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
setState {
|
setState {
|
||||||
copy(pendingRequest = Success(session.getVerificationService().requestKeyVerificationInDMs(supportedVerificationMethods, otherUserId, roomId)))
|
copy(
|
||||||
|
pendingRequest = Success(session
|
||||||
|
.getVerificationService()
|
||||||
|
.requestKeyVerificationInDMs(supportedVerificationMethods, otherUserId, roomId)
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@ package im.vector.riotx.features.crypto.verification.request
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import com.airbnb.mvrx.fragmentViewModel
|
|
||||||
import com.airbnb.mvrx.parentFragmentViewModel
|
import com.airbnb.mvrx.parentFragmentViewModel
|
||||||
import com.airbnb.mvrx.withState
|
import com.airbnb.mvrx.withState
|
||||||
import im.vector.riotx.R
|
import im.vector.riotx.R
|
||||||
|
@ -42,7 +41,6 @@ class VerificationRequestFragment @Inject constructor(
|
||||||
setupRecyclerView()
|
setupRecyclerView()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
bottomSheetVerificationRecyclerView.cleanup()
|
bottomSheetVerificationRecyclerView.cleanup()
|
||||||
controller.listener = null
|
controller.listener = null
|
||||||
|
|
|
@ -1024,7 +1024,7 @@ class RoomDetailFragment @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onAvatarClicked(informationData: MessageInformationData) {
|
override fun onAvatarClicked(informationData: MessageInformationData) {
|
||||||
//roomDetailViewModel.handle(RoomDetailAction.RequestVerification(informationData.senderId))
|
// roomDetailViewModel.handle(RoomDetailAction.RequestVerification(informationData.senderId))
|
||||||
openRoomMemberProfile(informationData.senderId)
|
openRoomMemberProfile(informationData.senderId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ class TimelineItemFactory @Inject constructor(private val messageItemFactory: Me
|
||||||
private val defaultItemFactory: DefaultItemFactory,
|
private val defaultItemFactory: DefaultItemFactory,
|
||||||
private val roomCreateItemFactory: RoomCreateItemFactory,
|
private val roomCreateItemFactory: RoomCreateItemFactory,
|
||||||
private val verificationConclusionItemFactory: VerificationItemFactory,
|
private val verificationConclusionItemFactory: VerificationItemFactory,
|
||||||
private val userPreferencesProvider: UserPreferencesProvider ) {
|
private val userPreferencesProvider: UserPreferencesProvider) {
|
||||||
|
|
||||||
fun create(event: TimelineEvent,
|
fun create(event: TimelineEvent,
|
||||||
nextEvent: TimelineEvent?,
|
nextEvent: TimelineEvent?,
|
||||||
|
|
|
@ -120,7 +120,6 @@ object PopupAlertManager {
|
||||||
}
|
}
|
||||||
currentAlerter = next
|
currentAlerter = next
|
||||||
next?.let {
|
next?.let {
|
||||||
|
|
||||||
if (next.shouldBeDisplayedIn?.invoke(currentActivity) == false) return
|
if (next.shouldBeDisplayedIn?.invoke(currentActivity) == false) return
|
||||||
val currentTime = System.currentTimeMillis()
|
val currentTime = System.currentTimeMillis()
|
||||||
if (next.expirationTimestamp != null && currentTime > next.expirationTimestamp!!) {
|
if (next.expirationTimestamp != null && currentTime > next.expirationTimestamp!!) {
|
||||||
|
|
|
@ -78,7 +78,7 @@ class RoomMemberProfileController @Inject constructor(
|
||||||
if (state.userMXCrossSigningInfo != null) {
|
if (state.userMXCrossSigningInfo != null) {
|
||||||
// Cross signing is enabled for this user
|
// Cross signing is enabled for this user
|
||||||
if (state.userMXCrossSigningInfo.isTrusted()) {
|
if (state.userMXCrossSigningInfo.isTrusted()) {
|
||||||
//User is trusted
|
// User is trusted
|
||||||
val icon = if (state.allDevicesAreTrusted.invoke() == true) R.drawable.ic_shield_trusted
|
val icon = if (state.allDevicesAreTrusted.invoke() == true) R.drawable.ic_shield_trusted
|
||||||
else R.drawable.ic_shield_warning
|
else R.drawable.ic_shield_warning
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ class RoomMemberProfileController @Inject constructor(
|
||||||
action = { callback?.onShowDeviceList() }
|
action = { callback?.onShowDeviceList() }
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
//Not trusted, propose to verify
|
// Not trusted, propose to verify
|
||||||
if (!state.isMine) {
|
if (!state.isMine) {
|
||||||
buildProfileAction(
|
buildProfileAction(
|
||||||
id = "learn_more",
|
id = "learn_more",
|
||||||
|
|
|
@ -101,7 +101,6 @@ class RoomMemberProfileFragment @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,31 +147,8 @@ class RoomMemberProfileFragment @Inject constructor(
|
||||||
|
|
||||||
override fun onTapVerify() {
|
override fun onTapVerify() {
|
||||||
viewModel.handle(RoomMemberProfileAction.VerifyUser())
|
viewModel.handle(RoomMemberProfileAction.VerifyUser())
|
||||||
// if (state.isRoomEncrypted) {
|
|
||||||
// if( !state.isMine && state.userMXCrossSigningInfo?.isTrusted == false) {
|
|
||||||
// // we want to verify
|
|
||||||
// // TODO do not use current room, find or create DM
|
|
||||||
// VerificationBottomSheet.withArgs(
|
|
||||||
// state.roomId,
|
|
||||||
// state.userId
|
|
||||||
// ).show(parentFragmentManager, "REQ")
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// override fun onTapVerify() = withState(viewModel) { state ->
|
|
||||||
// if (state.isRoomEncrypted) {
|
|
||||||
// if( !state.isMine && state.userMXCrossSigningInfo?.isTrusted == false) {
|
|
||||||
// // we want to verify
|
|
||||||
// // TODO do not use current room, find or create DM
|
|
||||||
// VerificationBottomSheet.withArgs(
|
|
||||||
// state.roomId,
|
|
||||||
// state.userId
|
|
||||||
// ).show(parentFragmentManager, "REQ")
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
override fun onShowDeviceList() = withState(viewModel) {
|
override fun onShowDeviceList() = withState(viewModel) {
|
||||||
DeviceListBottomSheet.newInstance(it.userId).show(parentFragmentManager, "DEV_LIST")
|
DeviceListBottomSheet.newInstance(it.userId).show(parentFragmentManager, "DEV_LIST")
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,9 +48,7 @@ import im.vector.matrix.rx.unwrap
|
||||||
import im.vector.riotx.R
|
import im.vector.riotx.R
|
||||||
import im.vector.riotx.core.platform.VectorViewModel
|
import im.vector.riotx.core.platform.VectorViewModel
|
||||||
import im.vector.riotx.core.resources.StringProvider
|
import im.vector.riotx.core.resources.StringProvider
|
||||||
import im.vector.riotx.core.utils.DataSource
|
|
||||||
import im.vector.riotx.core.utils.LiveEvent
|
import im.vector.riotx.core.utils.LiveEvent
|
||||||
import im.vector.riotx.core.utils.PublishDataSource
|
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
import io.reactivex.functions.BiFunction
|
import io.reactivex.functions.BiFunction
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
@ -149,7 +147,6 @@ class RoomMemberProfileViewModel @AssistedInject constructor(@Assisted private v
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun observeRoomMemberSummary(room: Room) {
|
private fun observeRoomMemberSummary(room: Room) {
|
||||||
|
|
|
@ -23,7 +23,6 @@ import com.airbnb.mvrx.Uninitialized
|
||||||
import im.vector.matrix.android.api.session.crypto.crosssigning.MXCrossSigningInfo
|
import im.vector.matrix.android.api.session.crypto.crosssigning.MXCrossSigningInfo
|
||||||
import im.vector.matrix.android.api.session.room.model.PowerLevelsContent
|
import im.vector.matrix.android.api.session.room.model.PowerLevelsContent
|
||||||
import im.vector.matrix.android.api.util.MatrixItem
|
import im.vector.matrix.android.api.util.MatrixItem
|
||||||
import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo
|
|
||||||
|
|
||||||
data class RoomMemberProfileViewState(
|
data class RoomMemberProfileViewState(
|
||||||
val userId: String,
|
val userId: String,
|
||||||
|
|
|
@ -55,7 +55,6 @@ class DeviceListEpoxyController @Inject constructor(private val stringProvider:
|
||||||
}
|
}
|
||||||
when (data.cryptoDevices) {
|
when (data.cryptoDevices) {
|
||||||
Uninitialized -> {
|
Uninitialized -> {
|
||||||
|
|
||||||
}
|
}
|
||||||
is Loading -> {
|
is Loading -> {
|
||||||
loadingItem {
|
loadingItem {
|
||||||
|
@ -64,12 +63,10 @@ class DeviceListEpoxyController @Inject constructor(private val stringProvider:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is Success -> {
|
is Success -> {
|
||||||
|
|
||||||
val deviceList = data.cryptoDevices.invoke().sortedByDescending {
|
val deviceList = data.cryptoDevices.invoke().sortedByDescending {
|
||||||
it.isVerified
|
it.isVerified
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Build top header
|
// Build top header
|
||||||
val allGreen = deviceList.fold(true, { prev, device ->
|
val allGreen = deviceList.fold(true, { prev, device ->
|
||||||
prev && device.isVerified
|
prev && device.isVerified
|
||||||
|
@ -96,7 +93,6 @@ class DeviceListEpoxyController @Inject constructor(private val stringProvider:
|
||||||
id("sessions")
|
id("sessions")
|
||||||
style(GenericItem.STYLE.BIG_TEXT)
|
style(GenericItem.STYLE.BIG_TEXT)
|
||||||
title(stringProvider.getString(R.string.room_member_profile_sessions_section_title))
|
title(stringProvider.getString(R.string.room_member_profile_sessions_section_title))
|
||||||
|
|
||||||
}
|
}
|
||||||
if (deviceList.isEmpty()) {
|
if (deviceList.isEmpty()) {
|
||||||
// Can this really happen?
|
// Can this really happen?
|
||||||
|
|
|
@ -34,7 +34,6 @@ class DeviceTrustInfoActionFragment @Inject constructor(
|
||||||
val epoxyController: DeviceTrustInfoEpoxyController
|
val epoxyController: DeviceTrustInfoEpoxyController
|
||||||
) : VectorBaseFragment(), DeviceTrustInfoEpoxyController.InteractionListener {
|
) : VectorBaseFragment(), DeviceTrustInfoEpoxyController.InteractionListener {
|
||||||
|
|
||||||
|
|
||||||
override fun getLayoutResId() = R.layout.bottom_sheet_generic_list
|
override fun getLayoutResId() = R.layout.bottom_sheet_generic_list
|
||||||
|
|
||||||
private val viewModel: DeviceListBottomSheetViewModel by parentFragmentViewModel(DeviceListBottomSheetViewModel::class)
|
private val viewModel: DeviceListBottomSheetViewModel by parentFragmentViewModel(DeviceListBottomSheetViewModel::class)
|
||||||
|
@ -66,5 +65,3 @@ class DeviceTrustInfoActionFragment @Inject constructor(
|
||||||
viewModel.manuallyVerify(device)
|
viewModel.manuallyVerify(device)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -118,7 +118,6 @@ class CrossSigningEpoxyController @Inject constructor(
|
||||||
id("loading")
|
id("loading")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
val crossSigningKeys = data.crossSigningInfo
|
val crossSigningKeys = data.crossSigningInfo
|
||||||
|
|
||||||
crossSigningKeys?.masterKey()?.let {
|
crossSigningKeys?.masterKey()?.let {
|
||||||
|
|
|
@ -122,4 +122,3 @@ class CrossSigningSettingsFragment @Inject constructor(
|
||||||
viewModel.handle(CrossSigningAction.InitializeCrossSigning())
|
viewModel.handle(CrossSigningAction.InitializeCrossSigning())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,6 @@ class CrossSigningSettingsViewModel @AssistedInject constructor(@Assisted privat
|
||||||
copy(isUploadingKeys = true)
|
copy(isUploadingKeys = true)
|
||||||
}
|
}
|
||||||
session.getCrossSigningService().initializeCrossSigning(auth, object : MatrixCallback<Unit> {
|
session.getCrossSigningService().initializeCrossSigning(auth, object : MatrixCallback<Unit> {
|
||||||
|
|
||||||
override fun onSuccess(data: Unit) {
|
override fun onSuccess(data: Unit) {
|
||||||
setState {
|
setState {
|
||||||
copy(isUploadingKeys = false)
|
copy(isUploadingKeys = false)
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
package im.vector.riotx.features.settings.devices
|
package im.vector.riotx.features.settings.devices
|
||||||
|
|
||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
@ -110,7 +109,6 @@ abstract class DeviceItem : VectorEpoxyModel<DeviceItem.Holder>() {
|
||||||
it.isVisible = false
|
it.isVisible = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Holder : VectorEpoxyHolder() {
|
class Holder : VectorEpoxyHolder() {
|
||||||
|
|
|
@ -43,7 +43,7 @@ class DeviceVerificationInfoBottomSheet : VectorBaseBottomSheetDialogFragment(),
|
||||||
|
|
||||||
private val viewModel: DeviceVerificationInfoBottomSheetViewModel by fragmentViewModel(DeviceVerificationInfoBottomSheetViewModel::class)
|
private val viewModel: DeviceVerificationInfoBottomSheetViewModel by fragmentViewModel(DeviceVerificationInfoBottomSheetViewModel::class)
|
||||||
|
|
||||||
private val sharedViewModel: DevicesViewModel by parentFragmentViewModel (DevicesViewModel::class)
|
private val sharedViewModel: DevicesViewModel by parentFragmentViewModel(DevicesViewModel::class)
|
||||||
|
|
||||||
@Inject lateinit var deviceVerificationInfoViewModelFactory: DeviceVerificationInfoBottomSheetViewModel.Factory
|
@Inject lateinit var deviceVerificationInfoViewModelFactory: DeviceVerificationInfoBottomSheetViewModel.Factory
|
||||||
|
|
||||||
|
@ -91,5 +91,4 @@ class DeviceVerificationInfoBottomSheet : VectorBaseBottomSheetDialogFragment(),
|
||||||
dismiss()
|
dismiss()
|
||||||
sharedViewModel.handle(action)
|
sharedViewModel.handle(action)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,8 @@ class DeviceVerificationInfoBottomSheetViewModel @AssistedInject constructor(@As
|
||||||
companion object : MvRxViewModelFactory<DeviceVerificationInfoBottomSheetViewModel, DeviceVerificationInfoBottomSheetViewState> {
|
companion object : MvRxViewModelFactory<DeviceVerificationInfoBottomSheetViewModel, DeviceVerificationInfoBottomSheetViewState> {
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
override fun create(viewModelContext: ViewModelContext, state: DeviceVerificationInfoBottomSheetViewState): DeviceVerificationInfoBottomSheetViewModel? {
|
override fun create(viewModelContext: ViewModelContext, state: DeviceVerificationInfoBottomSheetViewState)
|
||||||
|
: DeviceVerificationInfoBottomSheetViewModel? {
|
||||||
val fragment: DeviceVerificationInfoBottomSheet = (viewModelContext as FragmentViewModelContext).fragment()
|
val fragment: DeviceVerificationInfoBottomSheet = (viewModelContext as FragmentViewModelContext).fragment()
|
||||||
return fragment.deviceVerificationInfoViewModelFactory.create(state)
|
return fragment.deviceVerificationInfoViewModelFactory.create(state)
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,11 +22,9 @@ import im.vector.riotx.core.epoxy.dividerItem
|
||||||
import im.vector.riotx.core.epoxy.loadingItem
|
import im.vector.riotx.core.epoxy.loadingItem
|
||||||
import im.vector.riotx.core.resources.ColorProvider
|
import im.vector.riotx.core.resources.ColorProvider
|
||||||
import im.vector.riotx.core.resources.StringProvider
|
import im.vector.riotx.core.resources.StringProvider
|
||||||
import im.vector.riotx.core.resources.UserPreferencesProvider
|
|
||||||
import im.vector.riotx.core.ui.list.GenericItem
|
import im.vector.riotx.core.ui.list.GenericItem
|
||||||
import im.vector.riotx.core.ui.list.genericItem
|
import im.vector.riotx.core.ui.list.genericItem
|
||||||
import im.vector.riotx.features.crypto.verification.epoxy.bottomSheetVerificationActionItem
|
import im.vector.riotx.features.crypto.verification.epoxy.bottomSheetVerificationActionItem
|
||||||
import im.vector.riotx.features.home.AvatarRenderer
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class DeviceVerificationInfoEpoxyController @Inject constructor(private val stringProvider: StringProvider,
|
class DeviceVerificationInfoEpoxyController @Inject constructor(private val stringProvider: StringProvider,
|
||||||
|
@ -43,7 +41,6 @@ class DeviceVerificationInfoEpoxyController @Inject constructor(private val stri
|
||||||
id("loading")
|
id("loading")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (device.isVerified) {
|
if (device.isVerified) {
|
||||||
genericItem {
|
genericItem {
|
||||||
id("trust${device.deviceId}")
|
id("trust${device.deviceId}")
|
||||||
|
@ -85,7 +82,7 @@ class DeviceVerificationInfoEpoxyController @Inject constructor(private val stri
|
||||||
}
|
}
|
||||||
|
|
||||||
if (device.deviceId != session.sessionParams.credentials.deviceId) {
|
if (device.deviceId != session.sessionParams.credentials.deviceId) {
|
||||||
//Add the delete option
|
// Add the delete option
|
||||||
dividerItem {
|
dividerItem {
|
||||||
id("d2")
|
id("d2")
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,6 @@ import im.vector.riotx.core.epoxy.errorWithRetryItem
|
||||||
import im.vector.riotx.core.epoxy.loadingItem
|
import im.vector.riotx.core.epoxy.loadingItem
|
||||||
import im.vector.riotx.core.error.ErrorFormatter
|
import im.vector.riotx.core.error.ErrorFormatter
|
||||||
import im.vector.riotx.core.resources.StringProvider
|
import im.vector.riotx.core.resources.StringProvider
|
||||||
import im.vector.riotx.core.ui.list.genericFooterItem
|
|
||||||
import im.vector.riotx.core.ui.list.genericItemHeader
|
import im.vector.riotx.core.ui.list.genericItemHeader
|
||||||
import im.vector.riotx.features.settings.VectorPreferences
|
import im.vector.riotx.features.settings.VectorPreferences
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
@ -97,7 +96,6 @@ class DevicesController @Inject constructor(private val errorFormatter: ErrorFor
|
||||||
|
|
||||||
// Other devices
|
// Other devices
|
||||||
if (devices.size > 1) {
|
if (devices.size > 1) {
|
||||||
|
|
||||||
genericItemHeader {
|
genericItemHeader {
|
||||||
id("others")
|
id("others")
|
||||||
text(stringProvider.getString(R.string.devices_other_devices))
|
text(stringProvider.getString(R.string.devices_other_devices))
|
||||||
|
|
|
@ -96,7 +96,7 @@ class DevicesViewModel @AssistedInject constructor(@Assisted initialState: Devic
|
||||||
|
|
||||||
override fun transactionCreated(tx: VerificationTransaction) {}
|
override fun transactionCreated(tx: VerificationTransaction) {}
|
||||||
override fun transactionUpdated(tx: VerificationTransaction) {
|
override fun transactionUpdated(tx: VerificationTransaction) {
|
||||||
if(tx.state == VerificationTxState.Verified) {
|
if (tx.state == VerificationTxState.Verified) {
|
||||||
refreshDevicesList()
|
refreshDevicesList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue