Add read receipt debugging

Change-Id: I2cd0b5feb23962bc36295380fe3e77346f0ea694
This commit is contained in:
SpiritCroc 2022-12-15 10:35:21 +01:00
parent ed3049f04e
commit aa9e0bc627
11 changed files with 40 additions and 2 deletions

View File

@ -162,6 +162,7 @@
<string name="settings_sc_dbg_timeline_chunks">Timeline consistency debugging</string>
<string name="settings_sc_dbg_show_display_index">Show displayIndex in timeline</string>
<string name="settings_sc_dbg_show_read_tracking">Show read tracking</string>
<string name="settings_sc_dbg_read_receipts">Read receipt debugging</string>
<string name="settings_sc_dbg_view_pager">ViewPager debugging</string>
<string name="settings_sc_dbg_view_pager_visuals">Show ViewPager debugging information</string>

View File

@ -8,6 +8,7 @@ import timber.log.Timber
object DbgUtil {
const val DBG_READ_MARKER = "DBG_READ_MARKER"
const val DBG_SHOW_READ_TRACKING = "DBG_SHOW_READ_TRACKING"
const val DBG_READ_RECEIPTS = "DBG_READ_RECEIPTS"
const val DBG_TIMELINE_CHUNKS = "DBG_TIMELINE_CHUNKS"
const val DBG_SHOW_DISPLAY_INDEX = "DBG_SHOW_DISPLAY_INDEX"
const val DBG_VIEW_PAGER = "DBG_VIEW_PAGER"
@ -18,6 +19,7 @@ object DbgUtil {
val ALL_PREFS = arrayOf(
DBG_READ_MARKER,
DBG_SHOW_READ_TRACKING,
DBG_READ_RECEIPTS,
DBG_TIMELINE_CHUNKS,
DBG_SHOW_DISPLAY_INDEX,
DBG_VIEW_PAGER,

View File

@ -16,6 +16,7 @@
package org.matrix.android.sdk.internal.database.helper
import de.spiritcroc.matrixsdk.util.DbgUtil
import de.spiritcroc.matrixsdk.util.Dimber
import io.realm.Realm
import io.realm.kotlin.createObject
@ -125,6 +126,8 @@ internal fun computeIsUnique(
}
}
val rrDimber = Dimber("ReadReceipts", DbgUtil.DBG_READ_RECEIPTS)
private fun handleReadReceipts(realm: Realm, roomId: String, eventEntity: EventEntity, senderId: String): ReadReceiptsSummaryEntity {
val readReceiptsSummaryEntity = ReadReceiptsSummaryEntity.where(realm, eventEntity.eventId).findFirst()
?: realm.createObject<ReadReceiptsSummaryEntity>(eventEntity.eventId).apply {
@ -137,10 +140,13 @@ private fun handleReadReceipts(realm: Realm, roomId: String, eventEntity: EventE
// If the synced RR is older, update
if (timestampOfEvent > readReceiptOfSender.originServerTs) {
val previousReceiptsSummary = ReadReceiptsSummaryEntity.where(realm, eventId = readReceiptOfSender.eventId).findFirst()
rrDimber.i{"Handle outdated chunk RR $roomId / $senderId thread ${eventEntity.rootThreadEventId}: event ${readReceiptOfSender.eventId} -> ${eventEntity.eventId}"}
readReceiptOfSender.eventId = eventEntity.eventId
readReceiptOfSender.originServerTs = timestampOfEvent
previousReceiptsSummary?.readReceipts?.remove(readReceiptOfSender)
readReceiptsSummaryEntity.readReceipts.add(readReceiptOfSender)
} else {
rrDimber.i{"Handled chunk RR $roomId / $senderId thread ${eventEntity.rootThreadEventId}: keep ${readReceiptOfSender.eventId} (not ${eventEntity.eventId})"}
}
}
return readReceiptsSummaryEntity

View File

@ -16,6 +16,8 @@
package org.matrix.android.sdk.internal.database.mapper
import de.spiritcroc.matrixsdk.util.DbgUtil
import de.spiritcroc.matrixsdk.util.Dimber
import io.realm.Realm
import io.realm.RealmList
import org.matrix.android.sdk.api.session.room.model.ReadReceipt
@ -30,6 +32,8 @@ internal class ReadReceiptsSummaryMapper @Inject constructor(
private val realmSessionProvider: RealmSessionProvider
) {
val rrDimber = Dimber("ReadReceipts", DbgUtil.DBG_READ_RECEIPTS)
fun map(readReceiptsSummaryEntity: ReadReceiptsSummaryEntity?): List<ReadReceipt> {
if (readReceiptsSummaryEntity == null) {
return emptyList()
@ -48,6 +52,7 @@ internal class ReadReceiptsSummaryMapper @Inject constructor(
private fun map(readReceipts: RealmList<ReadReceiptEntity>, realm: Realm): List<ReadReceipt> {
return readReceipts
.mapNotNull {
rrDimber.i{"Map ${it.eventId} receipt ${it.userId} thread ${it.threadId}"}
val roomMember = RoomMemberSummaryEntity.where(realm, roomId = it.roomId, userId = it.userId).findFirst()
?: return@mapNotNull null
ReadReceipt(roomMember.asDomain(), it.originServerTs.toLong(), it.threadId)

View File

@ -16,6 +16,8 @@
package org.matrix.android.sdk.internal.session.sync.handler.room
import de.spiritcroc.matrixsdk.util.DbgUtil
import de.spiritcroc.matrixsdk.util.Dimber
import io.realm.Realm
import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.internal.database.model.ReadReceiptEntity
@ -43,6 +45,8 @@ internal class ReadReceiptHandler @Inject constructor(
private val roomSyncEphemeralTemporaryStore: RoomSyncEphemeralTemporaryStore
) {
val rrDimber = Dimber("ReadReceipts", DbgUtil.DBG_READ_RECEIPTS)
companion object {
fun createContent(
@ -107,6 +111,7 @@ internal class ReadReceiptHandler @Inject constructor(
val ts = paramsDict[TIMESTAMP_KEY] as? Double ?: 0.0
val threadId = paramsDict[THREAD_ID_KEY] as String?
val receiptEntity = ReadReceiptEntity.createUnmanaged(roomId, eventId, userId, threadId, ts)
rrDimber.i{"Handle initial sync RR $roomId / $userId thread $threadId: event $eventId"}
readReceiptsSummary.readReceipts.add(receiptEntity)
}
readReceiptSummaries.add(readReceiptsSummary)
@ -144,12 +149,15 @@ internal class ReadReceiptHandler @Inject constructor(
val receiptEntity = ReadReceiptEntity.getOrCreate(realm, roomId, userId, threadId)
// ensure new ts is superior to the previous one
if (ts > receiptEntity.originServerTs) {
rrDimber.i{"Handle outdated sync RR $roomId / $userId thread $threadId: event ${receiptEntity.eventId} -> $eventId"}
ReadReceiptsSummaryEntity.where(realm, receiptEntity.eventId).findFirst()?.also {
it.readReceipts.remove(receiptEntity)
}
receiptEntity.eventId = eventId
receiptEntity.originServerTs = ts
readReceiptsSummary.readReceipts.add(receiptEntity)
} else {
rrDimber.i{"Handle keep sync RR $roomId / $userId thread $threadId: event ${receiptEntity.eventId} (not $eventId)"}
}
}
}

View File

@ -26,6 +26,7 @@ import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.extensions.setTextOrHide
import im.vector.app.features.displayname.getBestName
import im.vector.app.features.home.AvatarRenderer
import org.matrix.android.sdk.api.util.MatrixItem
@ -37,11 +38,13 @@ abstract class DisplayReadReceiptItem : VectorEpoxyModel<DisplayReadReceiptItem.
@EpoxyAttribute var timestamp: String? = null
@EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var userClicked: ClickListener? = null
@EpoxyAttribute var debugInfo: String? = null
override fun bind(holder: Holder) {
super.bind(holder)
avatarRenderer.render(matrixItem, holder.avatarView)
holder.displayNameView.text = matrixItem.getBestName()
holder.debugView.setTextOrHide(debugInfo)
timestamp?.let {
holder.timestampView.text = it
holder.timestampView.isVisible = true
@ -54,6 +57,7 @@ abstract class DisplayReadReceiptItem : VectorEpoxyModel<DisplayReadReceiptItem.
class Holder : VectorEpoxyHolder() {
val avatarView by bind<ImageView>(R.id.readReceiptAvatar)
val displayNameView by bind<TextView>(R.id.readReceiptName)
val debugView by bind<TextView>(R.id.readReceiptDebugAdd)
val timestampView by bind<TextView>(R.id.readReceiptDate)
}
}

View File

@ -17,6 +17,7 @@
package im.vector.app.features.home.room.detail.readreceipts
import com.airbnb.epoxy.TypedEpoxyController
import de.spiritcroc.matrixsdk.util.DbgUtil
import im.vector.app.core.date.DateFormatKind
import im.vector.app.core.date.VectorDateFormatter
import im.vector.app.features.home.AvatarRenderer
@ -43,6 +44,7 @@ class DisplayReadReceiptsController @Inject constructor(
DisplayReadReceiptItem_()
.id(readReceiptData.userId)
.matrixItem(readReceiptData.toMatrixItem())
.debugInfo(readReceiptData.threadId.toString().takeIf { DbgUtil.isDbgEnabled(DbgUtil.DBG_READ_RECEIPTS) })
.avatarRenderer(avatarRender)
.timestamp(timestamp)
.userClicked { listener?.didSelectUser(readReceiptData.userId) }

View File

@ -45,7 +45,7 @@ class ReadReceiptsItemFactory @Inject constructor(
}
val readReceiptsData = readReceipts
.map {
ReadReceiptData(it.roomMember.userId, it.roomMember.avatarUrl, it.roomMember.displayName, it.originServerTs)
ReadReceiptData(it.roomMember.userId, it.roomMember.avatarUrl, it.roomMember.displayName, it.originServerTs, it.threadId)
}
.sortedByDescending { it.timestamp }
val threadReadReceiptsSupported = session.homeServerCapabilitiesService().getHomeServerCapabilities().canUseThreadReadReceiptsAndNotifications

View File

@ -88,7 +88,8 @@ data class ReadReceiptData(
val userId: String,
val avatarUrl: String?,
val displayName: String?,
val timestamp: Long
val timestamp: Long,
val threadId: String?,
) : Parcelable
@Parcelize

View File

@ -20,6 +20,7 @@ class VectorSettingsScDebuggingFragment @Inject constructor(
DbgPref(DbgUtil.DBG_SHOW_DISPLAY_INDEX, R.string.settings_sc_dbg_show_display_index),
DbgPref(DbgUtil.DBG_READ_MARKER, R.string.settings_sc_dbg_read_marker),
DbgPref(DbgUtil.DBG_SHOW_READ_TRACKING, R.string.settings_sc_dbg_show_read_tracking),
DbgPref(DbgUtil.DBG_READ_RECEIPTS, R.string.settings_sc_dbg_read_receipts),
DbgPref(DbgUtil.DBG_VIEW_PAGER, R.string.settings_sc_dbg_view_pager),
DbgPref(DbgUtil.DBG_VIEW_PAGER_VISUALS, R.string.settings_sc_dbg_view_pager_visuals),
)

View File

@ -24,6 +24,14 @@
style="@style/BottomSheetItemTextMain"
tools:text="@sample/users.json/data/displayName" />
<TextView
android:id="@+id/readReceiptDebugAdd"
style="@style/BottomSheetItemTextSecondary"
android:maxLines="1"
android:ellipsize="end"
android:layout_marginHorizontal="8dp"
tools:text="@sample/messages.json/data/message" />
<TextView
android:id="@+id/readReceiptDate"
style="@style/BottomSheetItemTime"