From 842f00ee546ada6ab33083d59412572229a6d328 Mon Sep 17 00:00:00 2001 From: Brice Date: Wed, 6 Jan 2021 16:11:00 +1100 Subject: [PATCH] downloadattachmentjob implementation --- .../attachments/DatabaseAttachmentProvider.kt | 12 +++++--- .../events/AttachmentProgressEvent.kt | 6 ---- .../messaging/jobs/AttachmentDownloadJob.kt | 18 ++++++------ .../attachments/SessionServiceAttachment.kt | 28 ------------------- .../SessionServiceAttachmentStream.kt | 4 +-- .../messaging/utilities/DotNetAPI.kt | 4 +-- 6 files changed, 20 insertions(+), 52 deletions(-) delete mode 100644 libsession/src/main/java/org/session/libsession/events/AttachmentProgressEvent.kt diff --git a/app/src/main/java/org/thoughtcrime/securesms/attachments/DatabaseAttachmentProvider.kt b/app/src/main/java/org/thoughtcrime/securesms/attachments/DatabaseAttachmentProvider.kt index cb60005f17..da4a20f9ff 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/attachments/DatabaseAttachmentProvider.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/attachments/DatabaseAttachmentProvider.kt @@ -2,14 +2,18 @@ package org.thoughtcrime.securesms.attachments import android.content.Context import com.google.protobuf.ByteString +import org.greenrobot.eventbus.EventBus 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.SessionServiceAttachmentPointer import org.session.libsession.messaging.sending_receiving.attachments.SessionServiceAttachmentStream 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.DatabaseFactory import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper +import org.thoughtcrime.securesms.events.PartProgressEvent import org.thoughtcrime.securesms.jobs.AttachmentUploadJob import org.thoughtcrime.securesms.mms.PartAuthority import org.thoughtcrime.securesms.util.MediaUtil @@ -58,7 +62,9 @@ fun DatabaseAttachment.toAttachmentPointer(): SessionServiceAttachmentPointer { fun DatabaseAttachment.toAttachmentStream(context: Context): SessionServiceAttachmentStream { 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.isAudio = MediaUtil.isAudio(this) attachmentStream.isGif = MediaUtil.isGif(this) @@ -66,12 +72,10 @@ fun DatabaseAttachment.toAttachmentStream(context: Context): SessionServiceAttac attachmentStream.isImage = MediaUtil.isImage(this) attachmentStream.key = ByteString.copyFrom(this.key?.toByteArray()) - attachmentStream.digest = this.digest + attachmentStream.digest = Optional.fromNullable(this.digest) attachmentStream.url = this.url - //TODO attachmentStream.listener - return attachmentStream } diff --git a/libsession/src/main/java/org/session/libsession/events/AttachmentProgressEvent.kt b/libsession/src/main/java/org/session/libsession/events/AttachmentProgressEvent.kt deleted file mode 100644 index 9a17652a57..0000000000 --- a/libsession/src/main/java/org/session/libsession/events/AttachmentProgressEvent.kt +++ /dev/null @@ -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) { -} \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentDownloadJob.kt b/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentDownloadJob.kt index c7d7347085..6289fcbf9c 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentDownloadJob.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentDownloadJob.kt @@ -1,14 +1,10 @@ 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.fileserver.FileServerAPI 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.libsignal.service.api.crypto.AttachmentCipherInputStream -import org.session.libsignal.service.api.messages.SignalServiceAttachment import java.io.File import java.io.FileInputStream @@ -33,7 +29,7 @@ class AttachmentDownloadJob(val attachmentID: Long, val tsIncomingMessageID: Lon override fun execute() { 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) val tempFile = createTempFile() val handleFailure: (java.lang.Exception) -> Unit = { exception -> @@ -51,19 +47,21 @@ class AttachmentDownloadJob(val attachmentID: Long, val tsIncomingMessageID: Lon } } try { - //TODO find how to implement a functional interface in kotlin + use it here & on AttachmentUploadJob (see TODO in DatabaseAttachmentProvider.kt on app side) - 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) + FileServerAPI.shared.downloadFile(tempFile, attachmentStream.url, MAX_ATTACHMENT_SIZE, attachmentStream.listener) } catch (e: Exception) { return handleFailure(e) } + // DECRYPTION + // 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) - else AttachmentCipherInputStream.createForAttachment(tempFile, attachmentPointer.size.or(0).toLong(), attachmentPointer.key?.toByteArray(), attachmentPointer.digest.get()) + var stream = if (!attachmentStream.digest.isPresent || attachmentStream.key == null) FileInputStream(tempFile) + else AttachmentCipherInputStream.createForAttachment(tempFile, attachmentStream.length.or(0).toLong(), attachmentStream.key?.toByteArray(), attachmentStream?.digest.get()) messageDataProvider.insertAttachment(tsIncomingMessageID, attachmentID, stream) + tempFile.delete() + } private fun handleSuccess() { diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/attachments/SessionServiceAttachment.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/attachments/SessionServiceAttachment.kt index 67e0ce0d49..e7686da4c2 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/attachments/SessionServiceAttachment.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/attachments/SessionServiceAttachment.kt @@ -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 { @JvmStatic fun newStreamBuilder(): 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 diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/attachments/SessionServiceAttachmentStream.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/attachments/SessionServiceAttachmentStream.kt index caebe874a6..43a851a787 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/attachments/SessionServiceAttachmentStream.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/attachments/SessionServiceAttachmentStream.kt @@ -22,7 +22,7 @@ class SessionServiceAttachmentStream(val inputStream: InputStream?, contentType: // Though now required, `digest` may be null for pre-existing records or from // messages received from other clients - var digest: ByteArray? = null + var digest: Optional = Optional.absent() // This only applies for attachments being uploaded. var isUploaded: Boolean = false @@ -48,7 +48,7 @@ class SessionServiceAttachmentStream(val inputStream: InputStream?, contentType: builder.size = this.length.toInt() 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 //TODO I did copy the behavior of iOS below, not sure if that's relevant here... diff --git a/libsession/src/main/java/org/session/libsession/messaging/utilities/DotNetAPI.kt b/libsession/src/main/java/org/session/libsession/messaging/utilities/DotNetAPI.kt index 43b2c8a6af..380b2d1248 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/utilities/DotNetAPI.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/utilities/DotNetAPI.kt @@ -185,7 +185,7 @@ open class DotNetAPI { /** * 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 var remainingAttempts = 4 var exception: Exception? = null @@ -205,7 +205,7 @@ open class DotNetAPI { /** * 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 // because the underlying Signal logic requires these to work correctly val oldPrefixedHost = "https://" + HttpUrl.get(url).host()