downloadattachmentjob implementation

pull/420/head
Brice 4 years ago
parent 3a9304098b
commit 842f00ee54

@ -2,14 +2,18 @@ package org.thoughtcrime.securesms.attachments
import android.content.Context import android.content.Context
import com.google.protobuf.ByteString import com.google.protobuf.ByteString
import org.greenrobot.eventbus.EventBus
import org.session.libsession.database.MessageDataProvider import org.session.libsession.database.MessageDataProvider
import org.session.libsession.events.AttachmentProgressEvent
import org.session.libsession.messaging.sending_receiving.attachments.AttachmentState import org.session.libsession.messaging.sending_receiving.attachments.AttachmentState
import org.session.libsession.messaging.sending_receiving.attachments.SessionServiceAttachmentPointer import org.session.libsession.messaging.sending_receiving.attachments.SessionServiceAttachmentPointer
import org.session.libsession.messaging.sending_receiving.attachments.SessionServiceAttachmentStream import org.session.libsession.messaging.sending_receiving.attachments.SessionServiceAttachmentStream
import org.session.libsignal.libsignal.util.guava.Optional import org.session.libsignal.libsignal.util.guava.Optional
import org.session.libsignal.service.api.messages.SignalServiceAttachment
import org.thoughtcrime.securesms.database.Database import org.thoughtcrime.securesms.database.Database
import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper
import org.thoughtcrime.securesms.events.PartProgressEvent
import org.thoughtcrime.securesms.jobs.AttachmentUploadJob import org.thoughtcrime.securesms.jobs.AttachmentUploadJob
import org.thoughtcrime.securesms.mms.PartAuthority import org.thoughtcrime.securesms.mms.PartAuthority
import org.thoughtcrime.securesms.util.MediaUtil import org.thoughtcrime.securesms.util.MediaUtil
@ -58,7 +62,9 @@ fun DatabaseAttachment.toAttachmentPointer(): SessionServiceAttachmentPointer {
fun DatabaseAttachment.toAttachmentStream(context: Context): SessionServiceAttachmentStream { fun DatabaseAttachment.toAttachmentStream(context: Context): SessionServiceAttachmentStream {
val stream = PartAuthority.getAttachmentStream(context, this.dataUri!!) val stream = PartAuthority.getAttachmentStream(context, this.dataUri!!)
var attachmentStream = SessionServiceAttachmentStream(stream, this.contentType, this.size, Optional.fromNullable(this.fileName), this.isVoiceNote, Optional.absent(), this.width, this.height, Optional.fromNullable(this.caption), null) val listener = SignalServiceAttachment.ProgressListener { total: Long, progress: Long -> EventBus.getDefault().postSticky(PartProgressEvent(this, total, progress))}
var attachmentStream = SessionServiceAttachmentStream(stream, this.contentType, this.size, Optional.fromNullable(this.fileName), this.isVoiceNote, Optional.absent(), this.width, this.height, Optional.fromNullable(this.caption), listener)
attachmentStream.attachmentId = this.attachmentId.rowId attachmentStream.attachmentId = this.attachmentId.rowId
attachmentStream.isAudio = MediaUtil.isAudio(this) attachmentStream.isAudio = MediaUtil.isAudio(this)
attachmentStream.isGif = MediaUtil.isGif(this) attachmentStream.isGif = MediaUtil.isGif(this)
@ -66,12 +72,10 @@ fun DatabaseAttachment.toAttachmentStream(context: Context): SessionServiceAttac
attachmentStream.isImage = MediaUtil.isImage(this) attachmentStream.isImage = MediaUtil.isImage(this)
attachmentStream.key = ByteString.copyFrom(this.key?.toByteArray()) attachmentStream.key = ByteString.copyFrom(this.key?.toByteArray())
attachmentStream.digest = this.digest attachmentStream.digest = Optional.fromNullable(this.digest)
attachmentStream.url = this.url attachmentStream.url = this.url
//TODO attachmentStream.listener
return attachmentStream return attachmentStream
} }

@ -1,6 +0,0 @@
package org.session.libsession.events
import org.session.libsession.messaging.sending_receiving.attachments.SessionServiceAttachment
class AttachmentProgressEvent(attachment: SessionServiceAttachment, total: Long, progress: Long) {
}

@ -1,14 +1,10 @@
package org.session.libsession.messaging.jobs package org.session.libsession.messaging.jobs
import org.greenrobot.eventbus.EventBus
import org.session.libsession.events.AttachmentProgressEvent
import org.session.libsession.messaging.MessagingConfiguration import org.session.libsession.messaging.MessagingConfiguration
import org.session.libsession.messaging.fileserver.FileServerAPI import org.session.libsession.messaging.fileserver.FileServerAPI
import org.session.libsession.messaging.sending_receiving.attachments.AttachmentState import org.session.libsession.messaging.sending_receiving.attachments.AttachmentState
import org.session.libsession.messaging.sending_receiving.attachments.SessionServiceAttachment
import org.session.libsession.messaging.utilities.DotNetAPI import org.session.libsession.messaging.utilities.DotNetAPI
import org.session.libsignal.service.api.crypto.AttachmentCipherInputStream import org.session.libsignal.service.api.crypto.AttachmentCipherInputStream
import org.session.libsignal.service.api.messages.SignalServiceAttachment
import java.io.File import java.io.File
import java.io.FileInputStream import java.io.FileInputStream
@ -33,7 +29,7 @@ class AttachmentDownloadJob(val attachmentID: Long, val tsIncomingMessageID: Lon
override fun execute() { override fun execute() {
val messageDataProvider = MessagingConfiguration.shared.messageDataProvider val messageDataProvider = MessagingConfiguration.shared.messageDataProvider
val attachmentPointer = messageDataProvider.getAttachmentPointer(attachmentID) ?: return handleFailure(Error.NoAttachment) val attachmentStream = messageDataProvider.getAttachmentStream(attachmentID) ?: return handleFailure(Error.NoAttachment)
messageDataProvider.setAttachmentState(AttachmentState.STARTED, attachmentID, this.tsIncomingMessageID) messageDataProvider.setAttachmentState(AttachmentState.STARTED, attachmentID, this.tsIncomingMessageID)
val tempFile = createTempFile() val tempFile = createTempFile()
val handleFailure: (java.lang.Exception) -> Unit = { exception -> val handleFailure: (java.lang.Exception) -> Unit = { exception ->
@ -51,19 +47,21 @@ class AttachmentDownloadJob(val attachmentID: Long, val tsIncomingMessageID: Lon
} }
} }
try { try {
//TODO find how to implement a functional interface in kotlin + use it here & on AttachmentUploadJob (see TODO in DatabaseAttachmentProvider.kt on app side) FileServerAPI.shared.downloadFile(tempFile, attachmentStream.url, MAX_ATTACHMENT_SIZE, attachmentStream.listener)
val listener = SessionServiceAttachment.ProgressListener { override fun onAttachmentProgress(total: Long, progress: Long) { EventBus.getDefault().postSticky(AttachmentProgressEvent(attachmentPointer, total, progress)) } }
FileServerAPI.shared.downloadFile(tempFile, attachmentPointer.url, MAX_ATTACHMENT_SIZE, listener)
} catch (e: Exception) { } catch (e: Exception) {
return handleFailure(e) return handleFailure(e)
} }
// DECRYPTION
// Assume we're retrieving an attachment for an open group server if the digest is not set // Assume we're retrieving an attachment for an open group server if the digest is not set
var stream = if (!attachmentPointer.digest.isPresent) FileInputStream(tempFile) var stream = if (!attachmentStream.digest.isPresent || attachmentStream.key == null) FileInputStream(tempFile)
else AttachmentCipherInputStream.createForAttachment(tempFile, attachmentPointer.size.or(0).toLong(), attachmentPointer.key?.toByteArray(), attachmentPointer.digest.get()) else AttachmentCipherInputStream.createForAttachment(tempFile, attachmentStream.length.or(0).toLong(), attachmentStream.key?.toByteArray(), attachmentStream?.digest.get())
messageDataProvider.insertAttachment(tsIncomingMessageID, attachmentID, stream) messageDataProvider.insertAttachment(tsIncomingMessageID, attachmentID, stream)
tempFile.delete()
} }
private fun handleSuccess() { private fun handleSuccess() {

@ -92,40 +92,12 @@ abstract class SessionServiceAttachment protected constructor(val contentType: S
} }
} }
/**
* An interface to receive progress information on upload/download of
* an attachment.
*/
/*interface ProgressListener {
/**
* Called on a progress change event.
*
* @param total The total amount to transmit/receive in bytes.
* @param progress The amount that has been transmitted/received in bytes thus far
*/
fun onAttachmentProgress(total: Long, progress: Long)
}*/
companion object { companion object {
@JvmStatic @JvmStatic
fun newStreamBuilder(): Builder { fun newStreamBuilder(): Builder {
return Builder() return Builder()
} }
} }
/**
* An interface to receive progress information on upload/download of
* an attachment.
*/
interface ProgressListener {
/**
* Called on a progress change event.
*
* @param total The total amount to transmit/receive in bytes.
* @param progress The amount that has been transmitted/received in bytes thus far
*/
fun onAttachmentProgress(total: Long, progress: Long)
}
} }
// matches values in AttachmentDatabase.java // matches values in AttachmentDatabase.java

