Skip to content

Commit 06ba478

Browse files
committed
Send files to several rooms at a time
1 parent 81de914 commit 06ba478

File tree

11 files changed

+281
-89
lines changed

11 files changed

+281
-89
lines changed

matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/send/SendService.kt

+9-2
Original file line numberDiff line numberDiff line change
@@ -52,20 +52,27 @@ interface SendService {
5252
* Method to send a media asynchronously.
5353
* @param attachment the media to send
5454
* @param compressBeforeSending set to true to compress media before sending them
55+
* @param roomIds set of roomIds to where the media will be sent. The current roomId will be add to this set if not present.
56+
* It can be useful to send media to multiple room. It's safe to include the current roomId in this set
5557
* @return a [Cancelable]
5658
*/
5759
fun sendMedia(attachment: ContentAttachmentData,
5860
// TODO Change to a Compression Level Enum
59-
compressBeforeSending: Boolean): Cancelable
61+
compressBeforeSending: Boolean,
62+
roomIds: Set<String>): Cancelable
6063

6164
/**
6265
* Method to send a list of media asynchronously.
6366
* @param attachments the list of media to send
67+
* @param compressBeforeSending set to true to compress media before sending them
68+
* @param roomIds set of roomIds to where the media will be sent. The current roomId will be add to this set if not present.
69+
* It can be useful to send media to multiple room. It's safe to include the current roomId in this set
6470
* @return a [Cancelable]
6571
*/
6672
fun sendMedias(attachments: List<ContentAttachmentData>,
6773
// TODO Change to a Compression Level Enum
68-
compressBeforeSending: Boolean): Cancelable
74+
compressBeforeSending: Boolean,
75+
roomIds: Set<String>): Cancelable
6976

