Stop sending media in an infinite loop in case of error (part of #587)
Not sure how this commit fix it, but the issue is not observed anymore with it
This commit is contained in:
parent
f3039601bf
commit
f077cc8467
|
@ -17,7 +17,6 @@
|
||||||
package im.vector.matrix.android.internal.crypto.attachments
|
package im.vector.matrix.android.internal.crypto.attachments
|
||||||
|
|
||||||
import android.util.Base64
|
import android.util.Base64
|
||||||
import arrow.core.Try
|
|
||||||
import im.vector.matrix.android.internal.crypto.model.rest.EncryptedFileInfo
|
import im.vector.matrix.android.internal.crypto.model.rest.EncryptedFileInfo
|
||||||
import im.vector.matrix.android.internal.crypto.model.rest.EncryptedFileKey
|
import im.vector.matrix.android.internal.crypto.model.rest.EncryptedFileKey
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
@ -50,7 +49,7 @@ object MXEncryptedAttachments {
|
||||||
* @param mimetype the mime type
|
* @param mimetype the mime type
|
||||||
* @return the encryption file info
|
* @return the encryption file info
|
||||||
*/
|
*/
|
||||||
fun encryptAttachment(attachmentStream: InputStream, mimetype: String): Try<EncryptionResult> {
|
fun encryptAttachment(attachmentStream: InputStream, mimetype: String): EncryptionResult {
|
||||||
val t0 = System.currentTimeMillis()
|
val t0 = System.currentTimeMillis()
|
||||||
val secureRandom = SecureRandom()
|
val secureRandom = SecureRandom()
|
||||||
|
|
||||||
|
@ -70,7 +69,7 @@ object MXEncryptedAttachments {
|
||||||
|
|
||||||
val outStream = ByteArrayOutputStream()
|
val outStream = ByteArrayOutputStream()
|
||||||
|
|
||||||
try {
|
outStream.use {
|
||||||
val encryptCipher = Cipher.getInstance(CIPHER_ALGORITHM)
|
val encryptCipher = Cipher.getInstance(CIPHER_ALGORITHM)
|
||||||
val secretKeySpec = SecretKeySpec(key, SECRET_KEY_SPEC_ALGORITHM)
|
val secretKeySpec = SecretKeySpec(key, SECRET_KEY_SPEC_ALGORITHM)
|
||||||
val ivParameterSpec = IvParameterSpec(initVectorBytes)
|
val ivParameterSpec = IvParameterSpec(initVectorBytes)
|
||||||
|
@ -114,19 +113,7 @@ object MXEncryptedAttachments {
|
||||||
)
|
)
|
||||||
|
|
||||||
Timber.v("Encrypt in ${System.currentTimeMillis() - t0} ms")
|
Timber.v("Encrypt in ${System.currentTimeMillis() - t0} ms")
|
||||||
return Try.just(result)
|
return result
|
||||||
} catch (oom: OutOfMemoryError) {
|
|
||||||
Timber.e(oom, "## encryptAttachment failed")
|
|
||||||
return Try.Failure(oom)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Timber.e(e, "## encryptAttachment failed")
|
|
||||||
return Try.Failure(e)
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
outStream.close()
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Timber.e(e, "## encryptAttachment() : fail to close outStream")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ import retrofit2.Call
|
||||||
import retrofit2.Callback
|
import retrofit2.Callback
|
||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
import java.io.IOException
|
||||||
import kotlin.coroutines.resume
|
import kotlin.coroutines.resume
|
||||||
import kotlin.coroutines.resumeWithException
|
import kotlin.coroutines.resumeWithException
|
||||||
|
|
||||||
|
@ -50,6 +51,24 @@ internal suspend fun <T> Call<T>.awaitResponse(): Response<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal suspend fun okhttp3.Call.awaitResponse(): okhttp3.Response {
|
||||||
|
return suspendCancellableCoroutine { continuation ->
|
||||||
|
continuation.invokeOnCancellation {
|
||||||
|
cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
enqueue(object : okhttp3.Callback {
|
||||||
|
override fun onResponse(call: okhttp3.Call, response: okhttp3.Response) {
|
||||||
|
continuation.resume(response)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFailure(call: okhttp3.Call, e: IOException) {
|
||||||
|
continuation.resumeWithException(e)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a retrofit Response to a Failure, and eventually parse errorBody to convert it to a MatrixError
|
* Convert a retrofit Response to a Failure, and eventually parse errorBody to convert it to a MatrixError
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -16,12 +16,11 @@
|
||||||
|
|
||||||
package im.vector.matrix.android.internal.session.content
|
package im.vector.matrix.android.internal.session.content
|
||||||
|
|
||||||
import arrow.core.Try
|
|
||||||
import arrow.core.Try.Companion.raise
|
|
||||||
import com.squareup.moshi.Moshi
|
import com.squareup.moshi.Moshi
|
||||||
import im.vector.matrix.android.api.auth.data.SessionParams
|
import im.vector.matrix.android.api.auth.data.SessionParams
|
||||||
import im.vector.matrix.android.internal.di.Authenticated
|
import im.vector.matrix.android.internal.di.Authenticated
|
||||||
import im.vector.matrix.android.internal.network.ProgressRequestBody
|
import im.vector.matrix.android.internal.network.ProgressRequestBody
|
||||||
|
import im.vector.matrix.android.internal.network.awaitResponse
|
||||||
import im.vector.matrix.android.internal.network.toFailure
|
import im.vector.matrix.android.internal.network.toFailure
|
||||||
import okhttp3.*
|
import okhttp3.*
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
@ -38,28 +37,26 @@ internal class FileUploader @Inject constructor(@Authenticated
|
||||||
private val responseAdapter = moshi.adapter(ContentUploadResponse::class.java)
|
private val responseAdapter = moshi.adapter(ContentUploadResponse::class.java)
|
||||||
|
|
||||||
|
|
||||||
fun uploadFile(file: File,
|
suspend fun uploadFile(file: File,
|
||||||
filename: String?,
|
filename: String?,
|
||||||
mimeType: String,
|
mimeType: String,
|
||||||
progressListener: ProgressRequestBody.Listener? = null): Try<ContentUploadResponse> {
|
progressListener: ProgressRequestBody.Listener? = null): ContentUploadResponse {
|
||||||
|
|
||||||
val uploadBody = RequestBody.create(MediaType.parse(mimeType), file)
|
val uploadBody = RequestBody.create(MediaType.parse(mimeType), file)
|
||||||
return upload(uploadBody, filename, progressListener)
|
return upload(uploadBody, filename, progressListener)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun uploadByteArray(byteArray: ByteArray,
|
suspend fun uploadByteArray(byteArray: ByteArray,
|
||||||
filename: String?,
|
filename: String?,
|
||||||
mimeType: String,
|
mimeType: String,
|
||||||
progressListener: ProgressRequestBody.Listener? = null): Try<ContentUploadResponse> {
|
progressListener: ProgressRequestBody.Listener? = null): ContentUploadResponse {
|
||||||
|
|
||||||
val uploadBody = RequestBody.create(MediaType.parse(mimeType), byteArray)
|
val uploadBody = RequestBody.create(MediaType.parse(mimeType), byteArray)
|
||||||
return upload(uploadBody, filename, progressListener)
|
return upload(uploadBody, filename, progressListener)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun upload(uploadBody: RequestBody, filename: String?, progressListener: ProgressRequestBody.Listener?): Try<ContentUploadResponse> {
|
private suspend fun upload(uploadBody: RequestBody, filename: String?, progressListener: ProgressRequestBody.Listener?): ContentUploadResponse {
|
||||||
val urlBuilder = HttpUrl.parse(uploadUrl)?.newBuilder() ?: return raise(RuntimeException())
|
val urlBuilder = HttpUrl.parse(uploadUrl)?.newBuilder() ?: throw RuntimeException()
|
||||||
|
|
||||||
val httpUrl = urlBuilder
|
val httpUrl = urlBuilder
|
||||||
.addQueryParameter("filename", filename)
|
.addQueryParameter("filename", filename)
|
||||||
|
@ -72,8 +69,7 @@ internal class FileUploader @Inject constructor(@Authenticated
|
||||||
.post(requestBody)
|
.post(requestBody)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
return Try {
|
return okHttpClient.newCall(request).awaitResponse().use { response ->
|
||||||
okHttpClient.newCall(request).execute().use { response ->
|
|
||||||
if (!response.isSuccessful) {
|
if (!response.isSuccessful) {
|
||||||
throw response.toFailure()
|
throw response.toFailure()
|
||||||
} else {
|
} else {
|
||||||
|
@ -84,7 +80,4 @@ internal class FileUploader @Inject constructor(@Authenticated
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -93,32 +93,28 @@ internal class UploadContentWorker(context: Context, params: WorkerParameters) :
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
val contentUploadResponse = if (params.isRoomEncrypted) {
|
val contentUploadResponse = if (params.isRoomEncrypted) {
|
||||||
Timber.v("Encrypt thumbnail")
|
Timber.v("Encrypt thumbnail")
|
||||||
contentUploadStateTracker.setEncryptingThumbnail(eventId)
|
contentUploadStateTracker.setEncryptingThumbnail(eventId)
|
||||||
MXEncryptedAttachments.encryptAttachment(ByteArrayInputStream(thumbnailData.bytes), thumbnailData.mimeType)
|
val encryptionResult = MXEncryptedAttachments.encryptAttachment(ByteArrayInputStream(thumbnailData.bytes), thumbnailData.mimeType)
|
||||||
.flatMap { encryptionResult ->
|
|
||||||
uploadedThumbnailEncryptedFileInfo = encryptionResult.encryptedFileInfo
|
uploadedThumbnailEncryptedFileInfo = encryptionResult.encryptedFileInfo
|
||||||
|
fileUploader.uploadByteArray(encryptionResult.encryptedByteArray,
|
||||||
fileUploader
|
|
||||||
.uploadByteArray(encryptionResult.encryptedByteArray,
|
|
||||||
"thumb_${attachment.name}",
|
"thumb_${attachment.name}",
|
||||||
"application/octet-stream",
|
"application/octet-stream",
|
||||||
thumbnailProgressListener)
|
thumbnailProgressListener)
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
fileUploader
|
fileUploader.uploadByteArray(thumbnailData.bytes,
|
||||||
.uploadByteArray(thumbnailData.bytes,
|
|
||||||
"thumb_${attachment.name}",
|
"thumb_${attachment.name}",
|
||||||
thumbnailData.mimeType,
|
thumbnailData.mimeType,
|
||||||
thumbnailProgressListener)
|
thumbnailProgressListener)
|
||||||
}
|
}
|
||||||
|
|
||||||
contentUploadResponse
|
uploadedThumbnailUrl = contentUploadResponse.contentUri
|
||||||
.fold(
|
} catch (t: Throwable) {
|
||||||
{ Timber.e(it) },
|
Timber.e(t)
|
||||||
{ uploadedThumbnailUrl = it.contentUri }
|
return handleFailure(params, t)
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val progressListener = object : ProgressRequestBody.Listener {
|
val progressListener = object : ProgressRequestBody.Listener {
|
||||||
|
@ -133,27 +129,26 @@ internal class UploadContentWorker(context: Context, params: WorkerParameters) :
|
||||||
|
|
||||||
var uploadedFileEncryptedFileInfo: EncryptedFileInfo? = null
|
var uploadedFileEncryptedFileInfo: EncryptedFileInfo? = null
|
||||||
|
|
||||||
|
return try {
|
||||||
val contentUploadResponse = if (params.isRoomEncrypted) {
|
val contentUploadResponse = if (params.isRoomEncrypted) {
|
||||||
Timber.v("Encrypt file")
|
Timber.v("Encrypt file")
|
||||||
contentUploadStateTracker.setEncrypting(eventId)
|
contentUploadStateTracker.setEncrypting(eventId)
|
||||||
|
|
||||||
MXEncryptedAttachments.encryptAttachment(FileInputStream(attachmentFile), attachment.mimeType)
|
val encryptionResult = MXEncryptedAttachments.encryptAttachment(FileInputStream(attachmentFile), attachment.mimeType)
|
||||||
.flatMap { encryptionResult ->
|
|
||||||
uploadedFileEncryptedFileInfo = encryptionResult.encryptedFileInfo
|
uploadedFileEncryptedFileInfo = encryptionResult.encryptedFileInfo
|
||||||
|
|
||||||
fileUploader
|
fileUploader
|
||||||
.uploadByteArray(encryptionResult.encryptedByteArray, attachment.name, "application/octet-stream", progressListener)
|
.uploadByteArray(encryptionResult.encryptedByteArray, attachment.name, "application/octet-stream", progressListener)
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
fileUploader
|
fileUploader
|
||||||
.uploadFile(attachmentFile, attachment.name, attachment.mimeType, progressListener)
|
.uploadFile(attachmentFile, attachment.name, attachment.mimeType, progressListener)
|
||||||
}
|
}
|
||||||
|
|
||||||
return contentUploadResponse
|
handleSuccess(params, contentUploadResponse.contentUri, uploadedFileEncryptedFileInfo, uploadedThumbnailUrl, uploadedThumbnailEncryptedFileInfo)
|
||||||
.fold(
|
} catch (t: Throwable) {
|
||||||
{ handleFailure(params, it) },
|
Timber.e(t)
|
||||||
{ handleSuccess(params, it.contentUri, uploadedFileEncryptedFileInfo, uploadedThumbnailUrl, uploadedThumbnailEncryptedFileInfo) }
|
handleFailure(params, t)
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleFailure(params: Params, failure: Throwable): Result {
|
private fun handleFailure(params: Params, failure: Throwable): Result {
|
||||||
|
|
Loading…
Reference in New Issue