Get uploaded files for e2e rooms, from local DB

This commit is contained in:
Benoit Marty 2020-05-26 22:06:51 +02:00
parent 0eb36a607b
commit cf3dbb378e
3 changed files with 59 additions and 12 deletions

View file

@ -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
*/

View file

@ -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<GetUploadsResult>): Cancelable {
return getUploadsTask
.configureWith(GetUploadsTask.Params(roomId, numberOfEvents, since)) {
.configureWith(GetUploadsTask.Params(roomId, cryptoService.isRoomEncrypted(roomId), numberOfEvents, since)) {
this.callback = callback
}
.executeBy(taskExecutor)

View file

@ -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<GetUploadsTask.Params, GetUploadsResult
data class Params(
val roomId: String,
val isRoomEncrypted: Boolean,
val numberOfEvents: Int,
val since: String?
)
@ -51,11 +60,44 @@ internal class DefaultGetUploadsTask @Inject constructor(
: GetUploadsTask {
override suspend fun execute(params: GetUploadsTask.Params): GetUploadsResult {
val since = params.since ?: tokenStore.getLastToken() ?: throw IllegalStateException("No token available")
val result: GetUploadsResult
val events: List<Event>
val filter = FilterFactory.createUploadsFilter(params.numberOfEvents).toJSONString()
val chunk = executeRequest<PaginationResponse>(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<Event>()
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<PaginationResponse>(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<UploadEvent>()
@ -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<MessageContent>() ?: 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)
}
}