diff --git a/changelog.d/5421.bugfix b/changelog.d/5421.bugfix new file mode 100644 index 0000000000..2f9a1c0b1c --- /dev/null +++ b/changelog.d/5421.bugfix @@ -0,0 +1 @@ +Fixes crash when accepting or receiving VOIP calls 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 b057b4c319..751992fa7f 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 @@ -19,6 +19,9 @@ package org.matrix.android.sdk.internal.database import com.zhuinden.monarchy.Monarchy import io.realm.RealmConfiguration import io.realm.RealmResults +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import org.matrix.android.sdk.internal.database.mapper.asDomain import org.matrix.android.sdk.internal.database.model.EventEntity @@ -38,10 +41,22 @@ internal class EventInsertLiveObserver @Inject constructor(@SessionDatabase real it.where(EventInsertEntity::class.java).equalTo(EventInsertEntityFields.CAN_BE_PROCESSED, true) } + private val onResultsChangedFlow = MutableSharedFlow>() + + init { + onResultsChangedFlow + .onEach { handleChange(it) } + .launchIn(observerScope) + } + override fun onChange(results: RealmResults) { if (!results.isLoaded || results.isEmpty()) { return } + observerScope.launch { onResultsChangedFlow.emit(results) } + } + + private suspend fun handleChange(results: RealmResults) { val idsToDeleteAfterProcess = ArrayList() val filteredEvents = ArrayList(results.size) Timber.v("EventInsertEntity updated with ${results.size} results in db") @@ -58,30 +73,29 @@ internal class EventInsertLiveObserver @Inject constructor(@SessionDatabase real } idsToDeleteAfterProcess.add(it.eventId) } - observerScope.launch { - awaitTransaction(realmConfiguration) { realm -> - Timber.v("##Transaction: There are ${filteredEvents.size} events to process ") - filteredEvents.forEach { eventInsert -> - val eventId = eventInsert.eventId - val event = EventEntity.where(realm, eventId).findFirst() - if (event == null) { - Timber.v("Event $eventId not found") - return@forEach - } - val domainEvent = event.asDomain() - processors.filter { - it.shouldProcess(eventId, domainEvent.getClearType(), eventInsert.insertType) - }.forEach { - it.process(realm, domainEvent) - } + + awaitTransaction(realmConfiguration) { realm -> + Timber.v("##Transaction: There are ${filteredEvents.size} events to process ") + filteredEvents.forEach { eventInsert -> + val eventId = eventInsert.eventId + val event = EventEntity.where(realm, eventId).findFirst() + if (event == null) { + Timber.v("Event $eventId not found") + return@forEach + } + val domainEvent = event.asDomain() + processors.filter { + it.shouldProcess(eventId, domainEvent.getClearType(), eventInsert.insertType) + }.forEach { + it.process(realm, domainEvent) } - realm.where(EventInsertEntity::class.java) - .`in`(EventInsertEntityFields.EVENT_ID, idsToDeleteAfterProcess.toTypedArray()) - .findAll() - .deleteAllFromRealm() } - processors.forEach { it.onPostProcess() } + realm.where(EventInsertEntity::class.java) + .`in`(EventInsertEntityFields.EVENT_ID, idsToDeleteAfterProcess.toTypedArray()) + .findAll() + .deleteAllFromRealm() } + processors.forEach { it.onPostProcess() } } private fun shouldProcess(eventInsertEntity: EventInsertEntity): Boolean {