From 2e2deba3ac7f3f7fefce4d039f875b789b46af1f Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 24 Aug 2021 19:58:54 +0200 Subject: [PATCH] Fix message edition is not rendered in e2e rooms after pagination (#3887) --- changelog.d/3887.bugfix | 1 + .../database/EventInsertLiveObserver.kt | 31 ++++--------------- .../database/RealmSessionStoreMigration.kt | 10 +++++- .../internal/database/model/EventEntity.kt | 10 +++++- .../database/model/EventInsertEntity.kt | 7 ++++- .../database/query/EventEntityQueries.kt | 4 ++- .../session/room/send/LocalEchoRepository.kt | 2 +- .../room/timeline/TimelineEventDecryptor.kt | 3 +- 8 files changed, 37 insertions(+), 31 deletions(-) create mode 100644 changelog.d/3887.bugfix diff --git a/changelog.d/3887.bugfix b/changelog.d/3887.bugfix new file mode 100644 index 0000000000..eecd2cea19 --- /dev/null +++ b/changelog.d/3887.bugfix @@ -0,0 +1 @@ +Message edition is not rendered in e2e rooms after pagination \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/EventInsertLiveObserver.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/EventInsertLiveObserver.kt index 88aa432fb3..758c7aa5b9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/EventInsertLiveObserver.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/EventInsertLiveObserver.kt @@ -17,6 +17,9 @@ package org.matrix.android.sdk.internal.database import com.zhuinden.monarchy.Monarchy +import io.realm.RealmConfiguration +import io.realm.RealmResults +import kotlinx.coroutines.launch import org.matrix.android.sdk.internal.database.mapper.asDomain import org.matrix.android.sdk.internal.database.model.EventEntity import org.matrix.android.sdk.internal.database.model.EventInsertEntity @@ -24,20 +27,15 @@ import org.matrix.android.sdk.internal.database.model.EventInsertEntityFields import org.matrix.android.sdk.internal.database.query.where import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.session.EventInsertLiveProcessor -import io.realm.RealmConfiguration -import io.realm.RealmResults -import kotlinx.coroutines.launch -import org.matrix.android.sdk.internal.crypto.EventDecryptor import timber.log.Timber import javax.inject.Inject internal class EventInsertLiveObserver @Inject constructor(@SessionDatabase realmConfiguration: RealmConfiguration, - private val processors: Set<@JvmSuppressWildcards EventInsertLiveProcessor>, - private val eventDecryptor: EventDecryptor) + private val processors: Set<@JvmSuppressWildcards EventInsertLiveProcessor>) : RealmLiveEntityObserver(realmConfiguration) { - override val query = Monarchy.Query { - it.where(EventInsertEntity::class.java) + override val query = Monarchy.Query { + it.where(EventInsertEntity::class.java).equalTo(EventInsertEntityFields.CAN_BE_PROCESSED, true) } override fun onChange(results: RealmResults) { @@ -86,23 +84,6 @@ internal class EventInsertLiveObserver @Inject constructor(@SessionDatabase real } } -// private fun decryptIfNeeded(event: Event) { -// if (event.isEncrypted() && event.mxDecryptionResult == null) { -// try { -// val result = eventDecryptor.decryptEvent(event, event.roomId ?: "") -// event.mxDecryptionResult = OlmDecryptionResult( -// payload = result.clearEvent, -// senderKey = result.senderCurve25519Key, -// keysClaimed = result.claimedEd25519Key?.let { k -> mapOf("ed25519" to k) }, -// forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain -// ) -// } catch (e: MXCryptoError) { -// Timber.v("Failed to decrypt event") -// // TODO -> we should keep track of this and retry, or some processing will never be handled -// } -// } -// } - private fun shouldProcess(eventInsertEntity: EventInsertEntity): Boolean { return processors.any { it.shouldProcess(eventInsertEntity.eventId, eventInsertEntity.eventType, eventInsertEntity.insertType) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt index 28ae4d8bfd..aa96ca5e1a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt @@ -29,6 +29,7 @@ import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntityFie import org.matrix.android.sdk.internal.database.model.EditAggregatedSummaryEntityFields import org.matrix.android.sdk.internal.database.model.EditionOfEventFields import org.matrix.android.sdk.internal.database.model.EventEntityFields +import org.matrix.android.sdk.internal.database.model.EventInsertEntityFields import org.matrix.android.sdk.internal.database.model.HomeServerCapabilitiesEntityFields import org.matrix.android.sdk.internal.database.model.PendingThreePidEntityFields import org.matrix.android.sdk.internal.database.model.PreviewUrlCacheEntityFields @@ -46,7 +47,7 @@ import timber.log.Timber internal object RealmSessionStoreMigration : RealmMigration { - const val SESSION_STORE_SCHEMA_VERSION = 16L + const val SESSION_STORE_SCHEMA_VERSION = 17L override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) { Timber.v("Migrating Realm Session from $oldVersion to $newVersion") @@ -67,6 +68,7 @@ internal object RealmSessionStoreMigration : RealmMigration { if (oldVersion <= 13) migrateTo14(realm) if (oldVersion <= 14) migrateTo15(realm) if (oldVersion <= 15) migrateTo16(realm) + if (oldVersion <= 16) migrateTo17(realm) } private fun migrateTo1(realm: DynamicRealm) { @@ -330,4 +332,10 @@ internal object RealmSessionStoreMigration : RealmMigration { obj.setLong(HomeServerCapabilitiesEntityFields.LAST_UPDATED_TIMESTAMP, 0) } } + + private fun migrateTo17(realm: DynamicRealm) { + Timber.d("Step 16 -> 17") + realm.schema.get("EventInsertEntity") + ?.addField(EventInsertEntityFields.CAN_BE_PROCESSED, Boolean::class.java) + } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/EventEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/EventEntity.kt index c9edbcd889..4dc8712afb 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/EventEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/EventEntity.kt @@ -22,6 +22,7 @@ import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult import org.matrix.android.sdk.internal.di.MoshiProvider import io.realm.RealmObject import io.realm.annotations.Index +import org.matrix.android.sdk.internal.extensions.assertIsManaged internal open class EventEntity(@Index var eventId: String = "", @Index var roomId: String = "", @@ -56,15 +57,22 @@ internal open class EventEntity(@Index var eventId: String = "", companion object fun setDecryptionResult(result: MXEventDecryptionResult) { + assertIsManaged() val decryptionResult = OlmDecryptionResult( payload = result.clearEvent, senderKey = result.senderCurve25519Key, keysClaimed = result.claimedEd25519Key?.let { mapOf("ed25519" to it) }, forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain ) - val adapter = MoshiProvider.providesMoshi().adapter(OlmDecryptionResult::class.java) + val adapter = MoshiProvider.providesMoshi().adapter(OlmDecryptionResult::class.java) decryptionResultJson = adapter.toJson(decryptionResult) decryptionErrorCode = null decryptionErrorReason = null + + // If we have an EventInsertEntity for the eventId we make sures it can be processed now. + realm.where(EventInsertEntity::class.java) + .equalTo(EventInsertEntityFields.EVENT_ID, eventId) + .findFirst() + ?.canBeProcessed = true } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/EventInsertEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/EventInsertEntity.kt index f4426207be..5cfd306d2f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/EventInsertEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/EventInsertEntity.kt @@ -23,7 +23,12 @@ import io.realm.RealmObject * in EventEntity table. */ internal open class EventInsertEntity(var eventId: String = "", - var eventType: String = "" + var eventType: String = "", + /** + * This flag will be used to filter EventInsertEntity in EventInsertLiveObserver. + * Currently it's set to false when the event content is encrypted. + */ + var canBeProcessed: Boolean = true ) : RealmObject() { private var insertTypeStr: String = EventInsertType.INCREMENTAL_SYNC.name diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/EventEntityQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/EventEntityQueries.kt index 0bf62a19fe..57e24cf88f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/EventEntityQueries.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/EventEntityQueries.kt @@ -24,6 +24,7 @@ import io.realm.Realm import io.realm.RealmList import io.realm.RealmQuery import io.realm.kotlin.where +import org.matrix.android.sdk.api.session.events.model.EventType internal fun EventEntity.copyToRealmOrIgnore(realm: Realm, insertType: EventInsertType): EventEntity { val eventEntity = realm.where() @@ -31,7 +32,8 @@ internal fun EventEntity.copyToRealmOrIgnore(realm: Realm, insertType: EventInse .equalTo(EventEntityFields.ROOM_ID, roomId) .findFirst() return if (eventEntity == null) { - val insertEntity = EventInsertEntity(eventId = eventId, eventType = type).apply { + val canBeProcessed = type != EventType.ENCRYPTED || decryptionResultJson != null + val insertEntity = EventInsertEntity(eventId = eventId, eventType = type, canBeProcessed = canBeProcessed).apply { this.insertType = insertType } realm.insert(insertEntity) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoRepository.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoRepository.kt index e98e5646af..13095fbd58 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoRepository.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoRepository.kt @@ -77,7 +77,7 @@ internal class LocalEchoRepository @Inject constructor(@SessionDatabase private val timelineEvent = timelineEventMapper.map(timelineEventEntity) timelineInput.onLocalEchoCreated(roomId = roomId, timelineEvent = timelineEvent) taskExecutor.executorScope.asyncTransaction(monarchy) { realm -> - val eventInsertEntity = EventInsertEntity(event.eventId, event.type).apply { + val eventInsertEntity = EventInsertEntity(event.eventId, event.type, canBeProcessed = true).apply { this.insertType = EventInsertType.LOCAL_ECHO } realm.insert(eventInsertEntity) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineEventDecryptor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineEventDecryptor.kt index 3517f26c5d..721dae0b1b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineEventDecryptor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineEventDecryptor.kt @@ -106,7 +106,8 @@ internal class TimelineEventDecryptor @Inject constructor( val result = cryptoService.decryptEvent(request.event, timelineId) Timber.v("Successfully decrypted event ${event.eventId}") realm.executeTransaction { - EventEntity.where(it, eventId = event.eventId ?: "") + val eventId = event.eventId ?: "" + EventEntity.where(it, eventId = eventId) .findFirst() ?.setDecryptionResult(result) }