Fix / Test crash when crypto DB closed

Quick Work around
This commit is contained in:
Valere 2020-02-24 10:57:41 +01:00 committed by Benoit Marty
parent d537abc522
commit c579de1033
1 changed files with 26 additions and 25 deletions

View File

@ -27,9 +27,11 @@ import im.vector.matrix.android.internal.util.createBackgroundHandler
import io.realm.Realm import io.realm.Realm
import io.realm.RealmConfiguration import io.realm.RealmConfiguration
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.Subscribe
import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicBoolean
import timber.log.Timber
import java.util.concurrent.atomic.AtomicReference import java.util.concurrent.atomic.AtomicReference
import javax.inject.Inject import javax.inject.Inject
@ -47,7 +49,6 @@ internal class ShieldTrustUpdater @Inject constructor(
private val BACKGROUND_HANDLER = createBackgroundHandler("SHIELD_CRYPTO_DB_THREAD") private val BACKGROUND_HANDLER = createBackgroundHandler("SHIELD_CRYPTO_DB_THREAD")
} }
private val backgroundCryptoRealm = AtomicReference<Realm>()
private val backgroundSessionRealm = AtomicReference<Realm>() private val backgroundSessionRealm = AtomicReference<Realm>()
private val isStarted = AtomicBoolean() private val isStarted = AtomicBoolean()
@ -65,11 +66,6 @@ internal class ShieldTrustUpdater @Inject constructor(
if (isStarted.compareAndSet(false, true)) { if (isStarted.compareAndSet(false, true)) {
eventBus.register(this) eventBus.register(this)
BACKGROUND_HANDLER.post { BACKGROUND_HANDLER.post {
val cryptoRealm = Realm.getInstance(cryptoRealmConfiguration)
backgroundCryptoRealm.set(cryptoRealm)
// cryptoDevicesResult = cryptoRealm.where<DeviceInfoEntity>().findAll()
// cryptoDevicesResult?.addChangeListener(cryptoDeviceChangeListener)
backgroundSessionRealm.set(Realm.getInstance(sessionRealmConfiguration)) backgroundSessionRealm.set(Realm.getInstance(sessionRealmConfiguration))
} }
} }
@ -79,10 +75,6 @@ internal class ShieldTrustUpdater @Inject constructor(
if (isStarted.compareAndSet(true, false)) { if (isStarted.compareAndSet(true, false)) {
eventBus.unregister(this) eventBus.unregister(this)
BACKGROUND_HANDLER.post { BACKGROUND_HANDLER.post {
// cryptoDevicesResult?.removeAllChangeListeners()
backgroundCryptoRealm.getAndSet(null).also {
it?.close()
}
backgroundSessionRealm.getAndSet(null).also { backgroundSessionRealm.getAndSet(null).also {
it?.close() it?.close()
} }
@ -118,31 +110,40 @@ internal class ShieldTrustUpdater @Inject constructor(
private fun onCryptoDevicesChange(users: List<String>) { private fun onCryptoDevicesChange(users: List<String>) {
BACKGROUND_HANDLER.post { BACKGROUND_HANDLER.post {
val impactedRoomsId = backgroundSessionRealm.get().where(RoomMemberSummaryEntity::class.java) val impactedRoomsId = backgroundSessionRealm.get()?.where(RoomMemberSummaryEntity::class.java)
.`in`(RoomMemberSummaryEntityFields.USER_ID, users.toTypedArray()) ?.`in`(RoomMemberSummaryEntityFields.USER_ID, users.toTypedArray())
.findAll() ?.findAll()
.map { it.roomId } ?.map { it.roomId }
.distinct() ?.distinct()
val map = HashMap<String, List<String>>() val map = HashMap<String, List<String>>()
impactedRoomsId.forEach { roomId -> impactedRoomsId?.forEach { roomId ->
RoomMemberSummaryEntity.where(backgroundSessionRealm.get(), roomId) backgroundSessionRealm.get()?.let { realm ->
RoomMemberSummaryEntity.where(realm, roomId)
.findAll() .findAll()
.let { results -> .let { results ->
map[roomId] = results.map { it.userId } map[roomId] = results.map { it.userId }
} }
} }
}
map.forEach { entry -> map.forEach { entry ->
val roomId = entry.key val roomId = entry.key
val userList = entry.value val userList = entry.value
taskExecutor.executorScope.launch { taskExecutor.executorScope.launch {
withContext(coroutineDispatchers.crypto) {
try {
// Can throw if the crypto database has been closed in between, in this case log and ignore?
val updatedTrust = computeTrustTask.execute(ComputeTrustTask.Params(userList)) val updatedTrust = computeTrustTask.execute(ComputeTrustTask.Params(userList))
BACKGROUND_HANDLER.post { BACKGROUND_HANDLER.post {
backgroundSessionRealm.get()?.executeTransaction { realm -> backgroundSessionRealm.get()?.executeTransaction { realm ->
roomSummaryUpdater.updateShieldTrust(realm, roomId, updatedTrust) roomSummaryUpdater.updateShieldTrust(realm, roomId, updatedTrust)
} }
} }
} catch (failure: Throwable) {
Timber.e(failure)
}
}
} }
} }
} }