diff --git a/matrix-sdk-android/src/main/java/de/spiritcroc/matrixsdk/StaticScSdkHelper.kt b/matrix-sdk-android/src/main/java/de/spiritcroc/matrixsdk/StaticScSdkHelper.kt index 458c0b2150..b9ce614c91 100644 --- a/matrix-sdk-android/src/main/java/de/spiritcroc/matrixsdk/StaticScSdkHelper.kt +++ b/matrix-sdk-android/src/main/java/de/spiritcroc/matrixsdk/StaticScSdkHelper.kt @@ -15,6 +15,7 @@ package de.spiritcroc.matrixsdk fun roomUnreadKind(isDirect: Boolean): Int fun aggregateUnreadRoomCounts(): Boolean fun includeSpaceMembersAsSpaceRooms(): Boolean + fun annoyDevelopersWithToast(text: String) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt index 5de7a526e6..5ff7282b01 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt @@ -16,6 +16,7 @@ package org.matrix.android.sdk.internal.session.room.timeline +import de.spiritcroc.matrixsdk.StaticScSdkHelper import io.realm.Realm import io.realm.RealmConfiguration import kotlinx.coroutines.CoroutineScope @@ -296,9 +297,13 @@ internal class DefaultTimeline(private val roomId: String, private suspend fun postSnapshot() { val snapshot = strategy.buildSnapshot() Timber.v("Post snapshot of ${snapshot.size} events") - // Async debugging to not slow down things + // Async debugging to not slow down things too much timelineScope.launch(coroutineDispatchers.computation) { - checkTimelineConsistency("DefaultTimeline.postSnapshot", snapshot) + checkTimelineConsistency("DefaultTimeline.postSnapshot", snapshot) { msg -> + timelineScope.launch(coroutineDispatchers.main) { + StaticScSdkHelper.scSdkPreferenceProvider?.annoyDevelopersWithToast(msg) + } + } } withContext(coroutineDispatchers.main) { listeners.forEach { @@ -388,13 +393,14 @@ internal class DefaultTimeline(private val roomId: String, } } -fun checkTimelineConsistency(location: String, events: List) { +fun checkTimelineConsistency(location: String, events: List, sendToastFunction: (String) -> Unit = {}) { Timber.i("Check timeline consistency from $location for ${events.size} events, from ${events.firstOrNull()?.eventId} to ${events.lastOrNull()?.eventId}") try { var potentialIssues = 0 // Note that the "previous" event is actually newer than the currently looked at event, // since the list is ordered from new to old var prev: TimelineEvent? = null + var toastMsg = "" for (i in events.indices) { val event = events[i] if (prev != null) { @@ -409,11 +415,18 @@ fun checkTimelineConsistency(location: String, events: List) { // - Events between two chunks lead to a new indexing, so one may start at 1, or even something negative. // - The list may omit unsupported events (I guess?), thus causing gaps in the indices. Timber.w("Possible timeline inconsistency found at $location, $i/${events.size}: ${event.displayIndex}->${prev.displayIndex}, ${event.eventId} -> ${prev.eventId}") + // Toast only those which are particularly suspicious + if (prev.displayIndex != 1 && prev.displayIndex >= event.displayIndex) { + toastMsg += "${event.displayIndex}->${prev.displayIndex}," + } potentialIssues++ } } prev = event } + if (toastMsg.isNotEmpty()) { + sendToastFunction(toastMsg.substring(0, toastMsg.length-1)) + } Timber.i("Done check timeline consistency from $location, found $potentialIssues possible issues") } catch (t: Throwable) { Timber.e("Failed check timeline consistency from $location", t) diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt b/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt index 65c3760368..22e053fc22 100755 --- a/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt @@ -21,6 +21,7 @@ import android.media.RingtoneManager import android.net.Uri import android.os.Build import android.provider.MediaStore +import android.widget.Toast import androidx.annotation.BoolRes import androidx.core.content.edit import com.squareup.seismic.ShakeDetector @@ -983,6 +984,16 @@ class VectorPreferences @Inject constructor(private val context: Context, privat return defaultPrefs.getBoolean(SETTINGS_SPACE_MEMBERS_IN_SPACE_ROOMS, false) } + var prevToast: Toast? = null + override fun annoyDevelopersWithToast(text: String) { + if (developerShowDebugInfo()) { + prevToast?.cancel() + prevToast = Toast.makeText(context, text, Toast.LENGTH_LONG).also { + it.show() + } + } + } + // SC addition fun simplifiedMode(): Boolean { return defaultPrefs.getBoolean(SETTINGS_SIMPLIFIED_MODE, false)