Skip to content

Commit 96d6a72

Browse files
committed
Compress images before sending (for devices below Android 10).
Fixes #1333
1 parent 7b3fa50 commit 96d6a72

File tree

3 files changed

+75
-16
lines changed

3 files changed

+75
-16
lines changed

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Bugfix 🐛:
1313
- Incomplete predicate in RealmCryptoStore#getOutgoingRoomKeyRequest (#1519)
1414
- User could not redact message that they have sent (#1543)
1515
- Use vendor prefix for non merged MSC (#1537)
16+
- Compress images before sending (for devices below Android 10) (#1333)
1617

1718
Translations 🗣:
1819
-

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

Lines changed: 67 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,13 @@
1717
package im.vector.matrix.android.internal.session.content
1818

1919
import android.content.Context
20+
import android.graphics.BitmapFactory
21+
import android.os.Build
2022
import androidx.work.CoroutineWorker
2123
import androidx.work.WorkerParameters
2224
import com.squareup.moshi.JsonClass
25+
import id.zelory.compressor.Compressor
26+
import id.zelory.compressor.constraint.default
2327
import im.vector.matrix.android.api.session.content.ContentAttachmentData
2428
import im.vector.matrix.android.api.session.events.model.Event
2529
import im.vector.matrix.android.api.session.events.model.toContent
@@ -38,6 +42,9 @@ import im.vector.matrix.android.internal.worker.WorkerParamsFactory
3842
import im.vector.matrix.android.internal.worker.getSessionComponent
3943
import timber.log.Timber
4044
import java.io.ByteArrayInputStream
45+
import java.io.File
46+
import java.io.FileOutputStream
47+
import java.util.UUID
4148
import javax.inject.Inject
4249

4350
private data class NewImageAttributes(
@@ -154,26 +161,70 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter
154161
var uploadedFileEncryptedFileInfo: EncryptedFileInfo? = null
155162

156163
return try {
157-
val contentUploadResponse = if (params.isEncrypted) {
158-
Timber.v("Encrypt file")
159-
notifyTracker(params) { contentUploadStateTracker.setEncrypting(it) }
164+
// Temporary disable compressing for Android 10 and above.
165+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
166+
val contentUploadResponse = if (params.isEncrypted) {
167+
Timber.v("Encrypt file")
168+
notifyTracker(params) { contentUploadStateTracker.setEncrypting(it) }
160169

161-
val encryptionResult = MXEncryptedAttachments.encryptAttachment(inputStream, attachment.getSafeMimeType())
162-
uploadedFileEncryptedFileInfo = encryptionResult.encryptedFileInfo
170+
val encryptionResult = MXEncryptedAttachments.encryptAttachment(inputStream, attachment.getSafeMimeType())
171+
uploadedFileEncryptedFileInfo = encryptionResult.encryptedFileInfo
163172

164-
fileUploader
165-
.uploadByteArray(encryptionResult.encryptedByteArray, attachment.name, "application/octet-stream", progressListener)
173+
fileUploader
174+
.uploadByteArray(encryptionResult.encryptedByteArray, attachment.name, "application/octet-stream", progressListener)
175+
} else {
176+
fileUploader
177+
.uploadByteArray(inputStream.readBytes(), attachment.name, attachment.getSafeMimeType(), progressListener)
178+
}
179+
handleSuccess(params,
180+
contentUploadResponse.contentUri,
181+
uploadedFileEncryptedFileInfo,
182+
uploadedThumbnailUrl,
183+
uploadedThumbnailEncryptedFileInfo,
184+
newImageAttributes)
166185
} else {
167-
fileUploader
168-
.uploadByteArray(inputStream.readBytes(), attachment.name, attachment.getSafeMimeType(), progressListener)
169-
}
186+
val cacheFile = File.createTempFile(attachment.name ?: UUID.randomUUID().toString(), ".jpg", context.cacheDir)
187+
cacheFile.parentFile?.mkdirs()
188+
if (cacheFile.exists()) {
189+
cacheFile.delete()
190+
}
191+
cacheFile.createNewFile()
192+
cacheFile.deleteOnExit()
193+
194+
val outputStream = FileOutputStream(cacheFile)
195+
outputStream.use {
196+
inputStream.copyTo(outputStream)
197+
}
198+
199+
val contentUploadResponse = if (attachment.type == ContentAttachmentData.Type.IMAGE && params.compressBeforeSending) {
200+
Compressor.compress(context, cacheFile) {
201+
default(
202+
width = MAX_IMAGE_SIZE,
203+
height = MAX_IMAGE_SIZE
204+
)
205+
}.also { compressedFile ->
206+
val options = BitmapFactory.Options().apply { inJustDecodeBounds = true }
207+
BitmapFactory.decodeFile(compressedFile.absolutePath, options)
208+
val fileSize = compressedFile.length().toInt()
209+
newImageAttributes = NewImageAttributes(
210+
options.outWidth,
211+
options.outHeight,
212+
fileSize
213+
)
214+
}.let { compressedFile ->
215+
fileUploader.uploadFile(compressedFile, attachment.name, attachment.getSafeMimeType(), progressListener)
216+
}
217+
} else {
218+
fileUploader.uploadFile(cacheFile, attachment.name, attachment.getSafeMimeType(), progressListener)
219+
}
170220

171-
handleSuccess(params,
172-
contentUploadResponse.contentUri,
173-
uploadedFileEncryptedFileInfo,
174-
uploadedThumbnailUrl,
175-
uploadedThumbnailEncryptedFileInfo,
176-
newImageAttributes)
221+
handleSuccess(params,
222+
contentUploadResponse.contentUri,
223+
uploadedFileEncryptedFileInfo,
224+
uploadedThumbnailUrl,
225+
uploadedThumbnailEncryptedFileInfo,
226+
newImageAttributes)
227+
}
177228
} catch (t: Throwable) {
178229
Timber.e(t)
179230
handleFailure(params, t)

vector/src/main/java/im/vector/riotx/features/attachments/preview/AttachmentsPreviewFragment.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import android.app.Activity.RESULT_CANCELED
2121
import android.app.Activity.RESULT_OK
2222
import android.content.Intent
2323
import android.graphics.Color
24+
import android.os.Build
2425
import android.os.Bundle
2526
import android.os.Parcelable
2627
import android.view.Menu
@@ -143,6 +144,12 @@ class AttachmentsPreviewFragment @Inject constructor(
143144
attachmentPreviewerBigList.scrollToPosition(state.currentAttachmentIndex)
144145
attachmentPreviewerMiniatureList.scrollToPosition(state.currentAttachmentIndex)
145146
attachmentPreviewerSendImageOriginalSize.text = resources.getQuantityString(R.plurals.send_images_with_original_size, state.attachments.size)
147+
148+
// Temporary disable compressing for Android 10 and above.
149+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
150+
attachmentPreviewerSendImageOriginalSize.isChecked = true
151+
attachmentPreviewerSendImageOriginalSize.isEnabled = false
152+
}
146153
}
147154
}
148155

0 commit comments

Comments
 (0)