@ -22,7 +22,7 @@ class SessionServiceAttachmentStream(val inputStream: InputStream?, contentType:
// Though now required, `digest` may be null for pre-existing records or from // Though now required, `digest` may be null for pre-existing records or from
// messages received from other clients // messages received from other clients
var digest: ByteArray? = null var digest: Optional<ByteArray> = Optional.absent()
// This only applies for attachments being uploaded. // This only applies for attachments being uploaded.
var isUploaded: Boolean = false var isUploaded: Boolean = false
@ -48,7 +48,7 @@ class SessionServiceAttachmentStream(val inputStream: InputStream?, contentType:
builder.size = this.length.toInt() builder.size = this.length.toInt()
builder.key = this.key builder.key = this.key
builder.digest = ByteString.copyFrom(this.digest) builder.digest = ByteString.copyFrom(this.digest.get())
builder.flags = if (this.voiceNote) SignalServiceProtos.AttachmentPointer.Flags.VOICE_MESSAGE.number else 0 builder.flags = if (this.voiceNote) SignalServiceProtos.AttachmentPointer.Flags.VOICE_MESSAGE.number else 0
//TODO I did copy the behavior of iOS below, not sure if that's relevant here... //TODO I did copy the behavior of iOS below, not sure if that's relevant here...

@ -185,7 +185,7 @@ open class DotNetAPI {
/** /**
* Blocks the calling thread. * Blocks the calling thread.
*/ */
fun downloadFile(destination: File, url: String, maxSize: Int, listener: SessionServiceAttachment.ProgressListener?) { fun downloadFile(destination: File, url: String, maxSize: Int, listener: SignalServiceAttachment.ProgressListener?) {
val outputStream = FileOutputStream(destination) // Throws val outputStream = FileOutputStream(destination) // Throws
var remainingAttempts = 4 var remainingAttempts = 4
var exception: Exception? = null var exception: Exception? = null
@ -205,7 +205,7 @@ open class DotNetAPI {
/** /**
* Blocks the calling thread. * Blocks the calling thread.
*/ */
fun downloadFile(outputStream: OutputStream, url: String, maxSize: Int, listener: SessionServiceAttachment.ProgressListener?) { fun downloadFile(outputStream: OutputStream, url: String, maxSize: Int, listener: SignalServiceAttachment.ProgressListener?) {
// We need to throw a PushNetworkException or NonSuccessfulResponseCodeException // We need to throw a PushNetworkException or NonSuccessfulResponseCodeException
// because the underlying Signal logic requires these to work correctly // because the underlying Signal logic requires these to work correctly
val oldPrefixedHost = "https://" + HttpUrl.get(url).host() val oldPrefixedHost = "https://" + HttpUrl.get(url).host()

Loading…
Cancel
Save