mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-11-25 02:45:53 +03:00
Merge pull request #5080 from vector-im/feature/adm/encrypted-last-message
Updating encrypted room list message previews on key updates
This commit is contained in:
commit
3aac59a5ae
12 changed files with 90 additions and 29 deletions
1
changelog.d/4867.bugfix
Normal file
1
changelog.d/4867.bugfix
Normal file
|
@ -0,0 +1 @@
|
|||
Fixes room summaries showing encrypted content after verifying device
|
|
@ -140,7 +140,6 @@ interface CryptoService {
|
|||
fun getLiveCryptoDeviceInfo(userIds: List<String>): LiveData<List<CryptoDeviceInfo>>
|
||||
|
||||
fun addNewSessionListener(newSessionListener: NewSessionListener)
|
||||
|
||||
fun removeSessionListener(listener: NewSessionListener)
|
||||
|
||||
fun getOutgoingRoomKeyRequests(): List<OutgoingRoomKeyRequest>
|
||||
|
|
|
@ -242,4 +242,12 @@ interface RoomService {
|
|||
*/
|
||||
fun getFlattenRoomSummaryChildrenOfLive(spaceId: String?,
|
||||
memberships: List<Membership> = Membership.activeMemberships()): LiveData<List<RoomSummary>>
|
||||
|
||||
/**
|
||||
* Refreshes the RoomSummary LatestPreviewContent for the given @param roomId
|
||||
* If the roomId is null, all rooms are updated
|
||||
*
|
||||
* This is useful for refreshing summary content with encrypted messages after receiving new room keys
|
||||
*/
|
||||
fun refreshJoinedRoomSummaryPreviews(roomId: String?)
|
||||
}
|
||||
|
|
|
@ -15,6 +15,15 @@
|
|||
*/
|
||||
package org.matrix.android.sdk.internal.crypto
|
||||
|
||||
/**
|
||||
* This listener notifies on new Megolm sessions being created
|
||||
*/
|
||||
interface NewSessionListener {
|
||||
|
||||
/**
|
||||
* @param roomId the room id where the new Megolm session has been created for, may be null when importing from external sessions
|
||||
* @param senderKey the sender key of the device which the Megolm session is shared with
|
||||
* @param sessionId the session id of the Megolm session
|
||||
*/
|
||||
fun onNewSession(roomId: String?, senderKey: String, sessionId: String)
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import org.matrix.android.sdk.internal.crypto.MXOlmDevice
|
|||
import org.matrix.android.sdk.internal.crypto.MegolmSessionData
|
||||
import org.matrix.android.sdk.internal.crypto.OutgoingGossipingRequestManager
|
||||
import org.matrix.android.sdk.internal.crypto.RoomDecryptorProvider
|
||||
import org.matrix.android.sdk.internal.crypto.algorithms.megolm.MXMegolmDecryption
|
||||
import org.matrix.android.sdk.internal.crypto.model.ImportRoomKeysResult
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyRequestBody
|
||||
import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore
|
||||
|
@ -76,7 +77,11 @@ internal class MegolmSessionDataImporter @Inject constructor(private val olmDevi
|
|||
outgoingGossipingRequestManager.cancelRoomKeyRequest(roomKeyRequestBody)
|
||||
|
||||
// Have another go at decrypting events sent with this session
|
||||
decrypting.onNewSession(megolmSessionData.senderKey!!, sessionId!!)
|
||||
when (decrypting) {
|
||||
is MXMegolmDecryption -> {
|
||||
decrypting.onNewSession(megolmSessionData.roomId, megolmSessionData.senderKey!!, sessionId!!)
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "## importRoomKeys() : onNewSession failed")
|
||||
}
|
||||
|
|
|
@ -45,14 +45,6 @@ internal interface IMXDecrypting {
|
|||
*/
|
||||
fun onRoomKeyEvent(event: Event, defaultKeysBackupService: DefaultKeysBackupService) {}
|
||||
|
||||
/**
|
||||
* Check if the some messages can be decrypted with a new session
|
||||
*
|
||||
* @param senderKey the session sender key
|
||||
* @param sessionId the session id
|
||||
*/
|
||||
fun onNewSession(senderKey: String, sessionId: String) {}
|
||||
|
||||
/**
|
||||
* Determine if we have the keys necessary to respond to a room key request
|
||||
*
|
||||
|
|
|
@ -318,19 +318,20 @@ internal class MXMegolmDecryption(private val userId: String,
|
|||
|
||||
outgoingGossipingRequestManager.cancelRoomKeyRequest(content)
|
||||
|
||||
onNewSession(senderKey, roomKeyContent.sessionId)
|
||||
onNewSession(roomKeyContent.roomId, senderKey, roomKeyContent.sessionId)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the some messages can be decrypted with a new session
|
||||
*
|
||||
* @param roomId the room id where the new Megolm session has been created for, may be null when importing from external sessions
|
||||
* @param senderKey the session sender key
|
||||
* @param sessionId the session id
|
||||
*/
|
||||
override fun onNewSession(senderKey: String, sessionId: String) {
|
||||
fun onNewSession(roomId: String?, senderKey: String, sessionId: String) {
|
||||
Timber.tag(loggerTag.value).v("ON NEW SESSION $sessionId - $senderKey")
|
||||
newSessionListener?.onNewSession(null, senderKey, sessionId)
|
||||
newSessionListener?.onNewSession(roomId, senderKey, sessionId)
|
||||
}
|
||||
|
||||
override fun hasKeysForKeyRequest(request: IncomingRoomKeyRequest): Boolean {
|
||||
|
|
|
@ -52,7 +52,7 @@ import timber.log.Timber
|
|||
import javax.inject.Inject
|
||||
|
||||
internal class UpdateTrustWorker(context: Context, params: WorkerParameters, sessionManager: SessionManager) :
|
||||
SessionSafeCoroutineWorker<UpdateTrustWorker.Params>(context, params, sessionManager, Params::class.java) {
|
||||
SessionSafeCoroutineWorker<UpdateTrustWorker.Params>(context, params, sessionManager, Params::class.java) {
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
internal data class Params(
|
||||
|
|
|
@ -49,6 +49,10 @@ internal fun RoomSummaryEntity.Companion.getOrCreate(realm: Realm, roomId: Strin
|
|||
return where(realm, roomId).findFirst() ?: realm.createObject(roomId)
|
||||
}
|
||||
|
||||
internal fun RoomSummaryEntity.Companion.getOrNull(realm: Realm, roomId: String): RoomSummaryEntity? {
|
||||
return where(realm, roomId).findFirst()
|
||||
}
|
||||
|
||||
internal fun RoomSummaryEntity.Companion.getDirectRooms(realm: Realm,
|
||||
excludeRoomIds: Set<String>? = null): RealmResults<RoomSummaryEntity> {
|
||||
return RoomSummaryEntity.where(realm)
|
||||
|
|
|
@ -20,6 +20,7 @@ import androidx.lifecycle.LiveData
|
|||
import androidx.lifecycle.Transformations
|
||||
import androidx.paging.PagedList
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import org.matrix.android.sdk.api.query.QueryStringValue
|
||||
import org.matrix.android.sdk.api.session.events.model.Event
|
||||
import org.matrix.android.sdk.api.session.room.Room
|
||||
import org.matrix.android.sdk.api.session.room.RoomService
|
||||
|
@ -32,6 +33,7 @@ import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
|
|||
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams
|
||||
import org.matrix.android.sdk.api.session.room.peeking.PeekResult
|
||||
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
|
||||
import org.matrix.android.sdk.api.session.room.summary.RoomAggregateNotificationCount
|
||||
import org.matrix.android.sdk.api.util.Optional
|
||||
import org.matrix.android.sdk.api.util.toOptional
|
||||
|
@ -51,6 +53,7 @@ import org.matrix.android.sdk.internal.session.room.peeking.PeekRoomTask
|
|||
import org.matrix.android.sdk.internal.session.room.peeking.ResolveRoomStateTask
|
||||
import org.matrix.android.sdk.internal.session.room.read.MarkAllRoomsReadTask
|
||||
import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryDataSource
|
||||
import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryUpdater
|
||||
import org.matrix.android.sdk.internal.session.user.accountdata.UpdateBreadcrumbsTask
|
||||
import org.matrix.android.sdk.internal.util.fetchCopied
|
||||
import javax.inject.Inject
|
||||
|
@ -69,6 +72,7 @@ internal class DefaultRoomService @Inject constructor(
|
|||
private val roomSummaryDataSource: RoomSummaryDataSource,
|
||||
private val roomChangeMembershipStateDataSource: RoomChangeMembershipStateDataSource,
|
||||
private val leaveRoomTask: LeaveRoomTask,
|
||||
private val roomSummaryUpdater: RoomSummaryUpdater
|
||||
) : RoomService {
|
||||
|
||||
override suspend fun createRoom(createRoomParams: CreateRoomParams): String {
|
||||
|
@ -92,6 +96,23 @@ internal class DefaultRoomService @Inject constructor(
|
|||
return roomSummaryDataSource.getRoomSummaries(queryParams, sortOrder)
|
||||
}
|
||||
|
||||
override fun refreshJoinedRoomSummaryPreviews(roomId: String?) {
|
||||
val roomSummaries = getRoomSummaries(roomSummaryQueryParams {
|
||||
if (roomId != null) {
|
||||
this.roomId = QueryStringValue.Equals(roomId)
|
||||
}
|
||||
memberships = listOf(Membership.JOIN)
|
||||
})
|
||||
|
||||
if (roomSummaries.isNotEmpty()) {
|
||||
monarchy.runTransactionSync { realm ->
|
||||
roomSummaries.forEach {
|
||||
roomSummaryUpdater.refreshLatestPreviewContent(realm, it.roomId)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getRoomSummariesLive(queryParams: RoomSummaryQueryParams,
|
||||
sortOrder: RoomSortOrder): LiveData<List<RoomSummary>> {
|
||||
return roomSummaryDataSource.getRoomSummariesLive(queryParams, sortOrder)
|
||||
|
|
|
@ -64,7 +64,6 @@ import org.matrix.android.sdk.internal.session.room.accountdata.RoomAccountDataD
|
|||
import org.matrix.android.sdk.internal.session.room.membership.RoomDisplayNameResolver
|
||||
import org.matrix.android.sdk.internal.session.room.membership.RoomMemberHelper
|
||||
import org.matrix.android.sdk.internal.session.room.relationship.RoomChildRelationInfo
|
||||
import org.matrix.android.sdk.internal.util.Normalizer
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import kotlin.system.measureTimeMillis
|
||||
|
@ -75,8 +74,16 @@ internal class RoomSummaryUpdater @Inject constructor(
|
|||
private val roomAvatarResolver: RoomAvatarResolver,
|
||||
private val eventDecryptor: EventDecryptor,
|
||||
private val crossSigningService: DefaultCrossSigningService,
|
||||
private val roomAccountDataDataSource: RoomAccountDataDataSource,
|
||||
private val normalizer: Normalizer) {
|
||||
private val roomAccountDataDataSource: RoomAccountDataDataSource
|
||||
) {
|
||||
|
||||
fun refreshLatestPreviewContent(realm: Realm, roomId: String) {
|
||||
val roomSummaryEntity = RoomSummaryEntity.getOrNull(realm, roomId)
|
||||
if (roomSummaryEntity != null) {
|
||||
val latestPreviewableEvent = RoomSummaryEventsHelper.getLatestPreviewableEvent(realm, roomId)
|
||||
latestPreviewableEvent?.attemptToDecrypt()
|
||||
}
|
||||
}
|
||||
|
||||
fun update(realm: Realm,
|
||||
roomId: String,
|
||||
|
@ -128,6 +135,7 @@ internal class RoomSummaryUpdater @Inject constructor(
|
|||
val lastActivityFromEvent = latestPreviewableEvent?.root?.originServerTs
|
||||
if (lastActivityFromEvent != null) {
|
||||
roomSummaryEntity.lastActivityTime = lastActivityFromEvent
|
||||
latestPreviewableEvent.attemptToDecrypt()
|
||||
}
|
||||
|
||||
roomSummaryEntity.hasUnreadMessages = roomSummaryEntity.notificationCount > 0 ||
|
||||
|
@ -161,18 +169,6 @@ internal class RoomSummaryUpdater @Inject constructor(
|
|||
}
|
||||
roomSummaryEntity.updateHasFailedSending()
|
||||
|
||||
val root = latestPreviewableEvent?.root
|
||||
if (root?.type == EventType.ENCRYPTED && root.decryptionResultJson == null) {
|
||||
Timber.v("Should decrypt ${latestPreviewableEvent.eventId}")
|
||||
// mmm i want to decrypt now or is it ok to do it async?
|
||||
tryOrNull {
|
||||
runBlocking {
|
||||
eventDecryptor.decryptEvent(root.asDomain(), "")
|
||||
}
|
||||
}
|
||||
?.let { root.setDecryptionResult(it) }
|
||||
}
|
||||
|
||||
if (updateMembers) {
|
||||
val otherRoomMembers = RoomMemberHelper(realm, roomId)
|
||||
.queryActiveRoomMembersEvent()
|
||||
|
@ -189,6 +185,22 @@ internal class RoomSummaryUpdater @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun TimelineEventEntity.attemptToDecrypt() {
|
||||
when (val root = this.root) {
|
||||
null -> {
|
||||
Timber.v("Decryption skipped due to missing root event $eventId")
|
||||
}
|
||||
else -> {
|
||||
if (root.type == EventType.ENCRYPTED && root.decryptionResultJson == null) {
|
||||
Timber.v("Should decrypt $eventId")
|
||||
tryOrNull {
|
||||
runBlocking { eventDecryptor.decryptEvent(root.asDomain(), "") }
|
||||
}?.let { root.setDecryptionResult(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun RoomSummaryEntity.updateHasFailedSending() {
|
||||
hasFailedSending = TimelineEventEntity.findAllInRoomWithSendStates(realm, roomId, SendState.HAS_FAILED_STATES).isNotEmpty()
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@ import org.matrix.android.sdk.api.session.room.model.Membership
|
|||
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
|
||||
import org.matrix.android.sdk.api.util.toMatrixItem
|
||||
import org.matrix.android.sdk.flow.flow
|
||||
import org.matrix.android.sdk.internal.crypto.NewSessionListener
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
|
@ -88,9 +89,16 @@ class HomeDetailViewModel @AssistedInject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private val refreshRoomSummariesOnCryptoSessionChange = object : NewSessionListener {
|
||||
override fun onNewSession(roomId: String?, senderKey: String, sessionId: String) {
|
||||
session.refreshJoinedRoomSummaryPreviews(roomId)
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
observeSyncState()
|
||||
observeRoomGroupingMethod()
|
||||
session.cryptoService().addNewSessionListener(refreshRoomSummariesOnCryptoSessionChange)
|
||||
observeRoomSummaries()
|
||||
updatePstnSupportFlag()
|
||||
observeDataStore()
|
||||
|
@ -150,6 +158,7 @@ class HomeDetailViewModel @AssistedInject constructor(
|
|||
override fun onCleared() {
|
||||
super.onCleared()
|
||||
callManager.removeProtocolsCheckerListener(this)
|
||||
session.cryptoService().removeSessionListener(refreshRoomSummariesOnCryptoSessionChange)
|
||||
}
|
||||
|
||||
override fun onPSTNSupportUpdated() {
|
||||
|
|
Loading…
Reference in a new issue