7077
/**
7178
* Send a poll to the room.

matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/WorkManagerProvider.kt

+7-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@
1717
package im.vector.matrix.android.internal.di
1818

1919
import android.content.Context
20-
import androidx.work.*
20+
import androidx.work.Constraints
21+
import androidx.work.ListenableWorker
22+
import androidx.work.NetworkType
23+
import androidx.work.OneTimeWorkRequestBuilder
24+
import androidx.work.WorkManager
2125
import javax.inject.Inject
2226

2327
internal class WorkManagerProvider @Inject constructor(
@@ -54,5 +58,7 @@ internal class WorkManagerProvider @Inject constructor(
5458
val workConstraints = Constraints.Builder()
5559
.setRequiredNetworkType(NetworkType.CONNECTED)
5660
.build()
61+
62+
const val BACKOFF_DELAY = 10_000L
5763
}
5864
}

matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionComponent.kt

+12-9
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import im.vector.matrix.android.internal.session.pushers.PushersModule
3838
import im.vector.matrix.android.internal.session.room.RoomModule
3939
import im.vector.matrix.android.internal.session.room.relation.SendRelationWorker
4040
import im.vector.matrix.android.internal.session.room.send.EncryptEventWorker
41+
import im.vector.matrix.android.internal.session.room.send.MultipleEventSendingDispatcherWorker
4142
import im.vector.matrix.android.internal.session.room.send.RedactEventWorker
4243
import im.vector.matrix.android.internal.session.room.send.SendEventWorker
4344
import im.vector.matrix.android.internal.session.signout.SignOutModule
@@ -85,23 +86,25 @@ internal interface SessionComponent {
8586

8687
fun taskExecutor(): TaskExecutor
8788

88-
fun inject(sendEventWorker: SendEventWorker)
89+
fun inject(worker: SendEventWorker)
8990

90-
fun inject(sendEventWorker: SendRelationWorker)
91+
fun inject(worker: SendRelationWorker)
9192

92-
fun inject(encryptEventWorker: EncryptEventWorker)
93+
fun inject(worker: EncryptEventWorker)
9394

94-
fun inject(redactEventWorker: RedactEventWorker)
95+
fun inject(worker: MultipleEventSendingDispatcherWorker)
9596

96-
fun inject(getGroupDataWorker: GetGroupDataWorker)
97+
fun inject(worker: RedactEventWorker)
9798

98-
fun inject(uploadContentWorker: UploadContentWorker)
99+
fun inject(worker: GetGroupDataWorker)
99100

100-
fun inject(syncWorker: SyncWorker)
101+
fun inject(worker: UploadContentWorker)
101102

102-
fun inject(addHttpPusherWorker: AddHttpPusherWorker)
103+
fun inject(worker: SyncWorker)
103104

104-
fun inject(sendVerificationMessageWorker: SendVerificationMessageWorker)
105+
fun inject(worker: AddHttpPusherWorker)
106+
107+
fun inject(worker: SendVerificationMessageWorker)
105108

106109
@Component.Factory
107110
interface Factory {

matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/content/UploadContentWorker.kt

+54-18
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,15 @@ import im.vector.matrix.android.api.session.content.ContentAttachmentData
2424
import im.vector.matrix.android.api.session.events.model.Event
2525
import im.vector.matrix.android.api.session.events.model.toContent
2626
import im.vector.matrix.android.api.session.events.model.toModel
27-
import im.vector.matrix.android.api.session.room.model.message.*
27+
import im.vector.matrix.android.api.session.room.model.message.MessageAudioContent
28+
import im.vector.matrix.android.api.session.room.model.message.MessageContent
29+
import im.vector.matrix.android.api.session.room.model.message.MessageFileContent
30+
import im.vector.matrix.android.api.session.room.model.message.MessageImageContent
31+
import im.vector.matrix.android.api.session.room.model.message.MessageVideoContent
2832
import im.vector.matrix.android.internal.crypto.attachments.MXEncryptedAttachments
2933
import im.vector.matrix.android.internal.crypto.model.rest.EncryptedFileInfo
3034
import im.vector.matrix.android.internal.network.ProgressRequestBody
31-
import im.vector.matrix.android.internal.session.room.send.SendEventWorker
35+
import im.vector.matrix.android.internal.session.room.send.MultipleEventSendingDispatcherWorker
3236
import im.vector.matrix.android.internal.worker.SessionWorkerParams
3337
import im.vector.matrix.android.internal.worker.WorkerParamsFactory
3438
import im.vector.matrix.android.internal.worker.getSessionComponent
@@ -43,8 +47,7 @@ internal class UploadContentWorker(context: Context, params: WorkerParameters) :
4347
@JsonClass(generateAdapter = true)
4448
internal data class Params(
4549
override val sessionId: String,
46-
val roomId: String,
47-
val event: Event,
50+
val events: List<Event>,
4851
val attachment: ContentAttachmentData,
4952
val isRoomEncrypted: Boolean,
5053
val compressBeforeSending: Boolean,
@@ -68,14 +71,17 @@ internal class UploadContentWorker(context: Context, params: WorkerParameters) :
6871
val sessionComponent = getSessionComponent(params.sessionId) ?: return Result.success()
6972
sessionComponent.inject(this)
7073

71-
val eventId = params.event.eventId ?: return Result.success()
7274
val attachment = params.attachment
7375

7476
val attachmentFile = try {
7577
File(attachment.path)
7678
} catch (e: Exception) {
7779
Timber.e(e)
78-
contentUploadStateTracker.setFailure(params.event.eventId, e)
80+
params.events
81+
.mapNotNull { it.eventId }
82+
.forEach {
83+
contentUploadStateTracker.setFailure(it, e)
84+
}
7985
return Result.success(
8086
WorkerParamsFactory.toData(params.copy(
8187
lastFailureMessage = e.localizedMessage
@@ -91,14 +97,22 @@ internal class UploadContentWorker(context: Context, params: WorkerParameters) :
9197
ThumbnailExtractor.extractThumbnail(params.attachment)?.let { thumbnailData ->
9298
val thumbnailProgressListener = object : ProgressRequestBody.Listener {
9399
override fun onProgress(current: Long, total: Long) {
94-
contentUploadStateTracker.setProgressThumbnail(eventId, current, total)
100+
params.events
101+
.mapNotNull { it.eventId }
102+
.forEach {
103+
contentUploadStateTracker.setProgressThumbnail(it, current, total)
104+
}
95105
}
96106
}
97107

98108
try {
99109
val contentUploadResponse = if (params.isRoomEncrypted) {
100110
Timber.v("Encrypt thumbnail")
101-
contentUploadStateTracker.setEncryptingThumbnail(eventId)
111+
params.events
112+
.mapNotNull { it.eventId }
113+
.forEach {
114+
contentUploadStateTracker.setEncryptingThumbnail(it)
115+
}
102116
val encryptionResult = MXEncryptedAttachments.encryptAttachment(ByteArrayInputStream(thumbnailData.bytes), thumbnailData.mimeType)
103117
uploadedThumbnailEncryptedFileInfo = encryptionResult.encryptedFileInfo
104118
fileUploader.uploadByteArray(encryptionResult.encryptedByteArray,
@@ -121,11 +135,15 @@ internal class UploadContentWorker(context: Context, params: WorkerParameters) :
121135

122136
val progressListener = object : ProgressRequestBody.Listener {
123137
override fun onProgress(current: Long, total: Long) {
124-
if (isStopped) {
125-
contentUploadStateTracker.setFailure(eventId, Throwable("Cancelled"))
126-
} else {
127-
contentUploadStateTracker.setProgress(eventId, current, total)
128-
}
138+
params.events
139+
.mapNotNull { it.eventId }
140+
.forEach {
141+
if (isStopped) {
142+
contentUploadStateTracker.setFailure(it, Throwable("Cancelled"))
143+
} else {
144+
contentUploadStateTracker.setProgress(it, current, total)
145+
}
146+
}
129147
}
130148
}
131149

@@ -134,7 +152,11 @@ internal class UploadContentWorker(context: Context, params: WorkerParameters) :
134152
return try {
135153
val contentUploadResponse = if (params.isRoomEncrypted) {
136154
Timber.v("Encrypt file")
137-
contentUploadStateTracker.setEncrypting(eventId)
155+
params.events
156+
.mapNotNull { it.eventId }
157+
.forEach {
158+
contentUploadStateTracker.setEncrypting(it)
159+
}
138160

139161
val encryptionResult = MXEncryptedAttachments.encryptAttachment(FileInputStream(attachmentFile), attachment.mimeType)
140162
uploadedFileEncryptedFileInfo = encryptionResult.encryptedFileInfo
@@ -154,7 +176,12 @@ internal class UploadContentWorker(context: Context, params: WorkerParameters) :
154176
}
155177

156178
private fun handleFailure(params: Params, failure: Throwable): Result {
157-
contentUploadStateTracker.setFailure(params.event.eventId!!, failure)
179+
params.events
180+
.mapNotNull { it.eventId }
181+
.forEach {
182+
contentUploadStateTracker.setFailure(it, failure)
183+
}
184+
158185
return Result.success(
159186
WorkerParamsFactory.toData(
160187
params.copy(
@@ -170,9 +197,18 @@ internal class UploadContentWorker(context: Context, params: WorkerParameters) :
170197
thumbnailUrl: String?,
171198
thumbnailEncryptedFileInfo: EncryptedFileInfo?): Result {
172199
Timber.v("handleSuccess $attachmentUrl, work is stopped $isStopped")
173-
contentUploadStateTracker.setSuccess(params.event.eventId!!)
174-
val event = updateEvent(params.event, attachmentUrl, encryptedFileInfo, thumbnailUrl, thumbnailEncryptedFileInfo)
175-
val sendParams = SendEventWorker.Params(params.sessionId, params.roomId, event)
200+
params.events
201+
.mapNotNull { it.eventId }
202+
.forEach {
203+
contentUploadStateTracker.setSuccess(it)
204+
}
205+
206+
val updatedEvents = params.events
207+
.map {
208+
updateEvent(it, attachmentUrl, encryptedFileInfo, thumbnailUrl, thumbnailEncryptedFileInfo)
209+
}
210+
211+
val sendParams = MultipleEventSendingDispatcherWorker.Params(params.sessionId, updatedEvents, params.isRoomEncrypted)
176212
return Result.success(WorkerParamsFactory.toData(sendParams))
177213
}
178214

matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/relation/DefaultRelationService.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -196,13 +196,13 @@ internal class DefaultRelationService @AssistedInject constructor(
196196

197197
private fun createEncryptEventWork(event: Event, keepKeys: List<String>?): OneTimeWorkRequest {
198198
// Same parameter
199-
val params = EncryptEventWorker.Params(sessionId, roomId, event, keepKeys)
199+
val params = EncryptEventWorker.Params(sessionId, event, keepKeys)
200200
val sendWorkData = WorkerParamsFactory.toData(params)
201201
return timeLineSendEventWorkCommon.createWork<EncryptEventWorker>(sendWorkData, true)
202202
}
203203

204204
private fun createSendEventWork(event: Event, startChain: Boolean): OneTimeWorkRequest {
205-
val sendContentWorkerParams = SendEventWorker.Params(sessionId, roomId, event)
205+
val sendContentWorkerParams = SendEventWorker.Params(sessionId, event)
206206
val sendWorkData = WorkerParamsFactory.toData(sendContentWorkerParams)
207207
return timeLineSendEventWorkCommon.createWork<SendEventWorker>(sendWorkData, startChain)
208208
}

0 commit comments

Comments
 (0)