Fix / Handling multi open sessions

This commit is contained in:
Valere 2019-12-13 11:20:36 +01:00
parent 872baacfe4
commit 210dcca0ee
5 changed files with 63 additions and 5 deletions

View file

@ -27,4 +27,3 @@ class ReferencesAggregatedSummary(
val sourceEvents: List<String>,
val localEchos: List<String>
)

View file

@ -108,6 +108,7 @@ internal class DefaultSasVerificationService @Inject constructor(
onRoomStartRequestReceived(event)
}
EventType.KEY_VERIFICATION_CANCEL -> {
// MultiSessions | ignore events if i didn't sent the start from this device, or accepted from this device
onRoomCancelReceived(event)
}
EventType.KEY_VERIFICATION_ACCEPT -> {

View file

@ -19,14 +19,15 @@ import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.session.crypto.CryptoService
import im.vector.matrix.android.api.session.crypto.MXCryptoError
import im.vector.matrix.android.api.session.events.model.EventType
import im.vector.matrix.android.api.session.events.model.LocalEcho
import im.vector.matrix.android.api.session.events.model.toModel
import im.vector.matrix.android.api.session.room.model.message.MessageContent
import im.vector.matrix.android.api.session.room.model.message.MessageType
import im.vector.matrix.android.api.session.room.model.message.*
import im.vector.matrix.android.internal.crypto.algorithms.olm.OlmDecryptionResult
import im.vector.matrix.android.internal.database.RealmLiveEntityObserver
import im.vector.matrix.android.internal.database.mapper.asDomain
import im.vector.matrix.android.internal.database.model.EventEntity
import im.vector.matrix.android.internal.database.query.types
import im.vector.matrix.android.internal.di.DeviceId
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.task.TaskExecutor
@ -36,10 +37,12 @@ import io.realm.RealmResults
import timber.log.Timber
import java.util.*
import javax.inject.Inject
import kotlin.collections.ArrayList
internal class VerificationMessageLiveObserver @Inject constructor(
@SessionDatabase realmConfiguration: RealmConfiguration,
@UserId private val userId: String,
@DeviceId private val deviceId: String?,
private val cryptoService: CryptoService,
private val sasVerificationService: DefaultSasVerificationService,
private val taskExecutor: TaskExecutor
@ -58,6 +61,8 @@ internal class VerificationMessageLiveObserver @Inject constructor(
)
}
val transactionsHandledByOtherDevice = ArrayList<String>()
override fun onChange(results: RealmResults<EventEntity>, changeSet: OrderedCollectionChangeSet) {
// TODO do that in a task
// TODO how to ignore when it's an initial sync?
@ -65,8 +70,8 @@ internal class VerificationMessageLiveObserver @Inject constructor(
.asSequence()
.mapNotNull { results[it]?.asDomain() }
.filterNot {
// ignore mines ^^
it.senderId == userId
// ignore local echos
LocalEcho.isLocalEchoId(it.eventId ?: "")
}
.toList()
@ -112,6 +117,45 @@ internal class VerificationMessageLiveObserver @Inject constructor(
}
}
Timber.v("## SAS Verification live observer: received msgId: ${event.eventId} type: ${event.getClearType()}")
if (event.senderId == userId) {
// If it's send from me, we need to keep track of Requests or Start
// done from another device of mine
if (EventType.MESSAGE == event.type) {
val msgType = event.getClearContent().toModel<MessageContent>()?.type
if (MessageType.MSGTYPE_VERIFICATION_REQUEST == msgType) {
event.getClearContent().toModel<MessageVerificationRequestContent>()?.let {
if (it.fromDevice != deviceId) {
// The verification is requested from another device
Timber.v("## SAS Verification live observer: Transaction requested from other device tid:${event.eventId} ")
event.eventId?.let { txId -> transactionsHandledByOtherDevice.add(txId) }
}
}
}
} else if (EventType.KEY_VERIFICATION_START == event.type) {
event.getClearContent().toModel<MessageVerificationStartContent>()?.let {
if (it.fromDevice != deviceId) {
// The verification is started from another device
Timber.v("## SAS Verification live observer: Transaction started by other device tid:${it.transactionID} ")
it.transactionID?.let { txId -> transactionsHandledByOtherDevice.add(txId) }
}
}
} else if (EventType.KEY_VERIFICATION_CANCEL == event.type || EventType.KEY_VERIFICATION_DONE == event.type) {
event.getClearContent().toModel<MessageRelationContent>()?.relatesTo?.eventId?.let {
transactionsHandledByOtherDevice.remove(it)
}
}
return@forEach
}
val relatesTo = event.getClearContent().toModel<MessageRelationContent>()?.relatesTo?.eventId
if (relatesTo != null && transactionsHandledByOtherDevice.contains(relatesTo)) {
// Ignore this event, it is directed to another of my devices
Timber.v("## SAS Verification live observer: Ignore Transaction handled by other device tid:$relatesTo ")
return@forEach
}
when (event.getClearType()) {
EventType.KEY_VERIFICATION_START,
EventType.KEY_VERIFICATION_ACCEPT,

View file

@ -25,6 +25,13 @@ import javax.inject.Qualifier
@Retention(AnnotationRetention.RUNTIME)
internal annotation class UserId
/**
* Used to inject the userId
*/
@Qualifier
@Retention(AnnotationRetention.RUNTIME)
internal annotation class DeviceId
/**
* Used to inject the md5 of the userId
*/

View file

@ -77,6 +77,13 @@ internal abstract class SessionModule {
return credentials.userId
}
@JvmStatic
@DeviceId
@Provides
fun providesDeviceId(credentials: Credentials): String? {
return credentials.deviceId
}
@JvmStatic
@UserMd5
@Provides