From 5ef2341bec22d44e3f0fea487e67564426c4de89 Mon Sep 17 00:00:00 2001 From: SpiritCroc Date: Sun, 2 Apr 2023 12:32:49 +0200 Subject: [PATCH] [TEST] Fix another case of wrong read receipt location, to be observed Context: https://github.com/SchildiChat/SchildiChat-android-rageshakes/issues/995 So comparing timestamps for main vs null read receipts does not seem to work at all... so better only use that as fallback in case we really don't know which event came later...? Change-Id: I8f7df95735d1478784ec5f8bf3b0b1a70c534a29 --- .../sdk/internal/database/helper/ChunkEntityHelper.kt | 5 ++++- .../internal/session/sync/handler/room/ReadReceiptHandler.kt | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ChunkEntityHelper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ChunkEntityHelper.kt index aa068bfede..03a71ab376 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ChunkEntityHelper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ChunkEntityHelper.kt @@ -146,16 +146,19 @@ private fun handleReadReceipts(realm: Realm, roomId: String, eventEntity: EventE } receiptDestinations.forEach { rootThreadEventId -> val readReceiptOfSender = ReadReceiptEntity.getOrCreate(realm, roomId = roomId, userId = senderId, threadId = rootThreadEventId) + val shouldForceMon: Boolean val shouldSkipMon = if (rootThreadEventId == THREAD_ID_MAIN_OR_NULL) { val previousReceiptsSummary = ReadReceiptsSummaryEntity.where(realm, eventId = readReceiptOfSender.eventId).findFirst() val oldEventTs = previousReceiptsSummary?.let { EventEntity.where(realm, roomId, it.eventId).findFirst()?.originServerTs } val newEventTs = EventEntity.where(realm, roomId, eventEntity.eventId).findFirst()?.originServerTs + shouldForceMon = oldEventTs != null && newEventTs != null && oldEventTs < newEventTs oldEventTs != null && newEventTs != null && oldEventTs > newEventTs } else { + shouldForceMon = false false } // If the synced RR is older, update - if (timestampOfEvent > readReceiptOfSender.originServerTs && !shouldSkipMon) { + if (shouldForceMon || (timestampOfEvent > readReceiptOfSender.originServerTs && !shouldSkipMon)) { val previousReceiptsSummary = ReadReceiptsSummaryEntity.where(realm, eventId = readReceiptOfSender.eventId).findFirst() rrDimber.i { "Handle outdated chunk RR $roomId / $senderId thread $rootThreadEventId(${eventEntity.rootThreadEventId}): event ${readReceiptOfSender.eventId} -> ${eventEntity.eventId}" } readReceiptOfSender.eventId = eventEntity.eventId diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/ReadReceiptHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/ReadReceiptHandler.kt index 49f8e46f7d..d63cedb5c9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/ReadReceiptHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/ReadReceiptHandler.kt @@ -172,15 +172,18 @@ internal class ReadReceiptHandler @Inject constructor( } receiptDestinations.forEach { threadId -> val receiptEntity = ReadReceiptEntity.getOrCreate(realm, roomId, userId, threadId) + val shouldForceMon: Boolean val shouldSkipMon = if (threadId == THREAD_ID_MAIN_OR_NULL) { val oldEventTs = EventEntity.where(realm, roomId, receiptEntity.eventId).findFirst()?.originServerTs val newEventTs = EventEntity.where(realm, roomId, eventId).findFirst()?.originServerTs + shouldForceMon = oldEventTs != null && newEventTs != null && oldEventTs < newEventTs oldEventTs != null && newEventTs != null && oldEventTs > newEventTs } else { + shouldForceMon = false false } // ensure new ts is superior to the previous one - if (ts > receiptEntity.originServerTs && !shouldSkipMon) { + if (shouldForceMon || (ts > receiptEntity.originServerTs && !shouldSkipMon)) { rrDimber.i { "Handle outdated sync RR $roomId / $userId thread $threadId($syncedThreadId): event ${receiptEntity.eventId} -> $eventId" } ReadReceiptsSummaryEntity.where(realm, receiptEntity.eventId).findFirst()?.also { it.readReceipts.remove(receiptEntity)