diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/TimelineEventFilter.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/TimelineEventFilter.kt index ea8122bc6d..14560ead85 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/TimelineEventFilter.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/TimelineEventFilter.kt @@ -28,6 +28,13 @@ internal object TimelineEventFilter { internal const val RESPONSE = """{*"m.relates_to"*"rel_type":*"m.response"*}""" } + /** + * To apply to Event.decryptionResultJson + */ + internal object DecryptedContent { + internal const val URL = """{*"file":*"url":*}""" + } + /** * To apply to Event.unsigned */ diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/uploads/DefaultUploadsService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/uploads/DefaultUploadsService.kt index dd8269a079..6ec9abf8e2 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/uploads/DefaultUploadsService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/uploads/DefaultUploadsService.kt @@ -19,6 +19,7 @@ package im.vector.matrix.android.internal.session.room.uploads import com.squareup.inject.assisted.Assisted import com.squareup.inject.assisted.AssistedInject import im.vector.matrix.android.api.MatrixCallback +import im.vector.matrix.android.api.session.crypto.CryptoService import im.vector.matrix.android.api.session.room.uploads.GetUploadsResult import im.vector.matrix.android.api.session.room.uploads.UploadsService import im.vector.matrix.android.api.util.Cancelable @@ -28,7 +29,8 @@ import im.vector.matrix.android.internal.task.configureWith internal class DefaultUploadsService @AssistedInject constructor( @Assisted private val roomId: String, private val taskExecutor: TaskExecutor, - private val getUploadsTask: GetUploadsTask + private val getUploadsTask: GetUploadsTask, + private val cryptoService: CryptoService ) : UploadsService { @AssistedInject.Factory @@ -38,7 +40,7 @@ internal class DefaultUploadsService @AssistedInject constructor( override fun getUploads(numberOfEvents: Int, since: String?, callback: MatrixCallback): Cancelable { return getUploadsTask - .configureWith(GetUploadsTask.Params(roomId, numberOfEvents, since)) { + .configureWith(GetUploadsTask.Params(roomId, cryptoService.isRoomEncrypted(roomId), numberOfEvents, since)) { this.callback = callback } .executeBy(taskExecutor) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/uploads/GetUploadsTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/uploads/GetUploadsTask.kt index fa707c0bf8..7c0f46abff 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/uploads/GetUploadsTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/uploads/GetUploadsTask.kt @@ -17,12 +17,20 @@ package im.vector.matrix.android.internal.session.room.uploads import com.zhuinden.monarchy.Monarchy +import im.vector.matrix.android.api.session.events.model.Event +import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.events.model.toModel import im.vector.matrix.android.api.session.room.model.message.MessageContent import im.vector.matrix.android.api.session.room.model.message.MessageWithAttachmentContent +import im.vector.matrix.android.api.session.room.send.SendState import im.vector.matrix.android.api.session.room.sender.SenderInfo import im.vector.matrix.android.api.session.room.uploads.GetUploadsResult import im.vector.matrix.android.api.session.room.uploads.UploadEvent +import im.vector.matrix.android.internal.database.mapper.asDomain +import im.vector.matrix.android.internal.database.model.EventEntity +import im.vector.matrix.android.internal.database.model.EventEntityFields +import im.vector.matrix.android.internal.database.query.TimelineEventFilter +import im.vector.matrix.android.internal.database.query.whereType import im.vector.matrix.android.internal.network.executeRequest import im.vector.matrix.android.internal.session.filter.FilterFactory import im.vector.matrix.android.internal.session.room.RoomAPI @@ -38,6 +46,7 @@ internal interface GetUploadsTask : Task - val filter = FilterFactory.createUploadsFilter(params.numberOfEvents).toJSONString() - val chunk = executeRequest(eventBus) { - apiCall = roomAPI.getRoomMessagesFrom(params.roomId, since, PaginationDirection.BACKWARDS.value, params.numberOfEvents, filter) + if (params.isRoomEncrypted) { + // Get a chunk of events from cache for e2e rooms + + result = GetUploadsResult( + uploadEvents = emptyList(), + nextToken = "", + hasMore = false + ) + + var eventsFromRealm = emptyList() + monarchy.doWithRealm { realm -> + eventsFromRealm = EventEntity.whereType(realm, EventType.ENCRYPTED, params.roomId) + .like(EventEntityFields.DECRYPTION_RESULT_JSON, TimelineEventFilter.DecryptedContent.URL) + // FIXME Send event are stored twice in the DB. This is not normal. Keep only synced events + .like(EventEntityFields.SEND_STATE_STR, SendState.SYNCED.name) + .findAll() + .map { it.asDomain() } + // Exclude stickers + .filter { it.getClearType() != EventType.STICKER } + } + events = eventsFromRealm + } else { + val since = params.since ?: tokenStore.getLastToken() ?: throw IllegalStateException("No token available") + + val filter = FilterFactory.createUploadsFilter(params.numberOfEvents).toJSONString() + val chunk = executeRequest(eventBus) { + apiCall = roomAPI.getRoomMessagesFrom(params.roomId, since, PaginationDirection.BACKWARDS.value, params.numberOfEvents, filter) + } + + result = GetUploadsResult( + uploadEvents = emptyList(), + nextToken = chunk.end ?: "", + hasMore = chunk.hasMore() + ) + events = chunk.events } var uploadEvents = listOf() @@ -66,7 +108,7 @@ internal class DefaultGetUploadsTask @Inject constructor( monarchy.doWithRealm { realm -> val roomMemberHelper = RoomMemberHelper(realm, params.roomId) - uploadEvents = chunk.events.mapNotNull { event -> + uploadEvents = events.mapNotNull { event -> val eventId = event.eventId ?: return@mapNotNull null val messageContent = event.getClearContent()?.toModel() ?: return@mapNotNull null val messageWithAttachmentContent = (messageContent as? MessageWithAttachmentContent) ?: return@mapNotNull null @@ -91,10 +133,6 @@ internal class DefaultGetUploadsTask @Inject constructor( } } - return GetUploadsResult( - uploadEvents = uploadEvents, - nextToken = chunk.end ?: "", - hasMore = chunk.hasMore() - ) + return result.copy(uploadEvents = uploadEvents) } }